def audit(self, freq): ''' Tests an URL for local file inclusion vulnerabilities. @param freq: A fuzzableRequest ''' om.out.debug('localFileInclude plugin is testing: ' + freq.getURL()) oResponse = self._sendMutant(freq, analyze=False).getBody() # What payloads do I want to send to the remote end? local_files = [] local_files.append(freq.getURL().getFileName()) if not self._open_basedir: local_files.extend(self._get_local_file_list(freq.getURL())) mutants = createMutants(freq, local_files, oResponse=oResponse) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug('localFileInclude', 'localFileInclude', mutant.getURL(), mutant.getVar()): self._sendMutant(mutant, grepResult=False)
def _search_stored_xss(self, mutant): ''' Analyze the mutant for stored XSS. We get here because we already verified and the parameter is NOT being echoed back. @parameter mutant: A mutant that was used to test if the parameter was echoed back or not @return: None ''' xss_tests = self._get_xss_tests() xss_tests = xss_tests[:self._number_of_stored_xss_checks] # Get the strings only xss_strings = [ i[0] for i in xss_tests ] # And now replace the alert by fake_alert; I don't want to break web applications xss_strings = [ xss_test.replace('alert', 'fake_alert') for xss_test in xss_strings ] mutant_list = createMutants( mutant.getFuzzableReq() , xss_strings , \ fuzzableParamList=[mutant.getVar(), ]) # In the mutant, we have to save which browsers are vulnerable to that specific string for mutant in mutant_list: for xss_string, affected_browsers in xss_tests: if xss_string.replace('alert', 'fake_alert') in mutant.getModValue(): mutant.affected_browsers = affected_browsers for mutant in mutant_list: self._sendMutant(mutant)
def is_injectable( self, freq, parameter ): ''' Check if "parameter" of the fuzzable request object is injectable or not. @freq: The fuzzableRequest object that I have to modify @parameter: A string with the parameter name to test @return: A vulnerability object or None if nothing is found ''' # First save the original wait time _original_wait_time = self._sendMutant( freq, analyze=False ).getWaitTime() # Create the mutants parameter_to_test = [ parameter, ] statement_list = self._get_statements() sql_commands_only = [ i.sql_command for i in statement_list ] mutants = createMutants( freq , sql_commands_only, fuzzableParamList=parameter_to_test ) # And now I assign the statement to the mutant for statement in statement_list: for mutant in mutants: if statement.sql_command in mutant.getModValue(): mutant.statement = statement.sql_command mutant.dbms = statement.dbms # Perform the test for mutant in mutants: # Send response = self._sendMutant( mutant, analyze=False ) # Compare times if response.getWaitTime() > (_original_wait_time + self._wait_time-2): # Resend the same request to verify that this wasn't because of network delay # or some other rare thing _original_wait_time = self._sendMutant( freq, analyze=False ).getWaitTime() response = self._sendMutant( mutant, analyze=False ) # Compare times (once again) if response.getWaitTime() > (_original_wait_time + self._wait_time-2): # Now I can be sure that I found a vuln, I control the time of the response. v = vuln.vuln( mutant ) v.setName( 'Blind SQL injection - ' + mutant.dbms ) v.setSeverity(severity.HIGH) v.setDesc( 'Blind SQL injection was found at: ' + mutant.foundAt() ) v.setDc( mutant.getDc() ) v.setId( response.id ) v.setURI( response.getURI() ) return v return None
def _fuzz_with_echo( self, freq ): ''' Tests an URL for eval() usage vulnerabilities using echo strings. @param freq: A fuzzableRequest ''' oResponse = self._sendMutant( freq , analyze=False ).getBody() print_strings = self._get_print_strings() mutants = createMutants( freq , print_strings, oResponse=oResponse ) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug( 'eval' , 'eval', mutant.getURL() , mutant.getVar() ): self._sendMutant(mutant, analyze_callback=self._analyze_echo)
def _search_reflected_xss(self, mutant): ''' Analyze the mutant for reflected XSS. We get here because we already verified and the parameter is being echoed back. @parameter mutant: A mutant that was used to test if the parameter was echoed back or not @return: None ''' # Verify what characters are allowed try: allowed_chars = self._get_allowed_chars(mutant) except w3afException: # If something fails, every char is allowed allowed_chars = self._special_characters[:] # Filter the tests based on the knowledge we got from the previous test orig_xss_tests = self._get_xss_tests() filtered_xss_tests = [] for xss_string, affected_browsers in orig_xss_tests: for char in self._special_characters: all_allowed = True if char in xss_string and not char in allowed_chars: all_allowed = False break # Decide wether to send the test or not if all_allowed: filtered_xss_tests.append((xss_string, affected_browsers)) # Get the strings only xss_strings = [ i[0] for i in filtered_xss_tests ] mutant_list = createMutants( mutant.getFuzzableReq() , xss_strings , \ fuzzableParamList=[mutant.getVar(), ]) # In the mutant, we have to save which browsers are vulnerable to that specific string for mutant in mutant_list: for xss_string, affected_browsers in filtered_xss_tests: if xss_string in mutant.getModValue(): mutant.affected_browsers = affected_browsers for mutant in mutant_list: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug( 'xss' , 'xss', mutant.getURL() , mutant.getVar() ): self._sendMutant(mutant)
def _fuzz_with_echo(self, freq): ''' Tests an URL for eval() usage vulnerabilities using echo strings. @param freq: A fuzzableRequest ''' oResponse = self._sendMutant(freq, analyze=False).getBody() print_strings = self._get_print_strings() mutants = createMutants(freq, print_strings, oResponse=oResponse) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug('eval', 'eval', mutant.getURL(), mutant.getVar()): self._sendMutant(mutant, analyze_callback=self._analyze_echo)
def _with_echo(self, freq): ''' Tests an URL for OS Commanding vulnerabilities using cat/type to write the content of a known file (i.e. /etc/passwd) to the HTML. @param freq: A fuzzableRequest ''' original_response = self._sendMutant( freq , analyze=False ).getBody() # Prepare the strings to create the mutants command_list = self._get_echo_commands() only_command_strings = [ v.getCommand() for v in command_list ] mutants = createMutants( freq , only_command_strings, oResponse=original_response ) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug( 'osCommanding' , 'osCommanding', mutant.getURL() , mutant.getVar() ): self._sendMutant(mutant, analyze_callback=self._analyze_echo)
def _test_inclusion(self, freq): ''' Checks a fuzzableRequest for remote file inclusion bugs. @return: None ''' oResponse = self._sendMutant(freq, analyze=False).getBody() rfi_url_list = [self._rfi_url, self._rfi_url.urlJoin("\0")] mutants = createMutants(freq, rfi_url_list, oResponse=oResponse) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug('remoteFileInclude', 'remoteFileInclude', mutant.getURL(), mutant.getVar()): self._sendMutant(mutant)
def audit(self, freq ): ''' Tests an URL for SQL injection vulnerabilities. @param freq: A fuzzableRequest ''' om.out.debug( 'SQLi plugin is testing: ' + freq.getURL() ) oResponse = self._sendMutant( freq , analyze=False ).getBody() sqli_strings = self._get_sqli_strings() mutants = createMutants( freq , sqli_strings, oResponse=oResponse ) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug( 'sqli' , 'sqli', mutant.getURL() , mutant.getVar() ): self._sendMutant(mutant)
def _fuzz_with_time_delay( self, freq): ''' Tests an URL for eval() usage vulnerabilities using time delays. @param freq: A fuzzableRequest ''' res = self._sendMutant( freq, analyze=False, grepResult=False ) self._original_wait_time = res.getWaitTime() # Prepare the strings to create the mutants wait_strings = self._get_wait_strings() mutants = createMutants( freq, wait_strings ) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug( 'eval' , 'eval', mutant.getURL() , mutant.getVar() ): self._sendMutant(mutant, analyze_callback=self._analyze_wait)
def audit(self, freq): ''' Tests an URL for SQL injection vulnerabilities. @param freq: A fuzzableRequest ''' om.out.debug('SQLi plugin is testing: ' + freq.getURL()) oResponse = self._sendMutant(freq, analyze=False).getBody() sqli_strings = self._get_sqli_strings() mutants = createMutants(freq, sqli_strings, oResponse=oResponse) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug('sqli', 'sqli', mutant.getURL(), mutant.getVar()): self._sendMutant(mutant)
def _fuzz_with_time_delay(self, freq): ''' Tests an URL for eval() usage vulnerabilities using time delays. @param freq: A fuzzableRequest ''' res = self._sendMutant(freq, analyze=False, grepResult=False) self._original_wait_time = res.getWaitTime() # Prepare the strings to create the mutants wait_strings = self._get_wait_strings() mutants = createMutants(freq, wait_strings) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug('eval', 'eval', mutant.getURL(), mutant.getVar()): self._sendMutant(mutant, analyze_callback=self._analyze_wait)
def is_injectable( self, freq, parameter ): ''' Check if "parameter" of the fuzzable request object is injectable or not. @freq: The fuzzableRequest object that I have to modify @parameter: A string with the parameter name to test @return: A vulnerability object or None if nothing is found ''' dummy = ['', ] parameter_to_test = [ parameter, ] mutants = createMutants( freq , dummy, fuzzableParamList=parameter_to_test ) for mutant in mutants: statements = self._get_statements( mutant ) for statement_type in statements: vuln = self._findBsql( mutant, statements[statement_type], statement_type ) if vuln: return vuln return None
def _with_time_delay(self, freq): ''' Tests an URL for OS Commanding vulnerabilities using time delays. @param freq: A fuzzableRequest ''' # Send the fuzzableRequest without any fuzzing, so we can measure the response # time of this script in order to compare it later res = self._sendMutant( freq, analyze=False, grepResult=False ) self._original_wait_time = res.getWaitTime() # Prepare the strings to create the mutants command_list = self._get_wait_commands() only_command_strings = [ v.getCommand() for v in command_list ] mutants = createMutants( freq , only_command_strings ) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug( 'osCommanding' , 'osCommanding', mutant.getURL() , mutant.getVar() ): self._sendMutant(mutant, analyze_callback=self._analyze_wait)
def _with_echo(self, freq): ''' Tests an URL for OS Commanding vulnerabilities using cat/type to write the content of a known file (i.e. /etc/passwd) to the HTML. @param freq: A fuzzableRequest ''' original_response = self._sendMutant(freq, analyze=False).getBody() # Prepare the strings to create the mutants command_list = self._get_echo_commands() only_command_strings = [v.getCommand() for v in command_list] mutants = createMutants(freq, only_command_strings, oResponse=original_response) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug('osCommanding', 'osCommanding', mutant.getURL(), mutant.getVar()): self._sendMutant(mutant, analyze_callback=self._analyze_echo)
def _with_time_delay(self, freq): ''' Tests an URL for OS Commanding vulnerabilities using time delays. @param freq: A fuzzableRequest ''' # Send the fuzzableRequest without any fuzzing, so we can measure the response # time of this script in order to compare it later res = self._sendMutant(freq, analyze=False, grepResult=False) self._original_wait_time = res.getWaitTime() # Prepare the strings to create the mutants command_list = self._get_wait_commands() only_command_strings = [v.getCommand() for v in command_list] mutants = createMutants(freq, only_command_strings) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug('osCommanding', 'osCommanding', mutant.getURL(), mutant.getVar()): self._sendMutant(mutant, analyze_callback=self._analyze_wait)
def audit(self, freq ): ''' Tests an URL for local file inclusion vulnerabilities. @param freq: A fuzzableRequest ''' om.out.debug( 'localFileInclude plugin is testing: ' + freq.getURL() ) oResponse = self._sendMutant( freq , analyze=False ).getBody() # What payloads do I want to send to the remote end? local_files = [] local_files.append( freq.getURL().getFileName() ) if not self._open_basedir: local_files.extend( self._get_local_file_list(freq.getURL()) ) mutants = createMutants( freq , local_files, oResponse=oResponse ) for mutant in mutants: # Only spawn a thread if the mutant has a modified variable # that has no reported bugs in the kb if self._hasNoBug( 'localFileInclude' , 'localFileInclude', mutant.getURL() , mutant.getVar() ): self._sendMutant(mutant, grepResult=False)
def audit(self, freq ): ''' Tests an URL for XSS vulnerabilities. @param freq: A fuzzableRequest ''' om.out.debug( 'Xss plugin is testing: ' + freq.getURL() ) # Save it here, so I can search for permanent XSS self._fuzzableRequests.append( freq ) # This list is just to test if the parameter is echoed back fake_mutants = createMutants( freq , ['', ] ) for mutant in fake_mutants: # verify if the variable we are fuzzing is actually being echoed back if self._is_echoed( mutant ): # Search for reflected XSS self._search_reflected_xss(mutant) # And also check stored self._search_stored_xss(mutant) elif self._check_stored_xss: # Search for permanent XSS self._search_stored_xss(mutant)
def is_injectable(self, freq, parameter): ''' Check if "parameter" of the fuzzable request object is injectable or not. @freq: The fuzzableRequest object that I have to modify @parameter: A string with the parameter name to test @return: A vulnerability object or None if nothing is found ''' # First save the original wait time _original_wait_time = self._sendMutant(freq, analyze=False).getWaitTime() # Create the mutants parameter_to_test = [ parameter, ] statement_list = self._get_statements() sql_commands_only = [i.sql_command for i in statement_list] mutants = createMutants(freq, sql_commands_only, fuzzableParamList=parameter_to_test) # And now I assign the statement to the mutant for statement in statement_list: for mutant in mutants: if statement.sql_command in mutant.getModValue(): mutant.statement = statement.sql_command mutant.dbms = statement.dbms # Perform the test for mutant in mutants: # Send response = self._sendMutant(mutant, analyze=False) # Compare times if response.getWaitTime() > (_original_wait_time + self._wait_time - 2): # Resend the same request to verify that this wasn't because of network delay # or some other rare thing _original_wait_time = self._sendMutant( freq, analyze=False).getWaitTime() response = self._sendMutant(mutant, analyze=False) # Compare times (once again) if response.getWaitTime() > (_original_wait_time + self._wait_time - 2): # Now I can be sure that I found a vuln, I control the time of the response. v = vuln.vuln(mutant) v.setName('Blind SQL injection - ' + mutant.dbms) v.setSeverity(severity.HIGH) v.setDesc('Blind SQL injection was found at: ' + mutant.foundAt()) v.setDc(mutant.getDc()) v.setId(response.id) v.setURI(response.getURI()) return v return None