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
2 changes: 2 additions & 0 deletions .github/workflows/ldap_acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ on:
- 'metsploit-framework.gemspec'
- 'Gemfile.lock'
- '**/**ldap**'
- 'lib/metasploit/framework/tcp/**'
- 'lib/metasploit/framework/login_scanner/**'
- 'spec/acceptance/**'
- 'spec/support/acceptance/**'
- 'spec/acceptance_spec_helper.rb'
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/postgres_acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ on:
- 'metsploit-framework.gemspec'
- 'Gemfile.lock'
- '**/**postgres**'
- 'lib/metasploit/framework/tcp/**'
- 'lib/metasploit/framework/login_scanner/**'
- 'spec/acceptance/**'
- 'spec/support/acceptance/**'
- 'spec/acceptance_spec_helper.rb'
Expand Down
3 changes: 3 additions & 0 deletions lib/metasploit/framework/login_scanner/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ module Base
# @!attribute bruteforce_speed
# @return [Integer] The desired speed, with 5 being 'fast' and 0 being 'slow.'
attr_accessor :bruteforce_speed
# @!attribute sslkeylogfile
# @return [String] The SSL key log file path
attr_accessor :sslkeylogfile

validates :connection_timeout,
presence: true,
Expand Down
2 changes: 1 addition & 1 deletion lib/metasploit/framework/login_scanner/mssql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def attempt_login(credential)
}

begin
client = Rex::Proto::MSSQL::Client.new(framework_module, framework, host, port, proxies)
client = Rex::Proto::MSSQL::Client.new(framework_module, framework, host, port, proxies, sslkeylogfile: sslkeylogfile)
if client.mssql_login(credential.public, credential.private, '', credential.realm)
result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL
if use_client_as_proof
Expand Down
20 changes: 19 additions & 1 deletion lib/metasploit/framework/mssql/tdssslproxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ class TDSSSLProxy
TYPE_PRE_LOGIN_MESSAGE = 18
STATUS_END_OF_MESSAGE = 0x01

def initialize(sock)
def initialize(sock, sslkeylogfile: nil)
@tdssock = sock
@sslkeylogfile = sslkeylogfile
@s1, @s2 = Rex::Socket.tcp_socket_pair
end

Expand All @@ -48,10 +49,27 @@ def cleanup
@t1.join
end

def write_to_keylog_file(ctx, sslkeylogfile)
# writing to the sslkeylogfile is required, it adds support for network capture decryption which is useful to
# decrypt TLS traffic in wireshark
if sslkeylogfile
unless ctx.respond_to?(:keylog_cb)
raise 'Unable to create sslkeylogfile - Ruby 3.2 or above required for this functionality'
end

ctx.keylog_cb = proc do |_sock, line|
File.open(sslkeylogfile, 'ab') do |file|
file.write("#{line}\n")
end
end
end
end

def setup_ssl
@running = true
@t1 = Thread.start { ssl_setup_thread }
ctx = OpenSSL::SSL::SSLContext.new(:SSLv23)
write_to_keylog_file(ctx, @sslkeylogfile)
ctx.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:!SSLv3:+HIGH:+MEDIUM"
@ssl_socket = OpenSSL::SSL::SSLSocket.new(@s1, ctx)
@ssl_socket.connect
Expand Down
1 change: 1 addition & 0 deletions lib/metasploit/framework/tcp/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def connect(global = true, opts={})
'SSL' => dossl,
'SSLVersion' => opts['SSLVersion'] || ssl_version,
'SSLVerifyMode' => opts['SSLVerifyMode'] || ssl_verify_mode,
'SSLKeyLogFile' => opts['SSLKeyLogFile'] || sslkeylogfile,
'SSLCipher' => opts['SSLCipher'] || ssl_cipher,
'Proxies' => proxies,
'Timeout' => (opts['ConnectTimeout'] || connection_timeout || 10).to_i,
Expand Down
1 change: 1 addition & 0 deletions lib/msf/core/auxiliary/auth_brute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def initialize(info = {})
OptBool.new('REMOVE_USERPASS_FILE', [ true, "Automatically delete the USERPASS_FILE on module completion", false]),
OptBool.new('PASSWORD_SPRAY', [true, "Reverse the credential pairing order. For each password, attempt every possible user.", false]),
OptInt.new('TRANSITION_DELAY', [false, "Amount of time (in minutes) to delay before transitioning to the next user in the array (or password when PASSWORD_SPRAY=true)", 0]),
OptString.new('SSLKeyLogFile', [ false, 'The SSL key log file', ENV['SSLKeyLogFile']]),
OptInt.new('MaxGuessesPerService', [ false, "Maximum number of credentials to try per service instance. If set to zero or a non-number, this option will not be used.", 0]), # Tracked in @@guesses_per_service
OptInt.new('MaxMinutesPerService', [ false, "Maximum time in minutes to bruteforce the service instance. If set to zero or a non-number, this option will not be used.", 0]), # Tracked in @@brute_start_time
OptInt.new('MaxGuessesPerUser', [ false, %q{
Expand Down
10 changes: 7 additions & 3 deletions lib/rex/proto/mssql/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class Client
attr_accessor :ssl_version
attr_accessor :ssl_verify_mode
attr_accessor :ssl_cipher
# @!attribute sslkeylogfile
# @return [String] The SSL key log file path
attr_accessor :sslkeylogfile
attr_accessor :proxies
attr_accessor :connection_timeout
attr_accessor :send_lm
Expand All @@ -50,7 +53,7 @@ class Client
# @return [String] The database name this client is currently connected to.
attr_accessor :current_database

def initialize(framework_module, framework, rhost, rport = 1433, proxies = nil)
def initialize(framework_module, framework, rhost, rport = 1433, proxies = nil, sslkeylogfile: nil)
@framework_module = framework_module
@framework = framework
@connection_timeout = framework_module.datastore['ConnectTimeout'] || 30
Expand All @@ -68,6 +71,7 @@ def initialize(framework_module, framework, rhost, rport = 1433, proxies = nil)
@rhost = rhost
@rport = rport
@proxies = proxies
@sslkeylogfile = sslkeylogfile
@current_database = ''
end

Expand Down Expand Up @@ -336,7 +340,7 @@ def mssql_login(user='sa', pass='', db='', domain_name='')
# upon receiving the ntlm_negociate request it send an ntlm_challenge but the status flag of the tds packet header
# is set to STATUS_NORMAL and not STATUS_END_OF_MESSAGE, then internally it waits for the ntlm_authentification
if tdsencryption == true
proxy = TDSSSLProxy.new(sock)
proxy = TDSSSLProxy.new(sock, sslkeylogfile: sslkeylogfile)
proxy.setup_ssl
resp = proxy.send_recv(pkt)
else
Expand Down Expand Up @@ -454,7 +458,7 @@ def mssql_login(user='sa', pass='', db='', domain_name='')
pkt = "\x10\x01" + [pkt.length + 8].pack('n') + [0].pack('n') + [1].pack('C') + "\x00" + pkt

if self.tdsencryption == true
proxy = TDSSSLProxy.new(sock)
proxy = TDSSSLProxy.new(sock, sslkeylogfile: sslkeylogfile)
proxy.setup_ssl
resp = mssql_ssl_send_recv(pkt, proxy)
proxy.cleanup
Expand Down
Loading