8e94fd55db
Thanks, @HynekPetrak!
90 lines
1.7 KiB
Ruby
90 lines
1.7 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
#
|
|
# This mixin is a wrapper around Net::LDAP
|
|
#
|
|
|
|
require 'net-ldap'
|
|
|
|
module Msf
|
|
module Exploit::Remote::LDAP
|
|
|
|
def initialize(info = {})
|
|
super
|
|
|
|
register_options([
|
|
Opt::RHOST,
|
|
Opt::RPORT(389),
|
|
OptBool.new('SSL', [false, 'Enable SSL on the LDAP connection', false])
|
|
])
|
|
|
|
register_advanced_options([
|
|
OptFloat.new('ConnectTimeout', [true, 'Timeout for LDAP connect', 10.0])
|
|
])
|
|
end
|
|
|
|
def rhost
|
|
datastore['RHOST']
|
|
end
|
|
|
|
def rport
|
|
datastore['RPORT']
|
|
end
|
|
|
|
def peer
|
|
"#{rhost}:#{rport}"
|
|
end
|
|
|
|
def ldap_connect(opts = {}, &block)
|
|
connect_opts = {
|
|
host: rhost,
|
|
port: rport,
|
|
connect_timeout: datastore['ConnectTimeout']
|
|
}
|
|
|
|
if datastore['SSL']
|
|
connect_opts[:encryption] = {
|
|
method: :simple_tls,
|
|
tls_options: {
|
|
verify_mode: OpenSSL::SSL::VERIFY_NONE
|
|
}
|
|
}
|
|
end
|
|
|
|
Net::LDAP.open(connect_opts.merge(opts), &block)
|
|
end
|
|
|
|
def discover_base_dn(ldap)
|
|
print_status('Searching root DSE for base DN')
|
|
|
|
unless (root_dse = ldap.search_root_dse)
|
|
print_error('Could not retrieve root DSE')
|
|
return
|
|
end
|
|
|
|
vprint_line(root_dse.to_ldif)
|
|
|
|
# NOTE: Net::LDAP converts attribute names to lowercase
|
|
unless root_dse[:namingcontexts]
|
|
print_error('Could not find namingContexts attribute')
|
|
return
|
|
end
|
|
|
|
if root_dse[:namingcontexts].empty?
|
|
print_error('Could not find base DN')
|
|
return
|
|
end
|
|
|
|
# NOTE: We assume the first namingContexts value is the base DN
|
|
base_dn = root_dse[:namingcontexts].first
|
|
|
|
print_good("Discovered base DN: #{base_dn}")
|
|
base_dn
|
|
rescue Net::LDAP::Error => e
|
|
print_error("#{e.class}: #{e.message}")
|
|
nil
|
|
end
|
|
|
|
end
|
|
end
|