예제 #1
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)
예제 #2
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)
예제 #3
0
파일: web_spider.py 프로젝트: s0i37/__w3af
    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._requests_count += 1
                if self._requests_count <= self._max_requests_count:
                    self.output_queue.put(r)
예제 #4
0
    def _submit_form(self, form_params):
        """
        Complete the username and password in the form fields and submit it
        to the server.

        :param form_params: The form parameters as returned by the HTML parser
        :return: True if form was submitted to the server
        """
        #
        # Create a form instance, using the proper encoding (multipart
        # or url). The form_params instance only has the parameters and can
        # not be sent to the wire.
        #
        form = dc_from_form_params(form_params)

        form.set_login_username(self.username)
        form.set_login_password(self.password)

        #
        # Transform to a fuzzable request and send to the wire
        #
        fuzzable_request = FuzzableRequest.from_form(form)

        try:
            http_response = self._uri_opener.send_mutant(
                fuzzable_request,
                grep=False,
                cache=False,
                follow_redirects=True,
                debugging_id=self._debugging_id)
        except Exception, e:
            msg = 'Failed to submit the login form: %s'
            self._log_debug(msg % e)
            return False
예제 #5
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)
예제 #6
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_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)
        ds.add(fr)

        # Compare
        stored_fr = ds[1]

        self.assertEqual(stored_fr, fr)
        self.assertIsNot(stored_fr, fr)
    def create_simple_fuzzable_request(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)

        return FuzzableRequest.from_form(form)
예제 #8
0
    def create_simple_fuzzable_request(self):
        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)

        return FuzzableRequest.from_form(form)
예제 #9
0
        def create_fuzzable_request(_id):
            url_fmt = 'http://example.com/product/%s'

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

            form = dc_from_form_params(form_params)

            return FuzzableRequest.from_form(form)
예제 #10
0
        def create_fuzzable_request(_id):
            url_fmt = 'http://example.com/product/%s'

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

            form = dc_from_form_params(form_params)

            return FuzzableRequest.from_form(form)
예제 #11
0
    def test_clean_form_fuzzable_request_form(self):
        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)

        expected = u'(POST)-http://example.com/?id=number!username=string&address=string'
        self.assertEqual(self.vdb._clean_fuzzable_request(fr), expected)
예제 #12
0
    def test_clean_form_fuzzable_request_form(self):
        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)

        expected = u'(POST)-http://example.com/?id=number!username=string&address=string'
        self.assertEqual(self.vdb._clean_fuzzable_request(fr), expected)
예제 #13
0
        def create_fuzzable_request(_id):
            path_count = _id * 5
            paths = [rand_alnum(9) for _ in xrange(path_count)]
            url = 'http://example.com/%s' % '/'.join(paths)

            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(url))
            form_params.set_method('post')

            form = dc_from_form_params(form_params)

            return FuzzableRequest.from_form(form)
예제 #14
0
    def test_from_form_POST(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)

        self.assertIs(fr.get_uri(), form.get_action())
        self.assertIs(fr.get_raw_data(), form)
        self.assertEqual(fr.get_method(), 'POST')
        self.assertEqual(fr.get_uri().querystring, QueryString([('id', ['1'])]))
    def test_from_form_POST(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)

        self.assertIs(fr.get_uri(), form.get_action())
        self.assertIs(fr.get_raw_data(), form)
        self.assertEqual(fr.get_method(), 'POST')
        self.assertEqual(fr.get_uri().querystring, QueryString([('id', ['1'])]))
예제 #16
0
        def create_fuzzable_request(_id):
            path_count = _id * 5
            paths = [rand_alnum(9) for _ in xrange(path_count)]
            url = 'http://example.com/%s' % '/'.join(paths)

            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(url))
            form_params.set_method('post')

            form = dc_from_form_params(form_params)

            return FuzzableRequest.from_form(form)
예제 #17
0
    def create_simple_filecontent_mutant(self, container_klass):
        form_params = FormParameters()
        form_params.set_method('POST')
        form_params.set_action(self.url)
        form_params.add_input([("name", "username"), ("value", "")])
        form_params.add_input([("name", "address"), ("value", "")])
        form_params.add_file_input([("name", "file"), ("type", "file")])

        form = container_klass(form_params)
        freq = FuzzableRequest.from_form(form)

        m = FileContentMutant(freq)
        m.get_dc().set_token(('file', 0))
        m.set_token_value('abc')

        return m
예제 #18
0
    def create_simple_filecontent_mutant(self, container_klass):
        form_params = FormParameters()
        form_params.set_method('POST')
        form_params.set_action(self.url)
        form_params.add_input([("name", "username"), ("value", "")])
        form_params.add_input([("name", "address"), ("value", "")])
        form_params.add_file_input([("name", "file"), ("type", "file")])

        form = container_klass(form_params)
        freq = FuzzableRequest.from_form(form)

        m = FileContentMutant(freq)
        m.get_dc().set_token(('file', 0))
        m.set_token_value('abc')

        return m
    def test_from_form_default(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/'))
        # Without a method
        #form_params.set_method('GET')

        form = dc_from_form_params(form_params)
        fr = FuzzableRequest.from_form(form)

        expected_url = 'http://example.com/?username=abc&address='
        self.assertEqual(fr.get_uri().url_string, expected_url)
        self.assertEqual(fr.get_uri().querystring, 'username=abc&address=')
        self.assertIsInstance(fr.get_uri().querystring, URLEncodedForm)
        self.assertEqual(fr.get_method(), 'GET')
        self.assertIsNot(fr.get_raw_data(), form)
예제 #20
0
    def test_from_form_default(self):
        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/'))
        # Without a method
        #form_params.set_method('GET')

        form = dc_from_form_params(form_params)
        fr = FuzzableRequest.from_form(form)

        expected_url = 'http://example.com/?username=abc&address='
        self.assertEqual(fr.get_uri().url_string, expected_url)
        self.assertEqual(fr.get_uri().querystring, 'username=abc&address=')
        self.assertIsInstance(fr.get_uri().querystring, URLEncodedForm)
        self.assertEqual(fr.get_method(), 'GET')
        self.assertIsNot(fr.get_raw_data(), form)
예제 #21
0
    def test_store_fuzzable_request(self):
        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 = DiskSet()
        ds.add(fr)

        stored_fr = ds[0]

        self.assertEqual(stored_fr, fr)
        self.assertIsNot(stored_fr, fr)
예제 #22
0
    def test_store_fuzzable_request(self):
        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 = DiskSet()
        ds.add(fr)

        stored_fr = ds[0]

        self.assertEqual(stored_fr, fr)
        self.assertIsNot(stored_fr, fr)
예제 #23
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_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)
        ds.add(fr)

        # Compare
        stored_fr = ds[1]

        self.assertEqual(stored_fr, fr)
        self.assertIsNot(stored_fr, fr)
예제 #24
0
    def test_generate_all(self):
        fuzzer_config = {
            'fuzz_form_files': True,
            'fuzzed_files_extension': 'gif'
        }

        form_params = FormParameters()
        form_params.set_method('POST')
        form_params.set_action(self.url)
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "image"),
                                             ("type", "file")])

        form = MultipartContainer(form_params)
        freq = FuzzableRequest.from_form(form)

        ph = 'w3af.core.data.constants.file_templates.file_templates.rand_alpha'

        with patch(ph) as mock_rand_alpha:
            mock_rand_alpha.return_value = 'upload'
            generated_mutants = FileContentMutant.create_mutants(
                freq, self.payloads, [], False, fuzzer_config)

        self.assertEqual(len(generated_mutants), 2, generated_mutants)

        _, file_payload_abc, _ = get_template_with_payload('gif', 'abc')
        _, file_payload_def, _ = get_template_with_payload('gif', 'def')

        file_abc = NamedStringIO(file_payload_abc, 'upload.gif')
        file_def = NamedStringIO(file_payload_def, 'upload.gif')

        form_1 = MultipartContainer(copy.deepcopy(form_params))
        form_2 = MultipartContainer(copy.deepcopy(form_params))

        form_1['image'] = [file_abc]
        form_1['username'] = ['John8212']
        form_1['address'] = ['Bonsai Street 123']

        form_2['image'] = [file_def]
        form_2['username'] = ['John8212']
        form_2['address'] = ['Bonsai Street 123']

        expected_forms = [form_1, form_2]

        boundary = get_boundary()
        noop = '1' * len(boundary)

        expected_data = [
            encode_as_multipart(f, boundary) for f in expected_forms
        ]
        expected_data = set([s.replace(boundary, noop) for s in expected_data])

        generated_forms = [m.get_dc() for m in generated_mutants]
        generated_data = [
            str(f).replace(f.boundary, noop) for f in generated_forms
        ]

        self.assertEqual(expected_data, set(generated_data))

        str_file = generated_forms[0]['image'][0].get_value()
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(file_payload_abc, str_file)

        str_file = generated_forms[1]['image'][0].get_value()
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(file_payload_def, str_file)

        self.assertIn('name="image"; filename="upload.gif"', generated_data[0])
예제 #25
0
    def test_generate_all(self):
        fuzzer_config = {'fuzz_form_files': True,
                         'fuzzed_files_extension': 'gif'}

        form_params = FormParameters()
        form_params.set_method('POST')
        form_params.set_action(self.url)
        form_params.add_input([("name", "username"), ("value", "")])
        form_params.add_input([("name", "address"), ("value", "")])
        form_params.add_file_input([("name", "image"), ("type", "file")])

        form = MultipartContainer(form_params)
        freq = FuzzableRequest.from_form(form)

        ph = 'w3af.core.data.constants.file_templates.file_templates.rand_alpha'

        with patch(ph) as mock_rand_alpha:
            mock_rand_alpha.return_value = 'upload'
            generated_mutants = FileContentMutant.create_mutants(freq,
                                                                 self.payloads,
                                                                 [], False,
                                                                 fuzzer_config)

        self.assertEqual(len(generated_mutants), 2, generated_mutants)

        _, file_payload_abc, _ = get_template_with_payload('gif', 'abc')
        _, file_payload_def, _ = get_template_with_payload('gif', 'def')

        file_abc = NamedStringIO(file_payload_abc, 'upload.gif')
        file_def = NamedStringIO(file_payload_def, 'upload.gif')

        form_1 = MultipartContainer(copy.deepcopy(form_params))
        form_2 = MultipartContainer(copy.deepcopy(form_params))

        form_1['image'] = [file_abc]
        form_1['username'] = ['John8212']
        form_1['address'] = ['Bonsai Street 123']

        form_2['image'] = [file_def]
        form_2['username'] = ['John8212']
        form_2['address'] = ['Bonsai Street 123']

        expected_forms = [form_1, form_2]

        boundary = get_boundary()
        noop = '1' * len(boundary)

        expected_data = [encode_as_multipart(f, boundary) for f in expected_forms]
        expected_data = set([s.replace(boundary, noop) for s in expected_data])

        generated_forms = [m.get_dc() for m in generated_mutants]
        generated_data = [str(f).replace(f.boundary, noop) for f in generated_forms]

        self.assertEqual(expected_data, set(generated_data))

        str_file = generated_forms[0]['image'][0].get_value()
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(file_payload_abc, str_file)

        str_file = generated_forms[1]['image'][0].get_value()
        self.assertIsInstance(str_file, NamedStringIO)
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertEqual(file_payload_def, str_file)

        self.assertIn('name="image"; filename="upload.gif"', generated_data[0])