Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save carpedm20/27f5157c3ff8f2a63a37 to your computer and use it in GitHub Desktop.
Save carpedm20/27f5157c3ff8f2a63a37 to your computer and use it in GitHub Desktop.

Intercepts HTTPs Traffic with Python & mitmproxy


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/libmproxy. Mitmproxy ships with both a standalone command-line tool (mitmproxy) and a Python library (libmproxy).


  • Python, >= 2.7.3
    • install through brew install python on Mac OS X
  • mitmproxy
    1. git clone
    2. cd mitmproxy
    3. sudo python install
  • netlib, version matching mitmproxy
    1. git clone
    2. cd netlib
    3. sudo python 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 pyOpenSSL project page on PyPI website
    3. tar xvf pyOpenSSL-0.13.tar.gz
    4. cd pyOpenSSL-0.13
    5. python build
    6. sudo python install
  • 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

  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

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from libmproxy import controller, proxy
import os, sys, re, datetime, json

class RequestHacks:
  def example_com (msg):
    # tamper outgoing requests for
    if ('' in 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][] Fake location (%s, %s) sent when logging in' % (fake_lat, fake_lng)

class ResponseHacks:
  def example_org (msg):
    # simple substitution for
    if '' in
      regex = re.compile('/api/users/(\d+).json')
      match =
      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][] Private info of user #%s revealed' % user_id

  def example_com (msg):
    # JSON manipulation for
    if ('' in 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][] Access granted of user profile #%s' % data['id']

  def example_net (msg):
    # Response inspection for
    if '' in
      data = msg.get_decoded_content() # read decompressed content without modifying msg
      print '[ResponseHacks][] Respones: %s' % data

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

  def run (self):
    while True:
      except KeyboardInterrupt:
        print 'KeyboardInterrupt received. Shutting down'
      except Exception:
        print 'Exception catched. Intercepting proxy restarted'

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


  def handle_response (self, msg):

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)

if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment