$ cat writeup.md…
$ cat writeup.md…
hackthebox
English summary: Given an Android APK file that uses a native library to dynamically decrypt and load hidden code. The goal is to reverse engineer the native library, recover the XOR key, decrypt the hidden DEX payload, and extract the flag.
The malware forensics lab identified a new technique for hiding and executing code dynamically. A sample that seems to use this technique has just arrived in their queue. Can you help them?
English summary: Given an Android APK file that uses a native library to dynamically decrypt and load hidden code. The goal is to reverse engineer the native library, recover the XOR key, decrypt the hidden DEX payload, and extract the flag.
The challenge provides an APK file (SAW.apk). Initial extraction reveals:
classes.dex — main Dalvik bytecodelib/ — native libraries for multiple architectures (arm64-v8a, armeabi-v7a, x86, x86_64)
libdefault.so — loaded by the applibnative-lib.so — NOT loaded (decoy)Java Layer Analysis (jadx):
com.stego.sawlibdefault.so via System.loadLibrary("default")open=sesame to proceedpublic native String a(String str, String str2);
str = FILE_PATH_PREFIX (app's data directory)str2 = user input from EditText dialogNative Library Analysis (libdefault.so):
JNI_OnLoad: Registers native method a for com/stego/saw/MainActivity.data section:
l at 0x3de0: [10, 11, 24, 15, 94, 49, 12, 15]m at 0x3e00: [108, 103, 40, 110, 42, 88, 98, 104]input[i] XOR l[i] == m[i]jni_def symbol using mask 0x64 ('d')The key validation uses: input[i] XOR l[i] == m[i]
Therefore: key[i] = l[i] XOR m[i]
#!/usr/bin/env python3 l = [10, 11, 24, 15, 94, 49, 12, 15] m = [108, 103, 40, 110, 42, 88, 98, 104] key = ''.join(chr(l[i] ^ m[i]) for i in range(8)) print(f"XOR Key: {key}") # fl0ating
XOR Key: fl0ating
#!/usr/bin/env python3 # Extract encrypted data from libdefault.so and decrypt # Encrypted data location: jni_def symbol at offset 0x3180 # Size: 792 bytes (0x318) # XOR mask: 0x64 (character 'd') with open('libdefault.so', 'rb') as f: f.seek(0x3180) # jni_def offset in x86_64 version encrypted = f.read(792) decrypted = bytes([b ^ 0x64 for b in encrypted]) # Verify DEX magic print(f"Magic: {decrypted[:8]}") # dex\n035\x00 with open('decrypted.dex', 'wb') as f: f.write(decrypted)
The decrypted 792 bytes form a valid Dalvik DEX file containing:
x with method logprintstrings decrypted.dex | grep HTB # HTB{SawS0DCLing}
The flag HTB{SawS0DCLing} = "Saw Sideloading" — referencing the Android malware technique of DEX sideloading, where encrypted code payloads are decrypted and loaded at runtime using DexClassLoader or InMemoryDexClassLoader to evade static analysis.
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ grep --similar