def send_raw_request(self, head, postdata, fix_content_len=True): ''' In some cases the ExtendedUrllib user wants to send a request that was typed in a textbox or is stored in a file. When something like that happens, this library allows the user to send the request by specifying two parameters for the send_raw_request method: :param head: "<method> <URI> <HTTP version>\r\nHeader: Value\r\nHeader2: Value2..." :param postdata: The postdata, if any. If set to '' or None, no postdata is sent. :param fix_content_len: Indicates if the content length has to be fixed or not. :return: An HTTPResponse object. ''' # Parse the two strings fuzz_req = HTTPRequestParser(head, postdata) # Fix the content length if fix_content_len: headers = fuzz_req.get_headers() fixed = False for h in headers: if h.lower() == 'content-length': headers[h] = str(len(postdata)) fixed = True if not fixed and postdata: headers['content-length'] = str(len(postdata)) fuzz_req.set_headers(headers) # Send it function_reference = getattr(self, fuzz_req.get_method()) return function_reference(fuzz_req.get_uri(), data=fuzz_req.get_data(), headers=fuzz_req.get_headers(), cache=False, grep=False)
def html_export(request_string): ''' :param request_string: The string of the request to export :return: A HTML that will perform the same HTTP request. ''' request_lines = request_string.split('\n\n') header = request_lines[0] body = '\n\n'.join(request_lines[1:]) http_request = HTTPRequestParser(header, body) res = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Exported HTTP Request from w3af</title> </head> <body>\n''' res += '<form action="' + cgi.escape(http_request.get_uri().url_string, True) res += '" method="' + cgi.escape(http_request.get_method(), True) + '">\n' if http_request.get_data() and http_request.get_data() != '\n': post_data = http_request.get_dc() for param_name in post_data: for value in post_data[param_name]: res += '<label>' + cgi.escape(param_name) + '</label>\n' res += '<input type="text" name="' + \ cgi.escape(param_name.strip(), True) res += '" value="' + cgi.escape(value, True) + '">\n' res += '<input type="submit">\n' res += '</form>\n' res += '''</body>\n</html>''' return res
def html_export(request_string): ''' :param request_string: The string of the request to export :return: A HTML that will perform the same HTTP request. ''' request_lines = request_string.split('\n\n') header = request_lines[0] body = '\n\n'.join(request_lines[1:]) http_request = HTTPRequestParser(header, body) res = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Exported HTTP Request from w3af</title> </head> <body>\n''' res += '<form action="' + cgi.escape(http_request.get_uri() .url_string, True) res += '" method="' + cgi.escape(http_request.get_method(), True) + '">\n' if http_request.get_data() and http_request.get_data() != '\n': post_data = http_request.get_dc() for param_name in post_data: for value in post_data[param_name]: res += '<label>' + cgi.escape(param_name) + '</label>\n' res += '<input type="text" name="' + \ cgi.escape(param_name.strip(), True) res += '" value="' + cgi.escape(value, True) + '">\n' res += '<input type="submit">\n' res += '</form>\n' res += '''</body>\n</html>''' return res
def ruby_export(request_string): ''' :param request_string: The string of the request to export :return: A net/http based ruby script that will perform the same HTTP request. ''' # get the header and the body splitted_request = request_string.split('\n\n') header = splitted_request[0] body = '\n\n'.join(splitted_request[1:]) http_request = HTTPRequestParser(header, body) # Now I do the real magic... res = 'require \'net/https\'\n\n' res += 'url = URI.parse("' + ruby_escape_string( http_request.get_uri().url_string) + '")\n' if http_request.get_data() != '\n' and http_request.get_data() is not None: escaped_data = ruby_escape_string(str(http_request.get_data())) res += 'data = "' + escaped_data + '"\n' else: res += 'data = nil\n' res += 'headers = {\n' headers = http_request.get_headers() for header_name, header_value in headers.iteritems(): header_value = ruby_escape_string(header_value) header_name = ruby_escape_string(header_name) res += ' "' + header_name + '" => "' + header_value + '",\n' res = res[:-2] res += '\n}\n' method = http_request.get_method() res += 'res = Net::HTTP.start(url.host, url.port) do |http|\n' res += ' http.use_ssl = ' if http_request.get_url().get_protocol().lower() == 'https': res += 'true\n' else: res += 'false\n' res += ' http.send_request("' + method + '", url.path, data, headers)\n' res += 'end\n\n' res += 'puts res.body\n' return res
def test_GET_request(self): self.http_daemon = HTTPDaemon() self.http_daemon.start() self.http_daemon.wait_for_start() # # Send the request to our server using the GUI # self.double_click('localhost') self.type('127.0.0.1:%s' % self.http_daemon.get_port(), False) self.click('send') # Wait until we actually get the response, and verify we got the # response body we expected: self.find('abcdef') self.find('200_OK') # # Assert that it's what we really expected # requests = self.http_daemon.requests self.assertEqual(len(requests), 1) request = requests[0] head, postdata = MANUAL_REQUEST_EXAMPLE, '' http_request = HTTPRequestParser(head, postdata) self.assertEqual(http_request.get_url().get_path(), request.path) self.assertEqual(http_request.get_method(), request.command) for header_name, header_value in http_request.get_headers().iteritems( ): self.assertIn(header_name.lower(), request.headers) self.assertEqual(header_value, request.headers[header_name.lower()]) self.http_daemon.shutdown()
def test_GET_request(self): self.http_daemon = HTTPDaemon() self.http_daemon.start() self.http_daemon.wait_for_start() # # Send the request to our server using the GUI # self.double_click('localhost') self.type('127.0.0.1:%s' % self.http_daemon.get_port(), False) self.click('play') # Wait until we actually get the response, and verify we got the # response body we expected: self.click('response_tab') self.find('abcdef') self.find('200_OK') # # Assert that it's what we really expected # requests = self.http_daemon.requests self.assertEqual(len(requests), 10) head, postdata = FUZZY_REQUEST_EXAMPLE, '' parsed_request = HTTPRequestParser(head, postdata) for i, daemon_request in enumerate(self.http_daemon.requests): self.assertEqual('/%s' % i, daemon_request.path) self.assertEqual(parsed_request.get_method(), daemon_request.command) for header_name, header_value in parsed_request.get_headers().iteritems(): self.assertIn(header_name.lower(), daemon_request.headers) self.assertEqual(header_value, daemon_request.headers[header_name.lower()]) self.http_daemon.shutdown()
def ajax_export(request_string): ''' :param request_string: The string of the request to export :return: A javascript that will perform the same HTTP request. ''' # get the header and the body splitted_request = request_string.split('\n\n') header = splitted_request[0] body = '\n\n'.join(splitted_request[1:]) http_request = HTTPRequestParser(header, body) # Now I do the real magic... # This is the header, to include the AJAX stuff: res = '''/* Init AJAX stuff */ var xmlhttp = false; /*@cc_on @*/ /*@if (@_jscript_version >= 5) // JScript gives us Conditional compilation, we can cope with old IE versions. // and security blocked creation of the objects. try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } @end @*/ if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { try { xmlhttp = new XMLHttpRequest(); } catch (e) { xmlhttp = false; } } if (!xmlhttp && window.createRequest) { try { xmlhttp = window.createRequest(); } catch (e) { xmlhttp = false; } } /* Finished AJAX initialization */ /* Create the request, please remember the same-origin policy, which might affect how and if this request is sent by the browser */ ''' # Set the method and the path res += 'xmlhttp.open("' + http_request.get_method() + '", "' res += ajax_escape_string( http_request.get_uri().url_string) + '", true);\n' # For debugging res += ''' /* Debugging code, this should be removed for real life XSS exploits */ xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 ) { alert(xmlhttp.responseText); } } /* Add headers to the request and send it, please note taht custom headers might be removed by the browser and/or generate an exception that will make the request fail */ ''' # Now I add the headers: headers = http_request.get_headers() for header_name, header_value in headers.iteritems(): res += 'xmlhttp.setRequestHeaders("' + ajax_escape_string( header_name) + '", "' res += ajax_escape_string(header_value) + '");\n' # And finally the post data (if any) if http_request.get_data() and http_request.get_data() != '\n': res += 'var post_data = (<r><![CDATA[' + str( http_request.get_data()) + ']]></r>).toString();\n' res += 'xmlhttp.send(post_data);\n' else: res += 'xmlhttp.send(null);\n' return res
def test_qs(self): fuzzable_request = HTTPRequestParser( 'GET http://www.w3af.com/ HTTP/1.0', '') self.assertIsInstance(fuzzable_request, HTTPQSRequest) self.assertEqual(fuzzable_request.get_method(), 'GET')
def test_head_post_data(self): fuzzable_request = HTTPRequestParser( 'POST http://www.w3af.com/ HTTP/1.0', 'foo=bar') self.assertIsInstance(fuzzable_request, HTTPPostDataRequest) self.assertEqual(fuzzable_request.get_method(), 'POST')