def from_postdata(cls, headers, post_data): if not MultipartContainer.is_multipart(headers): raise ValueError('No multipart content-type header.') environ = {'REQUEST_METHOD': 'POST'} try: fs = cgi.FieldStorage(fp=StringIO.StringIO(post_data), headers=headers.to_dict(), environ=environ) except ValueError: raise ValueError('Failed to create MultipartContainer.') else: # Please note that the FormParameters is just a container for # the information. # # When the FuzzableRequest is sent the framework calls get_data() # which returns a string version of this object, properly encoded # using multipart/form-data # # To make sure the web application properly decodes the request, we # also include the headers in get_headers() which include the # boundary form_params = FormParameters() for key in fs.list: if key.filename is None: form_params.add_input([('name', key.name), ('type', 'text'), ('value', key.file.read())]) else: form_params.set_file_name(key.name, key.filename) form_params.add_file_input([('name', key.name)]) return cls(form_params)
def create_vuln(self): v = super(FileUploadTemplate, self).create_vuln() form_params = FormParameters() for file_var in self.file_vars: form_params.add_file_input([("name", file_var), ("type", "file")]) for token in self.data.iter_tokens(): if token.get_name() in self.file_vars: continue form_params.add_input([("name", token.get_value()), ("type", "text")]) mpc = MultipartContainer(form_params) freq = FuzzableRequest(self.url, method=self.method, post_data=mpc) mutant = PostDataMutant(freq) mutant.set_dc(mpc) mutant.set_token((self.vulnerable_parameter, 0)) # User configured settings v['file_vars'] = self.file_vars v['file_dest'] = self.file_dest v.set_mutant(mutant) return v
def create_vuln(self): v = super(FileUploadTemplate, self).create_vuln() form_params = FormParameters() for file_var in self.file_vars: form_params.add_file_input([("name", file_var), ("type", "file")]) for token in self.data.iter_tokens(): if token.get_name() in self.file_vars: continue form_params.add_input([("name", token.get_name()), ("type", "text"), ("value", token.get_value())]) mpc = MultipartContainer(form_params) freq = FuzzableRequest(self.url, method=self.method, post_data=mpc) mutant = PostDataMutant(freq) mutant.set_dc(mpc) mutant.set_token((self.vulnerable_parameter, 0)) # User configured settings v['file_vars'] = self.file_vars v['file_dest'] = self.file_dest v.set_mutant(mutant) return v
def upload_file(self, _file): form_params = FormParameters() form_params.add_file_input([("name", "uploadedfile")]) form_params.add_input([("name", "MAX_FILE_SIZE"), ("type", "hidden"), ("value", "10000")]) mpc = MultipartContainer(form_params) mpc["uploadedfile"][0] = _file resp = self.opener.POST(self.MOTH_FILE_UP_URL, data=str(mpc), headers=Headers(mpc.get_headers())) self.assertIn("was successfully uploaded", resp.get_body())
def test_upload_file_using_fuzzable_request(self): form_params = FormParameters() form_params.add_file_input([("name", "uploadedfile")]) form_params["uploadedfile"][0] = NamedStringIO("file content", name="test.txt") form_params.add_input([("name", "MAX_FILE_SIZE"), ("type", "hidden"), ("value", "10000")]) mpc = MultipartContainer(form_params) freq = FuzzableRequest(self.MOTH_FILE_UP_URL, post_data=mpc, method="POST") resp = self.opener.send_mutant(freq) self.assertIn("was successfully uploaded", resp.get_body())
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 upload_file(self, _file): form_params = FormParameters() form_params.add_file_input([('name', 'uploadedfile')]) form_params.add_input([('name', 'MAX_FILE_SIZE'), ('type', 'hidden'), ('value', '10000')]) mpc = MultipartContainer(form_params) mpc['uploadedfile'][0] = _file resp = self.opener.POST(self.MOTH_FILE_UP_URL, data=str(mpc), headers=Headers(mpc.get_headers())) self.assertIn('was successfully uploaded', resp.get_body())
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_upload_file_using_fuzzable_request(self): form_params = FormParameters() form_params.add_file_input([('name', 'uploadedfile')]) form_params['uploadedfile'][0] = NamedStringIO('file content', name='test.txt') form_params.add_input([('name', 'MAX_FILE_SIZE'), ('type', 'hidden'), ('value', '10000')]) mpc = MultipartContainer(form_params) freq = FuzzableRequest(self.MOTH_FILE_UP_URL, post_data=mpc, method='POST') resp = self.opener.send_mutant(freq) self.assertIn('was successfully uploaded', resp.get_body())
def test_mutant_smart_fill_with_file(self): form_params = FormParameters() form_params.add_input([("name", "username"), ("value", "")]) form_params.add_input([("name", "address"), ("value", "")]) form_params.add_file_input([("name", "file"), ("type", "file")]) form = Form(form_params) form['username'][0] = DataToken('username', '', ('username', 0)) form.smart_fill() self.assertEqual(form['username'], ['', ]) self.assertEqual(form['address'], ['Bonsai Street 123', ]) self.assertIsInstance(form['username'][0], DataToken) str_file = form['file'][0] self.assertEqual(str_file.name[-4:], '.gif') self.assertIn('GIF', str_file) self.assertIs(form.get_form_params(), form_params)
def test_mutant_creation_file(self): form_params = FormParameters() form_params.add_input([("name", "username"), ("value", "default")]) form_params.add_file_input([("name", "file_upload")]) form = MultipartContainer(form_params) freq = FuzzableRequest(URL('http://www.w3af.com/upload'), post_data=form, method='POST') payloads = [file(__file__)] created_mutants = PostDataMutant.create_mutants(freq, payloads, ['file_upload', ], False, self.fuzzer_config) self.assertEqual(len(created_mutants), 1, created_mutants) mutant = created_mutants[0] self.assertIsInstance(mutant.get_token().get_value(), file) self.assertEqual(mutant.get_dc()['username'][0], 'default')
def test_mutant_creation_file(self): form_params = FormParameters() form_params.add_input([("name", "username"), ("value", "default")]) form_params.add_file_input([("name", "file_upload")]) form = MultipartContainer(form_params) freq = FuzzableRequest(URL('http://www.w3af.com/upload'), post_data=form, method='POST') payloads = [file(__file__)] created_mutants = PostDataMutant.create_mutants( freq, payloads, [ 'file_upload', ], False, self.fuzzer_config) self.assertEqual(len(created_mutants), 1, created_mutants) mutant = created_mutants[0] self.assertIsInstance(mutant.get_token().get_value(), file) self.assertEqual(mutant.get_dc()['username'][0], 'default')
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_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_mutant_creation_post_data(self): form_params = FormParameters() 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(self.url, post_data=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 = PostDataMutant.create_mutants( freq, self.payloads, [], False, self.fuzzer_config) self.assertEqual(len(generated_mutants), 6, generated_mutants) _, gif_file_content, _ = get_file_from_template('gif') gif_named_stringio = NamedStringIO(gif_file_content, 'upload.gif') expected_forms = [] form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['def'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['abc'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) # TODO: Please note that these two multipart forms are a bug, since # they should never be created by PostDataMutant.create_mutants # (they are not setting the image as a file, just as a string) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = ['def'] form['username'] = ['John8212'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = ['abc'] form['username'] = ['John8212'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) # # TODO: /end # form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['John8212'] form['address'] = ['abc'] expected_forms.append(form) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['John8212'] form['address'] = ['def'] expected_forms.append(form) 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] self.assertIsInstance(str_file, NamedStringIO) self.assertEqual(str_file.name[-4:], '.gif') self.assertEqual(gif_file_content, str_file) str_file = generated_forms[1]['image'][0] self.assertIsInstance(str_file, NamedStringIO) self.assertEqual(str_file.name[-4:], '.gif') self.assertEqual(gif_file_content, str_file) self.assertIn('name="image"; filename="upload.gif"', generated_data[0])
def test_mutant_creation_post_data(self): form_params = FormParameters() 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(self.url, post_data=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 = PostDataMutant.create_mutants(freq, self.payloads, [], False, self.fuzzer_config) self.assertEqual(len(generated_mutants), 6, generated_mutants) _, gif_file_content, _ = get_file_from_template('gif') gif_named_stringio = NamedStringIO(gif_file_content, 'upload.gif') expected_forms = [] form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['def'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['abc'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) # TODO: Please note that these two multipart forms are a bug, since # they should never be created by PostDataMutant.create_mutants # (they are not setting the image as a file, just as a string) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = ['def'] form['username'] = ['John8212'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = ['abc'] form['username'] = ['John8212'] form['address'] = ['Bonsai Street 123'] expected_forms.append(form) # # TODO: /end # form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['John8212'] form['address'] = ['abc'] expected_forms.append(form) form = MultipartContainer(copy.deepcopy(form_params)) form['image'] = [gif_named_stringio] form['username'] = ['John8212'] form['address'] = ['def'] expected_forms.append(form) 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] self.assertIsInstance(str_file, NamedStringIO) self.assertEqual(str_file.name[-4:], '.gif') self.assertEqual(gif_file_content, str_file) str_file = generated_forms[1]['image'][0] self.assertIsInstance(str_file, NamedStringIO) self.assertEqual(str_file.name[-4:], '.gif') self.assertEqual(gif_file_content, str_file) self.assertIn('name="image"; filename="upload.gif"', generated_data[0])