Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions lib/metasploit/framework/ldap/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,11 @@ def ldap_auth_opts_plaintext(opts)

def ldap_auth_opts_schannel(opts, ssl)
auth_opts = {}
pfx_path = opts[:ldap_cert_file]
raise Msf::ValidationError, 'The SSL option must be enabled when using Schannel authentication.' unless ssl
raise Msf::ValidationError, 'Can not sign and seal when using Schannel authentication.' if opts.fetch(:sign_and_seal, false)

if pfx_path.present?
unless ::File.file?(pfx_path) && ::File.readable?(pfx_path)
raise Msf::ValidationError, 'Failed to load the PFX certificate file. The path was not a readable file.'
end

begin
pkcs = OpenSSL::PKCS12.new(File.binread(pfx_path), '')
rescue StandardError => e
raise Msf::ValidationError, "Failed to load the PFX file (#{e})"
end
if opts[:ldap_pkcs12].present?
pkcs = opts[:ldap_pkcs12][:value]
else
pkcs12_storage = Msf::Exploit::Remote::Pkcs12::Storage.new(
framework: opts[:framework],
Expand Down
3 changes: 2 additions & 1 deletion lib/msf/core/exploit/remote/ldap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,15 @@ def peer
# @return [Hash] The options to use when connecting to the target
# LDAP server.
def get_connect_opts
pkcs12_storage = Msf::Exploit::Remote::Pkcs12::Storage.new(framework: framework, framework_module: self)
opts = {
username: datastore['LDAPUsername'],
password: datastore['LDAPPassword'],
domain: datastore['LDAPDomain'],
base: datastore['BASE_DN'],
domain_controller_rhost: datastore['DomainControllerRhost'],
ldap_auth: datastore['LDAP::Auth'],
ldap_cert_file: datastore['LDAP::CertFile'],
ldap_pkcs12: datastore['LDAP::CertFile'] ? pkcs12_storage.read_pkcs12_cert_path(datastore['LDAP::CertFile']) : nil,
ldap_rhostname: datastore['LDAP::Rhostname'],
ldap_krb_offered_enc_types: datastore['LDAP::KrbOfferedEncryptionTypes'],
ldap_krb5_cname: datastore['LDAP::Krb5Ccname'],
Expand Down
17 changes: 17 additions & 0 deletions lib/msf/core/exploit/remote/pkcs12/storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ def initialize(framework: nil, framework_module: nil)
@framework_module = framework_module
end

# @param [String] cert_path A path to the file system where a pkcs12 cert is located, or a reference to a core database i.e., "id:123"
# @param [String] cert_pass The certificate password
# @param [String] workspace The workspace to restrict searches to
def read_pkcs12_cert_path(cert_path, cert_pass = '', workspace: nil)
is_readable = ::File.file?(cert_path) && ::File.readable?(cert_path)
raise Msf::ValidationError, 'Failed to load the PFX certificate file. The path was not a readable file.' unless is_readable
data = File.binread(cert_path)

begin
pkcs12 = OpenSSL::PKCS12.new(data, cert_pass)
rescue StandardError => e
raise Msf::ValidationError, "Failed to load the PFX file (#{e})"
end

{ path: cert_path, value: pkcs12 }
end

# Get stored pkcs12 matching the options query.
#
# @param [Hash] options The options for matching pkcs12's.
Expand Down
8 changes: 2 additions & 6 deletions modules/auxiliary/admin/kerberos/get_ticket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,8 @@ def initialize(info = {})

def validate_options
if datastore['CERT_FILE'].present?
certificate = File.binread(datastore['CERT_FILE'])
begin
@pfx = OpenSSL::PKCS12.new(certificate, datastore['CERT_PASSWORD'] || '')
rescue OpenSSL::PKCS12::PKCS12Error => e
fail_with(Failure::BadConfig, "Unable to parse certificate file (#{e})")
end
pkcs12_storage = Msf::Exploit::Remote::Pkcs12::Storage.new(framework: framework, framework_module: self)
@pfx = pkcs12_storage.read_pkcs12_cert_path(datastore['CERT_FILE'], datastore['CERT_PASSWORD'], workspace: workspace)[:value]

if datastore['USERNAME'].blank? && datastore['DOMAIN'].present?
fail_with(Failure::BadConfig, 'Domain override provided but no username override provided (must provide both or neither)')
Expand Down
5 changes: 3 additions & 2 deletions modules/auxiliary/scanner/ldap/ldap_login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ def run_host(ip)
ignore_private: ignore_private
)

pkcs12_storage = Msf::Exploit::Remote::Pkcs12::Storage.new(framework: framework, framework_module: self)
opts = {
domain: datastore['LDAPDomain'],
append_domain: datastore['APPEND_DOMAIN'],
ssl: datastore['SSL'],
proxies: datastore['PROXIES'],
domain_controller_rhost: datastore['DomainControllerRhost'],
ldap_auth: datastore['LDAP::Auth'],
ldap_cert_file: datastore['LDAP::CertFile'],
ldap_pkcs12: datastore['LDAP::CertFile'] ? pkcs12_storage.read_pkcs12_cert_path(datastore['LDAP::CertFile']) : nil,
ldap_rhostname: datastore['Ldap::Rhostname'],
ldap_krb_offered_enc_types: datastore['Ldap::KrbOfferedEncryptionTypes'],
ldap_krb5_cname: datastore['Ldap::Krb5Ccname']
Expand Down Expand Up @@ -167,7 +168,7 @@ def run_host(ip)
successful_logins << result
if opts[:ldap_auth] == Msf::Exploit::Remote::AuthOption::SCHANNEL
# Schannel auth has no meaningful credential information to store in the DB
msg = opts[:ldap_cert_file].nil? ? 'Using stored certificate' : "Cert File #{opts[:ldap_cert_file]}"
msg = opts[:ldap_pkcs12].nil? ? 'Using stored certificate' : "Cert File #{opts[:ldap_pkcs12][:path]} (#{opts[:ldap_pkcs12][:value].certificate.subject})"
print_brute level: :good, ip: ip, msg: "Success: '#{msg}'"
else
create_credential_and_login(credential_data) if result.credential.private
Expand Down
Loading