Android App Source code Extraction and Bypassing Root and SSL Pinning checks

In this blog I will be describing the pre-requesty steps I followed for one of the android application penetration testing which includes

Below are the steps with description

Source Code Extraction

Extracting jar file

As we know that the apk is also a archive file so we can simply rename it to a zip and extract the data

$ mv test.apk test.zip
$ unzip test.zip

After this there will be a classes.dex files, there can be more than one, like, classes2.dex, the dex files can be converted to jar file with dex2jar, you can install it in debian linux machine with the command below

$ apt install dex2jar

For converting a dex file into a jar, use below command

$ d2j-dex2jar classes.dex

after this a new jar file will be created in current directory

Deobfuscating code in jar file if obfuscated

Obfuscation is a process which changes the functions and varibale names and created a lot of classes to jump around in the code, which makes it difficult to understand. Programmers may deliberately obfuscate code to conceal its purpose (security through obscurity) or its logic or implicit values embedded in it, primarily, in order to prevent tampering, deter reverse engineering, or even as a puzzle or recreational challenge for someone reading the source code.

To deobfuscate code I mainly use tool called deobfuscator

To deobfuscate code download the tool from above link and follow below steps

Identifying obfuscator

Create a yaml file with below content for now let the file name test.yml

input: classes.jar
detect: true

This will a output like below

[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - Loading classpath
[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - Loading input
[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - Detecting known obfuscators
[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - 
[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - WhateverFunc: Some obfuscators don't remove the SourceFile attribute by default. This information can be recovered, and is very useful
[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - 	Found possible SourceFile attribute on ----
[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - Recommend transformers:
[Thread-0] INFO com.javadeobfuscator.deobfuscator.Deobfuscator - 	com.javadeobfuscator.deobfuscator.transformers.normalizer.SourceFileClassNormalizer

There can be more than one transformer take a note of this

Deobfuscating jar Create a new yaml file config.yml, the name needs to be same for this

input: classes.jar
output: classes-deobfuscated.jar
transformers:
  -com.javadeobfuscator.deobfuscator.transformers.normalizer.SourceFileClassNormalizer
  -anotherTranformer

The above listed transformer during obfuscator detection phase, there can be more than one transformers which can be listed each on a new file like the one lister above

Sometimes there are multiple layer of obfuscation, in that case above steps can be followed recursivly to get final jar with readable code

Finally open jd-gui and open the final jar, on the top-left corner inside file, click on Save all Sources, to save java code a zip file will be saved containing all the java code

Bypass Root Detection & SSL Pinning

Root Detection

So there was root detection and ssl pinning in the application which needs to be bypassed for further testing, I started searching for function names similar to root or detection, and found a function named RootDetection() let be in a file StartActivity.java on the top level directory, because the file I found is named respetive to the company app name

So functions structure was like, it is performing several checks and returning the final response as true or false, true means device is rooted, false means it is not

RootDetection() {
  if (new File("/usr/bin/su").exists()) continue:
      return true;
  --More if statements--
  return false

To bypass above protection I used Frida

Download frida server from here

To get the architecture of device, connect device to the host system and run below command

$ adb shell getprop ro.product.cpu.abi

unpack the xz file and transfer the server file to device, and start server with below commands

$ adb push frida-server /data/local/tmp/
$ adb shell
> cd /data/local/tmp
> chmod +x frida-server
> ./frida-server

Then i created a frida script to bypass root detection according to the application, which is a JavaScript file, names test.js

setTimeout(function(){
	Java.perform(function (){
		console.log("[*] Script loaded")

		var MenuActivity = Java.use("sg.vantagepoint.mstgkotlin.MenuActivity")

		StartActivity.RootDetection.overload().implementation = function() {
			console.log("[*] RootDetection function invoked")
			return false
		}
	});
});

For running the script install frida in your host machine, which can be installed from python-pip

$ pip install frida-server

Basic Usage

Connect frida to USB device
$ frida-ps -U
List running applications
$ frida-ps -Ua
List installed applications
$ frida-ps -Uai

Install the application in the device

Finally running the created script script

$ frida -U -l test.js -f *app_name* --no-pause 

You can get the app name by listing all installed applications, After running above steps, it will automatically restart the application and the root detection will be passed, applicaton can be successfully used in the rooted device

SSL Pinning

So after bypassing the root detection, the problem was the ssl pinning I used the Univeral SSL Pinning bypass script

Intially as I will be using burp suite for testing, I used burpsuite CA cert for this, cacert.der

Transfer this cert to the device, the location is specified is script, if you modify the file location or name remember to specify in script(line 30)

$ adb push cacert.der /data/local/tmp/cert-der.crt

Start the frida server in device and run below command

$ frida -U -l ssl-bypass.js -f *app_name* --no-pause 

The ssl-bypass.js is the file we downloaded previously

With this the SSL Pinning can be successfully bypassed, but as there is root detection so we need to combine both scripts into single to bypass both the checks, the final script which worked for me is here

Note: Many times there will be problems with the jar extracted from dex2jar in that can you can use simplify or dex-oracle

Written on June 29, 2020 by Vaibhav Joshi