Code Monkey home page Code Monkey logo

pymiproxy's Introduction

pymiproxy - Python Micro Interceptor Proxy

A small and sweet man-in-the-middle proxy capable of doing HTTP and HTTP over SSL.

Introduction

pymiproxy is a small, lightweight, man-in-the-middle proxy capable of performing HTTP and HTTPS (or SSL) inspection. The proxy provides a built-in certificate authority that is capable of generating certificates for SSL-based destinations. Pymiproxy is also extensible and provides two methods for extending the proxy: method overloading, and a pluggable interface. It is ideal for situations where you're in dire need of a cool proxy to tamper with out- and/or in-bound HTTP data.

Installation Requirements

The following modules are required:

  • pyOpenSSL

Installation

Just run the following command at the command prompt:

$ sudo python setup.py install

Usage

The module offers a few examples in the code. In brief, pymiproxy can be run right-away by issuing the following command at the the command-prompt:

$ python -m miproxy.proxy

This will invoke pymiproxy with the DebugInterceptor plugin which simply outputs the first 100 bytes of each request and response. The proxy runs on port 8080 and listens on all addresses. Go ahead and give it a try.

Extending or Implementing pymiproxy

There are two ways of extending the proxy:

  • Develop and register an Interceptor plugin; or
  • Overload the mitm_request, and mitm_response methods in the ProxyHandler class.

The decision on which method you choose to use is entirely dependant on whether or not you wish to push the data being intercepted through a set of interceptors or not.

Interceptor Plugins

There are currently two types of interceptor plugins:

  • RequestInterceptorPlugins: executed prior to sending the request to the remote server; and
  • ResponseInterceptorPlugins: executed prior to sending the response back to the client.

The following flow is taken by pymiproxy in this mode:

  1. Client request received
  2. Client request parsed
  3. Client request processed/transformed by Request Interceptor plugins
  4. Updated request sent to remote server
  5. Response received by remote server
  6. Response processed/transformed by Response Interceptor plugins
  7. Updated response sent to client

You can register as many plugins as you wish. However, keep in mind that plugins are executed in the order that they are registered in. Take care in how you register your plugins if the result of one plugin is dependent on the result of another.

The following is a simple code example of how to run the proxy with plugins:

from sys import argv
from miproxy.proxy import RequestInterceptorPlugin, ResponseInterceptorPlugin, AsyncMitmProxy

class DebugInterceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin):

        def do_request(self, data):
            print '>> %s' % repr(data[:100])
            return data

        def do_response(self, data):
            print '<< %s' % repr(data[:100])
            return data


if __name__ == '__main__':
    proxy = None
    if not argv[1:]:
        proxy = AsyncMitmProxy()
    else:
        proxy = AsyncMitmProxy(ca_file=argv[1])
    proxy.register_interceptor(DebugInterceptor)
    try:
        proxy.serve_forever()
    except KeyboardInterrupt:
        proxy.server_close()

Method Overloading

The alternate approach to extending the proxy functionality is to subclass the ProxyHandler class and overload the mitm_request and mitm_response methods. The following is a quick example:

from sys import argv
from miproxy.proxy import AsyncMitmProxy, ProxyHandler

class MitmProxyHandler(ProxyHandler):

    def mitm_request(self, data):
        print '>> %s' % repr(data[:100])
        return data

    def mitm_response(self, data):
        print '<< %s' % repr(data[:100])
        return data


if __name__ == '__main__':
    proxy = None
    if not argv[1:]:
        proxy = AsyncMitmProxy(RequestHandlerClass=MitmProxyHandler)
    else:
        proxy = AsyncMitmProxy(RequestHandlerClass=MitmProxyHandler, ca_file=argv[1])
    try:
        proxy.serve_forever()
    except KeyboardInterrupt:
        proxy.server_close()

Note: In both cases, the methods that process the data need to return the data back to the proxy handler. Otherwise, you'll get an exception.

Kudos

Thanks to the great documentation at python.org, GnuCitizen's PDP for the ideas, the pyOpenSSL group for making a great OpenSSL API.

pymiproxy's People

Contributors

allfro avatar bryant1410 avatar mk-pmb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pymiproxy's Issues

Pass the specific request through the proxy

Hi. First, thanks for a great tool.
Maybe a noob question and it's not an issue, but can you help?

I want to pass-through an a request to specified host without mitm it. If host == "somehost.com" send it in a usual way.

So, AsyncMitmProxy summon MitmProxy class at very beginning listening the port. My app has connected to proxy and it had already initialized with modified ca_file. Than it goes to ProxyHandler class and target host can be found it self.path.

Should I create copy of MitmProxy class on different port to detect target host or it can be done in more simple way?
Thanks!

python3 support

Can you help me make the project support python3?
I'm trying to convert to python3, but I just receive the response Bad Request(400)
This is the edited code
http://termbin.com/r6nk

error in 'egg_base' option: 'src' does not exist or is not a directory

Hi
I'm trying to execute the following command line
python setup.py install

but i'm getting the following log
running install
running bdist_egg
error: error in 'egg_base' option: 'src' does not exist or is not a directory

i'm executing it inside of a Docker Container, with the following configuration

Dockerfile

FROM python:3

WORKDIR /usr/src/app

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD [ "python", "./interceptor.py" ]

requirements.txt

pyOpenSSL

interceptor.py

from subprocess import call
print("Initializing interceptor.py")

call(["ls","-l"])
call([ "python", "pymiproxy-1.0/setup.py", "install"])

Browser not accepting self-signed SSL certs

Hi, looking to write my own ad stripping proxy. However most webmail/Facebook/etc won't accept the self-signed cert and won't let me load the page. Any way to get SSL pages working with the proxy? Either sharing the certs file with the browser or SSL stripping?

Thanks,

Phillip.

Availability on PyPI

Currently this package is not available via pip as it is not listed on PyPI - I have a derivative work based on pymiproxy (python-logging-proxy, found as a fork of your project on github, and also at https://pypi.python.org/pypi/python-logging-proxy). At them moment I am forced to include your project's source in order to distribute my own, whereas it would obviously be better to only require it, and have pip install it as a dependancy.

No link between request and response function ?

Hi,

I would like to process with interceptor a response with some information retrieved in request (example : an URL parameter).
I try to add variable in my interceptor class but I got mess when two requests are sent and then two responses received.
= The two responses are processed with information of the last request.

I just start to write python but if i read the code of "mitm_request" and "mitm_response" function, it seems not to be an instance of interceptor for each couple of request/response.

Is there a way to do what I want in your code ? To get a link between request and response to be able to say this response is from this request ?

Kind regards,

License

Hi,

I'm considering using this code base for a project, would it be possible to add a license to it? by default it's all right reserved to you. I can definitely respect this if you don't want it to be forked, but it needs to be more explicit :).

thanks.

Access requested URL in interceptor

Thanks for this cool little lib. Is there a way to access the requested URL inside the interceptor? My use case is, I want to add an HTTP header whenever the URL matches a specific pattern.

class DebugInterceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin):

    def do_request(self, data):
        # access request url and do a regex
        return data

    def do_response(self, data):
        return data

Does not work for HTTPS

I am not able to run it for HTTPS. Can you please guide me if there is some additional effort to run this for HTTPs as well. for HTTP its working fine.

how I actually make a change here?

I tried to change the original proxy file to see if anything happens but none.
what steps shall be done to create or enhance interceptors?
build? deploy?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.