def _analyze_result(self, mutant, response):
        '''
        Analyze results of the _send_mutant method.
        '''
        #
        #   I will only report the vulnerability once.
        #
        if self._has_no_bug(mutant):

            if self._header_was_injected(mutant, response):
                desc = 'Response splitting was found at: %s' % mutant.found_at()
                
                v = Vuln.from_mutant('Response splitting vulnerability', desc,
                                     severity.MEDIUM, response.id,
                                     self.get_name(), mutant)

                self.kb_append_uniq(self, 'response_splitting', v)
                
            # When trying to send a response splitting to php 5.1.2 I get :
            # Header may not contain more than a single header, new line detected
            for error in self.HEADER_ERRORS:

                if error in response:
                    desc = 'The variable "%s" at URL "%s" modifies the HTTP'\
                           ' response headers, but this error was sent while'\
                           ' testing for response splitting: "%s".'
                    desc = desc % (mutant.get_var(), mutant.get_url(), error)
                    i = Info.from_mutant('Parameter modifies response headers',
                                         desc, response.id, self.get_name(),
                                         mutant)
                    
                    self.kb_append_uniq(self, 'response_splitting', i)

                    return
    def _header_was_injected(self, mutant, response):
        '''
        This method verifies if a header was successfully injected

        :param mutant: The mutant that was sent to generate the response
        :param response: The HTTP response where I want to find the injected header.
        :return: True / False
        '''
        # Get the lower case headers
        headers = response.get_lower_case_headers()

        # Analyze injection
        for header, value in headers.items():
            if HEADER_NAME in header and value.lower() == HEADER_VALUE:
                return True

            elif HEADER_NAME in header and value.lower() != HEADER_VALUE:
                msg = 'The vulnerable header was added to the HTTP response,'\
                      ' but the value is not what w3af expected (%s: %s).'\
                      ' Please verify manually.'
                msg = msg % (HEADER_NAME,HEADER_VALUE)
                om.out.information(msg)

                i = Info.from_mutant('Parameter modifies response headers',
                                     msg, response.id, self.get_name(),
                                     mutant)
                
                self.kb_append_uniq(self, 'response_splitting', i)
                return False

        return False
Exemple #3
0
    def _send_request(self, mutant):
        '''
        Sends a mutant to the remote web server. I wrap urllib's _send_mutant
        just to handle errors in a different way.
        '''
        try:
            response = self._uri_opener.send_mutant(mutant)
        except (w3afException, w3afMustStopException):
            desc = 'A potential (most probably a false positive than a bug)' \
                   ' buffer-overflow was found when requesting: "%s", using' \
                   ' HTTP method %s. The data sent was: "%s".'
            desc = desc % (mutant.get_url(), mutant.get_method(), mutant.get_dc())

            i = Info.from_mutant('Potential buffer overflow vulnerability',
                                 desc, response.ids, self.get_name(), mutant)
            
            self.kb_append_uniq(self, 'buffer_overflow', i)
        else:
            self._analyze_result(mutant, response)
Exemple #4
0
    def test_from_mutant(self):
        dc = DataContainer()
        url = URL('http://moth/')
        payloads = ['abc', 'def']

        dc['a'] = ['1', ]
        dc['b'] = ['2', ]
        freq = FuzzableRequest(url, dc=dc)
        fuzzer_config = {}
        
        created_mutants = Mutant.create_mutants(freq, payloads, [], False,
                                                fuzzer_config)
                
        mutant = created_mutants[0]
        
        inst = Info.from_mutant('TestCase', 'desc' * 30, 1, 'plugin_name', mutant)
        
        self.assertIsInstance(inst, Info)
        
        self.assertEqual(inst.get_uri(), mutant.get_uri())
        self.assertEqual(inst.get_url(), mutant.get_url())
        self.assertEqual(inst.get_method(), mutant.get_method())
        self.assertEqual(inst.get_dc(), mutant.get_dc())
        self.assertEqual(inst.get_var(), mutant.get_var())
Exemple #5
0
    def _analyze_result(self, mutant, response):
        '''
        Analyze results of the _send_mutant method.
        Try to find the local file inclusions.
        '''
        # I analyze the response searching for a specific PHP error string
        # that tells me that open_basedir is enabled, and our request triggered
        # the restriction. If open_basedir is in use, it makes no sense to keep
        # trying to read "/etc/passwd", that is why this variable is used to
        # determine which tests to send if it was possible to detect the usage
        # of this security feature.
        if not self._open_basedir:
            
            basedir_warning = 'open_basedir restriction in effect'
            
            if basedir_warning in response and \
            basedir_warning not in mutant.get_original_response_body():
                self._open_basedir = True

        #
        #   I will only report the vulnerability once.
        #
        if self._has_bug(mutant):
            return

        #
        #   Identify the vulnerability
        #
        file_content_list = self._find_file(response)
        for file_pattern_match in file_content_list:
            if file_pattern_match not in mutant.get_original_response_body():
                
                desc = 'Local File Inclusion was found at: %s'
                desc = desc % mutant.found_at()
                
                v = Vuln.from_mutant('Local file inclusion vulnerability',
                                     desc, severity.MEDIUM, response.id,
                                     self.get_name(), mutant)

                v['file_pattern'] = file_pattern_match
                
                v.add_to_highlight(file_pattern_match)
                self.kb_append_uniq(self, 'lfi', v)
                return

        #
        #   If the vulnerability could not be identified by matching strings that commonly
        #   appear in "/etc/passwd", then I'll check one more thing...
        #   (note that this is run if no vulns were identified)
        #
        #   http://host.tld/show_user.php?id=show_user.php
        if mutant.get_mod_value() == mutant.get_url().get_file_name():
            match, lang = is_source_file(response.get_body())
            if match:
                # We were able to read the source code of the file that is
                # vulnerable to local file read
                desc = 'An arbitrary local file read vulnerability was'\
                       ' found at: %s' % mutant.found_at()
                
                v = Vuln.from_mutant('Local file inclusion vulnerability',
                                     desc, severity.MEDIUM, response.id,
                                     self.get_name(), mutant)

                #
                #    Set which part of the source code to match
                #
                match_source_code = match.group(0)
                v['file_pattern'] = match_source_code

                self.kb_append_uniq(self, 'lfi', v)
                return

        #
        #   Check for interesting errors (note that this is run if no vulns were
        #   identified)
        #
        for regex in self.get_include_errors():

            match = regex.search(response.get_body())

            if match and not regex.search(mutant.get_original_response_body()):
                desc = 'A file read error was found at: %s'
                desc = desc % mutant.found_at()
                
                i = Info.from_mutant('File read error', desc, response.id,
                                     self.get_name(), mutant)
                
                self.kb_append_uniq(self, 'error', i)