CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/ldap/client.rb
Views: 11784
1
# frozen_string_literal: true
2
3
require 'rex/proto/ldap/auth_adapter'
4
5
module Metasploit
6
module Framework
7
module LDAP
8
9
module Client
10
def ldap_connect_opts(rhost, rport, connect_timeout, ssl: true, opts: {})
11
connect_opts = {
12
host: rhost,
13
port: rport,
14
connect_timeout: connect_timeout,
15
proxies: opts[:proxies]
16
}
17
18
if ssl
19
connect_opts[:encryption] = {
20
method: :simple_tls,
21
tls_options: {
22
verify_mode: OpenSSL::SSL::VERIFY_NONE
23
}
24
}
25
end
26
27
case opts[:ldap_auth]
28
when Msf::Exploit::Remote::AuthOption::SCHANNEL
29
connect_opts.merge!(ldap_auth_opts_schannel(opts, ssl))
30
when Msf::Exploit::Remote::AuthOption::KERBEROS
31
connect_opts.merge!(ldap_auth_opts_kerberos(opts, ssl))
32
when Msf::Exploit::Remote::AuthOption::NTLM
33
connect_opts.merge!(ldap_auth_opts_ntlm(opts, ssl))
34
when Msf::Exploit::Remote::AuthOption::PLAINTEXT
35
connect_opts.merge!(ldap_auth_opts_plaintext(opts))
36
when Msf::Exploit::Remote::AuthOption::AUTO
37
if opts[:username].present? && opts[:domain].present?
38
connect_opts.merge!(ldap_auth_opts_ntlm(opts, ssl))
39
elsif opts[:username].present?
40
connect_opts.merge!(ldap_auth_opts_plaintext(opts))
41
end
42
end
43
44
connect_opts
45
end
46
47
private
48
49
def ldap_auth_opts_kerberos(opts, ssl)
50
auth_opts = {}
51
raise Msf::ValidationError, 'The LDAP::Rhostname option is required when using Kerberos authentication.' if opts[:ldap_rhostname].blank?
52
raise Msf::ValidationError, 'The DOMAIN option is required when using Kerberos authentication.' if opts[:domain].blank?
53
54
offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(opts[:ldap_krb_offered_enc_types])
55
raise Msf::ValidationError, 'At least one encryption type is required when using Kerberos authentication.' if offered_etypes.empty?
56
57
sign_and_seal = opts.fetch(:sign_and_seal, !ssl)
58
kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::LDAP.new(
59
host: opts[:domain_controller_rhost].blank? ? nil : opts[:domain_controller_rhost],
60
hostname: opts[:ldap_rhostname],
61
realm: opts[:domain],
62
username: opts[:username],
63
password: opts[:password],
64
framework: opts[:framework],
65
framework_module: opts[:framework_module],
66
cache_file: opts[:ldap_krb5_cname].blank? ? nil : opts[:ldap_krb5_cname],
67
ticket_storage: opts[:kerberos_ticket_storage],
68
offered_etypes: offered_etypes,
69
mutual_auth: true,
70
use_gss_checksum: sign_and_seal || ssl
71
)
72
73
auth_opts[:auth] = {
74
method: :rex_kerberos,
75
kerberos_authenticator: kerberos_authenticator,
76
sign_and_seal: sign_and_seal
77
}
78
79
auth_opts
80
end
81
82
def ldap_auth_opts_ntlm(opts, ssl)
83
auth_opts = {}
84
85
auth_opts[:auth] = {
86
# use the rex one provided by us to support TLS channel binding (see: ruby-ldap/ruby-net-ldap#407) and blank
87
# passwords (see: WinRb/rubyntlm#45)
88
method: :rex_ntlm,
89
username: opts[:username],
90
password: opts[:password],
91
domain: opts[:domain],
92
workstation: 'WORKSTATION',
93
sign_and_seal: opts.fetch(:sign_and_seal, !ssl)
94
}
95
96
auth_opts
97
end
98
99
def ldap_auth_opts_plaintext(opts)
100
auth_opts = {}
101
raise Msf::ValidationError, 'Can not sign and seal when using Plaintext authentication.' if opts.fetch(:sign_and_seal, false)
102
103
auth_opts[:auth] = {
104
method: :simple,
105
username: opts[:username],
106
password: opts[:password]
107
}
108
auth_opts
109
end
110
111
def ldap_auth_opts_schannel(opts, ssl)
112
auth_opts = {}
113
pfx_path = opts[:ldap_cert_file]
114
raise Msf::ValidationError, 'The SSL option must be enabled when using Schannel authentication.' unless ssl
115
raise Msf::ValidationError, 'The LDAP::CertFile option is required when using Schannel authentication.' if pfx_path.blank?
116
raise Msf::ValidationError, 'Can not sign and seal when using Schannel authentication.' if opts.fetch(:sign_and_seal, false)
117
118
unless ::File.file?(pfx_path) && ::File.readable?(pfx_path)
119
raise Msf::ValidationError, 'Failed to load the PFX certificate file. The path was not a readable file.'
120
end
121
122
begin
123
pkcs = OpenSSL::PKCS12.new(File.binread(pfx_path), '')
124
rescue StandardError => e
125
raise Msf::ValidationError, "Failed to load the PFX file (#{e})"
126
end
127
128
auth_opts[:auth] = {
129
method: :sasl,
130
mechanism: 'EXTERNAL',
131
initial_credential: '',
132
challenge_response: true
133
}
134
auth_opts[:encryption] = {
135
method: :start_tls,
136
tls_options: {
137
verify_mode: OpenSSL::SSL::VERIFY_NONE,
138
cert: pkcs.certificate,
139
key: pkcs.key
140
}
141
}
142
auth_opts
143
end
144
end
145
end
146
end
147
end
148
149