Beispiel #1
0
    def discover(self, fuzzable_request):
        """
        Checks if JBoss Interesting Directories exist in the target server.
        Also verifies some vulnerabilities.
        """
        base_url = fuzzable_request.get_url().base_url()

        args_iter = izip(repeat(base_url), self.JBOSS_VULNS)
        otm_send_request = one_to_many(self.send_request)
        response_pool = self.worker_pool.imap_unordered(otm_send_request,
                                                        args_iter)

        for vuln_db_instance, response in response_pool:

            if is_404(response):
                continue

            vuln_url = base_url.url_join(vuln_db_instance['url'])
            name = vuln_db_instance['name']
            desc = vuln_db_instance['desc']

            if vuln_db_instance['type'] == 'info':
                o = Info(name, desc, response.id, self.get_name())
            else:
                o = Vuln(name, desc, severity.LOW, response.id, self.get_name())

            o.set_url(vuln_url)
            kb.kb.append(self, 'find_jboss', o)

            for fr in self._create_fuzzable_requests(response):
                self.output_queue.put(fr)
Beispiel #2
0
    def discover(self, fuzzable_request):
        """
        Checks if JBoss Interesting Directories exist in the target server.
        Also verifies some vulnerabilities.
        """
        base_url = fuzzable_request.get_url().base_url()

        args_iter = izip(repeat(base_url), self.JBOSS_VULNS)
        otm_send_request = one_to_many(self.send_request)
        response_pool = self.worker_pool.imap_unordered(
            otm_send_request, args_iter)

        for vuln_db_instance, response in response_pool:

            if is_404(response):
                continue

            vuln_url = base_url.url_join(vuln_db_instance['url'])
            name = vuln_db_instance['name']
            desc = vuln_db_instance['desc']

            if vuln_db_instance['type'] == 'info':
                o = Info(name, desc, response.id, self.get_name())
            else:
                o = Vuln(name, desc, severity.LOW, response.id,
                         self.get_name())

            o.set_url(vuln_url)
            kb.kb.append(self, 'find_jboss', o)

            self.output_queue.put(FuzzableRequest(response.get_uri()))
Beispiel #3
0
    def _send_in_threads(self, base_url, vhosts):
        base_url_repeater = repeat(base_url)
        args_iterator = izip(base_url_repeater, vhosts)
        http_get = return_args(one_to_many(self._http_get_vhost))
        pool_results = self.worker_pool.imap_unordered(http_get, args_iterator)

        for ((base_url, vhost),), vhost_response in pool_results:
            yield vhost, vhost_response
Beispiel #4
0
    def _send_in_threads(self, base_url, vhosts):
        base_url_repeater = repeat(base_url)
        args_iterator = izip(base_url_repeater, vhosts)
        http_get = return_args(one_to_many(self._http_get_vhost))
        pool_results = self.worker_pool.imap_unordered(http_get, args_iterator)

        for ((base_url, vhost), ), vhost_response in pool_results:
            yield vhost, vhost_response
Beispiel #5
0
    def audit(self, freq, original_response):
        """
        Find all kind of "generic" bugs without using a fixed error database

        :param freq: A FuzzableRequest
        """
        # Prevent some false positives for cases where the original response
        # is already triggering an error
        if original_response.get_code() == 500:
            return

        # Get the original response and create the mutants
        mutants = create_mutants(freq, ['', ], orig_resp=original_response)

        original_response_repeat = repeat(original_response)
        args_iterator = izip(original_response_repeat, mutants)
        check_mutant = one_to_many(self._check_mutant)

        self.worker_pool.imap_unordered(check_mutant, args_iterator)
Beispiel #6
0
    def audit(self, freq, original_response):
        """
        Find all kind of "generic" bugs without using a fixed error database

        :param freq: A FuzzableRequest
        """
        # Prevent some false positives for cases where the original response
        # is already triggering an error
        if original_response.get_code() == 500:
            return

        # Get the original response and create the mutants
        mutants = create_mutants(freq, [
            '',
        ], orig_resp=original_response)

        original_response_repeat = repeat(original_response)
        args_iterator = izip(original_response_repeat, mutants)
        check_mutant = one_to_many(self._check_mutant)

        self.worker_pool.imap_unordered(check_mutant, args_iterator)
Beispiel #7
0
class php_eggs(InfrastructurePlugin):
    """
    Fingerprint the PHP version using documented easter eggs that exist in PHP.
    :author: Andres Riancho ([email protected])
    """
    PHP_EGGS = [('?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000', 'PHP Credits'),
                ('?=PHPE9568F34-D428-11d2-A769-00AA001ACF42', 'PHP Logo'),
                ('?=PHPE9568F35-D428-11d2-A769-00AA001ACF42', 'Zend Logo'),
                ('?=PHPE9568F36-D428-11d2-A769-00AA001ACF42', 'PHP Logo 2')]

    # Empty EGG_DB array, will be filled with external data
    EGG_DB = {}

    def __init__(self):
        InfrastructurePlugin.__init__(self)

        # Already analyzed extensions
        self._already_analyzed_ext = ScalableBloomFilter()

        # Internal DB
        self._db_file = os.path.join(ROOT_PATH, 'plugins', 'infrastructure',
                                     'php_eggs', 'eggs.json')

        # Get data from external JSON file and fill EGG_DB array
        data = self.read_jsondata(self._db_file)
        self.EGG_DB = self.fill_egg_array(data)

    def read_jsondata(self, jsonfile):
        """
        Read a JSON file. File handling for reading a JSON file
        :return: Raw JSON data.
        """
        json_data = open(jsonfile)
        file_data = json.load(json_data)
        json_data.close()
        return file_data

    def fill_egg_array(self, json_egg_data):
        """
        Fill an array with data from a JSON input file.
        :return: An array with PHP-versions with corresponding MD5 hashes.
        """
        egg_db = {}

        for egg in json_egg_data['db']:
            version = egg['version']
            egg_db[version] = {}

            for key in ('credits', 'php_1', 'php_2', 'zend'):
                if key in egg:
                    egg_db[version][key] = egg[key]

        return egg_db

    def discover(self, fuzzable_request):
        """
        Nothing strange, just do some GET requests to the eggs and analyze the
        response.

        :param fuzzable_request: A fuzzable_request instance that contains
                                 (among other things) the URL to test.
        """
        # Get the extension of the URL (.html, .php, .. etc)
        ext = fuzzable_request.get_url().get_extension()

        # Only perform this analysis if we haven't already analyzed this type
        # of extension OR if we get an URL like http://f00b5r/4/     (Note that
        # it has no extension) This logic will perform some extra tests... but
        # we won't miss some special cases. Also, we aren't doing something like
        # "if 'php' in ext:" because we never depend on something so easy to
        # modify as extensions to make decisions.
        if ext not in self._already_analyzed_ext:

            # Now we save the extension as one of the already analyzed
            self._already_analyzed_ext.add(ext)

            # Init some internal variables
            query_results = self._get_php_eggs(fuzzable_request, ext)

            if self._are_php_eggs(query_results):
                # analyze the info to see if we can identify the version
                self._extract_version_from_egg(query_results)
                raise NoMoreCalls

    def _get_php_eggs(self, fuzzable_request, ext):
        """
        HTTP GET the URLs for PHP Eggs
        :return: A list with the HTTP response objects
        """
        def http_get(fuzzable_request, (egg_url, egg_desc)):
            egg_url = fuzzable_request.get_url().uri2url().url_join(egg_url)
            response = self._uri_opener.GET(egg_url, cache=True, grep=False)
            return response, egg_url, egg_desc

        # Send the requests using threads:
        query_results = []

        http_get = one_to_many(http_get)
        fr_repeater = repeat(fuzzable_request)
        args_iterator = izip(fr_repeater, self.PHP_EGGS)
        pool_results = self.worker_pool.imap_unordered(http_get, args_iterator)

        for response, egg_URL, egg_desc in pool_results:
            eqr = EggQueryResult(response, egg_desc, egg_URL)
            query_results.append(eqr)

        return query_results
Beispiel #8
0
        def http_get(fuzzable_request, (egg_url, egg_desc)):
            egg_URL = fuzzable_request.get_url().uri2url().url_join(egg_url)
            try:
                response = self._uri_opener.GET(egg_URL, cache=True)
            except BaseFrameworkException, w3:
                raise w3
            else:
                return response, egg_URL, egg_desc

        # Send the requests using threads:
        query_results = []
        EggQueryResult = namedtuple('EggQueryResult', ['http_response',
                                                       'egg_desc',
                                                       'egg_URL'])
        
        http_get = one_to_many(http_get)
        fr_repeater = repeat(fuzzable_request)
        args_iterator = izip(fr_repeater, self.PHP_EGGS)
        pool_results = self.worker_pool.imap_unordered(http_get,
                                                       args_iterator)

        for response, egg_URL, egg_desc in pool_results:
            eqr = EggQueryResult(response, egg_desc, egg_URL)
            query_results.append(eqr)

        return query_results

    def _are_php_eggs(self, query_results):
        """
        Now I analyze if this is really a PHP eggs thing, or simply a response that
        changes a lot on each request. Before, I had something like this: