Curiosity got the best of me about a year ago when Pokemon Go came out, so I had to dig up ways to inspect traffic from iOS on a Mac. Since then, time has passed and today I decided to do it again, but couldn’t find a decent guide on how to do that (clearly I was missing some steps), so once I figured out what goes where, I thought I would do a write-up for posterity, and so that I can re-use it later. Hopefully this will be helpful to the broader audience as well!
First things first, I am just assuming that you have unfettered access to your iOS device. This is where I am talking about the fact that your device is not locked down by your company, or has any other constraints. The running assumption is that you can pretty much modify any settings that needs to be, given a stock configuration (you don’t need to have the device jailbroken).
Setting up the toolchain
We will need to use a tool called
mitmproxy. The easiest (IMHO) way to install it is via a publicly-maintained Docker image. Which means that I recommend you install Docker. Once Docker is on your system, just run this in the terminal:
Verify that the Docker image is there once the pull completes:
Given that everything went smoothly in the steps outlined above, now you can run the image and bind it to port 8080:
Capturing HTTP/S traffic
mitmproxy is running, it’s time to configure our iPhone to send traffic through it. In this scenario, the machine in which
mitmproxy is running is the actual pipe that channels data through it, so we need to find it’s IP address. You need to get the local IP, and for that, run the following command in your Terminal:
NOTE: You can open another Terminal window, since you have
mitmproxyrunning in the original one.
en0 typically stands for your wireless adapter (let’s face it, you’re probably running this on a MacBook, so this should work).
Sweet! Now you can set this up as a proxy on your phone. Go to Settings > Wi-Fi > Currently Connected Network > Configure Proxy > Manual and enter the server IP and port (remember - it’s 8080).
Once you tap on Save, you should be able to go to your browser and start sending requests, that will be reflected in the proxy Terminal:
Here is a problem, though:
Generally, sites and apps do SSL validation - in this case, because we are man-in-the-middle attacking our own device, the privacy check fails and no information is returned. That is, because we don’t yet have a certificate installed that the device trusts. Luckily, it comes out-of-the-box with
mitmproxy - all you need to do is go to https://mitm.it in your browser, while connected to the proxy:
NOTE: For this page to properly work, make sure you open it in Safari.
Since we are on iOS, the choice is obvious - tap on Apple. You should see a prompt that will ask your permission to view a custom profile:
Click Allow, and now you should be taken to the Install Profile page:
If prompted, make sure to enter your PIN - installing a profile is an administrative action (remember when I mentioned from the very beginning you’ll need full control of the device?). As with all very serious steps, it’s important to remind the reader - only install profiles and certificates that you trust. This enables your device traffic to be decrypted in its entirety.
We’re almost there. Now, we need to make sure that the iPhone device fully trusts the certificate to be able to read the piped traffic. To do that, go to Settings > General > About > Certificate Trust Settings and find mitmproxy:
Make sure to enable full trust for the newly installed certificate:
I will repeat myself - only install profiles and certificates that you trust. This enables your device traffic to be decrypted in its entirety by anyone.
Once you complete these steps, you will be able to analyze HTTPS traffic:
This might seem harder than it actually looks, but from start to finish this took around 10 minutes. For once, I am glad I don’t have to deal with
pip and other
brew-based installation shenanigans, given that now I can just pull a Docker image. Oh yeah, and make sure you install Kitematic for better container management on a Mac - that way, you can control the runtime of each and every one of them without the Terminal.
Have any thoughts? Let me know on Twitter!