Modern requirements to mobile data processing apps designed for work with personal and financial data include secure data transfer over the Internet. SSL pinning is a mechanism used to satisfy this requirement: it enables the user to identify a server based on an SSL certificate stamp embedded into the app. This makes Man-In-the-Middle attacks almost impossible and prevents the interception of the data traffic between a client and a server.
At the same time, this mechanism complicates the application analysis during penetration testing involving BlackBox or GreyBox methods because the pentester has to identify this mechanism and implement some workaround to intercept the traffic and analyze the client–server interaction. This article describes one of the ways to overcome SSL pinning in Android apps.
When our team received an app for research, it was only known that it uses SSL Pinning and Root / Emulator Detection. In addition, the development team reported that during previous penetration tests, the attacking team turned off these checks, so that should have been complicated.
An .apk file was downloaded for research and launched in the emulator with root rights and write access to the system memory area. After installing the app and setting up the emulator, we attempted to configure the proxy settings with the purpose to intercept the communication with the server, but unsuccessfully. Therefore, it was decided to decompile the application and examine the source code in order to identify the security mechanism.
The Jadx-GUI Android decompiler was chosen for decompilation and examination of the application source code. After loading the app into the decompiler, we got something like shown on the picture below:
The screenshot indicates that the app contains various classes, including the okhttp3 class —a library that allows you to manage the HTTP interactions of the app and includes a module for interaction with SSL Pinning. Further examination of the library has shown that there is nothing related to SSL Pinning in it.
Still, there is a protection mechanism, so we attempted to locate it using a code search. In the official okhttp3 library documentation, we found the name of the class related to the protection mechanism. Then we switched to Jadx-Gui and launched the search.
The search results are shown on the screenshot below:
As can be seen, this class is used in a huge number of places in the code. After examining the code of the io.intercom.okhttp3.CertificatePinner class, we located the public Builder add (String str, String … strArr) method; according to the official documentation, this method is used to associate a host with the sha256 hash of the certificate, and if it does not match, an exception is generated.
A search by the method name brought more than 4000 results, which indicates that the current approach is ineffective and a new one is required. Therefore, we run a search by the known hostname.
As can be seen, there are 2 function calls whose first parameter is the sought host. The second parameter is some sha256 hash, which indicates that this may be the target function. After jumping to the place of the call, we found another call of this function for two more domains. Our next step is to make sure that the protection mechanism is based on the okhttp3 library.
Success! We can replace the signatures of the certificates with the signatures of the certificate of our proxy here. The following 2 commands are used to generate sha256 for our certificate:
openssl x509 -inform der -in Burp.cer -out BurpPem.pem
openssl x509 -in BurpPem.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha1 -binary | openssl enc -base64
We unpack the application using apktool:
apktool d Application.apk
Next, we find the string with the target hashes, replace them with the new ones that we have generated for our certificate, and rebuild the app
apktool b Application/ -o Application-without-SSLPinning.apk
Finally, the app is signed with a pre-generated signature
keytool -genkey -v -keystore my-release-key.keystore -alias Cyberlands -keyalg RSA -keysize 2048 -validity 10000
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore Application-without-SSLPinning.apk Cyberlands
Now we can install the app on the emulator phone, configure the proxy, and examine the app’s traffic.
SSL Pinning can be bypassed in many ways, including both automated (e.g. frida.re) and manual (like the one shown above) techniques. The selection of a specific method depends on the implementation you are dealing with. In future articles, we will examine other methods used to bypass SSL Pinning and Root Detection, both automated and manual ones.