From 87b84b00fb2bd4a3aef40e0b917e829654e71a4c Mon Sep 17 00:00:00 2001 From: Dean Welch Date: Fri, 5 Apr 2024 11:32:12 +0100 Subject: [PATCH] Don't close sockets that we're using for sessions --- .../framework/login_scanner/mssql.rb | 1 + .../framework/login_scanner/mysql.rb | 5 ++-- .../framework/login_scanner/postgres.rb | 2 +- lib/metasploit/framework/login_scanner/smb.rb | 7 +++++- .../auxiliary/scanner/mssql/mssql_login.rb | 23 ++++++++++--------- .../auxiliary/scanner/mysql/mysql_login.rb | 20 ++++++++-------- .../scanner/postgres/postgres_login.rb | 22 +++++++++--------- modules/auxiliary/scanner/smb/smb_login.rb | 23 ++++++------------- 8 files changed, 50 insertions(+), 53 deletions(-) diff --git a/lib/metasploit/framework/login_scanner/mssql.rb b/lib/metasploit/framework/login_scanner/mssql.rb index a1e5a1195d26..e56699fa6068 100644 --- a/lib/metasploit/framework/login_scanner/mssql.rb +++ b/lib/metasploit/framework/login_scanner/mssql.rb @@ -82,6 +82,7 @@ def attempt_login(credential) result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL if use_client_as_proof result_options[:proof] = client + result_options[:connection] = client.sock else client.disconnect end diff --git a/lib/metasploit/framework/login_scanner/mysql.rb b/lib/metasploit/framework/login_scanner/mysql.rb index 3c64deca5f00..ebdd00b2403d 100644 --- a/lib/metasploit/framework/login_scanner/mysql.rb +++ b/lib/metasploit/framework/login_scanner/mysql.rb @@ -37,7 +37,7 @@ def attempt_login(credential) begin # manage our behind the scenes socket. Close any existing one and open a new one disconnect if self.sock - self.sock = connect + connect mysql_conn = ::Rex::Proto::MySQL::Client.connect(host, credential.public, credential.private, '', port, io: self.sock) @@ -75,7 +75,8 @@ def attempt_login(credential) # Additionally assign values to nil to avoid closing the socket etc automatically if use_client_as_proof result_options[:proof] = mysql_conn - nil + result_options[:connection] = self.sock + self.sock = nil else mysql_conn.close end diff --git a/lib/metasploit/framework/login_scanner/postgres.rb b/lib/metasploit/framework/login_scanner/postgres.rb index 6baf981a9214..68f90560f134 100644 --- a/lib/metasploit/framework/login_scanner/postgres.rb +++ b/lib/metasploit/framework/login_scanner/postgres.rb @@ -80,7 +80,7 @@ def attempt_login(credential) # Additionally assign values to nil to avoid closing the socket etc automatically if use_client_as_proof result_options[:proof] = pg_conn - pg_conn = nil + result_options[:connection] = pg_conn.conn else pg_conn.close end diff --git a/lib/metasploit/framework/login_scanner/smb.rb b/lib/metasploit/framework/login_scanner/smb.rb index 955bba993b56..81d10b3182c9 100644 --- a/lib/metasploit/framework/login_scanner/smb.rb +++ b/lib/metasploit/framework/login_scanner/smb.rb @@ -152,6 +152,7 @@ def attempt_login(credential) # Additionally assign values to nil to avoid closing the socket etc automatically if use_client_as_proof proof = client + connection = self.sock client = nil self.sock = nil self.dispatcher = nil @@ -184,7 +185,11 @@ def attempt_login(credential) access_level ||= AccessLevels::GUEST end - result = Result.new(credential: credential, status: status, proof: proof, access_level: access_level) + result = Result.new(credential: credential, + status: status, + proof: proof, + access_level: access_level, + connection: connection) result.host = host result.port = port result.protocol = 'tcp' diff --git a/modules/auxiliary/scanner/mssql/mssql_login.rb b/modules/auxiliary/scanner/mssql/mssql_login.rb index bfaf205cd28e..7ff2bc0e8628 100644 --- a/modules/auxiliary/scanner/mssql/mssql_login.rb +++ b/modules/auxiliary/scanner/mssql/mssql_login.rb @@ -132,12 +132,11 @@ def run_host(ip) if create_session? begin - mssql_client = result.proof - successful_sessions << session_setup(result, mssql_client) + successful_sessions << session_setup(result) rescue ::StandardError => e - elog('Failed: ', error: e) - print_error(e) - result.proof.conn.close if result.proof&.conn + elog('Failed to setup the session', error: e) + print_brute level: :error, ip: ip, msg: "Failed to setup the session - #{e.class} #{e.message}" + result.connection.close unless result.connection.nil? end end else @@ -148,11 +147,13 @@ def run_host(ip) { successful_logins: successful_logins, successful_sessions: successful_sessions } end - def session_setup(result, client) - return unless (result && client) - rstream = client.sock - my_session = Msf::Sessions::MSSQL.new(rstream, { client: client }) - merging = { + # @param [Metasploit::Framework::LoginScanner::Result] result + # @return [Msf::Sessions::MSSQL] + def session_setup(result) + return unless (result.connection && result.proof) + + my_session = Msf::Sessions::MSSQL.new(result.connection, { client: result.proof }) + merge_me = { 'USERPASS_FILE' => nil, 'USER_FILE' => nil, 'PASS_FILE' => nil, @@ -160,6 +161,6 @@ def session_setup(result, client) 'PASSWORD' => result.credential.private } - start_session(self, nil, merging, false, my_session.rstream, my_session) + start_session(self, nil, merge_me, false, my_session.rstream, my_session) end end diff --git a/modules/auxiliary/scanner/mysql/mysql_login.rb b/modules/auxiliary/scanner/mysql/mysql_login.rb index 49bf6b4f7d0d..0c9486965b9c 100644 --- a/modules/auxiliary/scanner/mysql/mysql_login.rb +++ b/modules/auxiliary/scanner/mysql/mysql_login.rb @@ -120,12 +120,11 @@ def run_host(ip) if create_session? begin - mysql_client = result.proof - successful_sessions << session_setup(result, mysql_client) + successful_sessions << session_setup(result) rescue ::StandardError => e - elog('Failed: ', error: e) - print_error(e) - result.proof.conn.close if result.proof&.conn + elog('Failed to setup the session', error: e) + print_brute level: :error, ip: ip, msg: "Failed to setup the session - #{e.class} #{e.message}" + result.connection.close unless result.connection.nil? end end else @@ -195,13 +194,12 @@ def int_version(str) end # @param [Metasploit::Framework::LoginScanner::Result] result - # @param [::Rex::Proto::MySQL::Client] client # @return [Msf::Sessions::MySQL] - def session_setup(result, client) - return unless (result && client) + def session_setup(result) + return unless (result.connection && result.proof) - my_session = Msf::Sessions::MySQL.new(client.io, { client: client }) - merging = { + my_session = Msf::Sessions::MySQL.new(result.connection, { client: result.proof }) + merge_me = { 'USERPASS_FILE' => nil, 'USER_FILE' => nil, 'PASS_FILE' => nil, @@ -209,6 +207,6 @@ def session_setup(result, client) 'PASSWORD' => result.credential.private } - start_session(self, nil, merging, false, my_session.rstream, my_session) + start_session(self, nil, merge_me, false, my_session.rstream, my_session) end end diff --git a/modules/auxiliary/scanner/postgres/postgres_login.rb b/modules/auxiliary/scanner/postgres/postgres_login.rb index ea240104dae1..96c7bb587690 100644 --- a/modules/auxiliary/scanner/postgres/postgres_login.rb +++ b/modules/auxiliary/scanner/postgres/postgres_login.rb @@ -116,12 +116,11 @@ def run_host(ip) if create_session? begin - postgresql_client = result.proof - successful_sessions << session_setup(result, postgresql_client) + successful_sessions << session_setup(result) rescue ::StandardError => e - elog('Failed: ', error: e) - print_error(e) - result.proof.conn.close if result.proof&.conn + elog('Failed to setup the session', error: e) + print_brute level: :error, ip: ip, msg: "Failed to setup the session - #{e.class} #{e.message}" + result.connection.close unless result.connection.nil? end end else @@ -142,12 +141,13 @@ def rport datastore['RPORT'] end - def session_setup(result, client) - return unless (result && client) + # @param [Metasploit::Framework::LoginScanner::Result] result + # @return [Msf::Sessions::PostgreSQL] + def session_setup(result) + return unless (result.connection && result.proof) - rstream = client.conn - my_session = Msf::Sessions::PostgreSQL.new(rstream, { client: client }) - merging = { + my_session = Msf::Sessions::PostgreSQL.new(result.connection, { client: result.proof }) + merge_me = { 'USERPASS_FILE' => nil, 'USER_FILE' => nil, 'PASS_FILE' => nil, @@ -155,6 +155,6 @@ def session_setup(result, client) 'PASSWORD' => result.credential.private } - start_session(self, nil, merging, false, my_session.rstream, my_session) + start_session(self, nil, merge_me, false, my_session.rstream, my_session) end end diff --git a/modules/auxiliary/scanner/smb/smb_login.rb b/modules/auxiliary/scanner/smb/smb_login.rb index effac65894df..a2c1388e3b5d 100644 --- a/modules/auxiliary/scanner/smb/smb_login.rb +++ b/modules/auxiliary/scanner/smb/smb_login.rb @@ -191,11 +191,11 @@ def run_host(ip) report_creds(ip, rport, result) if create_session? begin - smb_client = result.proof - successful_sessions << session_setup(result, smb_client) - rescue StandardError => e + successful_sessions << session_setup(result) + rescue ::StandardError => e elog('Failed to setup the session', error: e) print_brute level: :error, ip: ip, msg: "Failed to setup the session - #{e.class} #{e.message}" + result.connection.close unless result.connection.nil? end end :next_user @@ -296,20 +296,11 @@ def report_creds(ip, port, result) end # @param [Metasploit::Framework::LoginScanner::Result] result - # @param [RubySMB::Client] client # @return [Msf::Sessions::SMB] - def session_setup(result, client) - return unless client - - # Create a new session - rstream = client.dispatcher.tcp_socket - sess = Msf::Sessions::SMB.new( - rstream, - { - client: client - } - ) + def session_setup(result) + return unless (result.connection && result.proof) + my_session = Msf::Sessions::SMB.new(result.connection, { client: result.proof }) merge_me = { 'USERPASS_FILE' => nil, 'USER_FILE' => nil, @@ -318,7 +309,7 @@ def session_setup(result, client) 'PASSWORD' => result.credential.private } - start_session(self, nil, merge_me, false, sess.rstream, sess) + start_session(self, nil, merge_me, false, my_session.rstream, my_session) end end