Analyzing Android Encryption Processes with Frida

Serhat ÇİÇEK
InfoSec Write-ups
Published in
7 min readAug 6, 2022

--

Mobile applications usually use the HTTP protocol to communicate with the server. Mobile applications encrypt and transmit the session, user information, parameters specific to the action to be performed, transmitted over the HTTP protocol, to the server in order not to be detected in case of interference with a proxy software. The server decrypts the encrypted data and continues processing.

This article is the English translation of “Frida ile Android Şifreleme İşlemlerini İnceleme” and and analyzes RSA and AES encryptions with frida.

RSA ENCRYPTION

The OWASP MSTG-Hacking-Playground application will be examined in order to better understand how encryption processes are performed in Android applications.

After installing the APK file of the application on the mobile emulator or device, the application opens with a screen like this:

OWASP MSTG-Hacking-Playground
OWASP MSTG-Hacking-Playground

For encryption operations, it is necessary to log in to the OMTG-DATAST-001-KEYSTORE module.
After logging into the module, the following page opens:

OWASP MSTG-Hacking-Playground OMTG-DATAST-001-KEYSTORE
OWASP MSTG-Hacking-Playground OMTG-DATAST-001-KEYSTORE

When the module was analyzed on the android device, it was determined that the value entered in the “Clear Text” field was encrypted and decrypted again.

When the APK file is analyzed with the “jadx-gui” tool, the function that performs the “encrypt” encryption process (sg.vp.owasp_mobile.OMTG_Android.OMTG_DATAST_001_KeyStore) is detected.

sg.vp.owasp_mobile.OMTG_Android.OMTG_DATAST_001_KeyStore
sg.vp.owasp_mobile.OMTG_Android.OMTG_DATAST_001_KeyStore

To examine the code line by line:

145–146: Using the keystore, the “public-key” value required for RSA encryption is obtained.
157: The data to be encrypted is read from the input field.
163: The “Cipher” object is created with the required parameters.
164: The “init” function of the “Cipher” object is called and the encryption operation is performed.
166–173: The obtained encrypted data is encoded with base64 and printed on the screen and logs.

The actual code block where the encryption is performed is located on lines 163 and 164.

Cipher

From where the “Cipher” object is imported can be obtained by examining the lines at the top of the code line.

javax.crypto.Cipher

The source codes of the “Cipher” object are available at http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/javax/crypto/Cipher.java .

With Frida, the encryption process can be analyzed by hooking the “init” function. To hook the “init” function, the parameters of the function must first be determined. When the source codes in the URL above are examined, it has been determined that the “init” function is “overloaded” with different values. The application, takes a key value of type “int” in its first parameter and “RSAPublicKey” in its second parameter.

When the overloaded functions are analyzed, the running function can be determined with the parameters of the code that calls the “init” function.

javax.crypto.Cipher.init

After the necessary parameters are determined, the function can be hooked with frida.

When the Frida code is run, the output of the application and the frida interface is as in the screenshots below.

OWASP MSTG-Hacking-Playground OMTG-DATAST-001-KEYSTORE
OWASP MSTG-Hacking-Playground OMTG-DATAST-001-KEYSTORE
Frida interface
Frida Interface

The “init” function has been hooked successfully, but the application has thrown an error because the operations to be performed by the function are not executed while hooking it. In order to prevent this, the following frida code can be written.

The above code will call the init function again and make the operations run. In this way, its function was hooked and operations could be continued without disturbing the flow.

After this step, all functions of the “javax.crypto.Cipher” object can be called and necessary information can be retrieved. For example, the frida code that calls the “getOpmodeString” function:

Frida Interface

The encryption algorithm can also be obtained by using the “getAlgorithm” function of the corresponding Java (“javax.crypto.Cipher”) object.

To obtain the “Key” value, the source codes of the “java.security.Key” class should be analyzed:

The “Key” value can be obtained by using the “getEncoded” method of the https://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/7fcf35286d52/src/share/classes/java/security/Key.java object. Frida code for obtaining the “Key” value:

The output of the above-mentioned frida code is given below.

Frida Interface
Frida Interface

When the “java.security.Key” object is examined, it is understood that the relevant function returns a byte array:

javax.crypto.Cipher

In order to make the byte array more understandable, the functions of the “java.util.Base64” object of the Java language can be used:

Frida Interface

AES ENCRYPTION

“AES/CBC” encryption algorithm is generally used for encrypting data between server and client in mobile applications. It would be helpful to analyze the android application at https://github.com/Serhatcck/android_aes_encryption to understand how the related algorithm works.

When the application is installed on the android device, it opens with a simple interface.

Serhatcck/android_aes_encryption
Serhatcck/android_aes_encryption

When the encryption process is performed with the buttons on the application, two different situations arise. When the “RANDOM KEY ENCRYPT” button is clicked, a different value appears in each transaction. When the “ENCRYPT” button is clicked, the encrypted data is the same.

When the source codes of the application are analyzed, it has been determined that the function matching the “RANDOM KEY ENCRYPT” button produces a different “IV Secret” and “Secret Key” values in each operation.

Serhatcck/android_aes_encryption

It has been determined that the function that matches the “ENCRYPT” button produces “IV Secret” and “Secret Key” values for one time only.

Serhatcck/android_aes_encryption

When the source codes of the application are examined, it has been determined that the function that performs the encryption process is the “encrypt” function:

Serhatcck/android_aes_encryption

As can be seen in the image above, the application uses the 3-variable init function of the “javax.crypto.Cipher” object.

The following code block can be used to hook the relevant function with frida.

After hooking the function, we can get the information about the function with the following frida code:

When the above code block is run, it will output something like this:

Frida Interface

The “Secret Key” value could be obtained successfully, but the “Iv Key” value could not be obtained. The “javax.crypto.spec.IvParameterSpec” object must also be hooked in order to obtain the “Iv Key” value. When the source codes in the application are analyzed, it has been determined that the function that creates the “Iv Key” value is a function that takes a single byte array as a parameter:

Serhatcck/android_aes_encryption

The frida code to be used to hook the above-mentioned function is given below:

The output of the Frida code will be as follows.

Frida Interface

An important point is that although the “Iv Key” value is always output when the “RANDOM KEY ENCRYPT” button is pressed, it is given only when the “ENCRYPT” button is pressed for the first time. Since the function to which the “ENCRPYT” button is connected does not create a new “Iv Key” value each time, the “$init” function is not triggered and the “Iv Key” value is not displayed in the output.

By using the obtained “Secret Key” and “Iv Key” values, the sent cipher text can be decoded or any desired text can be encrypted.

The relevant frida code can be changed to provide more detailed information:

The output of the relevant Frida code will be as in the screenshot below:

Frida Interface

You can get a more customized version of Frida code at https://codeshare.frida.re/@Serhatcck/java-crypto-viewer/.

--

--