Ejemplo n.º 1
0
 def test_variants_true_similar_params(self):
     # change the url by adding a querystring. shouldn't affect anything.
     url = self.url.url_join('?a=z')
     fr = FuzzableRequest(url, method='GET', dc={'a': ['1'], 'b': ['bb']})
     fr_other = FuzzableRequest(
         self.url, method='GET', dc={'a': ['2'], 'b': ['cc']})
     self.assertTrue(fr.is_variant_of(fr_other))
Ejemplo n.º 2
0
    def __init__(self, uri, method="POST", headers=Headers(), cookie=None, dc=None):

        if dc is not None and not isinstance(dc, Form):
            msg = "The dc parameter for forms needs to be a Form instance," "got %s instead." % type(dc)
            TypeError(msg)

        FuzzableRequest.__init__(self, uri, method, headers, cookie, dc)
Ejemplo n.º 3
0
    def test_mutant_creation_repeated_params(self):
        qs = QueryString([('a', ['1', '2']), ('b', ['3'])])
        freq = FuzzableRequest(self.url)
        freq.set_querystring(qs)

        created_mutants = FakeMutant.create_mutants(freq, self.payloads, [],
                                                    False, self.fuzzer_config)

        expected_dcs = ['a=abc&a=2&b=3',
                        'a=1&a=abc&b=3',
                        'a=1&a=2&b=abc',
                        'a=def&a=2&b=3',
                        'a=1&a=def&b=3',
                        'a=1&a=2&b=def']

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEquals(expected_dcs, created_dcs)

        token_0 = created_mutants[0].get_token()
        self.assertIsInstance(token_0, DataToken)
        self.assertEqual(token_0.get_name(), 'a')
        self.assertEqual(token_0.get_original_value(), '1')
        self.assertEqual(token_0.get_value(), 'abc')

        token_1 = created_mutants[1].get_token()
        self.assertIsInstance(token_1, DataToken)
        self.assertEqual(token_1.get_name(), 'a')
        self.assertEqual(token_1.get_original_value(), '2')
        self.assertEqual(token_1.get_value(), 'abc')
Ejemplo n.º 4
0
    def test_mutant_creation(self):
        qs = QueryString(self.SIMPLE_KV)
        freq = FuzzableRequest(self.url)
        freq.set_querystring(qs)

        created_mutants = FakeMutant.create_mutants(freq, self.payloads, [],
                                                    False, self.fuzzer_config)

        expected_dcs = ['a=abc&b=2', 'a=1&b=abc',
                        'a=def&b=2', 'a=1&b=def']

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEquals(expected_dcs, created_dcs)

        token_0 = created_mutants[0].get_token()
        self.assertIsInstance(token_0, DataToken)
        self.assertEqual(token_0.get_name(), 'a')
        self.assertEqual(token_0.get_original_value(), '1')
        self.assertEqual(token_0.get_value(), 'abc')

        token_2 = created_mutants[1].get_token()
        self.assertIsInstance(token_0, DataToken)
        self.assertEqual(token_2.get_name(), 'b')
        self.assertEqual(token_2.get_original_value(), '2')
        self.assertEqual(token_2.get_value(), 'abc')

        self.assertTrue(all(isinstance(m, Mutant) for m in created_mutants))
        self.assertTrue(all(m.get_mutant_class() == 'FakeMutant' for m in created_mutants))
Ejemplo n.º 5
0
    def test_audit_plugin_timeout_threads(self):
        """
        I want to make sure that when stopit kills the real audit function,
        the threads which are called from it won't do anything strange.

        The plan is to scan something large with httpretty, with delays in the
        HTTP responses to simulate a slow network and a low PLUGIN_TIMEOUT to
        make the test quicker.
        """
        plugin_inst = self.w3afcore.plugins.get_plugin_inst('audit', 'sqli')

        url = URL(self.target_url)
        freq = FuzzableRequest(url)

        orig_response = plugin_inst.get_original_response(freq)

        mod = 'w3af.core.controllers.plugins.audit_plugin.%s'

        with patch(mod % 'om.out') as om_mock,\
             patch(mod % 'AuditPlugin.PLUGIN_TIMEOUT', new_callable=PropertyMock) as timeout_mock:

            timeout_mock.return_value = 2
            plugin_inst.audit_with_copy(freq, orig_response)

            msg = '[timeout] The "%s" plugin took more than %s seconds to'\
                  ' complete the analysis of "%s", killing it!'

            error = msg % (plugin_inst.get_name(),
                           plugin_inst.PLUGIN_TIMEOUT,
                           freq.get_url())

            self.assertIn(call.debug(error), om_mock.mock_calls)
Ejemplo n.º 6
0
    def test_add_QsRequest(self):
        ds = DiskSet()

        uri = URL('http://w3af.org/?id=2')
        hdr = Headers([('Referer', 'http://w3af.org/')])

        qsr1 = FuzzableRequest(uri, method='GET', headers=hdr)

        uri = URL('http://w3af.org/?id=3')
        qsr2 = FuzzableRequest(uri, method='GET', headers=hdr)

        uri = URL('http://w3af.org/?id=7')
        qsr3 = FuzzableRequest(uri, method='FOO', headers=hdr)

        ds.add(qsr1)
        ds.add(qsr2)
        ds.add(qsr2)
        ds.add(qsr1)

        self.assertEqual(ds[0], qsr1)
        self.assertEqual(ds[1], qsr2)
        self.assertFalse(qsr3 in ds)
        self.assertTrue(qsr2 in ds)
        self.assertEqual(len(ds), 2)

        # This forces an internal change in the URL object
        qsr2.get_url().url_string
        self.assertIn(qsr2, ds)
Ejemplo n.º 7
0
 def test_export_with_dc(self):
     fr = FuzzableRequest(URL("http://www.w3af.com/"))
     d = DataContainer()
     d['a'] = ['1',]
     fr.set_dc(d)
     self.assertEqual(fr.export(),
                      'GET,http://www.w3af.com/?a=1,')
Ejemplo n.º 8
0
 def test_find_csrf_token_true_simple(self):
     url = URL('http://moth/w3af/audit/csrf/')
     query_string = parse_qs('secret=f842eb01b87a8ee18868d3bf80a558f3')
     freq = FuzzableRequest(url, method='GET')
     freq.set_querystring(query_string)
     
     token = self.csrf_plugin._find_csrf_token(freq)
     self.assertIn('secret', token)
Ejemplo n.º 9
0
 def test_find_csrf_token_false(self):
     url = URL('http://moth/w3af/audit/csrf/')
     query_string = parse_qs('secret=not a token')
     freq = FuzzableRequest(url, method='GET')
     freq.set_querystring(query_string)
     
     token = self.csrf_plugin._find_csrf_token(freq)
     self.assertNotIn('secret', token)
    def test_sent_post_data(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", """d'z"0""")])
        form_params.add_field_by_attr_items([("name", "address"), ("value", "")])

        form = dc_from_form_params(form_params)

        f = FuzzableRequest(URL('http://example.com/'), post_data=form)
        self.assertTrue(f.sent('d%5C%27z%5C%220'))
    def test_export_import_with_post_data(self):
        dc = KeyValueContainer(init_val=[('a', ['1'])])
        fr = FuzzableRequest(URL("http://www.w3af.com/"), post_data=dc)

        self.assertEqual(fr.to_csv(), '"GET","http://www.w3af.com/","a=1"')

        raise SkipTest('Failing because we do NOT export headers')
        imported_fr = fr.from_csv(fr.to_csv())
        self.assertEqual(imported_fr, fr)
Ejemplo n.º 12
0
    def test_mutant_creation_empty_dc(self):
        qs = QueryString()
        freq = FuzzableRequest(self.url)
        freq.set_querystring(qs)

        created_mutants = FakeMutant.create_mutants(freq, self.payloads, [],
                                                    False, self.fuzzer_config)

        expected_dc_lst = []
        created_dc_lst = [i.get_dc() for i in created_mutants]

        self.assertEqual(created_dc_lst, expected_dc_lst)
Ejemplo n.º 13
0
    def test_basic(self):
        freq = FuzzableRequest(URL('http://www.w3af.com/'))
        fake_ref = 'http://w3af.org/'

        mutant = HeadersMutant(freq.copy())
        mutant.set_var('Referer')
        original_referer = freq.get_referer()
        mutant.set_original_value(original_referer)
        mutant.set_mod_value(fake_ref)

        self.assertEqual(mutant.get_headers()['Referer'], fake_ref)
        self.assertEqual(mutant.get_original_value(), original_referer)
Ejemplo n.º 14
0
    def test_dump_case01(self):
        expected = '\r\n'.join(['GET http://w3af.com/a/b/c.php HTTP/1.1',
                                'Hello: World',
                                '',
                                ''])
        headers = Headers([('Hello', 'World')])

        #TODO: Note that I'm passing a dc to the FuzzableRequest and it's not
        # appearing in the dump. It might be a bug...
        fr = FuzzableRequest(self.url, method='GET', dc={'a': ['b']},
                             headers=headers)
        self.assertEqual(fr.dump(), expected)
Ejemplo n.º 15
0
 def test_dump_case02(self):
     expected = u'\r\n'.join([u'GET http://w3af.com/a/b/c.php HTTP/1.1',
                              u'Hola: Múndo',
                              u'',
                              u''])
     headers = Headers([(u'Hola', u'Múndo')])
     
     #TODO: Note that I'm passing a dc to the FuzzableRequest and it's not
     # appearing in the dump. It might be a bug...
     fr = FuzzableRequest(self.url, method='GET', dc={u'á': ['b']},
                          headers=headers)
     self.assertEqual(fr.dump(), expected)
    def test_dump_case02(self):
        expected = u'\r\n'.join([u'GET http://w3af.com/a/b/c.php HTTP/1.1',
                                 u'Hola: Múndo',
                                 u'',
                                 u'a=b'])

        headers = Headers([(u'Hola', u'Múndo')])
        post_data = KeyValueContainer(init_val=[('a', ['b'])])
        fr = FuzzableRequest(self.url, method='GET', post_data=post_data,
                             headers=headers)

        self.assertEqual(fr.dump(), expected.encode('utf-8'))
Ejemplo n.º 17
0
    def test_mutant_creation_ignore_params(self):
        qs = QueryString(self.SIMPLE_KV)
        freq = FuzzableRequest(self.url)
        freq.set_querystring(qs)

        created_mutants = FakeMutant.create_mutants(freq, self.payloads, ['a'],
                                                    False, self.fuzzer_config)

        expected_dcs = ['a=abc&b=2', 'a=def&b=2']
        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(expected_dcs, created_dcs)
Ejemplo n.º 18
0
    def test_mutant_copy(self):
        qs = QueryString(self.SIMPLE_KV)
        freq = FuzzableRequest(self.url)
        freq.set_querystring(qs)

        mutant = FakeMutant(freq)
        mutant.set_token(('a', 0))

        mutant_copy = mutant.copy()

        self.assertEqual(mutant, mutant_copy)
        self.assertEqual(mutant.get_token(), mutant_copy.get_token())
        self.assertIsNot(None, mutant_copy.get_token())
Ejemplo n.º 19
0
    def test_basic(self):
        referer_1 = 'http://w3af.org/'
        referer_2 = 'http://spam.w3af.org/'

        freq = FuzzableRequest(URL('http://www.w3af.com/'),
                               headers=Headers([('Referer', referer_1)]))
        self.assertEqual(freq.get_referer(), referer_1)

        m = HeadersMutant(freq)
        m.get_dc().set_token(('Referer',))
        m.set_token_value(referer_2)

        self.assertEqual(m.get_token_value(), referer_2)
    def test_dump_case03(self):
        header_value = ''.join(chr(i) for i in xrange(256))
        
        expected = u'\r\n'.join([u'GET http://w3af.com/a/b/c.php HTTP/1.1',
                                 u'Hola: %s' % smart_unicode(header_value),
                                 u'',
                                 u'a=b'])

        headers = Headers([(u'Hola', header_value)])
        post_data = KeyValueContainer(init_val=[('a', ['b'])])
        fr = FuzzableRequest(self.url, method='GET', post_data=post_data,
                             headers=headers)

        self.assertEqual(fr.dump(), expected)
Ejemplo n.º 21
0
    def test_mutant_creation_append(self):
        qs = QueryString(self.SIMPLE_KV)
        freq = FuzzableRequest(self.url)
        freq.set_querystring(qs)

        created_mutants = FakeMutant.create_mutants(freq, self.payloads, [],
                                                    True, self.fuzzer_config)

        expected_dcs = ['a=1abc&b=2', 'a=1&b=2abc',
                        'a=1def&b=2', 'a=1&b=2def',]

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEquals(expected_dcs, created_dcs)
Ejemplo n.º 22
0
    def test_dump_case03(self):
        header_value = ''.join(chr(i) for i in xrange(256))
        
        expected = u'\r\n'.join([u'GET http://w3af.com/a/b/c.php HTTP/1.1',
                                 u'Hola: %s' % smart_unicode(header_value),
                                 u'',
                                 u''])

        headers = Headers([(u'Hola', header_value)])
        
        #TODO: Note that I'm passing a dc to the FuzzableRequest and it's not
        # appearing in the dump. It might be a bug...
        fr = FuzzableRequest(self.url, method='GET', dc={u'a': ['b']},
                             headers=headers)
        self.assertEqual(fr.dump(), expected)
Ejemplo n.º 23
0
    def crawl(self, fuzzable_request):
        """
        Get the sitemap.xml file and parse it.

        :param fuzzable_request: A fuzzable_request instance that contains
                                   (among other things) the URL to test.
        """
        base_url = fuzzable_request.get_url().base_url()
        sitemap_url = base_url.url_join('sitemap.xml')
        response = self._uri_opener.GET(sitemap_url, cache=True)

        if '</urlset>' in response and not is_404(response):
            # Send response to core
            fr = FuzzableRequest.from_http_response(response)
            self.output_queue.put(fr)

            om.out.debug('Parsing xml file with xml.dom.minidom.')
            try:
                dom = xml.dom.minidom.parseString(response.get_body())
            except:
                raise BaseFrameworkException('Error while parsing sitemap.xml')
            else:
                raw_url_list = dom.getElementsByTagName("loc")
                parsed_url_list = []
                for url in raw_url_list:
                    try:
                        url = url.childNodes[0].data
                        url = URL(url)
                    except ValueError, ve:
                        msg = 'Sitemap file had an invalid URL: "%s"'
                        om.out.debug(msg % ve)
                    except:
                        om.out.debug('Sitemap file had an invalid format')
 def test_str_with_postdata(self):
     headers = Headers([('content-type', URLEncodedForm.ENCODING)])
     fr = FuzzableRequest.from_parts("http://www.w3af.com/", post_data='a=1',
                                     headers=headers)
     expected = 'Method: GET | http://www.w3af.com/ | URL encoded ' \
                'form: (a)'
     self.assertEqual(str(fr), expected)
Ejemplo n.º 25
0
Archivo: grep.py Proyecto: knucker/w3af
    def _get_request_response_from_work_unit(self, work_unit):
        """
        In some cases the work unit is a tuple with request / response instances.

        In other cases it is an ID, which needs to be queried from the History DB
        to get the request / response.

        :param work_unit: One of the options explained above
        :return: A request / response tuple
        """
        if not isinstance(work_unit, int):
            request, response = work_unit
        else:
            # Before we sent requests and responses as work units,
            # but since we changed from Queue to CachedQueue for BaseConsumer
            # the database was growing really big (1GB) for storing that traffic
            # and I decided to migrate to using just the response.id and querying
            # the SQLite one extra time.
            history = HistoryItem()
            request, response = history.load_from_file(work_unit)

        # Create a fuzzable request based on the urllib2 request object
        headers_inst = Headers(request.header_items())
        request = FuzzableRequest.from_parts(request.url_object,
                                             request.get_method(),
                                             request.get_data() or '',
                                             headers_inst)

        return request, response
Ejemplo n.º 26
0
    def _check_if_exists(self, web_shell_url):
        """
        Check if the file exists.

        :param web_shell_url: The URL to check
        """
        try:
            response = self._uri_opener.GET(web_shell_url, cache=True)
        except BaseFrameworkException:
            om.out.debug('Failed to GET webshell:' + web_shell_url)
        else:
            if self._is_possible_backdoor(response):
                desc = 'A web backdoor was found at: "%s"; this could ' \
                       'indicate that the server has been compromised.'
                desc = desc % response.get_url()

                v = Vuln('Potential web backdoor', desc, severity.HIGH,
                         response.id, self.get_name())
                v.set_url(response.get_url())

                kb.kb.append(self, 'backdoors', v)
                om.out.vulnerability(v.get_desc(), severity=v.get_severity())

                fr = FuzzableRequest.from_http_response(response)
                self.output_queue.put(fr)
Ejemplo n.º 27
0
    def test_simplest(self):
        fr = FuzzableRequest.from_parts(self.url)

        self.assertEqual(fr.get_url(), self.url)
        self.assertEqual(fr.get_headers(), Headers())
        self.assertEqual(fr.get_method(), "GET")
        self.assertIsInstance(fr.get_raw_data(), KeyValueContainer)
Ejemplo n.º 28
0
    def _extract_html_forms(self, resp, fuzzable_req):
        """
        Parses the HTTP response body and extract HTML forms, resulting forms
        are put() on the output queue.
        """
        # Try to find forms in the document
        try:
            dp = parser_cache.dpc.get_document_parser_for(resp)
        except BaseFrameworkException:
            # Failed to find a suitable parser for the document
            return

        # Create one FuzzableRequest for each form variant
        mode = cf.cf.get('form_fuzzing_mode')
        for form_params in dp.get_forms():

            # Form exclusion #15161
            form_id_json = form_params.get_form_id().to_json()
            om.out.debug('A new form was found! Form-id is: "%s"' % form_id_json)

            if not self._should_analyze_url(form_params.get_action()):
                continue

            headers = fuzzable_req.get_headers()

            for form_params_variant in form_params.get_variants(mode):
                data_container = dc_from_form_params(form_params_variant)

                # Now data_container is one of Multipart of URLEncoded form
                # instances, which is a DataContainer. Much better than the
                # FormParameters instance we had before in form_params_variant
                r = FuzzableRequest.from_form(data_container, headers=headers)
                self.output_queue.put(r)
Ejemplo n.º 29
0
    def _extract_html_forms(self, resp, fuzzable_req):
        """
        Parses the HTTP response body and extract HTML forms, resulting forms
        are put() on the output queue.
        """
        # Try to find forms in the document
        try:
            dp = parser_cache.dpc.get_document_parser_for(resp)
        except BaseFrameworkException:
            # Failed to find a suitable parser for the document
            return

        same_domain = lambda f: f.get_action().get_domain() == \
                                resp.get_url().get_domain()

        # Create one FuzzableRequest for each form variant
        mode = cf.cf.get('form_fuzzing_mode')
        for form_params in dp.get_forms():

            if not same_domain(form_params):
                continue

            headers = fuzzable_req.get_headers()

            for form_params_variant in form_params.get_variants(mode):
                data_container = dc_from_form_params(form_params_variant)

                # Now data_container is one of Multipart of URLEncoded form
                # instances, which is a DataContainer. Much better than the
                # FormParameters instance we had before in form_params_variant
                r = FuzzableRequest.from_form(data_container, headers=headers)
                self.output_queue.put(r)
Ejemplo n.º 30
0
    def _do_request(self, url, mutant):
        """
        Perform a simple GET to see if the result is an error or not, and then
        run the actual fuzzing.
        """
        response = self._uri_opener.GET(
            mutant, cache=True, headers=self._headers)

        if not (is_404(response) or
        response.get_code() in (403, 401) or
        self._return_without_eval(mutant)):

            # Create the fuzzable request and send it to the core
            fr = FuzzableRequest.from_http_response(response)
            self.output_queue.put(fr)
            
            #
            #   Save it to the kb (if new)!
            #
            if response.get_url() not in self._seen and response.get_url().get_file_name():
                desc = 'A potentially interesting file was found at: "%s".'
                desc = desc % response.get_url()

                i = Info('Potentially interesting file', desc, response.id,
                         self.get_name())
                i.set_url(response.get_url())
                
                kb.kb.append(self, 'files', i)
                om.out.information(i.get_desc())

                # Report only once
                self._seen.add(response.get_url())
Ejemplo n.º 31
0
    def test_analyze_cookies_with_httponly_case_sensitive_expires(self):
        body = ''
        url = URL('https://www.w3af.com/')
        c = 'name2=value2; Expires=Wed, 09-Jun-2021 10:18:14 GMT;Secure;HttpOnly'
        headers = {'content-type': 'text/html', 'Set-Cookie': c}
        headers = Headers(headers.items())
        response = HTTPResponse(200, body, headers, url, url, _id=1)
        request = FuzzableRequest(url, method='GET')

        self.plugin.grep(request, response)

        self.assertEqual(len(kb.kb.get('analyze_cookies', 'cookies')), 1)
        self.assertEqual(len(kb.kb.get('analyze_cookies', 'security')), 0)
Ejemplo n.º 32
0
 def test_analyze_cookies_empty(self):
     body = ''
     url = URL('http://www.w3af.com/')
     headers = Headers({
         'content-type': 'text/html',
         'Set-Cookie': ''
     }.items())
     response = HTTPResponse(200, body, headers, url, url, _id=1)
     request = FuzzableRequest(url, method='GET')
     self.plugin.grep(request, response)
     self.assertEqual(len(kb.kb.get('analyze_cookies', 'cookies')), 1)
     self.assertEqual(len(kb.kb.get('analyze_cookies', 'invalid-cookies')),
                      0)
Ejemplo n.º 33
0
    def _fingerprint_installer(self, domain_path, wp_unique_url, response):
        """
        GET latest.zip and latest.tar.gz and compare with the hashes from the
        release.db that was previously generated from wordpress.org [0]
        and contains all release hashes.

        This gives the initial wordpress version, not the current one.

        [0] http://wordpress.org/download/release-archive/
        """
        zip_url = domain_path.url_join('latest.zip')
        tar_gz_url = domain_path.url_join('latest.tar.gz')
        install_urls = [zip_url, tar_gz_url]

        for install_url in install_urls:
            response = self._uri_opener.GET(install_url, cache=True,
                                            respect_size_limit=False)

            # md5sum the response body
            m = hashlib.md5()
            m.update(response.get_body())
            remote_release_hash = m.hexdigest()

            release_db = self._release_db

            for line in file(release_db):
                try:
                    line = line.strip()
                    release_db_hash, release_db_name = line.split(',')
                except:
                    continue

                if release_db_hash == remote_release_hash:

                    desc = ('The sysadmin used WordPress version "%s" during the'
                            ' installation, which was found by matching the contents'
                            ' of "%s" with the hashes of known releases. If the'
                            ' sysadmin did not update wordpress, the current version'
                            ' will still be the same.')
                    desc %= (release_db_name, install_url)

                    i = Info('Fingerprinted Wordpress version', desc, response.id,
                             self.get_name())
                    i.set_url(install_url)
                    
                    kb.kb.append(self, 'info', i)
                    om.out.information(i.get_desc())

                    # Send link to core
                    fr = FuzzableRequest(response.get_uri())
                    self.output_queue.put(fr)
Ejemplo n.º 34
0
    def _brute_worker(self, url, combination):
        """
        Try a user/password combination with HTTP basic authentication against
        a specific URL.

        :param url: A string representation of an URL
        :param combination: A tuple that contains (user,pass)
        """
        # Remember that this worker is called from a thread which lives in a
        # threadpool. If the worker finds something, it has to let the rest know
        # and the way we do that is by setting self._found.
        #
        # If one thread sees that we already bruteforced the access, the rest
        # will simply no-op
        if not self._found or not self._stop_on_first:
            user, passwd = combination

            raw_values = "%s:%s" % (user, passwd)
            auth = 'Basic %s' % base64.b64encode(raw_values).strip()
            headers = Headers([('Authorization', auth)])

            fr = FuzzableRequest(url, headers=headers, method='GET')

            try:
                response = self._uri_opener.send_mutant(fr,
                                                        cache=False,
                                                        grep=False)
            except BaseFrameworkException, w3:
                msg = 'Exception while brute-forcing basic authentication,' \
                      ' error message: "%s".'
                om.out.debug(msg % w3)
            else:
                # GET was OK
                if response.get_code() != 401:
                    self._found = True

                    desc = 'Found authentication credentials to: "%s".' \
                           ' A valid user and password combination is: %s/%s .'
                    desc = desc % (url, user, passwd)
                    v = Vuln('Guessable credentials', desc, severity.HIGH,
                             response.id, self.get_name())
                    v.set_url(url)

                    v['user'] = user
                    v['pass'] = passwd
                    v['response'] = response
                    v['request'] = fr

                    kb.kb.append(self, 'auth', v)
                    om.out.vulnerability(v.get_desc(),
                                         severity=v.get_severity())
Ejemplo n.º 35
0
    def test_analyze_cookies_no_httponly(self):
        body = ''
        url = URL('http://www.w3af.com/1')
        headers = Headers({
            'content-type': 'text/html',
            'Set-Cookie': 'abc=def'
        }.items())
        response = HTTPResponse(200, body, headers, url, url, _id=1)
        request = FuzzableRequest(url, method='GET')
        self.plugin.grep(request, response)

        url = URL('http://www.w3af.com/2')
        headers = Headers({
            'content-type': 'text/html',
            'Set-Cookie': 'abc=def'
        }.items())
        response = HTTPResponse(200, body, headers, url, url, _id=2)
        request = FuzzableRequest(url, method='GET')
        self.plugin.grep(request, response)

        http_only = kb.kb.get('analyze_cookies', 'http_only')

        self.assertEqual(len(http_only), 1)
        self.assertEqual(len(kb.kb.get('analyze_cookies', 'cookies')), 1)
        self.assertEqual(len(kb.kb.get('analyze_cookies', 'invalid-cookies')),
                         0)

        info_set = http_only[0]
        expected_desc = u'The application sent the "abc" cookie without the' \
                        u' HttpOnly flag in 2 different responses. The' \
                        u' HttpOnly flag prevents potential intruders from' \
                        u' accessing the cookie value through Cross-Site' \
                        u' Scripting attacks. The first ten URLs which sent' \
                        u' the insecure cookie are:\n' \
                        u' - http://www.w3af.com/2\n - http://www.w3af.com/1\n'
        self.assertEqual(info_set.get_desc(), expected_desc)
        self.assertEqual(info_set.get_id(), [1, 2])
        self.assertEqual(len(info_set.infos), 2)
Ejemplo n.º 36
0
    def test_is_suitable(self):
        # False because no cookie is set and no QS nor post-data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        # False because no cookie is set
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        url_sends_cookie = URL(
            'http://moth/w3af/core/cookie_handler/set-cookie.php')
        self.uri_opener.GET(url_sends_cookie)

        # Still false because it doesn't have any QS or POST data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        self.csrf_plugin._strict_mode = True

        # Still false because of the strict mode
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        # False, no items in post-data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='POST', post_data=URLEncodedForm())
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        # True, items in DC, POST (passes strict mode) and cookies
        url = URL('http://moth/')
        form_params = FormParameters()
        form_params.add_input([('name', 'test'), ('type', 'text')])
        form = URLEncodedForm(form_params)
        req = FuzzableRequest(url, method='POST', post_data=form)
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertTrue(suitable)

        self.csrf_plugin._strict_mode = False

        # True now that we have strict mode off, cookies and QS
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertTrue(suitable)
Ejemplo n.º 37
0
    def test_analyze_cookies_with_httponly_case_sensitive(self):
        body = ''
        url = URL('https://www.w3af.com/')
        headers = Headers({
            'content-type': 'text/html',
            'Set-Cookie': 'abc=def;Secure;HttpOnly'
        }.items())
        response = HTTPResponse(200, body, headers, url, url, _id=1)
        request = FuzzableRequest(url, method='GET')

        self.plugin.grep(request, response)

        self.assertEqual(len(kb.kb.get('analyze_cookies', 'cookies')), 1)
        self.assertEqual(len(kb.kb.get('analyze_cookies', 'http_only')), 0)
Ejemplo n.º 38
0
 def test_sl_3(self, *args):
     """
     Static link 3, text/javascript
     """
     body = 'function { ws_url =' \
            '"wss://www.example.com/socketserver:8080";' \
            'wslink = new WebSocket(url); return wslink} '
     url = URL('https://www.w3af.com/')
     headers = Headers([('content-type', 'text/javascript')])
     response = HTTPResponse(200, body, headers, url, url, _id=1)
     request = FuzzableRequest(url, method='GET')
     self.plugin.grep(request, response)
     self.assertEqual(len(kb.kb.get('websockets_links',
                                    'websockets_links')), 1)
Ejemplo n.º 39
0
    def test_clean_form_fuzzable_request_form(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", "abc")])
        form_params.add_field_by_attr_items([("name", "address"), ("value", "")])
        form_params.set_action(URL('http://example.com/?id=1'))
        form_params.set_method('post')

        form = dc_from_form_params(form_params)

        fr = FuzzableRequest.from_form(form)

        expected = u'(POST)-http://example.com/' \
                   u'?id=number!username=string&address=string'
        self.assertEqual(clean_fuzzable_request(fr), expected)
Ejemplo n.º 40
0
    def test_https_with_ect(self):
        body = ''
        url = URL('https://www.w3af.com/')
        headers = Headers([
            ('content-type', 'text/html'),
            ('expect-ct',
             'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'
             )
        ])
        request = FuzzableRequest(url, method='GET')
        resp = HTTPResponse(200, body, headers, url, url, _id=1)

        self.plugin.grep(request, resp)
        self.assertEquals(len(kb.kb.get('expect_ct', 'expect_ct')), 0)
Ejemplo n.º 41
0
    def test_not_php_serialized_objects(self):
        # Note that I'm sending the serialized object in reverse string order
        post_data = 'obj=%s' % base64.b64encode(
            SERIALIZED_PHP_OBJECTS[1][::-1])
        headers = Headers([('Content-Type',
                            'application/x-www-form-urlencoded')])

        form = URLEncodedForm.from_postdata(headers, post_data)
        request = FuzzableRequest(self.url, headers=headers, post_data=form)

        self.plugin.grep(request, self.response)

        self.assertEquals(
            len(kb.kb.get('serialized_object', 'serialized_object')), 0)
Ejemplo n.º 42
0
    def test_handle_exception(self):
        url = URL('http://moth/')
        fr = FuzzableRequest(url)
        try:
            raise Exception()
        except Exception as e:
            self.bc.handle_exception('audit', 'sqli', fr, e)

        exception_data = self.bc.out_queue.get()

        self.assertTrue(exception_data.traceback is not None)
        self.assertEqual(exception_data.phase, 'audit')
        self.assertEqual(exception_data.plugin, 'sqli')
        self.assertEqual(exception_data.exception, e)
    def test_json_post(self):
        post_data = '{"1":"2"}'
        hdr = Headers([('content-length', str(len(post_data))),
                       ('content-type', 'application/json')])

        fr = FuzzableRequest.from_parts(self.url,
                                        headers=hdr,
                                        post_data=post_data,
                                        method='POST')

        self.assertEqual(fr.get_url(), self.url)
        self.assertEqual(fr.get_headers(), hdr)
        self.assertEqual(fr.get_method(), 'POST')
        self.assertIsInstance(fr.get_raw_data(), JSONContainer)
Ejemplo n.º 44
0
    def _grep(self, request, response):

        url_instance = request.url_object
        domain = url_instance.get_domain()

        if self._grep_queue_put is not None and \
                        domain in cf.cf.get('target_domains'):
            # Create a fuzzable request based on the urllib2 request object
            headers_inst = Headers(request.header_items())
            fr = FuzzableRequest.from_parts(url_instance, request.get_method(),
                                            request.get_data() or '',
                                            headers_inst)

            self._grep_queue_put((fr, response))
Ejemplo n.º 45
0
        def create_fuzzable_request(_id):
            url = 'http://example.com/product/1'

            form_params = FormParameters()
            form_params.add_field_by_attr_items([("name", "username%s" % _id),
                                                 ("value", "abc")])
            form_params.add_field_by_attr_items([("name", "address"),
                                                 ("value", "")])
            form_params.set_action(URL(url))
            form_params.set_method('post')

            form = dc_from_form_params(form_params)

            return FuzzableRequest.from_form(form)
Ejemplo n.º 46
0
 def test_url_session_in_url(self):
     body = 'abc'
     url = URL('http://www.w3af.com/?JSESSIONID=231badb19b93e44f47da1bd64a8147f2')
     headers = Headers([('content-type', 'text/html')])
     request = FuzzableRequest(url, method='GET')
     resp = HTTPResponse(200, body, headers, url, url, _id=1)
     
     self.plugin.grep(request, resp)
     
     infos = kb.kb.get('url_session', 'url_session')
     self.assertEquals(len(infos), 1)
     
     info = infos[0]
     self.assertEqual(info.get_name(), 'Session ID in URL')       
Ejemplo n.º 47
0
    def audit(self, freq, orig_response):
        url = URL(freq.get_url() + self._PAYLOAD)
        print 'the url is %s', url
        freq_new = FuzzableRequest(url, method='GET')
        response = self._uri_opener.send_mutant(freq_new)
        print response.get_body()
        if 'root:/root' in response.get_body():
            msg = 'Directory Traversal Vulnerbility found at ' + freq.get_url()
            v = Vuln.from_fr('Directory Traversal vulnerability',
                             msg, severity.MEDIUM, orig_response.id,
                             self.get_name(), freq)

            print 'hello there'
            self.kb_append_uniq(self, 'directory_traversal', v)
Ejemplo n.º 48
0
    def test_mutant_creation(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"),
                                             ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/?id=3'),
                               post_data=form,
                               method='PUT')

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)

        expected_dcs = [
            'username=def&address=Bonsai%20Street%20123',
            'username=abc&address=Bonsai%20Street%20123',
            'username=John8212&address=def', 'username=John8212&address=abc'
        ]

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(set(created_dcs), set(expected_dcs))

        token = created_mutants[0].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[1].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[2].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        token = created_mutants[3].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'PUT')
Ejemplo n.º 49
0
 def test_image_with_image_content_type(self, *args):
     """
     Verify that our plugins don't break when we send them an image.
     """
     file_path = os.path.join(ROOT_PATH, 'plugins', 'tests', 'grep',
                              'data', 'w3af.png')        
     body = file(file_path).read()
     hdrs = Headers({'Content-Type': 'image/png'}.items())
     response = HTTPResponse(200, body, hdrs, self.url_inst, self.url_inst,
                             _id=random.randint(1, 5000))
     request = FuzzableRequest(self.url_inst)
     
     for pinst in self._plugins:
         pinst.grep(request, response)
Ejemplo n.º 50
0
    def test_php_serialized_objects_query_string(self):

        for i, obj in enumerate(SERIALIZED_PHP_OBJECTS):
            url = self.url.copy()

            qs = QueryString([(str(i), [obj])])
            url.set_querystring(qs)

            request = FuzzableRequest(url)

            self.plugin.grep(request, self.response)

        self.assertEquals(len(kb.kb.get('serialized_object',
                                        'serialized_object')), 2)
 def test_vs4(self, *args):
     body = 'header <form action="http://www.w3af.com/"><div>' \
            '<input type="password" name="passwd" /></div></form>footer'
     url = URL('https://www.w3af.com/')
     headers = Headers([('content-type', 'text/html')])
     response = HTTPResponse(200, body, headers, url, url, _id=1)
     request = FuzzableRequest(url, method='GET')
     self.plugin.grep(request, response)
     self.assertEqual(
         len(kb.kb.get('form_cleartext_password',
                       'form_cleartext_password')), 1)
     self.assertEqual(
         kb.kb.get('form_cleartext_password', 'form_cleartext_password')
         [0].get_name() == 'Insecure password submission over HTTP', 1)
 def test_n1(self, *args):
     """
     Not vulnerable
     """
     body = 'header <form action="https://www.w3af.com/">' \
            '<input type="text" /></form>footer'
     url = URL('http://www.w3af.com/')
     headers = Headers([('content-type', 'text/html')])
     response = HTTPResponse(200, body, headers, url, url, _id=1)
     request = FuzzableRequest(url, method='GET')
     self.plugin.grep(request, response)
     self.assertEqual(
         len(kb.kb.get('form_cleartext_password',
                       'form_cleartext_password')), 0)
Ejemplo n.º 53
0
    def setUp(self):
        super(TestCORSOrigin, self).setUp()

        self.co = cors_origin()

        self.url = URL('http://moth/')
        self.origin = 'http://moth/'
        self.response = HTTPResponse(200,
                                     '',
                                     Headers(),
                                     self.url,
                                     self.url,
                                     _id=3)
        self.request = FuzzableRequest(self.url)
    def test_https_with_sts(self):
        body = ''
        url = URL('https://www.w3af.com/')
        headers = Headers([('content-type', 'text/html'),
                           ('strict-transport-security',
                            'max-age=31536000; includeSubDomains; preload')])
        request = FuzzableRequest(url, method='GET')
        resp = HTTPResponse(200, body, headers, url, url, _id=1)

        self.plugin.grep(request, resp)
        self.assertEquals(
            len(
                kb.kb.get('strict_transport_security',
                          'strict_transport_security')), 0)
Ejemplo n.º 55
0
    def test_provides_cors_features_false(self):
        url = URL('http://moth/')
        fr = FuzzableRequest(url)

        http_response = HTTPResponse(200, '', Headers(), url, url)

        url_opener_mock = Mock()
        url_opener_mock.GET = MagicMock(return_value=http_response)

        cors = provides_cors_features(fr, url_opener_mock)

        call_header = Headers({'Origin': 'www.w3af.org'}.items())
        url_opener_mock.GET.assert_called_with(url, headers=call_header)

        self.assertFalse(cors)
Ejemplo n.º 56
0
def add_req():
    url = request.json["url"]
    method = request.json["method"]
    post_data = request.json["post_data"]
    headers = request.json["headers"]
    cookie_string = request.json['cookie']

    headers = Headers(headers.items())

    freq = FuzzableRequest(URL(url), method, headers, Cookie(cookie_string),
                           dc_from_hdrs_post(headers, post_data))
    urllist.req_queue.put_nowait(freq)
    print("req size %d" % urllist.req_queue.qsize())

    return jsonify({"status": True})
Ejemplo n.º 57
0
    def _create_fuzzable_request(self):
        """
        Based on the attributes, return a fuzzable request object.

        Important variables used here:
            - self.headers : Stores the headers for the request
            - self.rfile : A file like object that stores the post_data
            - self.path : Stores the URL that was requested by the browser
        """
        # See HTTPWrapperClass
        if hasattr(self.server, 'chainedHandler'):
            base_path = "https://" + self.server.chainedHandler.path
            path = base_path + self.path
        else:
            path = self.path

        fuzzable_request = FuzzableRequest(URL(path), self.command,
                                           Headers(self.headers.dict.items()))

        post_data = self._get_post_data()
        if post_data:
            fuzzable_request.set_data(post_data)

        return fuzzable_request
Ejemplo n.º 58
0
    def test_store_fuzzable_request_two(self):
        ds = DiskSet()

        # Add a simple fr, without post-data
        fr = FuzzableRequest(URL('http://example.com/?id=1'))
        ds.add(fr)

        # Add a fr with post-data
        form_params = FormParameters()
        form_params.add_input([("name", "username"), ("value", "abc")])
        form_params.add_input([("name", "address"), ("value", "")])
        form_params.set_action(URL('http://example.com/?id=1'))
        form_params.set_method('post')

        form = dc_from_form_params(form_params)

        fr = FuzzableRequest.from_form(form)
        ds.add(fr)

        # Compare
        stored_fr = ds[1]

        self.assertEqual(stored_fr, fr)
        self.assertIsNot(stored_fr, fr)
Ejemplo n.º 59
0
    def test_found_at(self):
        dc = JSONContainer(COMPLEX_OBJECT)
        freq = FuzzableRequest(self.url, post_data=dc, method='PUT')

        m = JSONMutant(freq)
        m.get_dc().set_token(('object-second_key-list-0-string', ))

        expected = '"http://www.w3af.com/", using HTTP method PUT.' \
                   ' The sent JSON-data was: "...object-second_key-list-' \
                   '0-string=abc..."'
        self.assertEqual(m.found_at(), expected)

        headers = m.get_headers()
        self.assertIn('Content-Type', headers)
        self.assertEqual(headers['Content-Type'], 'application/json')
Ejemplo n.º 60
0
 def create_vuln(self):
     v = super(XPathTemplate, self).create_vuln()
     
     original_value = self.data[self.vulnerable_parameter][0]
     
     freq = FuzzableRequest(self.url, method=self.method, dc=self.data)
     
     mutant = Mutant(freq)
     mutant.set_var(self.vulnerable_parameter)
     mutant.set_dc(self.data)
     mutant.set_original_value(original_value)
     
     v.set_mutant(mutant)
     
     return v