mitmproxy

An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers

http://mitmproxy.org

mitmproxy is an interactive, SSL-capable intercepting proxy with a console interface.

mitmdump is the command-line version of mitmproxy. Think tcpdump for HTTP.

mitmweb is a web-based interface for mitmproxy.

pathoc and pathod are perverse HTTP client and server applications designed to let you craft almost any conceivable HTTP request, including ones that creatively violate the standards.

 

Documentation & Help

General information, tutorials, and precompiled binaries can be found on the mitmproxy and pathod websites.

mitmproxy.org

The latest documentation for mitmproxy is also available on ReadTheDocs.

mitmproxy documentation

Join our discussion forum on Discourse to ask questions, help each other solve problems, and come up with new ideas for the project.

Discourse: mitmproxy

Join our developer chat on Slack if you would like to contribute to mitmproxy itself.

Slack Developer Chat

 

Installation

The installation instructions are here. If you want to contribute changes, keep on reading.

 

Contributing

As an open source project, mitmproxy welcomes contributions of all forms. If you would like to bring the project forward, please consider contributing in the following areas:

  • Maintenance: We are incredibly thankful for individuals who are stepping up and helping with maintenance. This includes (but is not limited to) triaging issues, reviewing pull requests and picking up stale ones, helping out other users in our forums, creating minimal, complete and verifiable examples or test cases for existing bug reports, updating documentation, or fixing minor bugs that have recently been reported.
  • Code Contributions: We actively mark issues that we consider are good first contributions. If you intend to work on a larger contribution to the project, please come talk to us first.

 

Development Setup

To get started hacking on mitmproxy, please follow the advanced installation steps to install mitmproxy from source, but stop right before running pip3 install mitmproxy. Instead, do the following:

git clone https://github.com/mitmproxy/mitmproxy.git
cd mitmproxy
./dev.sh  # "powershell .\dev.ps1" on Windows

The dev script will create a virtualenv environment in a directory called “venv” and install all mandatory and optional dependencies into it. The primary mitmproxy components – mitmproxy and pathod – are installed as “editable”, so any changes to the source in the repository will be reflected live in the virtualenv.

The main executables for the project – mitmdump, mitmproxy, mitmweb, pathod, and pathoc – are all created within the virtualenv. After activating the virtualenv, they will be on your $PATH, and you can run them like any other command:

. venv/bin/activate  # "venv\Scripts\activate" on Windows
mitmdump --version

 

Testing

If you’ve followed the procedure above, you already have all the development requirements installed, and you can run the full test suite (including tests for code style and documentation) with tox:

tox

For speedier testing, we recommend you run pytest directly on individual test files or folders:

cd test/mitmproxy/addons
pytest --cov mitmproxy.addons.anticache --looponfail test_anticache.py

As pytest does not check the code style, you probably want to run tox -e lint before committing your changes.

Please ensure that all patches are accompanied by matching changes in the test suite. The project tries to maintain 100% test coverage and enforces this strictly for some parts of the codebase.

 

Documentation

The mitmproxy documentation is build using Sphinx, which is installed automatically if you set up a development environment as described above. After installation, you can render the documentation like this:

cd docs
make clean
make html
make livehtml

The last command invokes sphinx-autobuild, which watches the Sphinx directory and rebuilds the documentation when a change is detected.

Introduction

mitmproxy is an interactive man-in-the-middle proxy for HTTP and HTTPS with a console interface.

mitmdump is the command-line version of mitmproxy. Think tcpdump for HTTP.

mitmweb is a web-based interface for mitmproxy.

Documentation, tutorials and distribution packages can be found on the mitmproxy website: mitmproxy.org

Features

  • Intercept HTTP & HTTPS requests and responses and modify them on the fly
  • Save complete HTTP conversations for later replay and analysis
  • Replay the client-side of an HTTP conversations
  • Replay HTTP responses of a previously recorded server
  • Reverse proxy mode to forward traffic to a specified server
  • Transparent proxy mode on OSX and Linux
  • Make scripted changes to HTTP traffic using Python
  • SSL/TLS certificates for interception are generated on the fly
  • And much, much more…

How mitmproxy works

Mitmproxy is an enormously flexible tool. Knowing exactly how the proxying process works will help you deploy it creatively, and take into account its fundamental assumptions and how to work around them. This document explains mitmproxy’s proxy mechanism in detail, starting with the simplest unencrypted explicit proxying, and working up to the most complicated interaction – transparent proxying of TLS-protected traffic [1] in the presence of Server Name Indication.

The MITM in mitmproxy

This is where mitmproxy’s fundamental trick comes into play. The MITM in its name stands for Man-In-The-Middle – a reference to the process we use to intercept and interfere with these theoretically opaque data streams. The basic idea is to pretend to be the server to the client, and pretend to be the client to the server, while we sit in the middle decoding traffic from both sides. The tricky part is that the Certificate Authority system is designed to prevent exactly this attack, by allowing a trusted third-party to cryptographically sign a server’s certificates to verify that they are legit. If this signature doesn’t match or is from a non-trusted party, a secure client will simply drop the connection and refuse to proceed. Despite the many shortcomings of the CA system as it exists today, this is usually fatal to attempts to MITM an TLS connection for analysis. Our answer to this conundrum is to become a trusted Certificate Authority ourselves. Mitmproxy includes a full CA implementation that generates interception certificates on the fly. To get the client to trust these certificates, we register mitmproxy as a trusted CA with the device manually.

Lets put all of this together into the complete explicitly proxied HTTPS flow.

_images/how-mitmproxy-works-explicit-https.png

  1. The client makes a connection to mitmproxy, and issues an HTTP CONNECT request.
  2. Mitmproxy responds with a 200 Connection Established, as if it has set up the CONNECT pipe.
  3. The client believes it’s talking to the remote server, and initiates the TLS connection. It uses SNI to indicate the hostname it is connecting to.
  4. Mitmproxy connects to the server, and establishes an TLS connection using the SNI hostname indicated by the client.
  5. The server responds with the matching certificate, which contains the CN and SAN values needed to generate the interception certificate.
  6. Mitmproxy generates the interception cert, and continues the client TLS handshake paused in step 3.
  7. The client sends the request over the established TLS connection.
  8. Mitmproxy passes the request on to the server over the TLS connection initiated in step 4.

Transparent HTTP

When a transparent proxy is used, the connection is redirected into a proxy at the network layer, without any client configuration being required. This makes transparent proxying ideal for those situations where you can’t change client behaviour – proxy-oblivious Android applications being a common example.

To achieve this, we need to introduce two extra components. The first is a redirection mechanism that transparently reroutes a TCP connection destined for a server on the Internet to a listening proxy server. This usually takes the form of a firewall on the same host as the proxy server – iptables on Linux or pf on OSX. Once the client has initiated the connection, it makes a vanilla HTTP request, which might look something like this:

GET /index.html HTTP/1.1

Note that this request differs from the explicit proxy variation, in that it omits the scheme and hostname. How, then, do we know which upstream host to forward the request to? The routing mechanism that has performed the redirection keeps track of the original destination for us. Each routing mechanism has a different way of exposing this data, so this introduces the second component required for working transparent proxying: a host module that knows how to retrieve the original destination address from the router. In mitmproxy, this takes the form of a built-in set of modules that know how to talk to each platform’s redirection mechanism. Once we have this information, the process is fairly straight-forward.

_images/how-mitmproxy-works-transparent.png

  1. The client makes a connection to the server.
  2. The router redirects the connection to mitmproxy, which is typically listening on a local port of the same host. Mitmproxy then consults the routing mechanism to establish what the original destination was.
  3. Now, we simply read the client’s request…
  4. … and forward it upstream.

Transparent HTTPS

The first step is to determine whether we should treat an incoming connection as HTTPS. The mechanism for doing this is simple – we use the routing mechanism to find out what the original destination port is. All incoming connections pass through different layers which can determin the actual protocol to use. Automatic TLS detection works for SSLv3, TLS 1.0, TLS 1.1, and TLS 1.2 by looking for a ClientHello message at the beginning of each connection. This works independently of the used TCP port.

From here, the process is a merger of the methods we’ve described for transparently proxying HTTP, and explicitly proxying HTTPS. We use the routing mechanism to establish the upstream server address, and then proceed as for explicit HTTPS connections to establish the CN and SANs, and cope with SNI.

_images/how-mitmproxy-works-transparent-https.png

  1. The client makes a connection to the server.
  2. The router redirects the connection to mitmproxy, which is typically listening on a local port of the same host. Mitmproxy then consults the routing mechanism to establish what the original destination was.
  3. The client believes it’s talking to the remote server, and initiates the TLS connection. It uses SNI to indicate the hostname it is connecting to.
  4. Mitmproxy connects to the server, and establishes an TLS connection using the SNI hostname indicated by the client.
  5. The server responds with the matching certificate, which contains the CN and SAN values needed to generate the interception certificate.
  6. Mitmproxy generates the interception cert, and continues the client TLS handshake paused in step 3.
  7. The client sends the request over the established TLS connection.
  8. Mitmproxy passes the request on to the server over the TLS connection initiated in step 4.

 

Modes of Operation

Mitmproxy has four modes of operation that allow you to use mitmproxy in a variety of scenarios:

  • Regular (the default)
  • Transparent
  • Reverse Proxy
  • Upstream Proxy

Now, which one should you pick? Use this flow chart:

_images/proxy-modes-flowchart.png

Regular Proxy

Mitmproxy’s regular mode is the simplest and the easiest to set up.

  1. Start mitmproxy.
  2. Configure your client to use mitmproxy by explicitly setting an HTTP proxy.
  3. Quick Check: You should already be able to visit an unencrypted HTTP site through the proxy.
  4. Open the magic domain mitm.it and install the certificate for your device.

Note

Unfortunately, some applications bypass the system HTTP proxy settings – Android applications are a common example. In these cases, you need to use mitmproxy’s transparent mode.

If you are proxying an external device, your network will probably look like this:

_images/proxy-modes-regular.pngThe square brackets signify the source and destination IP addresses. Your client explicitly connects to mitmproxy and mitmproxy explicitly connects to the target server.

Transparent Proxy

In transparent mode, traffic is directed into a proxy at the network layer, without any client configuration required. This makes transparent proxying ideal for situations where you can’t change client behaviour. In the graphic below, a machine running mitmproxy has been inserted between the router and the internet:

_images/proxy-modes-transparent-1.pngThe square brackets signify the source and destination IP addresses. Round brackets mark the next hop on the Ethernet/data link layer. This distinction is important: when the packet arrives at the mitmproxy machine, it must still be addressed to the target server. This means that Network Address Translation should not be applied before the traffic reaches mitmproxy, since this would remove the target information, leaving mitmproxy unable to determine the real destination.

_images/proxy-modes-transparent-wrong.png

Common Configurations

There are many ways to configure your network for transparent proxying. We’ll look at two common scenarios:

  1. Configuring the client to use a custom gateway/router/”next hop”
  2. Implementing custom routing on the router

In most cases, the first option is recommended due to its ease of use.

(a) Custom Gateway

One simple way to get traffic to the mitmproxy machine with the destination IP intact, is to simply configure the client with the mitmproxy box as the default gateway.

_images/proxy-modes-transparent-2.pngIn this scenario, we would:

  1. Configure the proxy machine for transparent mode. You can find instructions in the Transparent Proxying section.
  2. Configure the client to use the proxy machine’s IP as the default gateway.
  3. Quick Check: At this point, you should already be able to visit an unencrypted HTTP site over the proxy.
  4. Open the magic domain mitm.it and install the certificate for your device.

Setting the custom gateway on clients can be automated by serving the settings out to clients over DHCP. This lets set up an interception network where all clients are proxied automatically, which can save time and effort.

Troubleshooting Transparent Mode

Incorrect transparent mode configurations are a frequent source of error. If it doesn’t work for you, try the following things:

  • Open mitmproxy’s event log (press e) – do you see clientconnect messages? If not, the packets are not arriving at the proxy. One common cause is the occurrence of ICMP redirects, which means that your machine is telling the client that there’s a faster way to the internet by contacting your router directly (see the Transparent Proxying section on how to disable them). If in doubt, Wireshark may help you to see whether something arrives at your machine or not.
  • Make sure you have not explicitly configured an HTTP proxy on the client. This is not needed in transparent mode.
  • Re-check the instructions in the Transparent Proxying section. Anything you missed?

If you encounter any other pitfalls that should be listed here, please let us know!

(b) Custom Routing

In some cases, you may need more fine-grained control of which traffic reaches the mitmproxy instance, and which doesn’t. You may, for instance, choose only to divert traffic to some hosts into the transparent proxy. There are a huge number of ways to accomplish this, and much will depend on the router or packet filter you’re using. In most cases, the configuration will look like this:

_images/proxy-modes-transparent-3.png

Reverse Proxy

mitmproxy is usually used with a client that uses the proxy to access the Internet. Using reverse proxy mode, you can use mitmproxy to act like a normal HTTP server:

_images/proxy-modes-reverse.pngThere are various use-cases:

  • Say you have an internal API running at http://example.local/. You could now set up mitmproxy in reverse proxy mode at http://debug.example.local/ and dynamically point clients to this new API endpoint, which provides them with the same data and you with debug information. Similarly, you could move your real server to a different IP/port and set up mitmproxy in the original place to debug and or redirect all sessions.
  • Say you’re a web developer working on http://example.com/ (with a development version running on http://localhost:8000/). You can modify your hosts file so that example.com points to 127.0.0.1 and then run mitmproxy in reverse proxy mode on port 80. You can test your app on the example.com domain and get all requests recorded in mitmproxy.
  • Say you have some toy project that should get SSL support. Simply set up mitmproxy as a reverse proxy on port 443 and you’re done (mitmdump -p 443 -R http://localhost:80/). Mitmproxy auto-detects TLS traffic and intercepts it dynamically. There are better tools for this specific task, but mitmproxy is very quick and simple way to set up an SSL-speaking server.
  • Want to add a non-SSL-capable compression proxy in front of your server? You could even spawn a mitmproxy instance that terminates SSL (-R http://...), point it to the compression proxy and let the compression proxy point to a SSL-initiating mitmproxy (-R https://...), which then points to the real server. As you see, it’s a fairly flexible thing.

Caveat: Interactive Use

Reverse Proxy mode is usually not sufficient to create a copy of an interactive website at different URL. The HTML served to the client remains unchanged – as soon as the user clicks on an non-relative URL (or downloads a non-relative image resource), traffic no longer passes through mitmproxy.

Upstream Proxy

If you want to chain proxies by adding mitmproxy in front of a different proxy appliance, you can use mitmproxy’s upstream mode. In upstream mode, all requests are unconditionally transferred to an upstream proxy of your choice.

_images/proxy-modes-upstream.pngmitmproxy supports both explicit HTTP and explicit HTTPS in upstream proxy mode. You could in theory chain multiple mitmproxy instances in a row, but that doesn’t make any sense in practice (i.e. outside of our tests).


 Configuration

Mitmproxy is configured with a YAML file, located at ~/.mitmproxy/config.yaml. We’ll have complete documentation for all supported options in the next release in the meantime, please consult the source for a complete list of options and types.

Anticache

When the --anticache option is passed to mitmproxy, it removes headers (if-none-match and if-modified-since) that might elicit a 304 not modified response from the server. This is useful when you want to make sure you capture an HTTP exchange in its totality. It’s also often used during Client-side replay, when you want to make sure the server responds with complete data.

command-line --anticache
mitmproxy shortcut o then a

Filter expressions

Many commands in mitmproxy and mitmdump take a filter expression. Filter expressions consist of the following operators:

Expression Description
~a Match asset in response: CSS, Javascript, Flash, images.
~b regex Body
~bq regex Request body
~bs regex Response body
~c int HTTP response code
~d regex Domain
~dst regex Match destination address
~e Match error
~h regex Header
~hq regex Request header
~hs regex Response header
~http Match HTTP flows
~m regex Method
~marked Match marked flows
~q Match request with no response
~s Match response
~src regex Match source address
~t regex Content-type header
~tcp Match TCP flows
~tq regex Request Content-Type header
~ts regex Response Content-Type header
~u regex URL
! unary not
& and
| or
(…) grouping
  • Regexes are Python-style
  • Regexes can be specified as quoted strings
  • Header matching (~h, ~hq, ~hs) is against a string of the form “name: value”.
  • Strings with no operators are matched against the request URL.
  • The default binary operator is &.

Examples

URL containing “google.com”:

google\.com

Requests whose body contains the string “test”:

~q ~b test

Anything but requests with a text/html content type:

!(~q & ~t "text/html")


Client-side replay

Client-side replay does what it says on the tin: you provide a previously saved HTTP conversation, and mitmproxy replays the client requests one by one. Note that mitmproxy serializes the requests, waiting for a response from the server before starting the next request. This might differ from the recorded conversation, where requests may have been made concurrently.

You may want to use client-side replay in conjunction with the Anticache option, to make sure the server responds with complete data.

command-line -c path
mitmproxy shortcut R then c

Ignore Domains

There are two main reasons why you may want to exempt some traffic from mitmproxy’s interception mechanism:

  • Certificate pinning: Some traffic is is protected using Certificate Pinning and mitmproxy’s interception leads to errors. For example, the Twitter app, Windows Update or the Apple App Store fail to work if mitmproxy is active.
  • Convenience: You really don’t care about some parts of the traffic and just want them to go away. Note that mitmproxy’s “Limit” option is often the better alternative here, as it is not affected by the limitations listed below.

If you want to peek into (SSL-protected) non-HTTP connections, check out the TCP Proxy feature. If you want to ignore traffic from mitmproxy’s processing because of large response bodies, take a look at the Response Streaming feature.

How it works

command-line --ignore regex
mitmproxy shortcut o then I

mitmproxy allows you to specify a regex which is matched against a host:port string (e.g. “example.com:443”) to determine hosts that should be excluded.

Limitations

There are two important quirks to consider:

  • In transparent mode, the ignore pattern is matched against the IP and ClientHello SNI host. While we usually infer the hostname from the Host header if the --host argument is passed to mitmproxy, we do not have access to this information before the SSL handshake. If the client uses SNI however, then we treat the SNI host as an ignore target.
  • In regular mode, explicit HTTP requests are never ignored. [1] The ignore pattern is applied on CONNECT requests, which initiate HTTPS or clear-text WebSocket connections.

Tutorial

If you just want to ignore one specific domain, there’s usually a bulletproof method to do so:

  1. Run mitmproxy or mitmdump in verbose mode (-v) and observe the host:port information in the serverconnect messages. mitmproxy will filter on these.
  2. Take the host:port string, surround it with ^ and $, escape all dots (. becomes \.) and use this as your ignore pattern:
>>> mitmdump -v
127.0.0.1:50588: clientconnect
127.0.0.1:50588: request
  -> CONNECT example.com:443 HTTP/1.1
127.0.0.1:50588: Set new server address: example.com:443
127.0.0.1:50588: serverconnect
  -> example.com:443
^C
>>> mitmproxy --ignore ^example\.com:443$

Here are some other examples for ignore patterns:

# Exempt traffic from the iOS App Store (the regex is lax, but usually just works):
--ignore apple.com:443
# "Correct" version without false-positives:
--ignore '^(.+\.)?apple\.com:443$'

# Ignore example.com, but not its subdomains:
--ignore '^example.com:'

# Ignore everything but example.com and mitmproxy.org:
--ignore '^(?!example\.com)(?!mitmproxy\.org)'

# Transparent mode:
--ignore 17\.178\.96\.59:443
# IP address range:
--ignore 17\.178\.\d+\.\d+:443

See also

Footnotes

[1] This stems from an limitation of explicit HTTP proxying: A single connection can be re-used for multiple target domains – a GET http://example.com/ request may be followed by a GET http://evil.com/ request on the same connection. If we start to ignore the connection after the first request, we would miss the relevant second one.

 

Proxy Authentication

Asks the user for authentication before they are permitted to use the proxy. Authentication headers are stripped from the flows, so they are not passed to upstream servers. For now, only HTTP Basic authentication is supported. The proxy auth options are not compatible with the transparent, socks or reverse proxy mode.

Command-line --nonanonymous, --singleuser USER, --htpasswd PATH

Reverse Proxy

In reverse proxy mode, mitmproxy accepts standard HTTP(S) requests and forwards them to the specified upstream server. This is in contrast to Upstream proxy mode, in which mitmproxy forwards HTTP(S) proxy requests to an upstream proxy server.

command-line -R http[s]://hostname[:port]

Here, http[s] signifies if the proxy should use TLS to connect to the server. mitmproxy always accepts both encrypted and unencrypted requests and transforms them to what the server expects.

>>> mitmdump -R https://httpbin.org -p 80
>>> curl http://localhost/
# requests will be transparently upgraded to TLS by mitmproxy

>>> mitmdump -R https://httpbin.org -p 443
>>> curl https://localhost/
# mitmproxy will use TLS on both ends.

Host Header

In reverse proxy mode, mitmproxy automatically rewrites the Host header to match the upstream server. This allows mitmproxy to easily connect to existing endpoints on the open web (e.g. mitmproxy -R https://example.com).

However, keep in mind that absolute URLs within the returned document or HTTP redirects will NOT be rewritten by mitmproxy. This means that if you click on a link for “http://example.com” in the returned web page, you will be taken directly to that URL, bypassing mitmproxy.

One possible way to address this is to modify the hosts file of your OS so that “example.com” resolves to your proxy’s IP, and then access the proxy by going directly to example.com. Make sure that your proxy can still resolve the original IP, or specify an IP in mitmproxy.

 

SOCKS Mode

In this mode, mitmproxy acts as a SOCKS5 proxy server.

command-line --socks

 

Sticky cookies and auth

Sticky cookies

When the sticky cookie option is set, __mitmproxy__ will add the cookie most recently set by the server to any cookie-less request. Consider a service that sets a cookie to track the session after authentication. Using sticky cookies, you can fire up mitmproxy, and authenticate to a service as you usually would using a browser. After authentication, you can request authenticated resources through mitmproxy as if they were unauthenticated, because mitmproxy will automatically add the session tracking cookie to requests. Among other things, this lets you script interactions with authenticated resources (using tools like wget or curl) without having to worry about authentication.

Sticky cookies are especially powerful when used in conjunction with Client-side replay – you can record the authentication process once, and simply replay it on startup every time you need to interact with the secured resources.

command-line -t FILTER
mitmproxy shortcut o then t

Sticky auth

The sticky auth option is analogous to the sticky cookie option, in that HTTP Authorization headers are simply replayed to the server once they have been seen. This is enough to allow you to access a server resource using HTTP Basic authentication through the proxy. Note that mitmproxy doesn’t (yet) support replay of HTTP Digest authentication.

command-line -u FILTER
mitmproxy shortcut o then A

 

Upstream Certificates

When mitmproxy receives a connection destined for an SSL-protected service, it freezes the connection before reading its request data, and makes a connection to the upstream server to “sniff” the contents of its SSL certificate. The information gained – the Common Name and Subject Alternative Names – is then used to generate the interception certificate, which is sent to the client so the connection can continue.

This rather intricate little dance lets us seamlessly generate correct certificates even if the client has specified only an IP address rather than the hostname. It also means that we don’t need to sniff additional data to generate certs in transparent mode.

Upstream cert sniffing is on by default, and can optionally be turned off.

command-line --no-upstream-cert
mitmproxy shortcut o then U

 

Tutorials

Client playback: a 30 second example

My local cafe is serviced by a rickety and unreliable wireless network, generously sponsored with ratepayers’ money by our city council. After connecting, you are redirected to an SSL-protected page that prompts you for a username and password. Once you’ve entered your details, you are free to enjoy the intermittent dropouts, treacle-like speeds and incorrectly configured transparent proxy.

I tend to automate this kind of thing at the first opportunity, on the theory that time spent now will be more than made up in the long run. In this case, I might use Firebug to ferret out the form post parameters and target URL, then fire up an editor to write a little script using Python’s urllib to simulate a submission. That’s a lot of futzing about. With mitmproxy we can do the job in literally 30 seconds, without having to worry about any of the details. Here’s how.

1. Run mitmdump to record our HTTP conversation to a file.

>>> mitmdump -w wireless-login

2. Point your browser at the mitmdump instance.

I use a tiny Firefox addon called Toggle Proxy to switch quickly to and from mitmproxy. I’m assuming you’ve already configured your browser with mitmproxy’s SSL certificate authority.

3. Log in as usual.

And that’s it! You now have a serialized version of the login process in the file wireless-login, and you can replay it at any time like this:

>>> mitmdump -c wireless-login

Embellishments

We’re really done at this point, but there are a couple of embellishments we could make if we wanted. I use wicd to automatically join wireless networks I frequent, and it lets me specify a command to run after connecting. I used the client replay command above and voila! – totally hands-free wireless network startup.

We might also want to prune requests that download CSS, JS, images and so forth. These add only a few moments to the time it takes to replay, but they’re not really needed and I somehow feel compelled to trim them anyway. So, we fire up the mitmproxy console tool on our serialized conversation, like so:

>>> mitmproxy -r wireless-login

We can now go through and manually delete (using the d keyboard shortcut) everything we want to trim. When we’re done, we use w to save the conversation back to the file.

 

Setting highscores on Apple’s GameCenter

The setup

In this tutorial, I’m going to show you how simple it is to creatively interfere with Apple Game Center traffic using mitmproxy. To set things up, install the mitmproxy root certificate. Then start mitmproxy on your desktop, and configure the iPhone to use it as a proxy.

Taking a look at the Game Center traffic

Lets take a first look at the Game Center traffic. The game I’ll use in this tutorial is Super Mega Worm – a great little retro-apocalyptic sidescroller for the iPhone:

../_images/supermega.pngAfter finishing a game (take your time), watch the traffic flowing through mitmproxy:

../_images/one.pngWe see a bunch of things we might expect – initialisation, the retrieval of leaderboards and so forth. Then, right at the end, there’s a POST to this tantalising URL:

https://service.gc.apple.com/WebObjects/GKGameStatsService.woa/wa/submitScore

The contents of the submission are particularly interesting:

<!--(block|syntax("xml"))-->
<plist version="1.0">
  <dict>
    <key>scores</key>
    <array>
      <dict>
        <key>category</key>
        <string>SMW_Adv_USA1</string>
        <key>context</key>
        <integer>0</integer>
        <key>score-value</key>
        <integer>55</integer>
        <key>timestamp</key>
        <integer>1363515361321</integer>
      </dict>
    </array>
  </dict>
</plist>
<!--(end)-->

This is a property list, containing an identifier for the game, a score (55, in this case), and a timestamp. Looks pretty simple to mess with.

Modifying and replaying the score submission

Lets edit the score submission. First, select it in mitmproxy, then press enter to view it. Make sure you’re viewing the request, not the response – you can use tab to flick between the two. Now press e for edit. You’ll be prompted for the part of the request you want to change – press r for raw body. Your preferred editor (taken from the EDITOR environment variable) will now fire up. Lets bump the score up to something a bit more ambitious:

<!--(block|syntax("xml"))-->
<plist version="1.0">
  <dict>
    <key>scores</key>
    <array>
      <dict>
        <key>category</key>
        <string>SMW_Adv_USA1</string>
        <key>context</key>
        <integer>0</integer>
        <key>score-value</key>
        <integer>2200272667</integer>
        <key>timestamp</key>
        <integer>1363515361321</integer>
      </dict>
    </array>
  </dict>
</plist>
<!--(end)-->

Save the file and exit your editor.

The final step is to replay this modified request. Simply press r for replay.

The glorious result and some intrigue

../_images/leaderboard.pngAnd that’s it – according to the records, I am the greatest Super Mega Worm player of all time.

There’s a curious addendum to this tale. When I first wrote this tutorial, all the top competitors’ scores were the same: 2,147,483,647 (this is no longer the case, because there are now so many fellow cheaters using this tutorial). If you think that number seems familiar, you’re right: it’s 2^31-1, the maximum value you can fit into a signed 32-bit int. Now let me tell you another peculiar thing about Super Mega Worm – at the end of every game, it submits your highest previous score to the Game Center, not your current score. This means that it stores your highscore somewhere, and I’m guessing that it reads that stored score back into a signed integer. So, if you _were_ to cheat by the relatively pedestrian means of modifying the saved score on your jailbroken phone, then 2^31-1 might well be the maximum score you could get. Then again, if the game itself stores its score in a signed 32-bit int, you could get the same score through perfect play, effectively beating the game. So, which is it in this case? I’ll leave that for you to decide.

 

 

 

 

 

mitmproxy MITM

Post navigation


One thought on “mitmproxy MITM

  1. Thank you for some other informative website. The place else
    may I am getting that kind of info written in such a perfect approach?

    I’ve a venture that I am just now running on, and I
    have been at the glance out for such info.

Leave a Reply

Your email address will not be published. Required fields are marked *

Pin It on Pinterest