Security of Android applications. Reverse OWASP MASTG Crackme 1

Hi all! My name is Maxim and I research data sources. In my work I periodically have to deal with the research of Android applications. In this article I want to show the basic methods of reverse engineering and research of Android applications. Today's test subject – Crackme 1 of repository owasp-mastg. The Mobile Application Security Testing Guide (MASTG) is a project that talks about the security of Android applications and offers testing as a sandbox. 7 crackme5 of which are for android.

For the purposes of this article, I will assume that you have minimal experience in reverse engineering other applications, executables or libraries, as well as experience working with adb

Initial inspection of the application

After downloading the application, we have many options for how to launch it, even down to the physical device. I'm used to working with Android Virtual Device (AVD) since it allows you to create emulators with different architectures and different system versions. Before launching the application, the first thing we need to do is look at what we have to work with. For this, and in the future I will use jadx. Import the application into the interface and open AndroidManifest.xml. This file describes the application metadata; in large applications it can be up to 2000 lines or more.

AndroidManifest of our application

AndroidManifest of our application

This line tells us that there is only 1 activity <activity android:label="@string/app_name" android:name="sg.vangatepoint.uncrackable1.MainActivity">. Next you need to follow the path sg.vantagepoint.uncrackable1.MainActivity and see what it looks like. Before doing this, it’s worth looking at what libraries and other resources the application uses in the files that the application pulls with it. In our case, there are no libraries, which allows us to use any architecture in AVD.

Picture from MainActivy

As we can see, jadx was successfully able to decompile the main activity and all the logic is easy to read. Apparently in the method onCreate There is some kind of check for root and the presence of a debugger. There is also a method verify which checks whether crackme was successful or not.

At first glance, everything is clear, let’s try to launch the application.

Running on an emulator

The first thing you need to do is install the application. This can be done through the adb console or by simply dragging the .apk file into the emulator interface. The first option is usually needed to make the log more readable in case of an error, but we won’t need it now.

Running application

When we run it, we get the message we saw above in the jadx code. Apparently some of the root checks have passed, and we can’t do anything else in the application except close it. Most often I work on an AVD with root rights, since working with a stripped down system can be problematic, so let's try to bypass the root rights checks that the application does.

Double click on a class c go to the class definition and look at the check code

Checks for root rights
Listing of checks

Listing of checks

As you can see in the screenshot, there are 3 checks, we will analyze each separately.

Examination c.a checks if there is somewhere in PATH-binary directories su. Examination c.b checks if the string test-keys in one of the build tags. Examination c.c checks if the system has popular applications for escalation of rights in the system. I'm sure at least the check worked c.a since I definitely have it on my system suwhich means it is necessary to bypass this check.

Bypass verification

If it were crackme as an executable file, for example, .exe First of all, I would try to change simple opcodes in the check code, which allow you to simply turn them off, for example, for the first check, insert instead of the loop body

mov eax, 0
ret

or change jne on je in a loop to skip it, but in the case of an Android application this will not work, because the apk file is a zip archive, which is later used by the system to launch applications. In more detail you can read, for example, here. That is, to patch the checks, it would be necessary to decompile the application, make changes to the smali code, build the application, sign it, put it on AVD and check the result. For our case it would be long, so I want to use a simpler and more dynamic tool – frida. frida is a dynamic analysis tool that allows you to work with applications for different OSes, including Android.

To work with frida I will use frida-tools. In order to work with frida, we need to install frida-server on the system. You can find the version you need Here. Using adb we load the server onto the system and launch it.

Next, to bypass the checks, we need to write a patch for the methods described above.

Java.perform(function () {
    var it = setInterval(function () {
        try {
            console.log('hooking...')
            const clazz = Java.use('sg.vantagepoint.a.c')

            clazz.a.implementation = function () {
                return false;
            }
            clazz.b.implementation = function () {
                return false;
            }
            clazz.c.implementation = function () {
                return false;
            }
            clearInterval(it)
            console.log('...success')
        } catch (e) {
            console.log("failed!");
        }
    }, 10);
});

The general idea of ​​the bypass is that we take each method of our class, and replace their implementation with return false . You can read more about the capabilities this tool provides in the documentation.

You can launch the application via

frida -D emulator-5554 -l .\1\root_bypass.js -f owasp.mstg.uncrackable1

-D emulator-5554 is a parameter that specifies how to connect to the emulator. Information about setting up and running AVD with ADB is not within the scope of this article, but can be found, for example, here

Aaaand… after launching the application this way, we no longer receive a message about root.

Application without root detector
Bypassed root verification

Bypassed root verification

When we try to enter any text, we get an error, the code listing for which we saw in jadx above. Let's see what the method is a.a(), which determines the success of passing a given crackme. I want to clarify that from the very beginning we could have patched in the same way a.a also how to patch the check for root rights, however, it seems to me that this is not the point of this crackme.

Class listing sg.vantagepoint.uncrackable1.a

As we can see, this method uses some kind of encryption, apparently AES. Let's dig a little deeper and see the method sg.vantagepoint.a.a.a

Listing sg.vantagepoint.aaa

As we can see, AES is used here. We begin to remember that AES is a symmetric encryption algorithm. It's also worth looking at sg.vantagepoint.uncrackable1.b, where some kind of magic incomprehensible to humans occurs. Obviously, I don’t want to disassemble the logic of this magic, and when solving this crackme, I just wanted to insert all the logic into an empty android application and execute it to see the result, however, once again carefully looking at the method sg.vantagepoint.uncrackable1.a.a I realized that we don’t need to interact with this magical logic in any way. Try to think for yourself before reading further.

As we can see, our method a.a accepts a string, which it will later compare with the result of cipher magic, and here again we could simply return true and go on about our business, but we can use the ready-made logic of the written methods and thus obtain text that can be directly entered into the window. To do this, we'll use frida again. Let's add our patch, which will use ready-made code objects.

Ready solution
Java.perform(function () {
    var it = setInterval(function () {
        try {
            console.log('hooking...')
            const clazz = Java.use('sg.vantagepoint.a.c')

            clazz.a.implementation = function () {
                return false;
            }
            clazz.b.implementation = function () {
                return false;
            }
            clazz.c.implementation = function () {
                return false;
            }
            clearInterval(it)
            console.log('...success')
        } catch (e) {
            console.log("failed!");
        }
    }, 10);
    decode()
});

const decode = () => {
    const aes_encoder_clazz = Java.use('sg.vantagepoint.a.a') // method - a
    const local_encode_clazz = Java.use('sg.vantagepoint.uncrackable1.a') // method b - encode,
    const base64_clazz = Java.use('android.util.Base64') // method decode

    const local_encode_result = local_encode_clazz.b("8d127684cbc37c17616d806cf50473cc");
    const b64_decode_result = base64_clazz.decode("5UJiFctbmgbDoLXmpL12mkno8HT4Lv8dlat8FxR2GOc=", 0);
    const aes_result = aes_encoder_clazz.a(local_encode_result, b64_decode_result)
    console.log("result: ")
    console.log(aes_result)
}

I always try to write in Java.use specifically classes for 2 reasons:

  1. since many 1st class methods are often used

  2. sometimes it is the use of a method that throws an error stating that the method will not be found, but the above option works, calling the method through a dot works. If anyone knows what the magic is here, please share in the comments.

Thus, when we run the application with this patch, we get the result. Next, using a language convenient for you, you need to convert the received bytes into a string, for this I used Python and received the desired answer.

for ch in chars:
    print(chr(ch), end='')
Here is the answer to crackme

73,32,119,97,110,116,32,116,111,32,98,101,108,105,101,118,101

When you enter an answer in the input field, we receive the treasured message

Solved crackme

As a result, with the help of small tools, without going into details of the smali code, without rebuilding the application and other things, we were able to pass crackme 1 OWASP MASTG.

I will be glad to read your wishes, comments, etc., because this is my first article. The Chukchi is not a writer, the Chukchi is an everything-breaker.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *