Kaje
Challenge
- Name: Kaje
- Category: Reverse Engineering
- Points: 467
- Solves: 42
- Author: Anonimbus
- Description: "I don't know what is the intended solution anymore."
Solution
Binary Overview
The challenge provides a 64-bit ELF binary (kaje), not stripped, compiled from final.c. It contains three key functions: main, gen_entropy, and gen_keystream.
Analysis
gen_entropy (0x1290)
This function determines a seed value based on the runtime environment:
- Docker detection: Checks if
/.dockerenvexists usingaccess().- If the file exists (we are in Docker):
r12 = 0xcd9aadd8d9c9a989 - If the file does not exist (not in Docker):
r12 = 0x1337133713371337
- If the file exists (we are in Docker):
- Overlay filesystem detection: Opens
/proc/self/mountinfoand searches each line for the string"overlay".- If found:
r12 ^= 0xabcdef1234567890
- If found:
- Finalization: Applies the murmur3 64-bit finalizer (mix64) to
r12and returns it as the seed.
This creates four possible seed values depending on the environment.
gen_keystream (0x13b0)
Generates 32 bytes of keystream from the seed using a chained murmur3 hash:
s = seed
for i in 0..31:
v = s + i
s = mix64(v)
keystream[i] = s & 0xFF
Where mix64 is the standard murmur3 64-bit finalizer:
x ^= x >> 33
x *= 0xff51afd7ed558ccd
x ^= x >> 33
x *= 0xc4ceb9fe1a85ec53
x ^= x >> 33
main (0x1120)
- Calls
gen_entropy()to get the seed. - Calls
gen_keystream(seed)to generate 32 bytes of keystream on the stack. - XORs the keystream with 32 bytes of encrypted data stored in
.rodata(at offsets 0x2030 and 0x2040) using SSEpxorinstructions. - Prints the result with
puts().
Encrypted Data
From .rodata:
0x2030: 9f 12 d9 1b e2 12 bb ba fb f5 fe e8 a6 32 ac c6
0x2040: 04 36 92 d4 c9 3b bd be 22 a2 b4 83 6b 45 03 d3
Solving
The challenge description hints at multiple approaches -- but fundamentally, there are only four possible seeds based on the two boolean checks (docker present, overlay present). By trying all four combinations:
| Environment | r12 | Decrypted Output |
|---|---|---|
| Docker + overlay | 0x665742caed9fd119 |
Valid flag output |
| Docker + no overlay | 0xcd9aadd8d9c9a989 |
garbage |
| No docker + overlay | 0xb8fafc2527616ba7 |
garbage |
| No docker + no overlay | 0x1337133713371337 |
garbage |
The correct environment is Docker with overlay filesystem (the "intended" execution environment, matching how CTF challenges are typically deployed in containers).
The flag text mirrors the challenge description "I don't know what is the intended solution anymore."