Intercepting Android HTTPS Traffic when a Certificate is Pinned

As discussed in previous blog, decrypting HTTPS traffic in certain applications can be done by adding a root certificate to the mobile device or the emulated device. But some applications may not use system CAs at all and will stick to custom CAs added to the application by the developer. With such applications, it will not be possible to decrypt HTTPS traffic simply by adding a root certificate. Since the pinned certificate does not match with the certificate received through proxy, it will prevent making any requests via HTTPS and will not function properly.
In this experiment, I could successfully decrypt HTTPS traffic from the application by replacing the embedded (pinned) certificate with Burp Certificate.
Here is what I did:
1. Extract the APK file
Using apktool
, the APK file could be extracted
1
2
3
4
5
6
7
8
9
10
11
12
13
14
./apktool d <path-to-apk-file.apk>
I: Using Apktool 2.4.1 on com.xxxxxxxxxxxxx.xxxx.xxx.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/xxxx/.local/share/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
W: Cant find 9patch chunk in file: "drawable/xxxxxxx.png". Renaming it to *.png.
W: Cant find 9patch chunk in file: "drawable/xxxxxxx.png". Renaming it to *.png.
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
2. Replace the certificate file
Luckily, in my test app, the certificate file was available in ‘assets’ directory and replacing that was straightforward. I just removed the original .cer
file with Burp Certificate.
3. Repack and sign the APK
Using apktool
, repacked the APK file. Using jarsigner
, signed it.
1
2
3
4
5
6
7
./apktool b <path-to-extracted-apk-directory>
I: Using Apktool 2.4.1
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk...
New APK file is created inside dist
directory. Then we have to sign it using jarsigner
. To do that, it is necessary to have a key. Since I do not have a key, I created a self-signed key.
To create a keystore together with a self-signed key valid for 10,000 days, following command can be used:
1
keytool -genkey -v -keystore <keystore-name> -storepass <keystore-password> -alias <alias-name> -keypass <key-password> -keyalg RSA -keysize 2048 -validity 10000
When above command is executed, keytool
prompts to enter user name, organizational unit, organization, locality, state, and country code. Fill them appropriately. You can create the key with default values as well.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
What is your first and last name?
[Unknown]: xxxx xxxxxx
What is the name of your organizational unit?
[Unknown]: xxxx
What is the name of your organization?
[Unknown]: xxxx
What is the name of your City or Locality?
[Unknown]: xxxx
What is the name of your State or Province?
[Unknown]: xxxxx
What is the two-letter country code for this unit?
[Unknown]: xx
Is CN=xxxx xxxxxx, OU=xxxx, O=xxxx, L=xxxx, ST=xxxxx, C=xx correct?
[no]: yes
And then signed the APK using that key:
1
jarsigner -keystore <keystore-name> -storepass <keystore-password> -keypass <key-password> <path-to-unsigned-apk-file> <alias-name>
Install the APK in device
Once the signed APK is created, install it in device.
1
./adb install <path-to-signed-apk.apk>
Then the application started communicating properly without SSL errors and proxy could decrypt them.
References:
- https://blog.ropnop.com/configuring-burp-suite-with-android-nougat/
- https://docs.oracle.com/cd/E19798-01/821-1841/gjrgy/
- https://ibotpeaches.github.io/Apktool/