Example #1
0
 def _analyze_responses( self, oResponse, limit_response, error_response, mutant ):
     '''
     Analyze responses; if error_response doesn't look like oResponse nor limit_response,
     then we have a vuln.
     
     @return: None
     '''
     original_to_error = relative_distance(oResponse.getBody(), error_response.getBody() )
     limit_to_error = relative_distance( limit_response.getBody(), error_response.getBody() )
     original_to_limit = relative_distance( limit_response.getBody(), oResponse.getBody() )
     
     ratio = self._diff_ratio + ( 1 - original_to_limit )
     
     #om.out.debug('original_to_error: ' +  str(original_to_error) )
     #om.out.debug('limit_to_error: ' +  str(limit_to_error) )
     #om.out.debug('original_to_limit: ' +  str(original_to_limit) )
     #om.out.debug('ratio: ' +  str(ratio) )
     
     if original_to_error < ratio and limit_to_error < ratio:
         # Maybe the limit I requested wasn't really a non-existant one
         # (and the error page really found the limit), 
         # let's request a new limit (one that hopefully doesn't exist)
         # in order to remove some false positives
         limit_response2 = self._get_limit_response( mutant )
         
         id_list = [oResponse.id, limit_response.id, error_response.id]
         
         if relative_distance( limit_response2.getBody(), limit_response.getBody() ) > \
         1 - self._diff_ratio:
             # The two limits are "equal"; It's safe to suppose that we have found the
             # limit here and that the error string really produced an error
             v = vuln.vuln( mutant )
             v.setPluginName(self.getName())
             v.setId( id_list )
             v.setSeverity(severity.MEDIUM)
             v.setName( 'Unidentified vulnerability' )
             v.setDesc( 'An unidentified vulnerability was found at: ' + mutant.foundAt() )
             kb.kb.append( self, 'generic', v )
             self._already_reported.append( (mutant.getURL(), mutant.getVar()) )
         else:
             # *maybe* and just *maybe* this is a vulnerability
             i = info.info( mutant )
             i.setPluginName(self.getName())
             i.setId( id_list )
             i.setName( 'Possible unidentified vulnerability' )
             msg = '[Manual verification required] A possible vulnerability was found at: '
             msg += mutant.foundAt()
             i.setDesc( msg )
             kb.kb.append( self, 'generic', i )
             self._already_reported.append( (mutant.getURL(), mutant.getVar()) )
Example #2
0
 def _relative_distance(self, a, b):
     '''
     Calculates the distance between two responses based on the levenshtein distance
     
     @return: The distance
     '''
     return 1 - relative_distance(a.getBody(), b.getBody())
Example #3
0
    def _relative_distance(self, a, b):
        '''
        Calculates the distance between two responses based on the levenshtein distance

        :return: The distance
        '''
        return 1 - relative_distance(a.get_body(), b.get_body())
Example #4
0
 def getLD(self, A, B):
     global num
     num = num + 1
     
     result = int(relative_distance(A.getPage(), B.getPage())*100)
     print("\n-->(" + str(num) + ") " + str(len(A.getPage())) + " - " + str(len(B.getPage())) + " - " + str(result) )
     
     return result
Example #5
0
    def _analyze_responses(self, orig_resp, limit_response, error_response,
                           mutant):
        '''
        Analyze responses; if error_response doesn't look like orig_resp nor
        limit_response, then we have a vuln.

        :return: None
        '''
        original_to_error = relative_distance(orig_resp.get_body(),
                                              error_response.get_body())
        limit_to_error = relative_distance(limit_response.get_body(),
                                           error_response.get_body())
        original_to_limit = relative_distance(limit_response.get_body(),
                                              orig_resp.get_body())

        ratio = self._diff_ratio + (1 - original_to_limit)

        #om.out.debug('original_to_error: ' +  str(original_to_error) )
        #om.out.debug('limit_to_error: ' +  str(limit_to_error) )
        #om.out.debug('original_to_limit: ' +  str(original_to_limit) )
        #om.out.debug('ratio: ' +  str(ratio) )

        if original_to_error < ratio and limit_to_error < ratio:
            # Maybe the limit I requested wasn't really a non-existant one
            # (and the error page really found the limit),
            # let's request a new limit (one that hopefully doesn't exist)
            # in order to remove some false positives
            limit_response2 = self._get_limit_response(mutant)

            id_list = [orig_resp.id, limit_response.id, error_response.id]

            if relative_distance(limit_response2.get_body(), limit_response.get_body()) > \
                    1 - self._diff_ratio:
                # The two limits are "equal"; It's safe to suppose that we have found the
                # limit here and that the error string really produced an error
                self._potential_vulns.append(
                    (mutant.get_url(), mutant.get_var(), mutant, id_list))
Example #6
0
    def _analyze_responses(self, orig_resp, limit_response, error_response, mutant):
        '''
        Analyze responses; if error_response doesn't look like orig_resp nor
        limit_response, then we have a vuln.

        :return: None
        '''
        original_to_error = relative_distance(
            orig_resp.get_body(), error_response.get_body())
        limit_to_error = relative_distance(
            limit_response.get_body(), error_response.get_body())
        original_to_limit = relative_distance(
            limit_response.get_body(), orig_resp.get_body())

        ratio = self._diff_ratio + (1 - original_to_limit)

        #om.out.debug('original_to_error: ' +  str(original_to_error) )
        #om.out.debug('limit_to_error: ' +  str(limit_to_error) )
        #om.out.debug('original_to_limit: ' +  str(original_to_limit) )
        #om.out.debug('ratio: ' +  str(ratio) )

        if original_to_error < ratio and limit_to_error < ratio:
            # Maybe the limit I requested wasn't really a non-existant one
            # (and the error page really found the limit),
            # let's request a new limit (one that hopefully doesn't exist)
            # in order to remove some false positives
            limit_response2 = self._get_limit_response(mutant)

            id_list = [orig_resp.id, limit_response.id, error_response.id]

            if relative_distance(limit_response2.get_body(), limit_response.get_body()) > \
                    1 - self._diff_ratio:
                # The two limits are "equal"; It's safe to suppose that we have found the
                # limit here and that the error string really produced an error
                self._potential_vulns.append((mutant.get_url(),
                                              mutant.get_var(),
                                              mutant, id_list))
Example #7
0
    def test_all(self):
        acceptance_tests = []
        acceptance_tests.append(('a', 'a', 1.0))
        acceptance_tests.append(('a', 'a', 0.1))
        acceptance_tests.append(('a', 'a', 0.0))

        acceptance_tests.append(('a', 'b', 1.0))
        acceptance_tests.append(('a', 'b', 0.1))
        acceptance_tests.append(('a', 'b', 0.0))

        acceptance_tests.append(('a', 'ab', 1.0))
        acceptance_tests.append(('a', 'ab', 0.1))

        acceptance_tests.append(('a', 'b', 0.0000000000000000001))
        acceptance_tests.append(('a', 'b' * 100, 1.0))

        acceptance_tests.append(('a', 'ab', 0.66666666666))
        acceptance_tests.append(('a', 'aab', 0.5))
        acceptance_tests.append(('a', 'aaab', 0.4))
        acceptance_tests.append(
            ('a', 'aaaab',
             0.33333333333333333333333333333333333333333333333333333333))

        acceptance_tests.append(('a' * 25, 'a', 1.0))
        acceptance_tests.append(('aaa', 'aa', 1.0))
        acceptance_tests.append(('a', 'a', 1.0))

        acceptance_tests.append(('a' * 25, 'a', 0.076923076923076927))
        acceptance_tests.append(('aaa', 'aa', 0.8))

        acceptance_tests.append(('a', 'a', 0.0))

        for e, d, f in acceptance_tests:
            res1 = relative_distance_boolean(e, d, f)
            res2 = relative_distance(e, d) >= f

            msg = 'relative_distance_boolean and relative_distance returned'\
                  ' different results for the same parameters:\n'\
                  '    - %s\n'\
                  '    - %s\n'\
                  '    - Threshold: %s\n'\

            self.assertEqual(res1, res2, msg % (e, d, f))
Example #8
0
    def test_all(self):
        acceptance_tests = []
        acceptance_tests.append(('a', 'a', 1.0))
        acceptance_tests.append(('a', 'a', 0.1))
        acceptance_tests.append(('a', 'a', 0.0))

        acceptance_tests.append(('a', 'b', 1.0))
        acceptance_tests.append(('a', 'b', 0.1))
        acceptance_tests.append(('a', 'b', 0.0))

        acceptance_tests.append(('a', 'ab', 1.0))
        acceptance_tests.append(('a', 'ab', 0.1))

        acceptance_tests.append(('a', 'b', 0.0000000000000000001))
        acceptance_tests.append(('a', 'b' * 100, 1.0))

        acceptance_tests.append(('a', 'ab', 0.66666666666))
        acceptance_tests.append(('a', 'aab', 0.5))
        acceptance_tests.append(('a', 'aaab', 0.4))
        acceptance_tests.append(('a', 'aaaab', 0.33333333333333333333333333333333333333333333333333333333))

        acceptance_tests.append(('a' * 25, 'a', 1.0))
        acceptance_tests.append(('aaa', 'aa', 1.0))
        acceptance_tests.append(('a', 'a', 1.0))

        acceptance_tests.append(('a' * 25, 'a', 0.076923076923076927))
        acceptance_tests.append(('aaa', 'aa', 0.8))

        acceptance_tests.append(('a', 'a', 0.0))

        for e, d, f in acceptance_tests:
            res1 = relative_distance_boolean(e, d, f)
            res2 = relative_distance(e, d) >= f
            
            msg = 'relative_distance_boolean and relative_distance returned'\
                  ' different results for the same parameters:\n'\
                  '    - %s\n'\
                  '    - %s\n'\
                  '    - Threshold: %s\n'\
            
            self.assertEqual(res1, res2, msg % (e, d, f))