Mobile pentesting series part 2: reversing Android application

Mobile Pentesting Part 2
You may be curious, as a penetration tester, as to how a particular app feature operates or what library it utilizes. Otherwise, you may be interested in the underlying architectures or components of the application. Then, we can attempt to extract the application's source code in order to examine its functionality. We can begin the process of achieving our objective by considering reverse engineering.

The Android operating system utilizes the Android Package (APK) file format to facilitate the installation and distribution of mobile applications. It is capable of being implemented in Kotlin or Java.

Lab setup

Tools that you will require:

Installation of these tools is not difficult and is well described in their official documentation. For example, apk tool can be installed with a simple command in Kali Linux:

sudo apt install apktool

img

Practical Example

For the purpose of this blog and the examples, we will be working with an Android application that is publicly available on Github and is a vulnerable challenge:

img

In order to conduct a more in-depth examination, let's begin from the very beginning, when we have an APK file. It is possible to extract an Android program APK file, which is simply a ZIP archive, by using APKtool, which is included in the list of tools that was shown earlier. You are able to unzip an APK file; however, you will not have the ability to read all of the binary contents of the container.

You are able to execute the command that is provided below (change the binary name if it is different for you):

apktool d com.cybergym.lab1.apk

img

Following the completion of the decompilation process of the Android APK file, a folder with the same name will be generated. Below is a screenshot that will demonstrate an example of an Android application that has been decompiled:

img

The binary resources and the XML files have been converted to their original form.

You can see the AndroidManifest.xml file now:

img

After having a solid comprehension of the Android file structure and the process of decompiling an Android application, we are now in a position to investigate reverse engineering tools and the ways in which these tools might be utilized to discover vulnerabilities or to help address application problems.

We need to install the application to understand what is required to complete the challenge and use that information; hopefully, we can use reverse engineering tools and techniques to solve the challenge.

img

A pin with four digits is what the application is looking for. Considering the restricted number of possible variations, my initial thought was to simply bruteforce the pin code with all of my might. When it comes to entering a pin for testing purposes, however, the program only permits three attempts and then demands a sufficient amount of time in between each guess. As a result of all of this, it is highly recommended that we make an effort to fix this problem by utilizing reverse engineering techniques.

Users are able to access an Android application package (APK) directly and have it decompiled into readable Java code for study. JADX is the leader in this regard. Tools that are older, such as Dex2jar and JD-GUI, provide a similar function but take a more comprehensive approach.

To begin, we will make use of a JADX command in order to open the graphical user interface, decompile the android binary, and enable us to carry out a more in-depth study:

./jadx-gui com.cybergym.lab1.apk

img

You are able to view the structure of the APK file on the left-hand side of the JADX application. To have a better understanding of the application and the tasks that are being performed, we will begin with the "MainActivity"

img

Notice some interesting things:

You can see some obfuscation around the SQLite Database:

img

You can see two database names:

img

Additionally, there is a key that is "12345678" which will be intriguing as we proceed through the process:

img

As we can see, this code creates a table with name name, within the confines of the table, the columns labelled "user" and "pass" are utilized. To conclude, the values that are contained within those columns are moksh and password.:

SQLiteDatabase openOrCreateDatabase = SQLiteDatabase.openOrCreateDatabase(getDatabasePath("kkk.db"), "12345678", (SQLiteDatabase.CursorFactory) null);
openOrCreateDatabase.execSQL("CREATE TABLE IF NOT EXISTS name(user VARCHAR, pass VARCHAR)");
openOrCreateDatabase.execSQL("INSERT INTO name VALUES('moksh','password')");

We can also find via grep:

grep -iRn "password"

img

First, let's take a look at the second database and see what we can figure out from it.

A table with the name a is formed, as can be seen in the code that was just presented to you. A column labeled "z" and another labeled "a" are established within that table. A random number function is responsible for generating the random values that are being stored for the letters z and a (see the screenshot below for more information).

img

Just by performing some simple reverse engineering, we are able to gain an understanding of what the application is doing, which will assist us in conducting further in-depth study to find a solution to this problem.

Now that we have the application databases, we will pull them from the local android files in order to determine whether or not we are able to recognize some of the essential information that is being kept within these databases.

We will find the package name at first and pull the internal storage of the package with ADB.

adb shell pm list packages | grep lab
adb pull /data/data/com.moksh.lab1

img

Lets navigate into the directory and find out q.db file:

img

Lets check it with exiftool and hexdump:

exiftool q.db
hexdump -C q.db

img

img

It looks like the file is encrypted.

SQLCipher can be used to encrypt the database files in android:

img

At this point, we are able to open databases and view the contents. After we have completed that, we will be presented with a password screen, which indicates that we will need to return to the source code in order to conduct further analysis.

img

At this point, we are able to observe that the database creation procedure receives a str variable as an input. In addition, the str variable has the value 123456, which could be the answer to the problem. The SQLCipher algorithm is used to encrypt the database, and the secret key is passed through during the process of creating the database. Additionally, the key is required each time the database in question needs to be accessed, and this is accomplished through the use of the openOrCreateDatabase() method.

Lets use 123456 as the Pragma key and decrypt the database:

sqlcipher q.db

After loading the encrypted database, entering the PRAGMA key, migrating the version (depending on the version of your sqlcipher), and then looking at the results from the database, you can do all of these things by using the instructions that have been provided above:

img

Taking the results from the database and entering them into the challenge will provide you with the solution. However, this can be different for each individual.

img

We hope that this practical example demonstrated some of the power that is included inside tools such as JADX for Android, which has the capability to take an APK file, run analysis on it, and, through investigations, continue to exploit and uncover further vulnerabilities within an application.

Conclusion

In conclusion, this challenge contains a great deal of vulnerabilities that are chained together. The local database is where sensitive information such as credentials and PIN numbers are stored, and it is important to prevent accessing this information. The SQLCipher algorithm is used to encrypt the database; however, the key is not disclosed to the user. The source code should not contain the secret key as hardcoded. It is possible to save it on the server side or on the keystore of the Android device.

References