HackTheBox: APKey Mobile Challenge
Editing Smali code is a powerful technique in reverse engineering. In this write-up, I will solve the HTB APKey challenge by modifying its Smali code.
What is Smali Code?
Smali code represents the intermediate language of Android application bytecode. When Android apps are compiled from Java/Kotlin source code, they are translated into bytecode, which can then be converted into Smali code — a readable format that allows us to examine an app’s functionality and behavior. By mastering Smali code, you gain valuable insight into an app’s logic, proprietary algorithms, and its interactions with the Android system.
Diving into the Challenge
First, I downloaded the challenge’s zip file, extracted it, and obtained the ذ file. I then installed it on an emulator and also opened it using JADX, which converts complex bytecode into more readable Java code.
Step 1: Analyzing the Login Mechanism
When I launched the application, I encountered a login page. I attempted a default login using admin:admin
, but it displayed the error message: “Wrong Credentials!” To investigate further, I searched for this error message within the decompiled Java code using JADX. I found it inside the
onClick
method of the MainActivity
class:
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
public void onClick(View view) {
Toast makeText;
String str;
try {
if (MainActivity.this.f928c.getText().toString().equals("admin")) {
MainActivity mainActivity = MainActivity.this;
b bVar = mainActivity.e;
String obj = mainActivity.d.getText().toString();
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(obj.getBytes());
byte[] digest = messageDigest.digest();
StringBuffer stringBuffer = new StringBuffer();
for (byte b2 : digest) {
stringBuffer.append(Integer.toHexString(b2 & 255));
}
str = stringBuffer.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
str = "";
}
if (str.equals("a2a3d412e92d896134d9c9126d756f")) {
Context applicationContext = MainActivity.this.getApplicationContext();
MainActivity mainActivity2 = MainActivity.this;
b bVar2 = mainActivity2.e;
g gVar = mainActivity2.f;
makeText = Toast.makeText(applicationContext, b.a(g.a()), 1);
makeText.show();
}
}
makeText = Toast.makeText(MainActivity.this.getApplicationContext(), "Wrong Credentials!", 0);
makeText.show();
} catch (Exception e2) {
e2.printStackTrace();
}
}
From this analysis, I discovered that:
- The app uses
"admin"
as a hardcoded username. - It hashes the entered password using MD5 and compares it with the stored hash:
a2a3d412e92d896134d9c9126d756f
.
Step 2: Attempting to Crack the Hash
I attempted to crack this hash using different methods, but I was unable to find a valid plaintext password.
Step 3: Modifying the Smali Code
Since cracking the hash wasn’t successful, I decided to modify the Smali code directly. Decompiling the APK To achieve this, I used APKTool to decompile the APK:
1
java -jar apktool_2.11.0.jar d APKey.apk
After decompilation, I searched within the Smali files for the MainActivity
class and located the hash value. Before modifying it, I calculated the MD5 hash for my own password (e.g.,
kero
) and obtained a new hash. I then replaced the original hash in the Smali code with my new hash.
Step 4: Recompiling & Signing the APK
After making the necessary modifications, I rebuilt the APK using the same tool:
1
java -jar apktool_2.11.0.jar b APKey
Since Android requires signed APKs for installation.
I signed and aligned the modified APK using Uber APK Signer:
1
java -jar uber-apk-signer.jar -a APKey/dist/APKey.apk
Next, I uninstalled the original application and installed the newly modified version.
Step 5: Bypassing Authentication & Getting the Flag
After launching the modified app, I entered the new credentials based on my altered hash. This time, authentication was successful, and I retrieved the flag! 🎉
Successfully obtained the flag and submitted it to the HTB challenge.
THANKS FOR READING ❤️