Setup Android HTTPS Proxy using mitmproxy on Linux
I recently wanted to debug/reverse engineer the Web-API an Android app speaks with. I expected this to be much easier than it turned out to be in the end and had to do lots of trial and error, which is why I decided to write a little post about it.
I used Android-X86 in a QEMU VM, however other virtualization software like Virtualbox will work just as well. You need to create a virtual machine like any other and point it to the Android-X86 iso. The only important thing for this tutorial is that you choose NAT Networking.
You might be able to do this with a rooted physical phone with a little tweaking, however I haven't tried it.
Throughout this article the phone's IP will be
192.168.122.70 and the computer's
192.168.122.1. You will need to replace them with your own ones.
In the installer make sure to choose a writable
/system directory when prompted and then later in android's graphical installation connect to the virtual WiFi network.
Once you're in the Android interface, we will setup adb. Unlike with the usual USB method, in order to connect via adb over WiFi you will need to authorize your computer's public key by adding it to
/data/misc/adb/adb_keys. I didn't setup clipboard sharing so I transfered it to the VM via
Open a terminal on the phone and run:
su nc -lp 1337 >> /data/misc/adb/adb_keys
Then transfer the public key to the phone by running this on the computer:
cat ~/.android/adbkey.pub | nc 192.168.122.70 1337
Then start the adb server on the phone:
su start adbd
Now you should be able to connect to the phone via adb:
adb connect 192.168.122.70
Install root certificate
Next we will install mitmproxy's root certificate onto the device. This allows mitmproxy to decrypt HTTPS traffic.
In android CA certificates are named by the subject hash followed by
.0. You can get the subject hash by running
openssl x509 -in ~/.mitmproxy/mitmproxy-ca.pem -subject_hash_old -noout
For me it was
c8750f0d and it will probably be the same for you.
On the computer run:
cp ~/.mitmproxy/mitmproxy-ca.pem c8750f0d.0 openssl x509 -text -in ~/.mitmproxy/mitmproxy-ca.pem -text -noout >> c8750f0d.0 adb push c8750f0d.0 /data/local/tmp
Then launch an adb shell using
and run the following commands on the phone:
su mv /data/local/tmp/c8750f0d.0 /system/etc/security/cacerts/ chown root:root /system/etc/security/cacerts/c8750f0d.0 chmod 644 /system/etc/security/cacerts/c8750f0d.0
Finally you will need to reboot for the newly installed certificate to take effect:
Now the certificate is installed, so just set the proxy in the settings and you're good to go? Right? Wrong. HTTP Proxy settings on Android are weird and don't really apply to all apps. Or any apps at all for that matter. But traffic goes through the virtual network interface of the VM on the computer anyways and we can do whatever we want there without being handicapped by android.
iptables is running and create 2 rules to redirect all HTTP and HTTPS traffic coming from the vm to mitmproxy:
sudo iptables -t nat -A PREROUTING -s 192.168.122.0/24 -p tcp --dport 80 -j REDIRECT --to-port 8080 sudo iptables -t nat -A PREROUTING -s 192.168.122.0/24 -p tcp --dport 443 -j REDIRECT --to-port 8080
And then start mitmproxy in transparent mode:
That's it! If you surf around in the web browser or
curl websites you should see the requests pop up in mitmproxy!