Certificate SSL pinning is an extra security layer in the SSL validation process for certificate authenticity. This process verifies that the certificate/key provided by the remote server exactly matches the one pinned on the client side. We have already discussed pinning in an earlier post.
When an Android application uses SSL pinning, the user cannot use generic methods to proxy the traffic. This is because pinning uses a customized certificate store (pinned in the code) instead of the default Android keystore. The following techniques can bypass SSL pinning.
- The JustTrustMe module in the Xposed framework
- The Xposed framework allows us to modify system or application behavior at runtime without changing any application on the Android device.
- Download and install (The device must be rooted for installation.) Also available at Google Play. Supports Android 4.0.3 through 4.3.
- Install the module JustTrustMe.
- After successful installation, reboot the device/emulator.
- Enable JustTrustMe from the modules section of the framework.
- Restart the device.
- Install the test application on device/emulator. Route the traffic through a proxy.
- The framework will avoid SSL validation and allow the proxying of traffic
- Android-SSL-TrustKiller (for Android versions before 4.0)
- This tool disables SSL certificate validation (pinning) by forcing it to accept any SSL certificate.
- Before installing TrustKiller, download and install the Cydia Substrate This needs root access.
- Install the TrustKiller APK.
- Reboot the device through Cydia Substrate with the Restart System option.
- Install the test application.
- Open Cydia Substrate and select the Link Substrate Files option.
- This step will bypass SSL pinning and traffic will be visible in the proxy tool.
- This process may not work with the latest Android versions because the Cydia Substrate framework is not compatible with latest SSL pinning libraries.
- Reverse engineering
This process is very useful when using custom pinning and tools cannot bypass the SSL validation. The user has to manually bypass the SSL pinning implementation by modifying the code. The following process will guide you through the steps to reverse engineer the APK disassembly, reassembly, and signing.
- Download the Apktool and follow its installation steps.
- Once the setup is complete, it is time to disassemble the application APK. From the command prompt enter:
apktool d MyAPKpath\myapp.apk -o Anypath/Anyfoldername
- MyAPKpath is the path of the APK.
- Anypath/Anyfoldername is the path and folder where the Apktool will output the disassembled APK. For example: apktool d C:\Androiddata\MyApp.apk -o C:\Androiddata/MyFolder.
- Browse to the disassembled APK.
- This folder will have all XML and Smali files.
- Use Notepad to make changes to and save the Smali code.
Code changes, Case 1: When using public-key pinning/certificate pinning:
- Search for the public key/certificate for the application in the disassembled code.
- Replace it with a proxy tool’s (for example, Burp) certificate/public key.
- Save the changes and reassemble the code.
Code changes, Case 2: Overwrite the methods:
- The following are some of the responsible classes for SSL pinning implementation. Locate the methods for SSL pinning/certificate validation and modify them to bypass SSL restrictions.
Detailed information is available in the references. Once the changes are saved, reassemble the code.
- Use the following command to reassemble the modified code.
apktool b APKDpath/APKDfoldername -o Anypath/filename.apk
- APKDpath/APKDfoldername is the path of the disassembled APK.
- Anypath/filename.apk is the path where the APK tool will output the reassembled APK. For example: apktool b C:\Androiddata/MyFolder -o C:\Androiddata/MyApp1.apk.
Our new APK cannot be installed unless it is signed.
Signing the code
To sign the APK we use keytools and Jarsigner, both in the JDK/bin folder.
- From the command prompt we run the following command, which will create a keystore (my-release-key.keystore) in the root directory:
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
- The process will ask for a password and other details; enter those.
- Sign the APK using the keystore. From command prompt run this:
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore APPpath/filename.apk alias_name
- Jarsigner will prompt for the password; enter the password used to sign the APK.
- Once the APK is signed, it can be pushed to an emulator/device.
- Set the JDK/bin under environment variables.