Requiem
Requiem [RE] - Beginner-Friendly Writeup#
Challenge#
We are given one file: requiem.
Goal: find the flag in format apoorvctf{...}.
1) First look at the binary#
Check what kind of file it is:
file requiembashThis shows a Linux 64-bit ELF executable (stripped), so reverse engineering is expected.
Make it executable and run:
chmod +x requiem
./requiembashProgram output:
loading flag
printing flag.....
RETURN TO ZERO!!!!!!!!textIt says it is printing the flag, but no flag appears. That means the real flag is probably decoded in memory and then erased.
2) Collect clues from strings#
strings -n 6 requiem | rg -i "flag|zero|return"bashThis confirms those same messages are hardcoded. It also hints the author wants us to notice the “zero” behavior.
3) Manually inspect code logic#
Use disassembly tools:
readelf -S requiem
objdump -d -Mintel requiembashIn the important function, there is a loop that does this for each byte:
- Read a byte from a constant data region (
.rodata) - XOR it with
0x5a - Write it to an output buffer
- Repeat for
0x2dbytes (45 bytes)
The key instruction pattern includes:
xor bpl, 0x5aasmSo the hidden flag is XOR-obfuscated in the binary.
4) Optional dynamic confirmation in gdb#
You can catch output syscalls and inspect stack traces:
catch syscall write
run
btplaintextThis helps confirm the program decodes bytes before writing output, then later clears memory (matching “RETURN TO ZERO!!!!!!!!“).
5) Decode the bytes#
From the disassembly, encoded bytes are located at file offset 0x484f4 with length 0x2d.
Use a quick Python script:
from pathlib import Path
b = Path("requiem").read_bytes()
off = 0x484f4
enc = b[off:off+0x2d]
flag = bytes(x ^ 0x5a for x in enc)
print(flag.decode())pythonOutput:
apoorvctf{N0_M0R3_R3QU13M_1N_TH15_3XP3R13NC3}textFinal Flag#
apoorvctf{N0_M0R3_R3QU13M_1N_TH15_3XP3R13NC3}
Beginner Notes#
- If
objdumpoutput feels too large, search for known strings first, then find nearby code references. - In CTF RE, XOR is very common. If you see one-byte transforms in a loop, test XOR decode quickly.
- “Looks like it prints flag but does not” usually means decode + wipe, fake output, or anti-analysis tricks.