''' googleProxy.py Copyright 2006 Andres Riancho This file is part of w3af, w3af.sourceforge.net . w3af is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License. w3af is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with w3af; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ''' import core.controllers.outputManager as om from core.controllers.basePlugin.baseAttackPlugin import baseAttackPlugin from core.controllers.w3afException import w3afException from core.controllers.daemons.proxy import * import cgi , urllib import re class googleProxy(baseAttackPlugin): ''' This plugin is a local proxy for HTTP requests that @author: Andres Riancho ( andres.riancho@gmail.com ) ''' def __init__(self): baseAttackPlugin.__init__(self) # Internal variables self._proxyd = None # User options self._proxyAddress = '127.0.0.1' self._proxyPort = 8082 def setUrlOpener( self, urlOpener ): self._urlOpener = urlOpener # Now, I'm starting the proxy server ! self._proxy() def exploit( self ): ''' Do nothing, this plugin is rather odd. This plugin is a googleProxy server that's used for mangling requests. All the "magic" is done in the _proxy method and in the handler class. ''' om.out.information('google proxy listening on ' + self._proxyAddress + ':' + str(self._proxyPort) ) # All i need to run is runned from setUrlOpener and setOptions # All i need to run is self._proxy() with the correct parameters return True def canExploit( self ): return True def getType(self): return 'proxy' def fastExploit( self ): self.exploit() def getRootProbability( self ): return 0.0 def setOptions( self, OptionsMap ): self._proxyPort = OptionsMap['proxyPort'] self._proxyAddress = OptionsMap['proxyAddress'] # Restart the proxy, with the new options self._proxy() class proxyHandler(w3afProxyHandler): def _editResponse( self, responseBody ): #responseBody = responseBody.replace('/gwt/n?u=http%3A%2F%2F', 'http://') responseBody = responseBody.replace( '', '') responseBody = responseBody.replace('', '') responseBody = responseBody.replace('&_gwt_noimg=1', '') responseBody = responseBody.replace('&_gwt_srcpg=0', '') responseBody = responseBody.replace('&_gwt_ov=1', '') responseBody = re.sub('

P.*', '', responseBody) responseBody = re.sub('
.*?

', '', responseBody) for match in re.findall( '/gwt/n\?u=(.*?)"', responseBody ): responseBody = responseBody.replace( '/gwt/n?u=' + match, urllib.unquote_plus( match ), 1) return responseBody def _sendToBrowser( self, res ): ''' Send a response to the browser ''' # return the response to the browser try: self.send_response( res.getCode() ) for header in res.getHeaders(): if not header == 'content-type': self.send_header( header, res.getHeaders()[header] ) else: self.send_header( 'content-type', 'text/html' ) self.send_header( 'Connection', 'close') self.end_headers() self.wfile.write( self._editResponse( res.getBody() ) ) self.wfile.close() except Exception, e: om.out.debug('Failed to send the data to the browser: ' + str(e) ) def _sendToServer( self ): ''' I should send to the server: - http://www.google.com/gwt/n?u=http%3A%2F%2Fwww.joomla.org%2F&_gwt_noimg=1 When the client requests: - http://www.joomla.org ''' self.headers['Connection'] = 'close' # Prepare the url for google. googleProxyURL = 'http://www.google.com/gwt/n?' qs = queryString.queryString() qs['u'] = self.path qs['_gwt_noimg'] = 1 url = googleProxyURL + str( qs ) # Do the request to the remote server if self.headers.dict.has_key('content-length'): # POST cl = int( self.headers['content-length'] ) postData = self.rfile.read( cl ) try: res = self._urlOpener.POST( url , data=postData, headers=self.headers ) except w3afException, w: om.out.error('The proxy request failed, error: ' + str(w) ) raise w except: raise return res else: # GET try: res = self._urlOpener.GET( url, headers=self.headers ) except w3afException, w: om.out.error('The proxy request failed, error: ' + str(w) ) raise w except: raise return res def _proxy( self ): ''' This method starts the proxy server with the configured options. ''' if self._proxyd != None and self._proxyd.isRunning(): self._proxyd.stop() self._proxyd = proxy( self._proxyAddress, self._proxyPort , self._urlOpener, proxyHandler=self.proxyHandler ) self._proxyd.start2() def getOptionsXML(self): ''' This method returns a XML containing the Options that the plugin has. Using this XML the framework will build a window, a menu, or some other input method to retrieve the info from the user. The XML has to validate against the xml schema file located at : w3af/core/output.xsd ''' return '\ \ \ \ \ ' def getPluginDeps( self ): ''' @return: A list with the names of the plugins that should be runned before the current one. ''' return [] def getLongDesc( self ): ''' @return: A DETAILED description of the plugin functions and features. ''' return ''' This plugin exploits a service that google provides for mobile users and generates an HTTP proxy that can be used to navigate the web anonymously. Two configurable parameters exist: - proxyPort - proxyAddress '''