reversefreemedium

Arno

HackTheBox

Android APK (Unity IL2CPP game) themed around Assassin's Creed Unity. Arno Dorian — the game's protagonist — is "known for his memorable quotes". We need to make him "say the magic words". Inside the APK — an encrypted flag, with key and IV stored as static arrays in IL2CPP metadata.

$ ls tags/ techniques/
il2cpp_metadata_extractionarm64_disassemblystatic_data_extractionaes_256_cbc_decryption

$ cat /etc/rate-limit

Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.

Arno — HackTheBox

Description

Android APK (Unity IL2CPP game) themed around Assassin's Creed Unity. Arno Dorian — the game's protagonist — is "known for his memorable quotes". We need to make him "say the magic words". Inside the APK — an encrypted flag, with key and IV stored as static arrays in IL2CPP metadata.

"Arno Dorian is known for his memorable quotes, but he also has a knack for letting his sharp tongue get him into trouble, often saying the wrong thing at the worst possible moments. Can you make him say the magic words?"

Analysis

APK Structure

File Arno.apk inside challenge.zip (password: hackthebox). Key files:

FileDescription
lib/arm64-v8a/libil2cpp.so54MB ARM64 ELF — compiled IL2CPP code
assets/bin/Data/Managed/Metadata/global-metadata.datIL2CPP metadata v31 — class names, methods, string literals
assets/bin/Data/data.unity3dUnity asset bundle with game objects

Game objects from data.unity3d: Quote, QuoteButton, quotereversed, Flag, Submit — indicate mechanics involving quotes and flag verification.

IL2CPP Metadata Recovery (Il2CppDumper)

IL2CPP compiles C# → IL → C++ → native ARM64, but preserves metadata (class names, methods, fields) in global-metadata.dat. Il2CppDumper recovers original signatures:

DOTNET_ROLL_FORWARD=LatestMajor dotnet Il2CppDumper.dll libil2cpp.so global-metadata.dat output/

Output: dump.cs, stringliteral.json, script.json

Key Class: FlagControl (TypeDefIndex 8092)

public class FlagControl : MonoBehaviour { public GameObject textField; public List<string> quotes; public void PopulateQuotes() { } // RVA: 0x16D135C public void ShowQuote() { } // RVA: 0x16D1740 private void Start() { } // RVA: 0x16D1834 public byte[] GetKey() { } // RVA: 0x16D1838 public byte[] GetIV() { } // RVA: 0x16D18A8 public byte[] GetFlag() { } // RVA: 0x16D1918 public string DecryptFlag(byte[] key, byte[] iv, byte[] encryptedData) { } // RVA: 0x16D1988 public void .ctor() { } // RVA: 0x16D2120 }

...

$ grep --similar

Similar writeups