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 _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 _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 _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 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 test_sent_post_data(self): form_params = FormParameters() form_params.add_input([("name", "username"), ("value", """d'z"0""")]) form_params.add_input([("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_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 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_dc_from_form_params_without_files_nor_enctype(self): form_params = FormParameters() form_params.add_field_by_attr_items([('name', 'a'), ('type', 'text'), ('value', 'bcd')]) urlencode_dc = dc_from_form_params(form_params) self.assertIsInstance(urlencode_dc, URLEncodedForm) self.assertEqual(urlencode_dc.get_file_vars(), []) self.assertEqual(urlencode_dc['a'], ['bcd'])
def test_dc_from_form_params_without_files_with_multipart_enctype(self): form_params = FormParameters() form_params.set_form_encoding('multipart/form-data') form_params.add_field_by_attr_items([('name', 'a'), ('type', 'text'), ('value', 'bcd')]) mpdc = dc_from_form_params(form_params) self.assertIsInstance(mpdc, MultipartContainer) self.assertEqual(mpdc.get_file_vars(), []) self.assertEqual(mpdc['a'], ['bcd'])
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 test_dc_from_form_params_with_files(self): form_params = FormParameters() form_params.add_field_by_attr_items([('name', 'b'), ('type', 'file')]) form_params.add_field_by_attr_items([('name', 'a'), ('type', 'text'), ('value', 'bcd')]) form_params.set_file_name('b', 'hello.txt') mpdc = dc_from_form_params(form_params) self.assertIsInstance(mpdc, MultipartContainer) self.assertEqual(mpdc.get_file_vars(), ['b']) self.assertEqual(mpdc['a'], ['bcd'])
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_dc_from_form_params_with_files(self): form_params = FormParameters() form_params.set_file_name('b', 'hello.txt') form_params.add_file_input([('name', 'b')]) form_params.add_input([('name', 'a'), ('type', 'text'), ('value', 'bcd')]) mpdc = dc_from_form_params(form_params) self.assertIsInstance(mpdc, MultipartContainer) self.assertEqual(mpdc.get_file_vars(), ['b']) self.assertEqual(mpdc['a'], ['bcd'])
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_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_form_with_invalid_enctype(self): body = """ <html> <form action="" method="get" enctype="ilove/bugs"> <input type="text" name="test" value="hello"> <input type="submit" name="submit"> </form> </html>""" r = build_http_response(self.url, body) p = RaiseHTMLParser(r) p.parse() self.assertEqual(len(p.forms), 1) form = p.forms[0] self.assertEqual(form.get_method(), 'GET') self.assertIsInstance(form, FormParameters) self.assertEqual(form.get_form_encoding(), 'ilove/bugs') # But it translates to url-encoded form afterwards dc = dc_from_form_params(form) self.assertIsInstance(dc, URLEncodedForm)