'''
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('
', '', 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
'''