Snippets

grimhacker raw2proxy.py

You are viewing an old version of this snippet. View the current version.
Revised by grimhacker 7aafe67
'''
.       .1111...          | Title: raw2proxy.py
    .10000000000011.   .. | Author: Oliver Morton (Sec-1 Ltd)
 .00              000...  | Email: oliverm-tools@sec-1.com
1                  01..   | Description:
                    ..    | Parse files containing raw HTTP requests and
                   ..     | make these requests via a proxy.
GrimHacker        ..      |
                 ..       |
grimhacker.com  ..        |
@grimhacker    ..         |
----------------------------------------------------------------------------
Raw2Proxy - Send Raw HTTP Requests to a Proxy
    Copyright (C) 2015  Oliver Morton (Sec-1 Ltd)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
'''

__version__ = "$Revision: 1.0 $"
# $Source$

import os
import sys
import argparse
import logging
import urllib2
from BaseHTTPServer import BaseHTTPRequestHandler
from StringIO import StringIO


class HTTPRequest(BaseHTTPRequestHandler):
    def __init__(self, raw_request):
        self.rfile = StringIO(raw_request)
        self.raw_requestline = self.rfile.readline()
        self.error_code = None
        self.error_message = None
        self.parse_request()

    def send_error(self, code, message):
        self.error_code = code
        self.error_message = message


def make_request(raw_request, proxy={'http': '127.0.0.1:8080'}):
    try:
        logging.debug("Parsing raw_request")
        request = HTTPRequest(raw_request)#Parse the raw request to an object.
        #print request.error_code
        #print request.command
        #print request.path
        #print request.request_version
        #print len(request.headers)
        #print request.headers.keys()
        #print request.headers['host']
    except Exception as e:
        raise Exception("Failed to parse raw request. {0}".format(e))
    try:
        # Extract the information we need from the request object:
        logging.debug("Extracting required information")
        host = request.headers.get('host')
        url = "http://{host}{path}".format(host=host, path=request.path)
        body = request.rfile.read()
        args = {'headers': request.headers}
        if body:
            args['data'] = body  # Add body parameters if they exist.
    except Exception as e:
        raise Exception("Failed to extract fields from parsed request. {0}".format(e))
    try:
        # Create the Proxy Handler so we go through the proxy
        logging.debug("Creating ProxyHandler")
        proxy_handler = urllib2.ProxyHandler(proxy)
        logging.debug("Creating Opener")
        opener = urllib2.build_opener(proxy_handler)
        urllib2.install_opener(opener)
        # Build the HTTP Request
        logging.debug("Building HTTP request")
        r = urllib2.Request(url, **args)
        r.get_method = lambda: request.command  # Handle methods (PUT, DELETE, GET, etc)
    except Exception as e:
        raise Exception("Failed to create opener. {0}".format(e))
    try:
        # Send the HTTP Request
        logging.debug("Sending HTTP request")
        url = opener.open(r)
        logging.debug("Response = {0}".format(url))  # Print the reponse
    except urllib2.HTTPError, error:
        contents = error.read()
        logging.debug("Error response = {0}".format(contents))  # Print the error response (500, 401, etc)
    except Exception as e:
        raise Exception("Failed to send request. {0}".format(e))


def main(files, proxy):
    failed = []
    try:
        for file_ in files:
            logging.info("Handling: {0}".format(file_))
            try:
                with open(file_, "r") as f:
                    raw_request = f.read()
                    try:
                        make_request(raw_request, proxy={'http': proxy})
                    except Exception as e:
                        failed.append((file_, e))
                        logging.warning("Error handling: {0} - {1}".format(file_, e))
            except Exception as e:
                failed.append((file_, e))
                logging.warning("Error reading: {0} - {1}".format(file_, e))
    except Exception as e:
        for file_ in files:
            failed.append((file_, e))
        logging.critical("Error: {0}".format(e))
    if failed:
        print
        logging.warning("The following requests were not successfully handled and may not be in your proxy:\n{0}".format("\n".join(str(file_) for file_, reason in failed)))
    logging.info("Done. Check your proxy.")
                
def print_version():
    """Print command line version banner."""
    print """

.       .1111...          | Title: raw2proxy.py  {0}
    .10000000000011.   .. | Author: Oliver Morton (Sec-1 Ltd)
 .00              000...  | Email: oliverm-tools@sec-1.com
1                  01..   | Description:
                    ..    | Parse files containing raw HTTP requests and
                   ..     | make these requests via a proxy.
GrimHacker        ..      |
                 ..       |
grimhacker.com  ..        |
@grimhacker    ..         |
----------------------------------------------------------------------------
""".format(__version__)

if __name__ == "__main__":
    print """
    Raw2Proxy - Send Raw HTTP Requests to a Proxy {0}
    Copyright (C) 2015  Oliver Morton (Sec-1 Ltd)
    This program comes with ABSOLUTELY NO WARRANTY.
    This is free software, and you are welcome to redistribute it
    under certain conditions. See GPLv2 License.
""".format(__version__)

    parser = argparse.ArgumentParser(description="Send Raw HTTP Requests to a Proxy")
    parser.add_argument("-V", "--version", help="Print version banner", action="store_true")
    parser.add_argument("-v", "--verbose", help="Debug logging", action="store_true")
    parser.add_argument("-d", "--directory", help="Directory containing raw HTTP requests in files")
    parser.add_argument("-f", "--files", help="Files containing raw HTTP requests", nargs="+")
    parser.add_argument("-p", "--proxy", help="HTTP Proxy to send requests via", default="127.0.0.1:8080")
    args = parser.parse_args()
    
    if args.version:
        print_version()
        exit()
    
    if args.verbose:
            level = logging.DEBUG
    else:
        level = logging.INFO
    logging.basicConfig(level=level,
                        format="%(levelname)s: %(message)s")
    
    if not (args.files or args.directory):
        logging.critical("Specify directory and/or files!")
        parser.print_usage()
        exit()
    
    files = []
    if args.files:
        logging.debug("Getting file names from command line")
        files += args.files
    if args.directory:
        logging.debug("Getting file names from directory '{0}'".format(args.directory))
        try:
            for (dirpath, dirnames, filenames) in os.walk(args.directory):
                for filename in filenames:
                    files.append(os.path.join(dirpath, filename))
                break
        except Exception as e:
            logging.critical("Failed to get file names from directory '{0}'".format(args.directory))
            exit()
    main(files, args.proxy)
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.