Skip to content

Instantly share code, notes, and snippets.

@dannvix
Last active March 6, 2025 01:41
Show Gist options
  • Save dannvix/5285924 to your computer and use it in GitHub Desktop.
Save dannvix/5285924 to your computer and use it in GitHub Desktop.

Revisions

  1. dannvix revised this gist May 27, 2016. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,9 @@
    Intercepts HTTPs Traffic with Python & mitmproxy
    ================================================

    Warning
    -------
    This Gist is created in 2014, and it's highliy outdated now, according to one of `mitmproxy`'s manjor contributor (check his comment below). Thanks for letting us know, @mhils!

    Introduction
    ------------
  2. dannvix revised this gist Oct 5, 2014. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -114,13 +114,13 @@ class InterceptingMaster (controller.Master):
    request_url = '%s://%s%s' % (msg.scheme, .msg.host, msg.path)
    print '[%s %s] %s %s' % (timestamp, client_ip, msg.method, request_url)

    RequestHacks.example_com()
    RequestHacks.example_com(msg)
    msg.reply()

    def handle_response (self, msg):
    ResponseHacks.example_org()
    ResponseHacks.example_com()
    ResponseHacks.example_net()
    ResponseHacks.example_org(msg)
    ResponseHacks.example_com(msg)
    ResponseHacks.example_net(msg)
    msg.reply()


  3. dannvix revised this gist Apr 3, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ Requirements
    3. `sudo python setup.py install`
    * PyOpenSSL, >= 0.13
    1. install OpenSSL development package (through `sudo apt-get install libssl-dev` on Ubuntu)
    2. download `pyOpenSSL-0.13.tar.gz` from [PyPI website](https://pypi.python.org/pypi/pyOpenSSL)
    2. download `pyOpenSSL-0.13.tar.gz` from [pyOpenSSL project page](https://pypi.python.org/pypi/pyOpenSSL) on PyPI website
    3. `tar xvf pyOpenSSL-0.13.tar.gz`
    4. `cd pyOpenSSL-0.13`
    5. `python setup.py build`
  4. dannvix revised this gist Apr 3, 2013. 1 changed file with 48 additions and 23 deletions.
    71 changes: 48 additions & 23 deletions intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -50,6 +50,48 @@ Example of `proxy.py`
    from libmproxy import controller, proxy
    import os, sys, re, datetime, json

    class RequestHacks:
    @staticmethod
    def example_com (msg):
    # tamper outgoing requests for https://example.com/api/v2
    if ('example.org' in msg.host) and ('action=login' in msg.content):
    fake_lat, fake_lng = 25.0333, 121.5333
    tampered = re.sub('lat=([\d.]+)&lng=([\d.]+)', 'lat=%s&lng=%s' % (fake_lat, fake_lng), msg.content)
    msg.content = tampered
    print '[RequestHacks][Example.com] Fake location (%s, %s) sent when logging in' % (fake_lat, fake_lng)


    class ResponseHacks:
    @staticmethod
    def example_org (msg):
    # simple substitution for https://example.org/api/users/:id.json
    if 'example.org' in msg.request.host:
    regex = re.compile('/api/users/(\d+).json')
    match = regex.search(msg.request.path)
    if match and msg.content:
    c = msg.replace(''private_data_accessible':false', ''private_data_accessible':true')
    if c > 0:
    user_id = match.groups()[0]
    print '[ResponseHacks][Example.org] Private info of user #%s revealed' % user_id

    @staticmethod
    def example_com (msg):
    # JSON manipulation for https://example.com/api/v2
    if ('example.com' in msg.request.host) and ('action=user_profile' in msg.request.content):
    msg.decode() # need to decode the message first
    data = json.loads(msg.content) # parse JSON with decompressed content
    data['access_granted'] = true
    msg.content = json.dumps(data) # write back our changes
    print '[ResponseHacks][Example.com] Access granted of user profile #%s' % data['id']

    @staticmethod
    def example_net (msg):
    # Response inspection for https://example.net
    if 'example.net' in msg.request.host:
    data = msg.get_decoded_content() # read decompressed content without modifying msg
    print '[ResponseHacks][Example.net] Respones: %s' % data


    class InterceptingMaster (controller.Master):
    def __init__ (self, server):
    controller.Master.__init__(self, server)
    @@ -67,41 +109,24 @@ class InterceptingMaster (controller.Master):
    pass

    def handle_request (self, msg):
    timestamp = datetime.datetime.today().strftime("%Y/%m/%d %H:%M:%S")
    timestamp = datetime.datetime.today().strftime('%Y/%m/%d %H:%M:%S')
    client_ip = msg.client_conn.address[0]
    request_url = '%s://%s%s' % (msg.scheme, .msg.host, msg.path)
    print '[%s %s] %s %s' % (timestamp, client_ip, msg.method, request_url)

    RequestHacks.example_com()
    msg.reply()

    def handle_response (self, msg):
    # simple substitution for https://example.org/api/users/:id.json
    if "example.org" in msg.request.host:
    regex = re.compile("/api/users/(\d+).json")
    match = regex.search(msg.request.path)
    if match and msg.content:
    c = msg.replace('"private_data_accessible":false', '"private_data_accessible":true')
    if c > 0: print '[Example.org] Private info of user #%s revealed' % (match.groups()[0])

    # JSON manipulation for https://example.com/api/v2
    if ("example.com" in msg.request.host) and ("action=user_profile" in msg.request.content):
    msg.decode() # need to decode the message first
    data = json.loads(msg.content) # parse JSON with decompressed content
    data["access_granted"] = true
    msg.content = json.dumps(data) # write back our changes
    print '[Example.com] Access granted of user profile #%s' % data["id"]

    # Response inspection for https://example.net
    if "example.net" in msg.request.host:
    data = msg.get_decoded_content() # read decompressed content without modifying msg
    print '[Example.net] Respones: %s' % data

    ResponseHacks.example_org()
    ResponseHacks.example_com()
    ResponseHacks.example_net()
    msg.reply()


    def main (argv):
    config = proxy.ProxyConfig(
    cacert = os.path.expanduser("./mitmproxy.pem"),
    cacert = os.path.expanduser('./mitmproxy.pem'),
    )
    server = proxy.ProxyServer(config, 8080)
    print 'Intercepting Proxy listening on 8080'
  5. dannvix revised this gist Apr 3, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ Requirements
    3. `sudo python setup.py install`
    * PyOpenSSL, >= 0.13
    1. install OpenSSL development package (through `sudo apt-get install libssl-dev` on Ubuntu)
    2. download `pyOpenSSL-0.13.tar.gz` from [PyPi website](https://pypi.python.org/pypi/pyOpenSSL)
    2. download `pyOpenSSL-0.13.tar.gz` from [PyPI website](https://pypi.python.org/pypi/pyOpenSSL)
    3. `tar xvf pyOpenSSL-0.13.tar.gz`
    4. `cd pyOpenSSL-0.13`
    5. `python setup.py build`
  6. dannvix revised this gist Apr 2, 2013. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -46,6 +46,7 @@ Example of `proxy.py`
    ---------------------
    ```python
    #!/usr/bin/env python
    # -*- encoding: utf-8 -*-
    from libmproxy import controller, proxy
    import os, sys, re, datetime, json

  7. dannvix revised this gist Apr 2, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -45,10 +45,10 @@ Generate SSL Private Key and Certificate
    Example of `proxy.py`
    ---------------------
    ```python
    #!/usr/bin/env python
    from libmproxy import controller, proxy
    import os, sys, re, datetime, json


    class InterceptingMaster (controller.Master):
    def __init__ (self, server):
    controller.Master.__init__(self, server)
  8. dannvix revised this gist Apr 2, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions intercept-https-with-python-mitmproxy.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    Intercepts HTTPs Proxy with Python & mitmproxy
    ==============================================
    Intercepts HTTPs Traffic with Python & mitmproxy
    ================================================


    Introduction
  9. dannvix renamed this gist Apr 2, 2013. 1 changed file with 2 additions and 2 deletions.
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    Non-Transparent HTTPs Proxy with Python & mitmproxy
    =================================================
    Intercepts HTTPs Proxy with Python & mitmproxy
    ==============================================


    Introduction
  10. dannvix renamed this gist Apr 2, 2013. 1 changed file with 28 additions and 12 deletions.
    Original file line number Diff line number Diff line change
    @@ -1,18 +1,16 @@
    Non-Transparent SSL Proxy with Python & mitmproxy
    Non-Transparent HTTPs Proxy with Python & mitmproxy
    =================================================


    Introduction
    ------------
    Modern applications usually make use of back-end API servers to provide their services. With a non-transparent SSL proxy, which intercepts the communication between clients and servers (aka the man-in-the-middle scheme), you can easily manipulate both API requests and responses.
    Modern applications usually make use of back-end API servers to provide their services. With a non-transparent HTTPs proxy, which intercepts the communication between clients and servers (aka the man-in-the-middle scheme), you can easily manipulate both API requests and responses.

    This manual helps you create your own proxy with Python and [mitmproxy/libproxy](http://mitmproxy.org).
    This manual helps you create your own proxy with Python and [mitmproxy/libmproxy](http://mitmproxy.org). Mitmproxy ships with both a standalone command-line tool (`mitmproxy`) and a Python library (libmproxy).


    Requirements
    ------------
    Note: in my experience, mitmproxy depends on the **latest** netlib and PyOpenSSL, which cannot be installed from `Pip`. You may download the source tarball and install manually.

    * Python, >= 2.7.3
    - install through `brew install python` on Mac OS X
    * mitmproxy
    @@ -33,6 +31,8 @@ Note: in my experience, mitmproxy depends on the **latest** netlib and PyOpenSSL
    * pyasn1, >= 0.1.2
    - `pip install pyasn1`

    **Note:** In my experience, mitmproxy depends on the *latest* netlib and PyOpenSSL, which cannot be installed from Pip. You may download the source tarball and install them manually.


    Generate SSL Private Key and Certificate
    ----------------------------------------
    @@ -48,11 +48,12 @@ Example of `proxy.py`
    from libmproxy import controller, proxy
    import os, sys, re, datetime, json

    class InterceptingMaster(controller.Master):
    def __init__(self, server):

    class InterceptingMaster (controller.Master):
    def __init__ (self, server):
    controller.Master.__init__(self, server)

    def run(self):
    def run (self):
    while True:
    try:
    controller.Master.run(self)
    @@ -64,25 +65,40 @@ class InterceptingMaster(controller.Master):
    print 'Exception catched. Intercepting proxy restarted'
    pass

    def handle_request(self, msg):
    def handle_request (self, msg):
    timestamp = datetime.datetime.today().strftime("%Y/%m/%d %H:%M:%S")
    client_ip = msg.client_conn.address[0]
    request_url = '%s://%s%s' % (msg.scheme, .msg.host, msg.path)
    print '[%s %s] %s %s' % (timestamp, client_ip, msg.method, request_url)

    msg.reply()

    def handle_response(self, msg):
    if ("example.org" in msg.request.host):
    def handle_response (self, msg):
    # simple substitution for https://example.org/api/users/:id.json
    if "example.org" in msg.request.host:
    regex = re.compile("/api/users/(\d+).json")
    match = regex.search(msg.request.path)
    if match and msg.content:
    c = msg.replace('"private_data_accessible":false', '"private_data_accessible":true')
    if c > 0: print '[Example.org] Private info of user #%s revealed' % (match.groups()[0])

    # JSON manipulation for https://example.com/api/v2
    if ("example.com" in msg.request.host) and ("action=user_profile" in msg.request.content):
    msg.decode() # need to decode the message first
    data = json.loads(msg.content) # parse JSON with decompressed content
    data["access_granted"] = true
    msg.content = json.dumps(data) # write back our changes
    print '[Example.com] Access granted of user profile #%s' % data["id"]

    # Response inspection for https://example.net
    if "example.net" in msg.request.host:
    data = msg.get_decoded_content() # read decompressed content without modifying msg
    print '[Example.net] Respones: %s' % data

    msg.reply()


    def main(argv):
    def main (argv):
    config = proxy.ProxyConfig(
    cacert = os.path.expanduser("./mitmproxy.pem"),
    )
  11. dannvix revised this gist Apr 1, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions intercept-SSL-with-python-mitmproxy-libmproxy.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    Non-Transparent SSL Proxy with Python and mitmproxy
    ===================================================
    Non-Transparent SSL Proxy with Python & mitmproxy
    =================================================


    Introduction
  12. dannvix revised this gist Apr 1, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions intercept-SSL-with-python-mitmproxy-libmproxy.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    Create Non-Transparent SSL Proxy with Python and mitmproxy
    ==========================================================
    Non-Transparent SSL Proxy with Python and mitmproxy
    ===================================================


    Introduction
  13. dannvix created this gist Apr 1, 2013.
    96 changes: 96 additions & 0 deletions intercept-SSL-with-python-mitmproxy-libmproxy.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    Create Non-Transparent SSL Proxy with Python and mitmproxy
    ==========================================================


    Introduction
    ------------
    Modern applications usually make use of back-end API servers to provide their services. With a non-transparent SSL proxy, which intercepts the communication between clients and servers (aka the man-in-the-middle scheme), you can easily manipulate both API requests and responses.

    This manual helps you create your own proxy with Python and [mitmproxy/libproxy](http://mitmproxy.org).


    Requirements
    ------------
    Note: in my experience, mitmproxy depends on the **latest** netlib and PyOpenSSL, which cannot be installed from `Pip`. You may download the source tarball and install manually.

    * Python, >= 2.7.3
    - install through `brew install python` on Mac OS X
    * mitmproxy
    1. `git clone https://github.com/cortesi/mitmproxy.git`
    2. `cd mitmproxy`
    3. `sudo python setup.py install`
    * netlib, version matching mitmproxy
    1. `git clone https://github.com/cortesi/netlib.git`
    2. `cd netlib`
    3. `sudo python setup.py install`
    * PyOpenSSL, >= 0.13
    1. install OpenSSL development package (through `sudo apt-get install libssl-dev` on Ubuntu)
    2. download `pyOpenSSL-0.13.tar.gz` from [PyPi website](https://pypi.python.org/pypi/pyOpenSSL)
    3. `tar xvf pyOpenSSL-0.13.tar.gz`
    4. `cd pyOpenSSL-0.13`
    5. `python setup.py build`
    6. `sudo python setup.py install`
    * pyasn1, >= 0.1.2
    - `pip install pyasn1`


    Generate SSL Private Key and Certificate
    ----------------------------------------
    1. `openssl genrsa -out mitmproxy.key 2048`
    2. `openssl req -new -x509 -key mitmproxy.key -out mitmproxy.crt -days 3650 -subj /CN=MitmProxy`
    3. `cat mitmproxy.key mitmproxy.crt > mitmproxy.pem`
    4. install `mitmproxy.crt` on you device (desktop browser, iPhone, Android, etc.)


    Example of `proxy.py`
    ---------------------
    ```python
    from libmproxy import controller, proxy
    import os, sys, re, datetime, json

    class InterceptingMaster(controller.Master):
    def __init__(self, server):
    controller.Master.__init__(self, server)

    def run(self):
    while True:
    try:
    controller.Master.run(self)
    except KeyboardInterrupt:
    print 'KeyboardInterrupt received. Shutting down'
    self.shutdown()
    sys.exit(0)
    except Exception:
    print 'Exception catched. Intercepting proxy restarted'
    pass

    def handle_request(self, msg):
    timestamp = datetime.datetime.today().strftime("%Y/%m/%d %H:%M:%S")
    client_ip = msg.client_conn.address[0]
    request_url = '%s://%s%s' % (msg.scheme, .msg.host, msg.path)
    print '[%s %s] %s %s' % (timestamp, client_ip, msg.method, request_url)
    msg.reply()

    def handle_response(self, msg):
    if ("example.org" in msg.request.host):
    regex = re.compile("/api/users/(\d+).json")
    match = regex.search(msg.request.path)
    if match and msg.content:
    c = msg.replace('"private_data_accessible":false', '"private_data_accessible":true')
    if c > 0: print '[Example.org] Private info of user #%s revealed' % (match.groups()[0])

    msg.reply()


    def main(argv):
    config = proxy.ProxyConfig(
    cacert = os.path.expanduser("./mitmproxy.pem"),
    )
    server = proxy.ProxyServer(config, 8080)
    print 'Intercepting Proxy listening on 8080'
    m = InterceptingMaster(server)
    m.run()

    if __name__ == '__main__':
    main(sys.argv)
    ```