ctf-agent 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +131 -0
- package/Dockerfile +192 -0
- package/README.md +522 -0
- package/agents/ctf-analyzer.md +58 -0
- package/agents/ctf-controller.md +151 -0
- package/agents/ctf-speedrun.md +74 -0
- package/bin/ctf-agent.js +119 -0
- package/docker-compose.yml +13 -0
- package/mcp_config.json +19 -0
- package/package.json +44 -0
- package/references/ctf-triage-ladder.md +68 -0
- package/references/exploit-databases.md +575 -0
- package/references/llm-safety-and-policy-compliance.md +173 -0
- package/references/multi-agent-orchestration-and-policy-routing.md +278 -0
- package/references/security-events-and-intelligence.md +566 -0
- package/references/version-matrix.md +59 -0
- package/rules/ctf-execution-rules.md +44 -0
- package/rules/ctf-safety-framing-rules.md +140 -0
- package/rules/flag-validation-rules.md +25 -0
- package/scripts/__init__.py +1 -0
- package/scripts/ctf-tools.lock +205 -0
- package/scripts/ctf_init.py +1026 -0
- package/scripts/ctf_update.py +583 -0
- package/scripts/ctfd_client.py +81 -0
- package/scripts/cve_lookup.py +453 -0
- package/scripts/extract_flags.py +155 -0
- package/scripts/install_as_agent.py +278 -0
- package/scripts/install_ctf_tools.sh +603 -0
- package/scripts/parallel_triage.py +395 -0
- package/scripts/prompt_policy_sanitizer.py +283 -0
- package/scripts/scope_guard.py +444 -0
- package/scripts/skill_validator.py +504 -0
- package/scripts/workspace_cleaner.py +141 -0
- package/skills/ctf-ai-ml/SKILL.md +120 -0
- package/skills/ctf-ai-ml/adversarial-ml.md +623 -0
- package/skills/ctf-ai-ml/llm-attacks.md +487 -0
- package/skills/ctf-ai-ml/model-attacks.md +422 -0
- package/skills/ctf-crypto/SKILL.md +320 -0
- package/skills/ctf-crypto/advanced-math.md +798 -0
- package/skills/ctf-crypto/classic-ciphers.md +651 -0
- package/skills/ctf-crypto/ecc-attacks.md +347 -0
- package/skills/ctf-crypto/exotic-crypto-2.md +380 -0
- package/skills/ctf-crypto/exotic-crypto.md +528 -0
- package/skills/ctf-crypto/historical.md +113 -0
- package/skills/ctf-crypto/lattice-and-lwe.md +524 -0
- package/skills/ctf-crypto/modern-ciphers-2.md +563 -0
- package/skills/ctf-crypto/modern-ciphers-3.md +453 -0
- package/skills/ctf-crypto/modern-ciphers.md +649 -0
- package/skills/ctf-crypto/prng-attacks.md +257 -0
- package/skills/ctf-crypto/prng.md +664 -0
- package/skills/ctf-crypto/rsa-attacks-2.md +792 -0
- package/skills/ctf-crypto/rsa-attacks.md +487 -0
- package/skills/ctf-crypto/stream-ciphers.md +390 -0
- package/skills/ctf-crypto/zkp-and-advanced.md +456 -0
- package/skills/ctf-forensics/3d-printing.md +121 -0
- package/skills/ctf-forensics/SKILL.md +379 -0
- package/skills/ctf-forensics/disk-advanced.md +497 -0
- package/skills/ctf-forensics/disk-and-memory.md +491 -0
- package/skills/ctf-forensics/disk-recovery.md +699 -0
- package/skills/ctf-forensics/linux-forensics.md +511 -0
- package/skills/ctf-forensics/network-advanced.md +583 -0
- package/skills/ctf-forensics/network.md +645 -0
- package/skills/ctf-forensics/peripheral-capture.md +287 -0
- package/skills/ctf-forensics/signals-and-hardware.md +713 -0
- package/skills/ctf-forensics/steganography.md +694 -0
- package/skills/ctf-forensics/stego-advanced-2.md +475 -0
- package/skills/ctf-forensics/stego-advanced.md +481 -0
- package/skills/ctf-forensics/stego-image.md +691 -0
- package/skills/ctf-forensics/windows.md +625 -0
- package/skills/ctf-malware/SKILL.md +181 -0
- package/skills/ctf-malware/c2-and-protocols.md +274 -0
- package/skills/ctf-malware/pe-and-dotnet.md +108 -0
- package/skills/ctf-malware/scripts-and-obfuscation.md +449 -0
- package/skills/ctf-misc/SKILL.md +498 -0
- package/skills/ctf-misc/bashjails.md +323 -0
- package/skills/ctf-misc/ctfd-navigation.md +465 -0
- package/skills/ctf-misc/dns.md +255 -0
- package/skills/ctf-misc/encodings-advanced.md +504 -0
- package/skills/ctf-misc/encodings.md +431 -0
- package/skills/ctf-misc/games-and-vms-2.md +254 -0
- package/skills/ctf-misc/games-and-vms-3.md +690 -0
- package/skills/ctf-misc/games-and-vms-4.md +229 -0
- package/skills/ctf-misc/games-and-vms.md +529 -0
- package/skills/ctf-misc/linux-privesc.md +333 -0
- package/skills/ctf-misc/pyjails.md +671 -0
- package/skills/ctf-misc/rf-sdr.md +91 -0
- package/skills/ctf-osint/SKILL.md +198 -0
- package/skills/ctf-osint/geolocation-and-media.md +464 -0
- package/skills/ctf-osint/social-media.md +312 -0
- package/skills/ctf-osint/web-and-dns.md +341 -0
- package/skills/ctf-pwn/SKILL.md +214 -0
- package/skills/ctf-pwn/advanced-exploits-2.md +579 -0
- package/skills/ctf-pwn/advanced-exploits-3.md +598 -0
- package/skills/ctf-pwn/advanced-exploits-4.md +590 -0
- package/skills/ctf-pwn/advanced-exploits-5.md +119 -0
- package/skills/ctf-pwn/advanced-exploits.md +773 -0
- package/skills/ctf-pwn/advanced.md +326 -0
- package/skills/ctf-pwn/field-notes.md +245 -0
- package/skills/ctf-pwn/format-string.md +694 -0
- package/skills/ctf-pwn/heap-fsop.md +285 -0
- package/skills/ctf-pwn/heap-techniques-2.md +333 -0
- package/skills/ctf-pwn/heap-techniques.md +513 -0
- package/skills/ctf-pwn/kernel-bypass.md +421 -0
- package/skills/ctf-pwn/kernel-techniques.md +366 -0
- package/skills/ctf-pwn/kernel.md +636 -0
- package/skills/ctf-pwn/overflow-basics.md +611 -0
- package/skills/ctf-pwn/rop-advanced.md +725 -0
- package/skills/ctf-pwn/rop-and-shellcode.md +659 -0
- package/skills/ctf-pwn/sandbox-escape.md +313 -0
- package/skills/ctf-reverse/SKILL.md +163 -0
- package/skills/ctf-reverse/anti-analysis-ctf.md +204 -0
- package/skills/ctf-reverse/anti-analysis.md +693 -0
- package/skills/ctf-reverse/field-notes.md +376 -0
- package/skills/ctf-reverse/languages-compiled.md +666 -0
- package/skills/ctf-reverse/languages-platforms.md +592 -0
- package/skills/ctf-reverse/languages.md +553 -0
- package/skills/ctf-reverse/patterns-ctf-2.md +397 -0
- package/skills/ctf-reverse/patterns-ctf-3.md +797 -0
- package/skills/ctf-reverse/patterns-ctf.md +670 -0
- package/skills/ctf-reverse/patterns-runtime.md +274 -0
- package/skills/ctf-reverse/patterns.md +572 -0
- package/skills/ctf-reverse/platforms-hardware.md +387 -0
- package/skills/ctf-reverse/platforms.md +664 -0
- package/skills/ctf-reverse/tools-advanced-2.md +421 -0
- package/skills/ctf-reverse/tools-advanced.md +407 -0
- package/skills/ctf-reverse/tools-dynamic.md +679 -0
- package/skills/ctf-reverse/tools-emulation.md +319 -0
- package/skills/ctf-reverse/tools.md +573 -0
- package/skills/ctf-web/SKILL.md +153 -0
- package/skills/ctf-web/auth-and-access-2.md +82 -0
- package/skills/ctf-web/auth-and-access.md +783 -0
- package/skills/ctf-web/auth-infra.md +321 -0
- package/skills/ctf-web/auth-jwt.md +186 -0
- package/skills/ctf-web/client-side-advanced.md +739 -0
- package/skills/ctf-web/client-side.md +529 -0
- package/skills/ctf-web/cves.md +373 -0
- package/skills/ctf-web/field-notes.md +482 -0
- package/skills/ctf-web/node-and-prototype.md +200 -0
- package/skills/ctf-web/server-side-2.md +337 -0
- package/skills/ctf-web/server-side-advanced-2.md +559 -0
- package/skills/ctf-web/server-side-advanced-3.md +125 -0
- package/skills/ctf-web/server-side-advanced-4.md +480 -0
- package/skills/ctf-web/server-side-advanced.md +378 -0
- package/skills/ctf-web/server-side-deser.md +443 -0
- package/skills/ctf-web/server-side-exec-2.md +799 -0
- package/skills/ctf-web/server-side-exec.md +457 -0
- package/skills/ctf-web/server-side.md +629 -0
- package/skills/ctf-web/sql-injection.md +790 -0
- package/skills/ctf-web/web3.md +374 -0
- package/skills/ctf-writeup/SKILL.md +90 -0
- package/skills/solve-challenge/SKILL.md +269 -0
- package/skills.json +16 -0
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
# CTF Reverse - Platform-Specific Reversing
|
|
2
|
+
|
|
3
|
+
macOS/iOS, embedded/IoT firmware, kernel driver, automotive, and game engine reverse engineering.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [macOS / iOS Reversing](#macos--ios-reversing)
|
|
7
|
+
- [Mach-O Binary Format](#mach-o-binary-format)
|
|
8
|
+
- [Code Signing & Entitlements](#code-signing--entitlements)
|
|
9
|
+
- [Objective-C Runtime RE](#objective-c-runtime-re)
|
|
10
|
+
- [Swift Binary Reversing](#swift-binary-reversing)
|
|
11
|
+
- [iOS App Analysis](#ios-app-analysis)
|
|
12
|
+
- [dyld / Dynamic Linking](#dyld--dynamic-linking)
|
|
13
|
+
- [Embedded / IoT Firmware RE](#embedded--iot-firmware-re)
|
|
14
|
+
- [Firmware Extraction](#firmware-extraction)
|
|
15
|
+
- [Firmware Unpacking](#firmware-unpacking)
|
|
16
|
+
- [Architecture-Specific Notes](#architecture-specific-notes)
|
|
17
|
+
- [RTOS Analysis](#rtos-analysis)
|
|
18
|
+
- [Kernel Driver Reversing](#kernel-driver-reversing)
|
|
19
|
+
- [Linux Kernel Modules](#linux-kernel-modules)
|
|
20
|
+
- [eBPF Programs](#ebpf-programs)
|
|
21
|
+
- [Windows Kernel Drivers](#windows-kernel-drivers)
|
|
22
|
+
- [Game Engine Reversing](#game-engine-reversing)
|
|
23
|
+
- [Unreal Engine](#unreal-engine)
|
|
24
|
+
- [Unity (Beyond IL2CPP)](#unity-beyond-il2cpp)
|
|
25
|
+
- [Anti-Cheat Analysis](#anti-cheat-analysis)
|
|
26
|
+
- [Lua-Scripted Games](#lua-scripted-games)
|
|
27
|
+
- [Automotive / CAN Bus RE](#automotive--can-bus-re)
|
|
28
|
+
- [RISC-V QEMU Execution with GLIBC Symbol Version Patching (Pwn2Win 2018)](#risc-v-qemu-execution-with-glibc-symbol-version-patching-pwn2win-2018)
|
|
29
|
+
- [APK Certificate SHA-256 as AES Key (ASIS Finals 2018)](#apk-certificate-sha-256-as-aes-key-asis-finals-2018)
|
|
30
|
+
- [Moxie ISA Custom Opcode Discovery (SECCON 2018)](#moxie-isa-custom-opcode-discovery-seccon-2018)
|
|
31
|
+
- [Unity APK Assembly-CSharp.dll Runtime Patch (SECCON 2018)](#unity-apk-assembly-csharpdll-runtime-patch-seccon-2018)
|
|
32
|
+
- [Il2CppDumper for Unity IL2CPP Metadata Recovery (SECCON 2018)](#il2cppdumper-for-unity-il2cpp-metadata-recovery-seccon-2018)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## macOS / iOS Reversing
|
|
37
|
+
|
|
38
|
+
### Mach-O Binary Format
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# File identification
|
|
42
|
+
file binary # "Mach-O 64-bit executable arm64" or "x86_64"
|
|
43
|
+
otool -l binary # Load commands (segments, dylibs, entry point)
|
|
44
|
+
otool -L binary # Linked dynamic libraries
|
|
45
|
+
|
|
46
|
+
# Universal (fat) binaries — multiple architectures in one file
|
|
47
|
+
lipo -info universal_binary # List architectures
|
|
48
|
+
lipo universal_binary -thin arm64 -output binary_arm64 # Extract one arch
|
|
49
|
+
|
|
50
|
+
# Segments and sections
|
|
51
|
+
otool -l binary | grep -A5 "segment\|section"
|
|
52
|
+
# Key segments: __TEXT (code), __DATA (globals), __LINKEDIT (symbols)
|
|
53
|
+
# Key sections: __text (instructions), __cstring (C strings), __objc_methname
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Key Mach-O concepts:**
|
|
57
|
+
- Load commands drive the dynamic linker (`dyld`)
|
|
58
|
+
- `LC_MAIN` → entry point (replaces `LC_UNIXTHREAD`)
|
|
59
|
+
- `LC_LOAD_DYLIB` → shared library dependencies
|
|
60
|
+
- `LC_CODE_SIGNATURE` → code signing blob
|
|
61
|
+
- `__DATA_CONST.__got` → Global Offset Table
|
|
62
|
+
- `__DATA.__la_symbol_ptr` → Lazy symbol pointers (like PLT)
|
|
63
|
+
|
|
64
|
+
### Code Signing & Entitlements
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Check code signature
|
|
68
|
+
codesign -dvvv binary
|
|
69
|
+
codesign --verify binary
|
|
70
|
+
|
|
71
|
+
# Extract entitlements (capability permissions)
|
|
72
|
+
codesign -d --entitlements - binary
|
|
73
|
+
# Key entitlements: com.apple.security.app-sandbox, com.apple.security.network.client
|
|
74
|
+
|
|
75
|
+
# Remove code signature (for patching)
|
|
76
|
+
codesign --remove-signature binary
|
|
77
|
+
|
|
78
|
+
# Re-sign (ad-hoc, for testing)
|
|
79
|
+
codesign -f -s - binary
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**CTF relevance:** Patched binaries need re-signing to run on macOS. Ad-hoc signing (`-s -`) works for local testing.
|
|
83
|
+
|
|
84
|
+
### Objective-C Runtime RE
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Dump Objective-C class info
|
|
88
|
+
class-dump binary > classes.h
|
|
89
|
+
# Shows: @interface, @protocol, method signatures with types
|
|
90
|
+
|
|
91
|
+
# Runtime inspection with lldb
|
|
92
|
+
(lldb) expression -l objc -O -- [NSClassFromString(@"ClassName") new]
|
|
93
|
+
(lldb) expression -l objc -O -- [[ClassName alloc] init]
|
|
94
|
+
|
|
95
|
+
# Method swizzling detection (anti-tamper)
|
|
96
|
+
# Look for: method_exchangeImplementations, class_replaceMethod
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Objective-C in disassembly:**
|
|
100
|
+
```text
|
|
101
|
+
# objc_msgSend(receiver, selector, ...) is THE dispatch mechanism
|
|
102
|
+
# RDI = self (receiver), RSI = selector (char* method name)
|
|
103
|
+
|
|
104
|
+
# In Ghidra/IDA, look for:
|
|
105
|
+
objc_msgSend(obj, "checkPassword:", input)
|
|
106
|
+
# Selector strings are in __objc_methname section
|
|
107
|
+
# Cross-reference selectors to find implementations
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**class-dump alternatives:**
|
|
111
|
+
- `dsdump` — faster, supports Swift + Objective-C
|
|
112
|
+
- `otool -oV binary` — dump Objective-C segments
|
|
113
|
+
- Ghidra: Enable "Objective-C" analyzer in Analysis Options
|
|
114
|
+
|
|
115
|
+
### Swift Binary Reversing
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Detect Swift
|
|
119
|
+
strings binary | grep "swift"
|
|
120
|
+
otool -l binary | grep "swift" # __swift5_* sections
|
|
121
|
+
|
|
122
|
+
# Swift demangling
|
|
123
|
+
swift demangle 's14MyApp0A8ClassC10checkInput6resultSbSS_tF'
|
|
124
|
+
# → MyApp.MyAppClass.checkInput(result: String) -> Bool
|
|
125
|
+
|
|
126
|
+
# xcrun swift-demangle < mangled_names.txt
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Swift in disassembly:**
|
|
130
|
+
```text
|
|
131
|
+
# Swift uses value witness tables (VWT) for type operations
|
|
132
|
+
# Protocol witness tables (PWT) for dynamic dispatch (like vtables)
|
|
133
|
+
|
|
134
|
+
# Key runtime functions to watch:
|
|
135
|
+
swift_allocObject → heap allocation
|
|
136
|
+
swift_release → reference count decrement
|
|
137
|
+
swift_bridgeObjectRetain → bridged (ObjC ↔ Swift) retain
|
|
138
|
+
swift_once → lazy initialization (like dispatch_once)
|
|
139
|
+
|
|
140
|
+
# String layout:
|
|
141
|
+
# Small strings (≤15 bytes): inline in 16-byte buffer, tagged pointer
|
|
142
|
+
# Large strings: heap-allocated, pointer + length + flags
|
|
143
|
+
|
|
144
|
+
# Array<T>: pointer to ContiguousArrayStorage (header + elements)
|
|
145
|
+
# Dictionary<K,V>: hash table with open addressing
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Ghidra for Swift:** Enable "Swift" language module. Swift metadata sections (`__swift5_types`, `__swift5_proto`) contain type descriptors that Ghidra can parse.
|
|
149
|
+
|
|
150
|
+
### iOS App Analysis
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Extract IPA (iOS app package)
|
|
154
|
+
unzip app.ipa -d extracted/
|
|
155
|
+
ls extracted/Payload/*.app/
|
|
156
|
+
|
|
157
|
+
# Check if encrypted (App Store encryption / FairPlay DRM)
|
|
158
|
+
otool -l extracted/Payload/*.app/binary | grep -A4 "LC_ENCRYPTION_INFO"
|
|
159
|
+
# cryptid = 1 means encrypted, 0 means decrypted
|
|
160
|
+
|
|
161
|
+
# Decrypt with frida-ios-dump (requires jailbroken device)
|
|
162
|
+
# Or use Clutch / bfdecrypt on device
|
|
163
|
+
frida-ios-dump -H jailbroken_ip -p 22 "App Name"
|
|
164
|
+
|
|
165
|
+
# Analyze decrypted binary
|
|
166
|
+
class-dump decrypted_binary > headers.h
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Jailbreak detection and bypass:**
|
|
170
|
+
```javascript
|
|
171
|
+
// Common jailbreak checks:
|
|
172
|
+
// 1. Check for Cydia/Sileo
|
|
173
|
+
// 2. Check /private/var/lib/apt
|
|
174
|
+
// 3. fork() succeeds (sandboxed apps can't fork)
|
|
175
|
+
// 4. Open /etc/apt, /bin/sh with write
|
|
176
|
+
// 5. Check for substrate/substitute libraries
|
|
177
|
+
|
|
178
|
+
// Frida bypass:
|
|
179
|
+
var paths = ["/Applications/Cydia.app", "/bin/sh", "/etc/apt",
|
|
180
|
+
"/private/var/lib/apt", "/usr/bin/ssh"];
|
|
181
|
+
Interceptor.attach(Module.findExportByName(null, "access"), {
|
|
182
|
+
onEnter(args) {
|
|
183
|
+
this.path = Memory.readUtf8String(args[0]);
|
|
184
|
+
},
|
|
185
|
+
onLeave(retval) {
|
|
186
|
+
if (paths.some(p => this.path && this.path.includes(p))) {
|
|
187
|
+
retval.replace(-1); // File not found
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### dyld / Dynamic Linking
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# DYLD environment variables (for analysis, blocked in hardened runtime)
|
|
197
|
+
DYLD_PRINT_LIBRARIES=1 ./binary # Print loaded dylibs
|
|
198
|
+
DYLD_INSERT_LIBRARIES=hook.dylib ./binary # Inject dylib (like LD_PRELOAD)
|
|
199
|
+
# Note: SIP (System Integrity Protection) blocks this for system binaries
|
|
200
|
+
|
|
201
|
+
# Inspect dyld shared cache (contains all system frameworks)
|
|
202
|
+
dyld_shared_cache_util -list /System/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Embedded / IoT Firmware RE
|
|
208
|
+
|
|
209
|
+
### Firmware Extraction
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# binwalk — firmware analysis and extraction
|
|
213
|
+
binwalk firmware.bin # Identify embedded filesystems, compressed data
|
|
214
|
+
binwalk -e firmware.bin # Extract all identified components
|
|
215
|
+
binwalk -Me firmware.bin # Recursive extraction (matryoshka)
|
|
216
|
+
binwalk --dd='.*' firmware.bin # Extract everything raw
|
|
217
|
+
|
|
218
|
+
# Manual extraction by signature
|
|
219
|
+
strings firmware.bin | head -50 # Look for version strings, filesystem markers
|
|
220
|
+
hexdump -C firmware.bin | grep "hsqs" # SquashFS magic
|
|
221
|
+
hexdump -C firmware.bin | grep "UBI#" # UBI magic
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Hardware extraction methods (physical access):**
|
|
225
|
+
```text
|
|
226
|
+
UART: Serial console — often gives root shell or bootloader access
|
|
227
|
+
Tools: USB-UART adapter, baudrate detection (usually 115200)
|
|
228
|
+
Identify: 4 pins (GND, TX, RX, VCC), use multimeter
|
|
229
|
+
|
|
230
|
+
JTAG: Direct CPU debug — read/write flash, halt CPU, set breakpoints
|
|
231
|
+
Tools: OpenOCD, J-Link, Bus Pirate
|
|
232
|
+
Identify: 10/14/20-pin header, use JTAGulator for auto-detection
|
|
233
|
+
|
|
234
|
+
SPI Flash: Direct chip read — dump entire firmware
|
|
235
|
+
Tools: flashrom, CH341A programmer
|
|
236
|
+
Identify: 8-pin SOIC chip (Winbond, Macronix, etc.)
|
|
237
|
+
|
|
238
|
+
eMMC: Embedded MMC — common in routers, phones
|
|
239
|
+
Tools: eMMC reader, direct solder to test pads
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Firmware Unpacking
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# SquashFS (most common in routers)
|
|
246
|
+
unsquashfs -d output/ squashfs-root.sqfs
|
|
247
|
+
# If custom compression: try different compressors (-comp xz|lzma|lzo|gzip)
|
|
248
|
+
|
|
249
|
+
# JFFS2
|
|
250
|
+
jefferson -d output/ jffs2.img
|
|
251
|
+
|
|
252
|
+
# UBI/UBIFS
|
|
253
|
+
ubireader_extract_images firmware.ubi
|
|
254
|
+
ubireader_extract_files ubifs.img
|
|
255
|
+
|
|
256
|
+
# CPIO (initramfs)
|
|
257
|
+
cpio -idv < initramfs.cpio
|
|
258
|
+
|
|
259
|
+
# Device tree blob
|
|
260
|
+
dtc -I dtb -O dts -o output.dts device_tree.dtb
|
|
261
|
+
|
|
262
|
+
# Kernel extraction
|
|
263
|
+
binwalk -e firmware.bin
|
|
264
|
+
# Look for: zImage, uImage, vmlinux
|
|
265
|
+
# Extract vmlinux from compressed: vmlinux-to-elf tool
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Architecture-Specific Notes
|
|
269
|
+
|
|
270
|
+
**ARM (most common in IoT):**
|
|
271
|
+
```bash
|
|
272
|
+
# Cross-toolchain
|
|
273
|
+
apt install gcc-arm-linux-gnueabihf gdb-multiarch
|
|
274
|
+
|
|
275
|
+
# QEMU emulation
|
|
276
|
+
qemu-arm -L /usr/arm-linux-gnueabihf/ ./arm_binary
|
|
277
|
+
qemu-arm -g 1234 ./arm_binary # Start GDB server on port 1234
|
|
278
|
+
gdb-multiarch -ex 'target remote :1234' ./arm_binary
|
|
279
|
+
|
|
280
|
+
# ARM vs Thumb: ARM instructions are 4 bytes, Thumb are 2 bytes
|
|
281
|
+
# LSB of function pointer indicates mode: 0=ARM, 1=Thumb
|
|
282
|
+
# Ghidra: Right-click → Processor Options → ARM/Thumb mode
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**ARM64/AArch64:** See [platforms-hardware.md](platforms-hardware.md#arm64aarch64-reversing-and-exploitation) for AArch64 calling convention, ROP gadgets, and qemu-aarch64-static emulation.
|
|
286
|
+
|
|
287
|
+
**MIPS (routers, embedded):**
|
|
288
|
+
```bash
|
|
289
|
+
# Big-endian vs little-endian — check ELF header or file command
|
|
290
|
+
file binary # "MIPS, MIPS32 rel2 (MIPS-II), big-endian" or "little-endian"
|
|
291
|
+
|
|
292
|
+
# Emulation
|
|
293
|
+
qemu-mips -L /usr/mips-linux-gnu/ ./mips_binary # Big-endian
|
|
294
|
+
qemu-mipsel -L /usr/mipsel-linux-gnu/ ./mipsel_binary # Little-endian
|
|
295
|
+
|
|
296
|
+
# Key MIPS patterns:
|
|
297
|
+
# Branch delay slots — instruction AFTER branch always executes
|
|
298
|
+
# $gp (global pointer) — used for PIC, points to .got
|
|
299
|
+
# lui + addiu pair — loads 32-bit constant (upper 16 + lower 16)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**RISC-V:** See main [tools.md](tools.md#risc-v-binary-analysis-ehax-2026) for Capstone disassembly and [platforms-hardware.md](platforms-hardware.md#risc-v-advanced) for advanced extensions and debugging.
|
|
303
|
+
|
|
304
|
+
### RTOS Analysis
|
|
305
|
+
|
|
306
|
+
```text
|
|
307
|
+
FreeRTOS:
|
|
308
|
+
- Tasks (like threads): xTaskCreate → function pointer + stack
|
|
309
|
+
- Strings: "IDLE", "Tmr Svc", task names
|
|
310
|
+
- xQueueSend/xQueueReceive → inter-task communication
|
|
311
|
+
- Look for vTaskDelay() for timing, xSemaphoreTake() for sync
|
|
312
|
+
|
|
313
|
+
Zephyr:
|
|
314
|
+
- k_thread_create → kernel thread creation
|
|
315
|
+
- k_msgq_put/k_msgq_get → message queues
|
|
316
|
+
- CONFIG_* symbols reveal kernel configuration
|
|
317
|
+
|
|
318
|
+
Bare metal (no OS):
|
|
319
|
+
- Interrupt vector table at address 0x0 or 0x08000000 (STM32)
|
|
320
|
+
- main loop pattern: while(1) { read_input(); process(); output(); }
|
|
321
|
+
- Peripheral registers at memory-mapped addresses (check datasheet)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Kernel Driver Reversing
|
|
327
|
+
|
|
328
|
+
### Linux Kernel Modules
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# Identify kernel module
|
|
332
|
+
file module.ko # "ELF 64-bit LSB relocatable"
|
|
333
|
+
modinfo module.ko # Module info (description, author, license)
|
|
334
|
+
|
|
335
|
+
# List module symbols
|
|
336
|
+
nm module.ko | grep -v " U " # Exported symbols
|
|
337
|
+
|
|
338
|
+
# Strings for quick recon
|
|
339
|
+
strings module.ko | grep -i "flag\|secret\|ioctl\|device"
|
|
340
|
+
|
|
341
|
+
# Find ioctl handler
|
|
342
|
+
# Key pattern: .unlocked_ioctl = my_ioctl_handler in file_operations struct
|
|
343
|
+
# In Ghidra: find struct with function pointers, identify by position
|
|
344
|
+
|
|
345
|
+
# Load in Ghidra
|
|
346
|
+
# Language: x86:LE:64:default
|
|
347
|
+
# Base address: doesn't matter for .ko (relocatable)
|
|
348
|
+
# Look for init_module / cleanup_module entry points
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Common kernel module CTF patterns:**
|
|
352
|
+
```c
|
|
353
|
+
// Device creation (creates /dev/challenge)
|
|
354
|
+
alloc_chrdev_region(&dev, 0, 1, "challenge");
|
|
355
|
+
cdev_init(&cdev, &fops);
|
|
356
|
+
|
|
357
|
+
// ioctl handler (main interface)
|
|
358
|
+
long my_ioctl(struct file *f, unsigned int cmd, unsigned long arg) {
|
|
359
|
+
switch (cmd) {
|
|
360
|
+
case CUSTOM_CMD_1: /* operation */ break;
|
|
361
|
+
case CUSTOM_CMD_2: /* operation */ break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// copy_from_user / copy_to_user — data transfer with userspace
|
|
366
|
+
copy_from_user(kernel_buf, (void __user *)arg, size);
|
|
367
|
+
copy_to_user((void __user *)arg, kernel_buf, size);
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Debugging kernel modules:**
|
|
371
|
+
```bash
|
|
372
|
+
# QEMU + GDB for kernel debugging
|
|
373
|
+
qemu-system-x86_64 -kernel bzImage -initrd initrd.cpio -s -S \
|
|
374
|
+
-append "console=ttyS0 nokaslr" -nographic
|
|
375
|
+
|
|
376
|
+
# In another terminal
|
|
377
|
+
gdb vmlinux
|
|
378
|
+
(gdb) target remote :1234
|
|
379
|
+
(gdb) lx-symbols # Load module symbols (requires scripts)
|
|
380
|
+
(gdb) add-symbol-file module.ko 0x<loaded_address>
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### eBPF Programs
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
# Dump eBPF programs from running system
|
|
387
|
+
bpftool prog list
|
|
388
|
+
bpftool prog dump xlated id <N> # Disassemble
|
|
389
|
+
bpftool prog dump jited id <N> # JIT'd machine code
|
|
390
|
+
|
|
391
|
+
# eBPF bytecode analysis
|
|
392
|
+
# eBPF has 11 registers (r0-r10), 64-bit
|
|
393
|
+
# r0 = return value, r1-r5 = arguments, r10 = frame pointer
|
|
394
|
+
# Instructions are 8 bytes each
|
|
395
|
+
|
|
396
|
+
# Disassemble .o file containing eBPF
|
|
397
|
+
llvm-objdump -d ebpf_prog.o
|
|
398
|
+
|
|
399
|
+
# Key eBPF patterns:
|
|
400
|
+
# bpf_map_lookup_elem → read from map
|
|
401
|
+
# bpf_map_update_elem → write to map
|
|
402
|
+
# bpf_probe_read → read kernel memory
|
|
403
|
+
# bpf_trace_printk → debug output
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Windows Kernel Drivers
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
# .sys files are PE format — load in IDA/Ghidra as normal PE
|
|
410
|
+
# Entry point: DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING)
|
|
411
|
+
|
|
412
|
+
# Key patterns:
|
|
413
|
+
# IoCreateDevice → creates device object
|
|
414
|
+
# IRP_MJ_DEVICE_CONTROL → ioctl handler
|
|
415
|
+
# MmMapIoSpace → memory-mapped I/O
|
|
416
|
+
# ObReferenceObjectByHandle → get kernel object from handle
|
|
417
|
+
# ZwCreateFile/ZwReadFile → kernel-mode file operations
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Game Engine Reversing
|
|
423
|
+
|
|
424
|
+
### Unreal Engine
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
# Pak file extraction
|
|
428
|
+
# UnrealPakTool or quickbms with unreal_tournament_4.bms
|
|
429
|
+
unrealpak.exe extract GameName.pak -output extracted/
|
|
430
|
+
|
|
431
|
+
# UE4/UE5 asset formats:
|
|
432
|
+
# .uasset — serialized UObject (meshes, textures, blueprints)
|
|
433
|
+
# .umap — level/map data
|
|
434
|
+
# .ushaderbytecode — compiled shader
|
|
435
|
+
# FModel (https://fmodel.app/) — GUI asset viewer/extractor
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
**Blueprint reversing:**
|
|
439
|
+
```text
|
|
440
|
+
Blueprints compile to bytecode in .uasset files.
|
|
441
|
+
- UAssetGUI / FModel to browse Blueprint assets
|
|
442
|
+
- Kismet bytecode → visual scripting logic
|
|
443
|
+
- Look for: K2_SetTimer, DoOnce, Branch, Custom Events
|
|
444
|
+
- Flag logic often in Blueprint event graphs, not C++
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
**UE4/UE5 C++ reversing:**
|
|
448
|
+
```bash
|
|
449
|
+
# Key engine classes:
|
|
450
|
+
# UObject → base class for everything
|
|
451
|
+
# AActor → entities in the world
|
|
452
|
+
# UGameInstance → game state
|
|
453
|
+
# APlayerController → player input handling
|
|
454
|
+
|
|
455
|
+
# Reflection system — UCLASS(), UPROPERTY(), UFUNCTION() macros
|
|
456
|
+
# Generates metadata accessible at runtime
|
|
457
|
+
# In Ghidra: look for UClass::StaticClass() calls → type identification
|
|
458
|
+
|
|
459
|
+
# String handling: FString (UTF-16), FName (hashed identifier), FText (localized)
|
|
460
|
+
# In memory: FString = {TCHAR* Data, int32 ArrayNum, int32 ArrayMax}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Unity (Beyond IL2CPP)
|
|
464
|
+
|
|
465
|
+
See [languages.md](languages.md#unity-il2cpp-games) for IL2CPP basics.
|
|
466
|
+
|
|
467
|
+
**Mono-based Unity (not IL2CPP):**
|
|
468
|
+
```bash
|
|
469
|
+
# Managed assemblies in Data/Managed/ directory
|
|
470
|
+
# Assembly-CSharp.dll contains game logic
|
|
471
|
+
dnspy Assembly-CSharp.dll # Full decompilation + debugging
|
|
472
|
+
ilspy Assembly-CSharp.dll # Decompilation only
|
|
473
|
+
|
|
474
|
+
# Common Unity patterns:
|
|
475
|
+
# MonoBehaviour.Start() → initialization
|
|
476
|
+
# MonoBehaviour.Update() → per-frame logic
|
|
477
|
+
# PlayerPrefs.GetString("key") → stored data
|
|
478
|
+
# SceneManager.LoadScene("level") → scene transitions
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**Unity asset extraction:**
|
|
482
|
+
```bash
|
|
483
|
+
# AssetStudio — extract textures, models, audio, scripts
|
|
484
|
+
# AssetRipper — comprehensive Unity asset extraction
|
|
485
|
+
# UABE (Unity Asset Bundle Extractor) — low-level asset editing
|
|
486
|
+
|
|
487
|
+
# Search for flags in:
|
|
488
|
+
# - Text assets (.txt, .json)
|
|
489
|
+
# - TextMesh / UI Text components
|
|
490
|
+
# - Shader source code
|
|
491
|
+
# - ScriptableObject assets
|
|
492
|
+
# - PlayerPrefs save files
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Anti-Cheat Analysis
|
|
496
|
+
|
|
497
|
+
```text
|
|
498
|
+
For CTF challenges involving game anti-cheat:
|
|
499
|
+
|
|
500
|
+
EasyAntiCheat (EAC):
|
|
501
|
+
- Kernel driver (EasyAntiCheat_EOS.sys)
|
|
502
|
+
- User-mode module injected into game
|
|
503
|
+
- Integrity checks on game memory
|
|
504
|
+
- Bypass: kernel-level memory R/W (for research only)
|
|
505
|
+
|
|
506
|
+
BattlEye:
|
|
507
|
+
- BEService.exe → BEClient.dll injected
|
|
508
|
+
- Communication via encrypted channel
|
|
509
|
+
- Screenshot capture, process scanning
|
|
510
|
+
- Module: BEClient2.dll
|
|
511
|
+
|
|
512
|
+
Valve Anti-Cheat (VAC):
|
|
513
|
+
- User-mode only (no kernel driver)
|
|
514
|
+
- Module hashing, memory scanning
|
|
515
|
+
- Network-based detection (server-side)
|
|
516
|
+
- Delayed bans (not immediate)
|
|
517
|
+
|
|
518
|
+
CTF approach:
|
|
519
|
+
1. Identify which anti-cheat (strings, loaded modules)
|
|
520
|
+
2. For CTF: usually need to bypass specific check, not full anti-cheat
|
|
521
|
+
3. Memory patching: find game state in memory, modify values
|
|
522
|
+
4. Save file manipulation: often easier than runtime cheating
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Lua-Scripted Games
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
# Many games embed Lua for scripting
|
|
529
|
+
# Look for: lua51.dll, luajit.dll, .lua files in assets
|
|
530
|
+
|
|
531
|
+
# Luac bytecode decompilation
|
|
532
|
+
luadec bytecode.luac > decompiled.lua # Lua 5.1-5.3
|
|
533
|
+
unluac bytecode.luac > decompiled.lua # Alternative
|
|
534
|
+
|
|
535
|
+
# LuaJIT bytecode
|
|
536
|
+
luajit -bl bytecode.lua # Disassemble
|
|
537
|
+
# ljd (LuaJIT decompiler): python3 ljd bytecode.lua
|
|
538
|
+
|
|
539
|
+
# Embedded Lua: strings binary | grep "lua_\|luaL_\|LUA_"
|
|
540
|
+
# Hook lua_pcall to intercept script execution
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## Automotive / CAN Bus RE
|
|
546
|
+
|
|
547
|
+
```bash
|
|
548
|
+
# CAN bus interface setup
|
|
549
|
+
sudo ip link set can0 type can bitrate 500000
|
|
550
|
+
sudo ip link set up can0
|
|
551
|
+
|
|
552
|
+
# Capture CAN traffic
|
|
553
|
+
candump can0 # Live capture
|
|
554
|
+
candump -l can0 # Log to file
|
|
555
|
+
cansniffer can0 # Filter/highlight changes
|
|
556
|
+
|
|
557
|
+
# Replay CAN messages
|
|
558
|
+
canplayer -I logfile.log can0
|
|
559
|
+
cansend can0 7DF#0201000000000000 # Send single frame (OBD-II request)
|
|
560
|
+
|
|
561
|
+
# UDS (Unified Diagnostic Services) — common in automotive CTF
|
|
562
|
+
# Service 0x27: Security Access (seed-key authentication)
|
|
563
|
+
# Service 0x2E: Write Data By Identifier
|
|
564
|
+
# Service 0x31: Routine Control
|
|
565
|
+
|
|
566
|
+
# Decode CAN frames
|
|
567
|
+
# ID: 11-bit or 29-bit identifier
|
|
568
|
+
# DLC: Data Length Code (0-8 bytes)
|
|
569
|
+
# Data: up to 8 bytes payload
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
**CTF automotive patterns:**
|
|
573
|
+
- Seed-key bypass: Reverse the key derivation algorithm from ECU firmware
|
|
574
|
+
- CAN message replay: Capture legitimate command, replay to unlock feature
|
|
575
|
+
- Firmware extraction from ECU via UDS/KWP2000
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## RISC-V QEMU Execution with GLIBC Symbol Version Patching (Pwn2Win 2018)
|
|
580
|
+
|
|
581
|
+
**Pattern:** Challenge binary targets a RISC-V Debian that isn't available natively. Extract the Debian libc6 and dynamic linker, then patch the binary's required GLIBC symbol version (e.g., `GLIBC_2.25` → `GLIBC_2.27`) in a hex editor so the available libc can serve it. Run with `qemu-riscv64 -L <sysroot>`.
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
ar x libc6_2.27-5_riscv64.deb && tar xf data.tar.xz
|
|
585
|
+
sed 's@GLIBC_2.25@GLIBC_2.27@g' -i binary
|
|
586
|
+
# Patch the symbol version hash too
|
|
587
|
+
objdump -p binary # note old hash
|
|
588
|
+
# replace bytes with xxd / hexedit
|
|
589
|
+
qemu-riscv64 -L ./sysroot ./binary
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Key insight:** `ld.so` symbol versioning is enforced by a hashed identifier next to each symbol. Patching both the string and its hash bypasses the check without rebuilding libc; `objdump -p` shows the hash slot to overwrite.
|
|
593
|
+
|
|
594
|
+
**References:** Pwn2Win CTF 2018 — Too Slow, writeup 12501+
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## APK Certificate SHA-256 as AES Key (ASIS Finals 2018)
|
|
599
|
+
|
|
600
|
+
**Pattern:** Android app derives its AES key from `SHA-256(packageInfo.signatures[0].toByteArray())`, truncated to 16 bytes. Because the signing cert is embedded in the APK, the key is recoverable offline — no reverse engineering of native code required.
|
|
601
|
+
|
|
602
|
+
```python
|
|
603
|
+
from hashlib import sha256
|
|
604
|
+
import base64, zipfile
|
|
605
|
+
|
|
606
|
+
cert = zipfile.ZipFile('app.apk').read('META-INF/CERT.RSA')
|
|
607
|
+
key = base64.b64encode(sha256(cert).digest())[:16]
|
|
608
|
+
# Decrypt config resources with AES-ECB using this key
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
**Key insight:** "Deterministic key from a public fingerprint" is a recurring Android anti-pattern. Audit `getSignature`, `getPackageInfo`, and MessageDigest usages for this shape; the fix is to store a real secret server-side.
|
|
612
|
+
|
|
613
|
+
**References:** ASIS CTF Finals 2018 — Gunshop, writeup 12420
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## Moxie ISA Custom Opcode Discovery (SECCON 2018)
|
|
618
|
+
|
|
619
|
+
**Pattern:** Binary is compiled for Moxie (obscure CPU architecture). `strings` on the ELF reveals a help banner declaring custom opcodes `SETRSEED (0x16)` and `GETRAND (0x17)`, with a non-standard xorshift32 implementation. Emulate those opcodes in Python to recover the PRNG stream, then XOR the ciphertext with the sequence.
|
|
620
|
+
|
|
621
|
+
```python
|
|
622
|
+
def xorshift32(s):
|
|
623
|
+
s ^= (s << 13) & 0xffffffff
|
|
624
|
+
s ^= (s >> 17)
|
|
625
|
+
s ^= (s << 15) & 0xffffffff # Note: *not* standard (<< 5)
|
|
626
|
+
return s & 0xffffffff
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
**Key insight:** Obscure ISAs often lean on small custom additions to implement crypto inline. Grep the binary for human-readable opcode documentation; it's frequently left in the help text for challenge authors' own debugging.
|
|
630
|
+
|
|
631
|
+
**References:** SECCON 2018 — Special Instructions, writeup 12001
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
## Unity APK Assembly-CSharp.dll Runtime Patch (SECCON 2018)
|
|
636
|
+
|
|
637
|
+
**Pattern:** Unity game ships compiled C# game logic in `assets/bin/Data/Managed/Assembly-CSharp.dll`. Decompile with dnSpy/ILSpy, modify the `Update()` or `Start()` methods (e.g., remove rotation animations that hide the flag), recompile, repack the APK with `apktool`, resign with `jarsigner`, install on emulator.
|
|
638
|
+
|
|
639
|
+
```bash
|
|
640
|
+
apktool d game.apk -o game_src
|
|
641
|
+
# Replace game_src/assets/bin/Data/Managed/Assembly-CSharp.dll with patched version
|
|
642
|
+
apktool b game_src -o patched.apk
|
|
643
|
+
jarsigner -keystore debug.keystore -storepass android patched.apk androiddebugkey
|
|
644
|
+
adb install -r patched.apk
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
**Key insight:** Unity games are "just C#" once you open the DLL. Any hidden flag rendered at the wrong angle or masked by an overlay is exposed by deleting the animation code.
|
|
648
|
+
|
|
649
|
+
**References:** SECCON 2018 — block, writeup 12001
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
## Il2CppDumper for Unity IL2CPP Metadata Recovery (SECCON 2018)
|
|
654
|
+
|
|
655
|
+
**Pattern:** Modern Unity games compile to IL2CPP (native code plus metadata) instead of shipping `Assembly-CSharp.dll`. Use `Il2CppDumper` against `libil2cpp.so` plus `assets/bin/Data/Managed/Metadata/global-metadata.dat` to recover pseudo-C#, then grep the output for endpoint strings, API paths, or crypto constants.
|
|
656
|
+
|
|
657
|
+
```bash
|
|
658
|
+
Il2CppDumper libil2cpp.so global-metadata.dat out/
|
|
659
|
+
grep -r "https://" out/ # find hardcoded endpoints
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
**Key insight:** IL2CPP looks opaque but the metadata file carries every type name, method name, and string literal. That is enough to reverse CTF-level logic without ever touching native disassembly.
|
|
663
|
+
|
|
664
|
+
**References:** SECCON 2018 — shooter, writeup 12001
|