
Adding to the write-up on UnCrackable Level 1 I have posted a few weeks back, this is a write-up on UnCrackable Level 2, another one of OWASP MSTG’s Crackmes, namely a collection of mobile reverse engineering challenges intended at teaching how to perform mobile application reverse engineering.
First, we obtain the APK from https://github.com/OWASP/owasp-mstg/tree/master/Crackmes/Android/Level_02:

Next we install and launch the application in order to take a look at how it behaves:

Just as for UnCrackable Level 1, it looks like in order to solve Level 2 we are supposed to submit the correct string into the input field:

Again, if we submit the wrong string, we get an error message:

Once more, we proceed to using APK Studio in order to reverse the app and take a look at the way it implements the verification in question. It looks like the verification is triggered at MainActivity.java
(line 73). Specifically, the input string is used to invoke method m.a
:

In turn, m
resolves into a CodeCheck
object. Furthermore, we find that the app loads a library named “foo”:

Such library is available at lib/
:

Next we take a look at what CodeCheck
does. Here it is:

So putting it together, the app checks the input string against native method bar
, which seems to come from library “foo”. CodeCheck.a
simply wraps bar
and its return value is used to validate user input against the secret.
Thus, our next step is to reverse one of the shared objects in question in order to find what string we’re supposed to submit so that CodeCheck.a
resolves to true
and hence we’ll solve the challenge. We’ll use Ghidra to accomplish this task.
After reversing the x86 library (arbitrary choice here), we can take a look at the implementation of native method bar
:

By examining Ghidra’s decompiled code, we find that bar
performs a rather promising string comparison using strncmp
(line 31):

Namely, bar
compares its string argument against something (referenced by local_30
). This something, very likely, is the string we are after. Now, if we take a look at what is stored in local_30,
we find that it points to a string:

Namely (in ASCII hex):
6873696620656874206c6c6120726f6620736b6e616854
Which represents an ASCII string. If we use Burp Decoder to decode it (this could also have been done manually using asciitable.com, for instance), we get:

And all of a sudden we find that the library in question has actually been written by dolphins:
Thanks for all the fish
This is not The Answer to the Ultimate Question of Life, the Universe, and Everything, but at least it’s the secret we’ve been looking for:
