# OWASP MSTG Crackme 2 writeup (Android)

## The application

To understand more about the application, we extract the source code from the APK and look into interesting classes.&#x20;

The structure of the app is the following

```haskell
├── owasp
│   └── mstg
│       └── uncrackable2
│           └── R.java
└── sg
    └── vantagepoint
        ├── a
        │   ├── a.java
        │   └── b.java
        └── uncrackable2
            ├── CodeCheck.java
            └── MainActivity.java
```

As we can see, the structure is very similar to the previous challenge, but there is a new file `CodeCheck.java`. When we inspect the content of `MainActivity.java`  we can see how the root detection is handled (same as in the previous challenge), and how the secret is checked. The function `verify` handles the secret checks

{% code title="MainActivity.java" %}

```java
 public void verify(View view) {
        String str;
        String obj = ((EditText) findViewById(R.id.edit_text)).getText().toString();
        AlertDialog create = new AlertDialog.Builder(this).create();
        if (this.m.a(obj)) {
            create.setTitle("Success!");
            str = "This is the correct secret.";
        } else {
            create.setTitle("Nope...");
            str = "That's not it. Try again.";
        }
        create.setMessage(str);
        create.setButton(-3, "OK", new DialogInterface.OnClickListener() {
            /* class sg.vantagepoint.uncrackable2.MainActivity.AnonymousClass3 */

            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
            }
        });
        create.show();
    }
```

{% endcode %}

where `this.m.a(obj)` is the function that will check whether the secret is the right one.&#x20;

### Who is this.m?

If we look right after the `MainActivity` class definition, we see

```java
 private CodeCheck m;

    static {
        System.loadLibrary("foo");
    }
```

where the `CodeCheck` class declares a function that is implemented from the native library `foo`.

```java
private native boolean bar(byte[] bArr);
```

So, our next step is to deep dive into the native module.

### CodeCheck native function

To find the logic of the `bar` function we will:

* rename the .apk in .zip
* extract the native module `lib/libfoo.so`
* reverse it using Ghidra

## Ghidra

Analyze the `libfoo.so`

![](/files/-Mct7e52DI6mOhPgd5R4)

Looking inside the binary we can identify the native function `Java_sg_vantagepoint_uncrackable2_CodeCheck_bar` that will check whether - the input string has 23 chars (`0x17`) - the string in input matches the secret using the `strncmp` function

The secret is directly passed to the `strncmp` function, so we could&#x20;

![](/files/-Mct7hJHciCEN9fJrapF)

Now let's get to Frida, to see how we can intercept and read the inputs passed to the `strncmp` function used in `libfoo.so`.

## Frida

Because we need to trigger the `strcmp` function, we need first to get rid of the root detection block.

#### Root detection control bypass <a href="#toc_6" id="toc_6"></a>

There are different ways of bypassing the root detection controls that will shut down the app once the OK button is clicked. A "dirty" way is to overload the `onClick` event of the OK button, to avoid that the application will call `System.exit(0)`.&#x20;

We can achieve this using the following Frida snippet

```javascript
/*

    Dirty way of bypassing the root detection, avoiding the app to close.

*/

Java.perform(function() {
   
   
    console.log("[*] Hijacking the onClick button")
    var clazz_main = Java.use('sg.vantagepoint.uncrackable2.MainActivity$1')

     clazz_main.onClick.implementation = function () {
        console.log('onCLick() is replaced ');
        
    };
    
});
```

Clicking OK will close the dialog, while the app will still run.

{% hint style="info" %}
Root detection: bypassed
{% endhint %}

### **Exploit**

The `strncmp` function has the following signature:

```cpp
int strncmp(char *__s1,char *__s2,size_t __n)
```

and is used in our `Java_sg_vantagepoint_uncrackable2_CodeCheck_bar` function in this way

```cpp
iVar1 = strncmp(__s1,(char *)&local_30,0x17);
```

where&#x20;

* `*__s1` is the text passed in input from the user
* `(char *)&local_30` is the secret we are looking for
* `0x17` is the length (23 bytes)

To extract the secret we can read the inputs of the compare function and print them out when `*__s1` matches our string **`I want your secret asap`**

The final script looks like

```javascript
function extractSecret(){

    /*
    
        To use this function, we need to pass in input an argument with 23 chars. We chose: I want your secret asap

    */

    console.log()
    console.log('[*] ACTION NEEDED: Insert the string "I want your secret asap" as input')
    console.log()
    setTimeout(function(){
        Interceptor.attach(Module.findExportByName('libfoo.so', 'strncmp'),{

            onEnter: function(args){

                if( Memory.readUtf8String(args[1]).length == 23 && Memory.readUtf8String(args[0]).includes("I want your secret asap")){
                    console.log()
                    console.log()
                    console.log("*******SECRET********")
                    console.log(Memory.readUtf8String(args[1]))
                    console.log("*******SECRET********")
                    console.log()
                    console.log()
                }

            },

            onLeave: function(retval){

            }

        });
    },2000);
}
```

Once we call the function via Frida, and insert our magic string, the secret will be printed in the console

![](/files/-Mct8MiqfNNVxI-8iBrM)

and when we insert the new secret in the input field we see

![](/files/-Mct8QBhoPuMOib_cthR)

The full script can be downloaded from our repo

{% embed url="<https://github.com/dcodx/owasp-mstg-crackme>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://1337.dcodx.com/research/owasp-mstg-crackme-2-writeup-android.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
