An unusual post again, but quite the adventure that I had to share. As a kid I used to venture into exploits and hacking. I've rekindled the old days and looked into a mobile app more deeply. To make sure I don't incriminate myself I won't mention the app, the main tech stack is as follows though - the app basically has a list of users that can be listed in a very slow manner (shows like 10 users and swiping+loading the next batch is super slow). The app talks with multiple backend services such as Firebase etc., but most importantly uses Algolia search. My goal was to get all users.
First, what I tried.
1/ Start simple: Get a network monitor such as "PCAPdroid" or "PCAP remote" directly on my phone (both good ones btw - I tried some more, those two are good). The goal was to understand more what kind of backend calls are made from the app. These kind of apps also allow injecting a self-signed certificate via a VPN to decrypt the HTTPS/SSL calls - but here I learned something new. Apparently mobile security has advanced and now in every state of the art app there exists this concept of public key pinning or certificate pinning. Won't go too deep into that, but it's basically a whitelist of certificates hard-coded into the app in some way or another, which means a self-signed certificate won't be accepted by the app.
2/ Next step was clear - I needed to decompile the app and take a deeper look.
So I did just that. I installed apktool via
brew install apktool and ran:
apktool d app
This results in smali files, which is the assembly language used by the Android system. Here I will shorten my adventure, since I now wasted a few hours trying to bypass the certificate pinning by trying to modify the internal files and smali code of the app by hand. In the end I likely simply missed something, since I did not get it to work. To be fair, the app was huge with a large set of external libraries.
To recompile I used the following process on Mac. First of all I had to add Android Studio (and the Python binary directory, but later more on that) to my PATH:
export PATH=/Users/instance/Library/Android/sdk/build-tools/33.0.0/:$PATH export PATH="/Users/instance/Library/Python/3.10/bin:$PATH"
Next, I used the following commands. Note that zipalign and apksigner come from the build tools directory added above to our PATH. This is very interesting since SO MANY ressources out there are just outdated or don't work. Especially signing with jarsigner is simply a meme - it DOES NOT WORK. At least not on my modern phone with one of the latest Android versions.
apktool b app cp app/dist/app.apk app2.apk rm -f app2-aligned.apk zipalign -v 4 app2.apk app2-aligned.apk apksigner sign --ks ~/.keystore --ks-key-alias am app2-aligned.apk
So as you can see you first recompile, then do the zipalign, and then use apksigner to sign. It should be noted that the ".keystore" file was generated beforehand. And again, lots of outdated stuff here! Security requirements move over time.
keytool -genkey -v -keystore ~/.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias app
3/ Finally, frida-gadget. I used the following repository to simply include frida-gadget in the apk directly: https://github.com/ksg97031/frida-gadget
I then installed objection, added the Python binary directory to PATH as mentioned before, enabled USB debugging in my phone (somehow this wasn't enabled yet?! As I said, I haven't been doing this kind of stuff in a while..), installed the modified app on my phone and finally ran in my terminal:
adb devices and making sure my phone is recognized)
This requires you to start the modified app beforehand by the way.
I then disabled certificate pinning in the objection terminal:
android sslpinning disable
And finally started PCAPdroid and voilá - decrypted HTTPs requests, including a juicy Algolia API key. The rest is very simple and took like 10 minutes - extracting all the data from Algolia via Python.