CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/login_scanner/kerberos.rb
Views: 1904
1
require 'metasploit/framework/login_scanner/base'
2
3
module Metasploit
4
module Framework
5
module LoginScanner
6
7
# Kerberos User scanner
8
class Kerberos
9
include Metasploit::Framework::LoginScanner::Base
10
include Msf::Exploit::Remote::Kerberos::Client
11
12
DEFAULT_PORT = 88
13
REALM_KEY = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN
14
DEFAULT_REALM = nil
15
LIKELY_PORTS = [ DEFAULT_PORT ].freeze
16
LIKELY_SERVICE_NAMES = [ 'kerberos', 'kerberos5', 'krb5', 'kerberos-sec' ].freeze
17
PRIVATE_TYPES = %i[ password ].freeze
18
CAN_GET_SESSION = true
19
20
def attempt_login(credential)
21
result_options = {
22
credential: credential,
23
host: host,
24
port: port,
25
protocol: 'tcp',
26
service_name: 'kerberos'
27
}
28
29
begin
30
res = send_request_tgt(
31
server_name: server_name,
32
client_name: credential.public,
33
password: credential.private,
34
realm: credential.realm
35
)
36
unless res.preauth_required
37
# Pre-auth not required - let's get an RC4-HMAC ticket, since it's more easily crackable
38
begin
39
res = send_request_tgt(
40
server_name: server_name,
41
client_name: credential.public,
42
password: credential.private,
43
realm: credential.realm,
44
offered_etypes: [Rex::Proto::Kerberos::Crypto::Encryption::RC4_HMAC]
45
)
46
rescue Rex::Proto::Kerberos::Model::Error::KerberosEncryptionNotSupported => e
47
# RC4 likely disabled - let's just use the initial response
48
end
49
end
50
51
result_options = result_options.merge(
52
{
53
status: Metasploit::Model::Login::Status::SUCCESSFUL,
54
proof: res
55
}
56
)
57
return Metasploit::Framework::LoginScanner::Result.new(result_options)
58
rescue ::EOFError => e
59
result_options = result_options.merge({ status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e })
60
return Metasploit::Framework::LoginScanner::Result.new(result_options)
61
rescue Rex::Proto::Kerberos::Model::Error::KerberosError => e
62
status = self.class.login_status_for_kerberos_error(e)
63
result_options = result_options.merge({ status: status, proof: e })
64
return Metasploit::Framework::LoginScanner::Result.new(result_options)
65
end
66
end
67
68
attr_accessor :server_name
69
70
# Override the kerberos client's methods with the login scanner implementations
71
alias rhost host
72
alias rport port
73
alias timeout connection_timeout
74
75
# @param [Rex::Proto::Kerberos::Model::Error::KerberosError] krb_err The kerberos error
76
def self.login_status_for_kerberos_error(krb_err)
77
error_code = krb_err.error_code
78
case error_code
79
when Rex::Proto::Kerberos::Model::Error::ErrorCodes::KDC_ERR_KEY_EXPIRED, Rex::Proto::Kerberos::Model::Error::ErrorCodes::KRB_AP_ERR_SKEW
80
# Correct password, but either password needs resetting or clock is skewed
81
Metasploit::Model::Login::Status::SUCCESSFUL
82
when Rex::Proto::Kerberos::Model::Error::ErrorCodes::KDC_ERR_C_PRINCIPAL_UNKNOWN
83
# The username doesn't exist
84
Metasploit::Model::Login::Status::INVALID_PUBLIC_PART
85
when Rex::Proto::Kerberos::Model::Error::ErrorCodes::KDC_ERR_CLIENT_REVOKED
86
# Locked out, disabled or expired
87
# It doesn't appear to be documented anywhere, but Microsoft gives us a bit
88
# of extra information in the e-data section
89
begin
90
pa_data_entry = krb_err.res.e_data_as_pa_data_entry
91
if pa_data_entry && pa_data_entry.type == Rex::Proto::Kerberos::Model::PreAuthType::PA_PW_SALT
92
pw_salt = pa_data_entry.decoded_value
93
if pw_salt.nt_status
94
case pw_salt.nt_status.value
95
when ::WindowsError::NTStatus::STATUS_ACCOUNT_LOCKED_OUT
96
Metasploit::Model::Login::Status::LOCKED_OUT
97
when ::WindowsError::NTStatus::STATUS_ACCOUNT_DISABLED
98
Metasploit::Model::Login::Status::DISABLED
99
when ::WindowsError::NTStatus::STATUS_ACCOUNT_EXPIRED
100
# Actually expired, which is effectively Disabled
101
Metasploit::Model::Login::Status::DISABLED
102
else
103
# Unknown - maintain existing behaviour
104
Metasploit::Model::Login::Status::DISABLED
105
end
106
else
107
Metasploit::Model::Login::Status::DISABLED
108
end
109
else
110
Metasploit::Model::Login::Status::DISABLED
111
end
112
rescue Rex::Proto::Kerberos::Model::Error::KerberosDecodingError
113
# Could be a non-MS implementation?
114
Metasploit::Model::Login::Status::DISABLED
115
end
116
else
117
Metasploit::Model::Login::Status::INCORRECT
118
end
119
end
120
121
private
122
123
def set_sane_defaults
124
self.connection_timeout = 10 if self.connection_timeout.nil?
125
self.port = DEFAULT_PORT unless self.port
126
end
127
128
def print_status(*args)
129
framework_module.print_status(*args) if framework_module
130
end
131
132
def print_good(*args)
133
framework_module.print_good(*args) if framework_module
134
end
135
136
def vprint_status(*args)
137
framework_module.vprint_status(*args) if framework_module
138
end
139
end
140
end
141
end
142
end
143
144