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)
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)
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
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)
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)
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)
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)
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)
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)
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 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)
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)
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)
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])
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])