Analyze Android app's data transmission (both HTTP and HTTPS) using MITM (Man-in-the-middle)
Ever wondered, what your android app is secretly sending to its servers? This is my attempt, at trying to intercept and decrypted the transmission by an android app. To understand what’s happening on my device.
For this, we do a Man-In-The-Middle (MITM), which means that rather than having my phone communicate directly with the internet, I will make it go through my laptop and watch the data which goes/comes. We will use Charles Proxy (trial version), this will be used to intercept the traffic. In order to do this, we will install this software on laptop (and route the network data from phone through this software).
To analyze just HTTP traffic, a non-rooted phone works. In case you wish to analyze the encrypted (HTTPS) traffic, we would need a rooted phone.
We will be showing all the steps on a macOS machine. Similar steps can be found out for other operating systems.
Intercept HTTP Traffic (Unencrypted)
Install softwares on laptop
- https://www.charlesproxy.com/download/. We will use the unpaid version, which has limited session size of 30 minutes.
Configure Proxy Settings on android
- Go to settings
- Tap
Wi-Fi
- (for Redmi’s OS), click on the arrow button next to the connected Wireless
- Scroll down to
Proxy
and tapManual
- Fill in the
IP Address
in Hostname, and Port Number inPort
. - NOTE: On your Mac, press
alt
and click on the wireless Icon, to know your laptop’s IP address. You can find required port number in Charles App. In menu bar, Proxy > Proxy Settings. If you are unable to find IP and port number, see: https://community.tealiumiq.com/t5/Tealium-for-Android/Setting-up-Charles-to-Proxy-your-Android-Device/ta-p/5121#configure_charles
Simply use the app whose communication you wish to interpret, and you will be able to see the transmitted data in your laptop (on Charles)
Intercept+Decrypt HTTPS Traffic (Encrypted)
Install softwares on laptop
- https://www.charlesproxy.com/download/. We will use the unpaid version, which has limited session size of 30 minutes.
- Install
brew
if you do not already have it; https://brew.sh/ (just run/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
in Terminal) brew cask install android-platform-tools
, in order to installadb
brew install apktool
(for decompile-recompile)
Configure Proxy Settings on android
- Go to settings
- Tap
Wi-Fi
- (for Redmi’s OS), click on the arrow button next to the connected Wireless
- Scroll down to
Proxy
and tapManual
- Fill in the
IP Address
in Hostname, and Port Number inPort
. - NOTE: On your Mac, press
alt
and click on the wireless Icon, to know your laptop’s IP address. You can find required port number in Charles App. In menu bar, Proxy > Proxy Settings. If you are unable to find IP and port number, see: https://community.tealiumiq.com/t5/Tealium-for-Android/Setting-up-Charles-to-Proxy-your-Android-Device/ta-p/5121#configure_charles
Setting Charles to use SSL Proxying on all locations
Go to Proxy > SSL Proxying Settings, and add *.*
. For more details, see: https://community.tealiumiq.com/t5/Tealium-for-Android/Setting-up-Charles-to-Proxy-your-Android-Device/ta-p/5121#configure_charles
Rooting your android phone
NOTE: Do it only if you are okay, if your phone gets bricked (the OS can get corrupted), and you will need to spend some time to fix it. I do not take ANY Responsibility, to what these steps might result it. This is just a summarization of the different blogs/websites that I had to follow, to achieve the results I needed.
I used a Redmi Note 4 for this task. YouTube video describing the process
- Unlock the bootloader. (Youtube video)
- Make sure you have an account signed in with MIUI (Settings > Mi Account)
- Enable Developer options Settings > About phone > MIUI version, tap on MIUI version for 7-10 times continously, which will give you a pop up saying that developer options are now enabled
- Settings > Additional settings (under SYSTEM SETTINGS category) > Developer options > OEM unlocking
- Go to https://en.miui.com/unlock/, and click on
Unlock Now
. - It leads to https://en.miui.com/unlock/download_en.html, from where you can install a
zip
containing Mi Unlock app (needs to be run on a Windows machine), which is used to unlock bootloader. Sign in to your MI Account in this app - Shut down your phone manually, and hold Volume down key and Power button to enter Fastboot mode
- Connect your phone to PC using USB cable and click “Unlock”. NOTE: A lot of blogs/websites mention that you need to fill up a form and wait for your request to be approved, but in my case I did not get any such thing and my bootloader was unlocked immediately (it might be the case that they have removed the review process now)
- Transfer the required files to your phone: Super SU, Lazy Flasher (these links are from YouTube video)
- Put phone in Fastboot mode (Switch off your phone, and power on by keeping Power button + Volume Down button pressed)
- Connect the phone to laptop
- Ensure
fastboot devices
list an entry - Flash TWRP Recovery. (for Redmi Note 4; I downloaded RedWolf, mentioned in forum.xda-developers).
fastboot flash recovery <recovery-img-path>
- Restart phone with Power button + Volume Up button
- Install
Super SU
zip using TWRP (RedWolf) - Install
Lazy Flasher
using TWRP (RedWolf) - Reboot your phone
- Your phone should be rooted now! You will be able to find a
SuperSU
app installed. - Now you can do
adb shell
andsu
, to access all the files on your phone through ADB, and much more! (when running thesu
command, you might have to authorize it from theSuperSU
app on your phone)
Installing the certificate as root (requires rooted phone)
- Install Root Certificate Manager(ROOT) android app (from Google Play Store).
- Download the certificate, by visiting
chls.pro/ssl
(needs Charles to be running and wireless proxy configured on phone) - Add the certificate using the app
You have two options now
1. Xposed Framework
You can install the Xposed Framework. There is a Youtube Video which describes this complete procress: https://www.youtube.com/watch?v=yJRlMmJjrhY
- Download the framework
- https://repo.xposed.info/module/de.robv.android.xposed.installer, which links to
- http://forum.xda-developers.com/showthread.php?t=3034811 (for Android 5 or higher), which links to
- https://dl-xda.xposed.info/framework/, choose the SDK corresponding to your android version. You can check this on https://source.android.com/setup/start/build-numbers (API Level number corresponding to your android version). In my case, it was SDK 24, corresponding to Android 7.0, which links to
- https://dl-xda.xposed.info/framework/sdk24/, searching on google for the phone architecture lead me to a post on xda-developers forum, which suggested that Redmi Note 4, has
arm64
architecture, which links to - https://dl-xda.xposed.info/framework/sdk24/arm64/, download the latest version
- which in my case, is https://dl-xda.xposed.info/framework/sdk24/arm64/xposed-v89-sdk24-arm64.zip
- Transfer this zip to your phone
- Reboot phone in recovery mode, and install this zip, using TWRP (or similar)
- Now you need to install SSL Unpinning module for Xposed Framework. (https://repo.xposed.info/module/mobi.acpm.sslunpinning which links to, https://dl-xda.xposed.info/modules/mobi.acpm.sslunpinning_v2_37f44f.apk).
- Install the downloaded APK
- Open Xposed Framework app, and select
Modules
from the left side bar. (Your phone might need a restart for this module to appear) - Enable (tick) SSL Unpinning module, and restart your phone
- Open the SSL Unpinning app, and click on a listed app, to unpin SSL certificate for it.
- Now you should be able to view the app’s encrypted data (in unencrypted form) in Charles. Though this method might not work for some applications.
[OR] 2. Recompile the APK
Decompile APK, add some parameters, recompile and install the APK. Blog describes the process in a detailed manner, I am adding the problems+solutions I had to use on top of what is mentioned there.
- Get the installed apk from your Android device
adb devices
ensure that your device shows up (try other USB ports if the phone does not show up)adb shell pm list packages -f app-name
to get the path of the application- You essentially need to run
adb pull /data/app/bazingaa.nusbuses-1/base.apk
(replacing your app name instead), but this did not work for me, as the directory/data/app/bazingaa.nusbuses-1/base.apk
is only allowed access for root user. To overcome this, I used a process described at: https://android.stackexchange.com/a/129665/246838 adb shell
su
cp /data/path/of/file/copyme /data/local/tmp
chown shell.shell /data/local/tmp/copyme
exit
exit
adb pull /data/local/tmp/copyme /destination/copyme
- Decompile the APK, with command
apktool d -f base.apk
(rename your APK tobase.apk
) android:networkSecurityConfig="@xml/network_security_config"
andandroid:debuggable="true"
need to be added underapplication
tag inAndroidManifest.xml
file. (for more details check https://medium.com/@ferrygunawan/debug-ssl-traffic-with-charles-proxy-872aedb228d)- Add/Modify
res/xml/network_security_config.xml
, with content:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <debug-overrides> <trust-anchors> <!-- Trust user added CAs while debuggable only --> <certificates src="user" /> </trust-anchors> </debug-overrides> </network-security-config>
- Rebuild the APK
apktool b base
- If there is no error, you will get the
base.apk
underbase/dist
directory. - You would need to sign the APK (reference)
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -validity 10000
- Run
jarsigner -verbose -keystore my-release-key.keystore <your-app-file> alias_name
after replacing<your-app-file>
with your file name, eg.jarsigner --verbose --keystore my-release-key.keystore base.apk alias_name
NOTE: You may changealias_name
andmy-release-key.keystore
, if you wish; but you need to keep it consistent across the two commands
- Uninstall the original app from your phone
- Install signed-APK that you created, using
adb install base-signed.apk
. You might need to enable apps to be installed via USB, under Developer options.
Extra; to look at the data that the app is storing locally
adb shell
su
cd /data/data/
ls
, will show a list of all the app folderscd <appropriate-folder-name>
, for example:cd com.android.bluetooth
. This will take you inside the directory used to store all the app data and you can explore here, to find what you are looking for.
If you wish to copy this on your local system (for ease of viewing), you can use adb pull
. For me, it did not let me directly pull the folder, as it requires su
to view it. As a workaround, you can run the following commands:
adb shell
su
cp /data/path/of/file/copyme /data/local/tmp
chown shell.shell /data/local/tmp/copyme
exit
exit
adb pull /data/local/tmp/copyme /destination/copyme