← Back to Writeups
HTBN/AMobile

APKey

XESXOR8/23/20265 min read
#mobile#htb#n/a

APKey

Platform: HackTheBox | Category: Mobile | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-02-03 | Status: Solved Techniques: aes_ecb_decryption, apk_decompilation, code_deobfuscation, string_reconstruction

Summary

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.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: HackTheBox | ID: 20260203_hackthebox_apkey
  • Tags: reverse_engineering, java, deobfuscation, android, apk, aes
  • Indicators: APK file, obfuscated class names (single letters), AES encryption, Base64 encoded data, array index lookups for string building
  • Source: 20260203_hackthebox_apkey.md

Foothold

Vulnerability / Misconfiguration

  1. Aes_ecb_decryption
  2. Apk_decompilation
  3. Code_deobfuscation
  4. String_reconstruction
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • aes_ecb_decryption
  • apk_decompilation
  • code_deobfuscation
  • string_reconstruction
  • Tags: reverse_engineering, java, deobfuscation, android, apk, aes

Original Writeup

<details><summary>Click to expand original content</summary>

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
  1. 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

</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR