Supermarket - Hack The Box (htb) | 40 points
Challenge: Supermarket (HTB | Hack the box): 40 points
It took me just 3-4 minutes for completing this challenge (including decompile, patch the code and recompile).
There are multiple ways to solve this challenge, like:
- Read the encrypted strings from
jni
and write a script in any chosen language to decrypt it. - Hook the function and read the value from it which will require a rooted android phone/emulator.
- Use self written custom tool and save some precious time
(Which I did by the way)
.
If you check the code after de-compilation, you can see that it’s reading strings from a jni
library name supermarket
which is present in lib
folder.
1
2
3
static {
System.loadLibrary("supermarket");
}
I already have my self written tool specially for reverse engineering, so I didn’t even bother to check that supermarket.so
and spending time to write a script to get the string and decrypt it. I simply used my tool to inject in the app and got the decrypted string. Please check the original and patched code I mentioned below. I’m not pasting my code to receive that string on Telegram. Below is the java similar code snippet from the decompiled apk.
I needed to focus on reading the value of new String(cipher.doFinal(Base64.decode(stringFromJNI, 0)), "utf-8")
because I have a smali code using which I can read this decrypted string and send it to my Telegram
chat. I Just needed to import that and send that to imported function as function parameter.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public void onTextChanged(CharSequence charSequence, int i2, int i3, int i4) {
try {
...
if (!obj.equals(new String(cipher.doFinal(Base64.decode(stringFromJNI, 0)), "utf-8"))) {
MainActivity.this.f2081w.clear();
MainActivity.this.f2076r = 5.0d;
while (true) {
String[] strArr = this.f2085c;
if (i5 >= strArr.length) {
break;
}
MainActivity.this.f2081w.add(strArr[i5]);
i5++;
}
}
...
} catch (Exception e2) {
e2.printStackTrace();
}
MainActivity.this.s();
}
Code of interest from the decompiled apk (smali)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.method public onTextChanged(Ljava/lang/CharSequence;III)V
...
.line 2
invoke-virtual {p2}, Lcom/example/supermarket/MainActivity;->stringFromJNI3()Ljava/lang/String;
move-result-object p2
invoke-static {p2}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;
move-result-object p2
const/4 v0, 0x2
invoke-virtual {p2, v0, p4}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;)V
const/4 p4, 0x0
invoke-static {p3, p4}, Landroid/util/Base64;->decode(Ljava/lang/String;I)[B
move-result-object p3
invoke-virtual {p2, p3}, Ljavax/crypto/Cipher;->doFinal([B)[B
move-result-object p2
new-instance p3, Ljava/lang/String;
const-string v0, "utf-8"
invoke-direct {p3, p2, v0}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
...
return-void
.end method
Injecting code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
;these are the 6 lines of code in smali I injected into the original APK
;to call my smali module with telegram code.
const-string v3, "Coupon-Code: "
invoke-static {p3}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
move-result-object v4
new-instance v5, Lcom/example/supermarket/SendTelegram;
invoke-direct {v5}, Lcom/example/supermarket/SendTelegram;-><init>()V
invoke-virtual {v5, v3, p3}, Lcom/example/supermarket/SendTelegram;->sendMessage(Ljava/lang/String;Ljava/lang/String;)V
Last but not least, don’t forget to add internet permisison to the manifest.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="31" android:compileSdkVersionCodename="12" package="com.example.supermarket" platformBuildVersionCode="31" platformBuildVersionName="12">
<!-- Add this -->
<uses-permission android:name="android.permission.INTERNET"/>
<application android:allowBackup="true" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Supermarket">
<activity android:exported="true" android:name="com.example.supermarket.MainActivity" android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<provider android:authorities="com.example.supermarket.androidx-startup" android:exported="false" android:name="androidx.startup.InitializationProvider">
<meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer" android:value="androidx.startup"/>
<meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer" android:value="androidx.startup"/>
</provider>
</application>
</manifest>
Finally, I just had to click/touch the coupon code box and I got the result as message in my Telegram chat.
FLAG:
HTB{n0_xxxx_xxxxxxx_xxxxx@uc3!}