def audit(self, freq, orig_response, debugging_id): """ Searches for file upload vulns. :param freq: A FuzzableRequest :param orig_response: The HTTP response associated with the fuzzable request :param debugging_id: A unique identifier for this call to audit() """ if freq.get_method().upper() != 'POST' or not freq.get_file_vars(): return # Unique payload for the files we upload payload = rand_alnum(239) for file_parameter in freq.get_file_vars(): for extension in self._extensions: _, file_content, file_name = get_template_with_payload( extension, payload) # Only file handlers are passed to the create_mutants functions named_stringio = NamedStringIO(file_content, file_name) mutants = create_mutants(freq, [named_stringio], fuzzable_param_list=[file_parameter]) for mutant in mutants: mutant.uploaded_file_name = file_name mutant.extension = extension mutant.file_content = file_content mutant.file_payload = payload self._send_mutants_in_threads(self._uri_opener.send_mutant, mutants, self._analyze_result, debugging_id=debugging_id)
def build_file(self, value): if isinstance(value, basestring): _, file_content, fname = get_template_with_payload(self._extension, value) # I have to create the NamedStringIO with a "name", # required for MultipartContainer to properly encode this as # multipart/post return NamedStringIO(file_content, name=fname) return value
def build_file(self, value): if isinstance(value, basestring): _, file_content, fname = get_template_with_payload( self._extension, value) # I have to create the NamedStringIO with a "name", # required for MultipartContainer to properly encode this as # multipart/post return NamedStringIO(file_content, name=fname) return value
def build_file(self, value): # # We don't want to create a new file if value is already a NamedStringIO # but if it is a string, we should create a new NamedStringIO instance # and return it # # The last "not isinstance" is important due to the fact that # NamedStringIO is a basestring subclass # if isinstance(value, basestring) and not isinstance(value, NamedStringIO): _, file_content, fname = get_template_with_payload(self._extension, value) # I have to create the NamedStringIO with a "name", # required for MultipartContainer to properly encode this as # multipart/post return NamedStringIO(file_content, name=fname) return value
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])
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])