The goal is to get the password to this app. APK Download
Running the app
First, install the APK on an emulator or device with adb install UnCrackable-Level1.apk
.
The app yells at us about the emulator being rooted, so we’ll have to patch that out. In the background we can see that there is a text box prompting for a password.
Decompiling
Convert the APK to a JAR with dex2jar
by running d2j-dex2jar -o app.jar UnCrackable-Level1.apk
.
Then make a new directory to store the source code, I’m calling it java.
I will use fernflower to decompile the JAR into sources java -jar fernflower.jar app.jar -o java
.
This generates a jar file inside the directory, and the sources can be obtained by unzipping it.
In the onCreate()
method we can see that it uses the c
class in a
to check for root.
Examining the c
class shows that it has several methods to do root checking.
There are several ways that we can make all of them return true, I’m going to be using the patching method.
However we have to decompile the APK into another format called smali
which is like assembler but for dex.
This is easily accomplished with apktool d UnCrackable-Level1.apk
.
The smali disassembly of the root checker class looks like this.
Patching
Take a look at this part of the disassembly.
const-string v6, "su"
invoke-direct {v5, v4, v6}, Ljava/io/File;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-virtual {v5}, Ljava/io/File;->exists()Z
move-result v4
if-eqz v4, :cond_0
const/4 v0, 0x1
return v0
:cond_0
add-int/lit8 v3, v3, 0x1
v0, v1, v2, v3… those are registers. The method returns the v0 register when root is detected, so to bypass the check we can change the line before the return to.
const/4 v0, 0x0
This causes the method to return false instead of true, and we just have to do the same to the other methods.
Building and running
With the same tool, the APK can be built with apktool b UnCrackable-Level1 -o patched-unsigned.apk
.
To install it, signing is required, for that refer to here.
Then remove the app and install the patched version with:
$ adb uninstall owasp.mstg.uncrackable && adb install patched-signed.apk
Launching the app should now show no prompt.
Static analysis for secret
Back to the Java sources, the input seem to be checked with uncrackable1.a.a
, and the source for that shows a base64 string and what seems like a key.
I say key because it is hex and 32 characters long, usually that is an AES-128 key in CTFs, this is reinforced with “AES error: " being logged on failure.
The other a
class tells us that it is decrypted with AES
in ECB
mode and PKCS7
padding.
Since it is in ECB
mode, we already have everything we need to decrypt the base64 string.
Just decrypt the string with openssl
$ echo 5UJiFctbmgbDoLXmpL12mkno8HT4Lv8dlat8FxR2GOc= | openssl enc -aes-128-ecb -base64 -d -nopad -K 8d127684cbc37c17616d806cf50473cc
I want to believe