mobilefreemedium

APKey

HackTheBox

Android reverse engineering challenge involving an APK file with obfuscated code protecting a flag. The application implements a login screen with hardcoded credentials, and upon successful authentication, decrypts and displays the flag.

$ ls tags/ techniques/
apk_decompilationcode_deobfuscationaes_ecb_decryptionstring_reconstruction

APKey - HackTheBox

Description

Android reverse engineering challenge involving an APK file with obfuscated code protecting a flag. The application implements a login screen with hardcoded credentials, and upon successful authentication, decrypts and displays the flag.

Analysis

Initial Reconnaissance

  1. Extracted APK (password: hackthebox)

    • Standard Android application package
    • Contains obfuscated Java code
  2. Decompiled with jadx to obtain Java source:

    • Main logic in com.example.apkey.MainActivity
    • Obfuscated helper classes in c.b.a.* package (single-letter class names)

Authentication Flow

The MainActivity implements a simple authentication check:

  • Username must equal "admin"
  • Password MD5 hash must equal a2a3d412e92d896134d9c9126d756f
  • On success, calls c.b.a.g.a() to get encrypted data and c.b.a.b.a() to decrypt

Obfuscation Pattern

The obfuscation uses multiple helper classes, each returning a string from an array at a specific index:

ClassMethodReturnsArray Index
ha()"kHtZuV"6
ia()"rSE6qY"4
fa()"6HxWkw"1
ea()"HyeaX9"7
ca()"FlEGyL"4
da()"wAxcoc"0
aa()"85S94kFpV1"3

Key Functions

  • g.a() - Builds Base64-encoded encrypted string by concatenating values from multiple arrays
  • g.b() - Returns "AES" (cipher algorithm) built from d.a()[1] + i.a()[2] + i.a()[1]
  • b.a() - Decrypts using AES-ECB with key built from character positions across helper functions

Reconstructed Values

Encrypted string (Base64):

1UlBm2kHtZuVrSE6qY6HxWkwHyeaX92DabnRFlEGyLWod2bkwAxcoc85S94kFpV1

AES Key (16 bytes):

kV9qhuzZkvvrgW6F

Key construction uses specific character positions from helper functions with some lowercase transformations.

Solution

#!/usr/bin/env python3 """ APKey - HackTheBox Mobile Challenge Android APK reverse engineering with AES decryption """ import base64 from Crypto.Cipher import AES # Helper functions returning values from obfuscated arrays def h_a(): return "kHtZuV" # arrayList.get(6) def i_a(): return "rSE6qY" # arrayList.get(4) def f_a(): return "6HxWkw" # arrayList.get(1) def e_a(): return "HyeaX9" # arrayList.get(7) def c_a(): return "FlEGyL" # arrayList.get(4) def d_a(): return "wAxcoc" # arrayList.get(0) def a_a(): return "85S94kFpV1" # arrayList.get(3) # g.a() - builds the encrypted string from multiple array lookups def g_a(): sb = "" sb += "1UlBm2" # arrayList[8] sb += h_a() # kHtZuV sb += i_a() # rSE6qY sb += f_a() # 6HxWkw sb += e_a() # HyeaX9 sb += "2DabnR" # arrayList2[9] sb += c_a() # FlEGyL sb += "Wod2bk" # arrayList3[5] sb += d_a() # wAxcoc sb += a_a() # 85S94kFpV1 return sb # Build AES key from character positions across helper functions # Each character is extracted from specific index with optional .lower() key = ( h_a()[0] + # k a_a()[8] + # V e_a()[5] + # 9 i_a()[4] + # q h_a()[1].lower() + # h -> h h_a()[4] + # u h_a()[3].lower() + # z -> z h_a()[3] + # Z h_a()[0] + # k a_a()[8].lower() + # V -> v a_a()[8].lower() + # V -> v i_a()[0] + # r c_a()[3].lower() + # G -> g f_a()[3] + # W f_a()[0] + # 6 c_a()[0] # F ) # key = "kV9qhuzZkvvrgW6F" # Get encrypted data and decrypt encrypted_b64 = g_a() print(f"Encrypted (Base64): {encrypted_b64}") print(f"AES Key: {key}") # Decrypt using AES-ECB cipher = AES.new(key.encode(), AES.MODE_ECB) decrypted = cipher.decrypt(base64.b64decode(encrypted_b64)) flag = decrypted.decode('utf-8').rstrip('\x00').rstrip() print(f"Flag: {flag}")

Lessons Learned

  1. jadx is essential for Android reverse engineering - produces readable Java from DEX
  2. Obfuscation through array indirection is common but easily reversible
  3. Trace all helper function calls to reconstruct the full logic
  4. AES-ECB mode is weak but still used in CTF challenges
  5. Character-by-character key construction is a common obfuscation pattern

References

$ cat /etc/motd

Liked this one?

Pro unlocks every writeup, every flag, and API access. $9/mo.

$ cat pricing.md

$ grep --similar

Similar writeups