Recently, I wanted to reverse engineer an Android application. As a part of my analysis, I wanted to look at how the app is using an external web API. In this post, I want to present how I set up my environment to intercept HTTPS requests from the Android device.
I used the Android Emulator to run the app. There are three types of Android systems you can run on the emulator:
During the setup, you have to select a virtual device to emulate. Just pick any device without the Play Store logo:
When selecting your ROM, use the Google APIs version:
Note: This section is based on https://docs.mitmproxy.org/stable/howto-install-system-trusted-ca-android/.
You should run mitmproxy
(or mitmweb
) as some other user than yourself. This will allow nftables
to distinguish between mitmproxy traffic and traffic that should be intercepted.
After starting mitmproxy
for the first time, you will find certificates and keys in ~/.mitmproxy/
where ~
is the home directory of the user you are running mitmproxy
as.
As that user, we do the following:
cd ~/.mitmproxy
hashed_name=`openssl x509 -inform PEM -subject_hash_old -in mitmproxy-ca-cert.cer | head -1` && cp mitmproxy-ca-cert.cer $hashed_name.0
This creates a file like c8750f0d.0
. We perform the following steps:
emulator -list-avds
.emulator -avd <avd_name_here> -writable-system
.adb root
adb shell avbctl disable-verification
adb remount
(adb reboot && adb root && adb remount
if necessary)adb push <path_to_certificate> /system/etc/security/cacerts
adb shell chmod 664 /system/etc/security/cacerts/<name_of_pushed_certificate>
adb reboot
You can now check in the device settings that the certificate is installed. You need to start the emulator with the -writable-system
flag every time you want to intercept traffic with mitmproxy.
Start mitmweb
. We want to redirect all IPv4 and IPv6 HTTP and HTTPS traffic to mitmproxy. Put the following in your /etc/nftables.conf
(replace root with your mitmproxy user) and apply by running /etc/nftables.conf
:
#!/usr/sbin/nft -f
flush ruleset
table ip nat {
chain output {
type nat hook output priority 0; policy accept;
skuid != root tcp dport {http, https} counter redirect to :8080
}
}
table ip6 nat {
chain output {
type nat hook output priority 0; policy accept;
skuid != root tcp dport {http, https} counter redirect to :8080
}
}
Note: this will proxy your own traffic as well. If you use your webbrowser, you will see certificate warnings popping up.
When running the app, you should see the traffic in mitmweb
. To view the traffic in Wireshark, you can instruct mitmproxy to write SSL master secrets to a file:
SSLKEYLOGFILE="$PWD/.mitmproxy/sslkeylogfile.txt" mitmweb
In Wireshark, you can decrypt the TLS traffic by going to Edit > Preferences > Protocols > TLS > (Pre)-Master-Secret log filename
.