Example #1
0
    def grep(self, request, response):
        '''
        Plugin entry point, search for the code disclosures.

        Unit tests are available at plugins/grep/tests.

        :param request: The HTTP request object.
        :param response: The HTTP response object
        :return: None
        '''
        if response.is_text_or_html() and \
        response.get_url() not in self._already_added:

            match, lang = is_source_file(response.get_body())

            if match:
                # Check also for 404
                if not is_404(response):
                    desc = 'The URL: "%s" has a %s code disclosure vulnerability.'
                    desc = desc % (response.get_url(), lang)
                    
                    v = Vuln('Code disclosure vulnerability', desc,
                             severity.LOW, response.id, self.get_name())

                    v.set_url(response.get_url())
                    v.add_to_highlight(match.group())
                    
                    self.kb_append_uniq(self, 'code_disclosure', v, 'URL')
                    self._already_added.add(response.get_url())

                else:
                    self._first_404 = False
                    
                    desc = 'The URL: "%s" has a %s code disclosure'\
                           ' vulnerability in the customized 404 script.'
                    desc = desc % (v.get_url(), lang)
                    
                    v = Vuln('Code disclosure vulnerability in 404 page', desc,
                             severity.LOW, response.id, self.get_name())

                    v.set_url(response.get_url())
                    v.add_to_highlight(match.group())
                    self.kb_append_uniq(self, 'code_disclosure', v, 'URL')
Example #2
0
    def grep(self, request, response):
        '''
        Plugin entry point, search for the code disclosures.

        Unit tests are available at plugins/grep/tests.

        :param request: The HTTP request object.
        :param response: The HTTP response object
        :return: None
        '''
        if response.is_text_or_html() and \
        response.get_url() not in self._already_added:

            match, lang = is_source_file(response.get_body())

            if match:
                # Check also for 404
                if not is_404(response):
                    desc = 'The URL: "%s" has a %s code disclosure vulnerability.'
                    desc = desc % (response.get_url(), lang)

                    v = Vuln('Code disclosure vulnerability', desc,
                             severity.LOW, response.id, self.get_name())

                    v.set_url(response.get_url())
                    v.add_to_highlight(match.group())

                    self.kb_append_uniq(self, 'code_disclosure', v, 'URL')
                    self._already_added.add(response.get_url())

                else:
                    self._first_404 = False

                    desc = 'The URL: "%s" has a %s code disclosure'\
                           ' vulnerability in the customized 404 script.'
                    desc = desc % (v.get_url(), lang)

                    v = Vuln('Code disclosure vulnerability in 404 page', desc,
                             severity.LOW, response.id, self.get_name())

                    v.set_url(response.get_url())
                    v.add_to_highlight(match.group())
                    self.kb_append_uniq(self, 'code_disclosure', v, 'URL')
Example #3
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)
Example #4
0
    def grep(self, request, response):
        '''
        Plugin entry point, search for the code disclosures.
        
        Unit tests are available at plugins/grep/tests.
        
        @parameter request: The HTTP request object.
        @parameter response: The HTTP response object
        @return: None
        Init
        >>> import codeDisclosure
        >>> from core.data.url.httpResponse import httpResponse
        >>> from core.data.request.fuzzableRequest import fuzzableRequest
        >>> from core.controllers.misc.temp_dir import create_temp_dir
        >>> from core.data.parsers.urlParser import url_object
        >>> from core.controllers.coreHelpers.fingerprint_404 import fingerprint_404_singleton
        >>> from core.data.url.xUrllib import xUrllib
        >>> xurllib = xUrllib()
        >>> f = fingerprint_404_singleton( [False, False, False] )
        >>> f.set_urlopener( xurllib )
        >>> o = create_temp_dir()

        Simple test, empty string.
        >>> body = ''
        >>> url = url_object('http://www.w3af.com/')
        >>> headers = {'content-type': 'text/html'}
        >>> response = httpResponse(200, body , headers, url, url)
        >>> request = fuzzableRequest()
        >>> request.setURL(url)
        >>> request.setMethod('GET')
        >>> c = codeDisclosure.codeDisclosure()
        >>> c.grep(request, response)
        >>> len(kb.kb.getData('codeDisclosure', 'codeDisclosure'))
        0
        
        Disclose some PHP code,
        >>> kb.kb.cleanup()
        >>> body = 'header <? echo "a"; ?> footer'
        >>> url = url_object('http://www.w3af.com/')
        >>> headers = {'content-type': 'text/html'}
        >>> response = httpResponse(200, body , headers, url, url)
        >>> request = fuzzableRequest()
        >>> request.setURL(url)
        >>> request.setMethod('GET')
        >>> c = codeDisclosure.codeDisclosure()
        >>> c.grep(request, response)
        >>> len(kb.kb.getData('codeDisclosure', 'codeDisclosure'))
        1

        '''
        if response.is_text_or_html() and response.getURL() not in self._already_added:
            
            match, lang  = is_source_file(response.getBody())
            
            if match:
                # Check also for 404
                if not is_404( response ):
                    v = vuln.vuln()
                    v.setPluginName(self.getName())
                    v.setURL( response.getURL() )
                    v.setId( response.id )
                    v.setSeverity(severity.LOW)
                    v.setName( lang + ' code disclosure vulnerability' )
                    v.addToHighlight(match.group())
                    msg = 'The URL: "' + v.getURL() + '" has a '+lang+' code disclosure vulnerability.'
                    v.setDesc( msg )
                    kb.kb.append( self, 'codeDisclosure', v )
                    self._already_added.add( response.getURL() )
                
                else:
                    self._first_404 = False
                    v = vuln.vuln()
                    v.setPluginName(self.getName())
                    v.setURL( response.getURL() )
                    v.setId( response.id )
                    v.setSeverity(severity.LOW)
                    v.addToHighlight(match.group())
                    v.setName( lang + ' code disclosure vulnerability in 404 page' )
                    msg = 'The URL: "' + v.getURL() + '" has a '+lang+' code disclosure vulnerability in'
                    msg += ' the customized 404 script.'
                    v.setDesc( msg )
                    kb.kb.append( self, 'codeDisclosure', v )
 def _analyzeResult( self, mutant, response ):
     '''
     Analyze results of the _sendMutant method.
     Try to find the local file inclusions.
     '''
     #
     #   Only one thread at the time can enter here. This is because I want to report each
     #   vulnerability only once, and by only adding the "if self._hasNoBug" statement, that
     #   could not be done.
     #
     with self._plugin_lock:
         
         #
         #   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:
             if 'open_basedir restriction in effect' in response\
             and 'open_basedir restriction in effect' not in mutant.getOriginalResponseBody():
                 self._open_basedir = True
         
         #
         #   I will only report the vulnerability once.
         #
         if self._hasNoBug( 'localFileInclude' , 'localFileInclude' , mutant.getURL() , mutant.getVar() ):
             
             #
             #   Identify the vulnerability
             #
             file_content_list = self._find_file( response )
             for file_pattern_regex, file_content in file_content_list:
                 if not file_pattern_regex.search( mutant.getOriginalResponseBody() ):
                     v = vuln.vuln( mutant )
                     v.setPluginName(self.getName())
                     v.setId( response.id )
                     v.setName( 'Local file inclusion vulnerability' )
                     v.setSeverity(severity.MEDIUM)
                     v.setDesc( 'Local File Inclusion was found at: ' + mutant.foundAt() )
                     v['file_pattern'] = file_content
                     v.addToHighlight( file_content )
                     kb.kb.append( self, 'localFileInclude', 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.getModValue() == urlParser.getFileName( mutant.getURL() ):
                 match, lang = is_source_file( response.getBody() )
                 if match:
                     #   We were able to read the source code of the file that is vulnerable to
                     #   local file read
                     v = vuln.vuln( mutant )
                     v.setPluginName(self.getName())
                     v.setId( response.id )
                     v.setName( 'Local file read vulnerability' )
                     v.setSeverity(severity.MEDIUM)
                     msg = 'An arbitrary local file read vulnerability was found at: '
                     msg += mutant.foundAt()
                     v.setDesc( msg )
                     
                     #
                     #    Set which part of the source code to match
                     #
                     match_source_code = match.group(0)
                     v['file_pattern'] = match_source_code
                     
                     kb.kb.append( self, 'localFileInclude', 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.getBody() )
                 
                 if match and not \
                 regex.search( mutant.getOriginalResponseBody() ):
                     i = info.info( mutant )
                     i.setPluginName(self.getName())
                     i.setId( response.id )
                     i.setName( 'File read error' )
                     i.setDesc( 'A file read error was found at: ' + mutant.foundAt() )
                     kb.kb.append( self, 'error', i )
Example #6
0
File: lfi.py Project: weisst/w3af
    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)
Example #7
0
 def test_no_code_case04(self):
     source = 'foo <?ypacket ?> "bar'
     match, lang = is_source_file(source)
     
     self.assertNotEqual(match, None)
     self.assertEqual(lang, 'PHP')
Example #8
0
 def test_no_code_case02(self):
     source = 'foo <?xml ?> "bar'
     match, lang = is_source_file(source)
     
     self.assertEqual(match, None)
     self.assertEqual(lang, None)
Example #9
0
    def test_php(self):
        source = 'foo <? echo "a"; ?> bar'
        match, lang = is_source_file(source)

        self.assertNotEqual(match, None)
        self.assertEqual(lang, 'PHP')
Example #10
0
    def test_no_code_case04(self):
        source = 'foo <?ypacket ?> "bar'
        match, lang = is_source_file(source)

        self.assertNotEqual(match, None)
        self.assertEqual(lang, 'PHP')
Example #11
0
    def test_no_code_case02(self):
        source = 'foo <?xml ?> "bar'
        match, lang = is_source_file(source)

        self.assertEqual(match, None)
        self.assertEqual(lang, None)
Example #12
0
    def test_php(self):
        source = 'foo <? echo "a"; ?> bar'
        match, lang = is_source_file(source)

        self.assertNotEqual(match, None)
        self.assertEqual(lang, 'PHP')