''' sharedHosting.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.w3afException import w3afException import core.data.kb.knowledgeBase as kb import core.data.kb.vuln as vuln from core.data.searchEngines.msn import msn as msn from core.controllers.basePlugin.baseDiscoveryPlugin import baseDiscoveryPlugin import core.data.parsers.urlParser as urlParser import socket from core.controllers.w3afException import w3afRunOnce class sharedHosting(baseDiscoveryPlugin): ''' This plugin uses MSN search to determine if the website is in a shared hosting. @author: Andres Riancho ( andres.riancho@gmail.com ) ''' def __init__(self): baseDiscoveryPlugin.__init__(self) self._run = True # User variables self._resultLimit = 300 def discover(self, fuzzableRequest ): ''' @parameter fuzzableRequest: A fuzzableRequest instance that contains (among other things) the URL to test. ''' if not self._run: # This will remove the plugin from the discovery plugins to be runned. raise w3afRunOnce() else: # I will only run this one time. All calls to sharedHosting return the same url's self._run = False self._msn = msn( self._urlOpener ) domain = urlParser.getDomain( fuzzableRequest.getURL() ) if self._msn.isPrivate( domain ): om.out.debug('sharedHosting plugin is not checking for subdomains for domain: ' + domain + ' because its a private address.' ) else: # Get the ip and do the search addrinfo = None try: addrinfo = socket.getaddrinfo(domain, 0) except: raise w3afException('Could not resolve hostname: ' + domain ) ips = [info[4][0] for info in addrinfo] # Selecting the first IP address of the dns response ip = ips[0] results = self._msn.getNResults('ip:'+ ip, self._resultLimit ) results = [ urlParser.baseUrl( r.URL ) for r in results ] results = list( set( results ) ) if len( results ) > 1: v = vuln.vuln() v.setURL( fuzzableRequest.getURL() ) v.setId( 0 ) v['alsoInHosting'] = results v.setDesc( 'The web application under test seems to be in a shared hosting.' ) kb.kb.append( self, 'sharedHosting', v ) om.out.vulnerability( v.getDesc() ) om.out.vulnerability('This list of domains, and the domain of the web application under test, all point to the same IP address (%s):' % ip ) for url in results: om.out.vulnerability('- ' + url ) return [] 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/ui/userInterface.dtd @return: XML with the plugin options. ''' return '\ \ \ \ ' def setOptions( self, optionsMap ): ''' This method sets all the options that are configured using the user interface generated by the framework using the result of getOptionsXML(). @parameter OptionList: A dictionary with the options for the plugin. @return: No value is returned. ''' self._resultLimit = optionsMap['resultLimit'] 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 tries to find out if the web application under test is stored in a shared hosting. The procedure is pretty simple, using MSN search engine, the plugin searches for "ip:1.2.3.4" where 1.2.3.4 is the IP address of the webserver. '''