on
Intercept Android traffic using QEMU, mitmproxy and Frida
Recently, I wanted to take a look at the network traffic of an Android App that I was using. I did this a while back when, it was relatively easy to configure an HTTP Proxy and import a custom CA cert to mitm a HTTPS connection but was aware that it got more difficulty in the recent years. This guide describes the setup I used to still achieve my goal.
QEMU and Android-x86
Since I didn’t want to install the entire Android SDK and emulator, I used Android-x86 and QEMU to run an Android VM. This repo contains some nice default parameters to use. To start the installation process I ran:
$ qemu-img create -f qcow2 "android.img" 4G # new vm image
$ qemu-system-x86_64 -enable-kvm -vga std \
-m 2048 -smp 2 -cpu host \
-soundhw ac97 \
-net nic,model=e1000 -net user \
-cdrom "android-x68.iso" \
-hda "android.img" \
-boot d \
-monitor stdio
Networking
Since we need to intercept the traffic of the VM, I modified the network config to not use the default usermode networking, but a tap device instead.
$ ip tuntap add dev tap0 mode tap user $USER
$ ip addr add dev tap0 192.168.1.1/24 # 192.168.1.0/24 is the network I choose for my VM
$ ip link set up tap0
$ iptables -t nat -A POSTROUTING -o enp42s0 -j MASQUERADE # mode -o to use your hosts ethernet interface
I also configured my host system to act as a NAT gateway, so the VM can reach the net.
Proxy setup
Since I don’t run a dedicated DHCP server for the VM, it is necessary to set a static IP in the Wi-Fi settings of the
VM. I choose 192.168.1.128
and set 192.168.1.1
as default gateway (choose whatever you set for your tap0
device).
To redirect HTTP and HTTPS traffic to mitmproxy we have to insert two additional rules in our firewall:
$ # redirect request to port 80 / 443 to 8080 on the host
$ iptables -t nat -A PREROUTING -s 192.168.1.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.233:8080
$ iptables -t nat -A PREROUTING -s 192.168.1.128 -p tcp --dport 443 -j DNAT --to-destination 192.168.0.233:8080
$ # start mitmproxy with the webgui. Listens on :8080 by default
$ mitmweb --mode transparent --showhost
Replace 192.168.1.128
with the IP of your VM and 192.168.0.233
with the IP of your host.
TLS pinning and Frida
Most apps ignore user installed CA certs on Android, and some even explicitly pin the cert they use. This makes it hard for us to configure the mitmproxy CA that allows us to intercept HTTPS traffic. Luckily, there is a practical workaround: Frida can be used to patch Apps at runtime to accept any cert. Without going too much into detail, this is how it works:
Install Frida using pip install frida-tools
and grab the latest frida-server-*-android-x86_64
from the
release page. Connect to your emulator using ADB and upload the Frida
server binary:
$ # ensure ADB and ADB over network are enabled in the Android developer settings
$ adb connect 192.168.1.128:5555
$ adb root
$ chmod +x frida-server-*
$ adb push frida-server-* /data/local/tmp/frida-server
$ adb shell /data/local/tmp/frida-server & # run frida-server in the background
This is all the setup needed for Frida. Now you can use it to inspect and patch Apps running on your emulator. The easiest way to disable all cert validation checks for the currently shown app is to run
frida --codeshare sowdust/universal-android-ssl-pinning-bypass-2 -U -F --no-pause
which injects this simple script. Now you should be able to see all HTTP and HTTPS request in the mitmproxy web interface.