Recently when looking at an Android mobile application for a Bug Bounty program, I came across a custom certificate pinning solution, instead of using the normal X509TrustManager, this app decided to check the certs themselves with a function.
Now normally, cert pinning is automatically bypassed for me thanks to the amazing work here:
https://github.com/NVISO-BE/MagiskTrustUserCerts and https://github.com/ViRb3/TrustMeAlready
If you don’t already have Magisk and Xposed with these two modules, you should definitely look into these! NVISO also has an amazing blog with methods for intercepting SSL.
But for this we need to go a little further since the application developers chose to do a custom integration for testing for cert pinning.
You’ll need the following prerequisites in order to use the methods here:
- Rooted phone with MagiskSU or other su method.
- Frida-server installed and running on the phone. See https://frida.re/docs/android/
After checking out the contents of the source of the app (Using JADX to decompile APK), I found the following function:
Do you see where this may be going? This function is a simple boolean that will return whether or not the cert is trusted. Thanks to Frida, we can hook this function to make it always return true, therefore bypassing the cert pinning on the custom function.
Now we launch the app with Frida using the command:
# frida -U --no-pause -f com.******.*** -l frida-func-override.js
Now when the app gets to a part where it uses a backend API call, we’re now able to see requests in Burp as the cert pinning has successfully been bypassed!
Spawned `com.******.***`. Resuming main thread! [Google Pixel XL::com.******.***]-> validateHostnamePinning Method Called: ***.************.com Output is: true validateHostnamePinning Method Called: ***.************.com Output is: true validateHostnamePinning Method Called: ***.************.com Output is: true
Happy Bug Hunting 😊