Often I need to reverse engineer how an Android app loads its data. If I can determine the relevant server endpoints then I can call them directly in future via a script and bypass the app. This process is more complex when the app uses HTTPS for network communication, which is becoming more common now that Let’s Encrypt provides SSL certificates for free.

To work with secure network traffic I use mitmproxy, which is an open source interactive HTTPS proxy written in Python. Installation steps are documented here. Once installed you need to determine the local IP address assigned by a router to your computer - this is different than the external IP address seen from the internet. On Mac I use the following to determine the local IP:

$ ipconfig getifaddr en0
192.168.0.105

Now start mitmproxy at this local IP and at a port of your choosing, such as 4444:

$ mitmproxy --listen-host=192.168.0.105 --listen-port=4444

Next step is to setup your Android device to communicate with mitmproxy:

  • Go to wifi settings and long press your connection
  • Select Modify network
  • Open advanced settings and change Proxy to Manual
  • Set Proxy hostname and Proxy port to the details used in the earlier mitmproxy command
  • Navigate the web browser to mitm.it and you should see a list of certificates to install - if not then the proxy settings are not working
  • Download the Android certificate

If the proxy is working then you should start to see requests from the web browser in the mitmproxy console window:

The network activity for Android apps is also viewable. If we open the Exchange Rates app then the following network activity will be triggered, which loads the exchange rate data used by the app:

This is a HTTPS request but we can still observe the internals because of the custom certificate installed.

Note that this approach will only work up to Android Marshmallow - in Android Nougat the security model was changed so that user installed certificates are no longer trusted by default. Also apps that use certificate pinning will not work, since this forces the app to only use a hardcoded trusted certificate. In these case more advanced techniques would need to be employed such as modifying the APK or tampering with the app at runtime with Frida.