How to bypass encryption mechanism in Android apps

3 years ago 245
BOOK THIS SPACE FOR AD
ARTICLE AD

Jaimin Gohel

Original artwork by raywenderlich.com

Hi Folks, hope you are well. As you know developers and pentesters are always into a cat and mouse game. No matter how much we want to deny the fact but we make each other’s life a little tough.

Mobile application developers these days implement an encryption mechanism in their applications to prevent tampering.

However, there are ways to bypass such mechanisms. I am going to demonstrate a scenario that will help you when you come across such application behavior.

We are going to use Injured Android for the demonstration. Injured Android is a CTF style vulnerable application built to practice android testing. Huge shoutout to the author B3nac for building this application.

I have come across many applications that rely highly on client-side encryption, as an extra layer of security for us to uncover. When you intercept the traffic using your favorite proxy tool, all you’ll see is encrypted text.

It is because all of the requests are being encrypted on the client-side and sent to the server. The server will have the same encryption algorithm coded, so upon receiving the data, it will decrypt and fetch the values.

If you are into Android testing or want to get started, this article is for you.

Download the latest build from here. I am using genymotion for this article. Get the virtual device rolling using genymotion and install the APK by entering the following command.

adb install injuredandroid.apk

After the successful installation, you’ll see the following screen.

We are interested in FLAG SIX — LOGIN 3. This is how our FlagSix screen looks like, it has a single textbox and a SUBMIT button.

I have tried entering random text and clicked on submit but nothing happened. Our next step is to look at the java source code in order to understand the functionality of this activity.

Let’s decompile the APK to fetch the application source code. I used MobSF for the sake of simplicity, it makes the task a lot easier. Below is the synopsis of our APK from MobSF.

There are a whole bunch of activities to look at. FlagSixLoginActivity seems to be our destination.

Let’s take a look at the code. Focus on submitFlag() Method

Here, we can clearly see submitFlag method which will be called on click of SUBMIT button. It takes value from the text box(editText3), converts it to string, and compares it with the output of j.a("k3FElEG9lnoWbOateGhj5pX6QsXRNJKh///8Jxi8KXW7iDpk2xRxhQ==") method.

k3FElEG9lnoWbOateGhj5pX6QsXRNJKh///8Jxi8KXW7iDpk2xRxhQ== is our encrypted text.

This application has some level of obfuscation used, we need to identify what j.a() method is? We have b3nac/injuredandroid/j.java class in our package.

a() method has the following code, it is a decryption method. We can clearly figure out from the code that DES symmetric-key algorithm is used.

Congrats first milestone achieved!

The code below uses the value from f2002a to generate the secret key.

Our next goal is to find the key, it must be coded somewhere.

Expedition continues..

Class j has a byte array defined which takes value from h.a() method.

private static final byte[] f2002a = h.a();

Method a() returns a byte array of the key, but before that, it is decoding a base64 string Q2FwdHVyM1RoMXM=

Let’s decode it to find out the actual key.

echo Q2FwdHVyM1RoMXM= | base64 -d

We got the key: Captur3Th1s

Now this key can be used to decrypt the ciphertext using some custom java class or online tool. But we are going for a much simpler option.

While testing an application there are some keywords that will quickly help us in identifying classes, algorithm used for the encryption. Although it can be a little tricky when the code is obfuscated.

Keywords

encrypt, decrypt, crypt, AES, DES, SecretKeyFactory, secretKey, Cipher, InvalidKeyException etc.

Let’s search these keywords in the current APK to see if we actually land on j.java file.

DES

SecretKeyFactory

InvalidKeyException

This is how we can quickly identify the classes responsible for encryption.

We have the decryption method at our disposal. Now as per our understanding, the application is taking user input and comparing it with the decrypted value of k3FElEG9lnoWbOateGhj5pX6QsXRNJKh///8Jxi8KXW7iDpk2xRxhQ==.

What if, we can see what the decrypted value of the aforementioned ciphertext is, when the application is comparing the value? Yes!! we can definitely do that!

To accomplish this task we are going to use FRIDA, it is a Dynamic instrumentation toolkit. Using Frida we can modify application logic on run-time, it allows us to inject our scripts into running processes. It is a must have toolkit in your android testing arsenal.

To summarize: We’ll hook the decryption method a() of class j and when the application attempts to compare the strings, we’ll print the plain text value.

Let’s have a quick look at the following JS code which will invoke the decryption method a() with our supplied value. We have built this JS code to override the decryption method.

decrypt.js

Method a() requires only one argument, the ciphertext to decrypt. We have supplied the ciphertext in the this.a() method it’ll store the response in the string variable ret.

Time to run the Frida script.

frida -U -f b3nac.injuredadnroid --no-pause -l decrypt.js

As we can see, Frida script is running successfully. This will start the application in our emulator.

Frida script has overridden the decryption method. We’ll see the effect of this when we interact with the flag6 activity. So let’s go to flag six activity. Enter any value and click on SUBMIT button.

There is no activity happening on the screen but if we go to our Frida console we’ll have the following output along with the decrypted text

{This_Isn't_Where_I_Parked_My_Car}

By overriding the decryption method we have successfully decrypted the cipher text to plain text.

Now imagine, if this was a real application then you can use the same technique to inject your payloads before it gets encrypted and sent to the server. This way we have bypassed the encryption logic written in the application, which was there to make the app tamper-free.

I enjoyed writing this article and hope that you enjoyed reading it.

Happy hacking :-)

https://github.com/B3nac/InjuredAndroidhttps://github.com/MobSF/Mobile-Security-Framework-MobSFhttps://frida.re/docs/android/

Twitter: @jaimin_gohel
LinkedIn: @jaimin-gohel-440a4a52

Read Entire Article