reversefreemedium

CubeMadness2

HackTheBox

Unity IL2CPP game protected by CodeStage AntiCheat Toolkit (ObscuredInt, ObscuredFloat, ObscuredString). The goal is to collect 20 cubes to get the flag, but only ~14 cubes exist in the game world, making legitimate victory impossible. The game runs on a remote Windows server accessible via WinRM.

$ ls tags/ techniques/
il2cpp_metadata_extractionruntime_binary_patchingconditional_jump_bypassvirtualprotectexanticheat_bypassremote_game_interactionwinrm_exploitation

$ cat /etc/rate-limit

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

CubeMadness2 — HackTheBox

Description

Unity IL2CPP game protected by CodeStage AntiCheat Toolkit (ObscuredInt, ObscuredFloat, ObscuredString). The goal is to collect 20 cubes to get the flag, but only ~14 cubes exist in the game world, making legitimate victory impossible. The game runs on a remote Windows server accessible via WinRM.

Analysis

Metadata Extraction (Il2CppDumper)

IL2CPP compiles C# to native code but preserves metadata (class names, methods, fields) in global-metadata.dat. Il2CppDumper extracts this metadata:

GameAssembly.dll + global-metadata.dat → dump.cs, script.json, stringliteral.json

Key classes (names obfuscated):

ClassParentDescriptionKey fields/methods
CubeCounter (extends j)MonoBehaviourCube counterText rmu (0x18), int rmv (0x20), int rmw (0x24)
FlagCheck (extends m)MonoBehaviourWin checkSpriteRenderer rmx (0x18), string rmy (0x20)
PlayerMonoBehaviourPlayerTypeDefIndex 2814
Cube (extends g)MonoBehaviourCollectible cubeTypeDefIndex 2815
ObscuredString (extends g)Encrypted stringTypeDefIndex 2820

FlagCheck (m) methods:

  • Start() RVA 0x740660
  • Update() RVA 0x740810 — main win condition check
  • cbm() RVA 0x7409B0
  • onh() RVA 0x740A40

Win Condition Analysis

In m.Update() (RVA 0x740810) found the check:

mov rcx, [rax+0xB8] ; load ObscuredInt cube counter cmp dword ptr [rcx], 0x6874 ; compare with encrypted threshold jge +0x17 ; if >= threshold → show flag (SpriteRenderer.SetActive)
  • 0x6874 — encrypted threshold value (ObscuredInt: hiddenValue = value ^ currentCryptoKey)
  • jge (opcode 7D) — conditional jump controlling flag sprite display
  • Flag is not stored in files — constructed at runtime from ObscuredString

Asset Extraction (AssetRipper)

...

$ grep --similar

Similar writeups