←
$ Rev: gcc
Flag: BITSCTF{n4n0m1t3s_4nd_s3lf_d3struct_0ur0b0r0s}Summary
The binary is a stripped 64-bit PIE ELF that behaves like a wrapper around gcc, but it contains a self-modifying/self-erasing mechanism.
A hidden 64-byte region in the binary (.data, file offset 0x3020) is decrypted at runtime with a key derived from the binary contents itself. The first 8 decrypted bytes must match BITSCTF{ to pass an internal check.
By reimplementing the same logic offline on a fresh copy from chall.zip, the flag can be recovered directly.
High-Level Behavior
ghost_compilerscans its own file for an 8-byte marker pattern stored at runtime in.data.- It computes a hash of the file while skipping a 64-byte window starting at that marker offset.
- A key is derived from the hash.
- The 64-byte hidden block is XOR-decrypted with a rotating key stream.
- If decrypted prefix is
BITSCTF{, execution continues. - It then zeroes (
memset) the same 64-byte region and writes the file back, so later runs lose the embedded secret material.
Important Reversed Components
- Marker search function (
.text+0xe9at0x1349)
- Opens target file in
rbmode. - Searches for an 8-byte sequence beginning with first byte at
0x4020. - Returns the first match offset.
- Hash/key derivation (
.text+0x265at0x14b5)
- Implements FNV-1a style hashing:
- init:
0xcbf29ce484222325 - prime:
0x100000001b3
- init:
- Skips bytes in
[offset, offset+0x3f]. - Returns:
hash ^ 0xcafebabe00000000.
- Decryption & prefix check (
.text+0x333at0x1583)
- For 64 bytes:
out[i] = enc[i] XOR (key & 0xff)- rotate key right by 1 each byte (
ror 64-bit, 1)
- Validates first 8 output bytes as:
42 49 54 53 43 54 46 7b->BITSCTF{
- Self-erase step (
.text+0x5c0onward)
- If checks pass, it wipes 64 bytes at found offset with zeros.
- Rewrites the input file and continues to build a
gcc ...command.
Why Fresh Binary Matters
The binary modifies itself. If executed once, the secret block may be overwritten, preventing later extraction. Recovering from a clean copy in chall.zip is essential.
Reproduction Script Logic (used)
- Extract fresh
ghost_compiler. - Locate marker at
0x3020. - Recompute hash while skipping 64-byte protected window.
- Derive 64-bit key:
hash ^ 0xcafebabe00000000. - Decrypt 64 bytes with rolling XOR/rotate.
- Read plaintext flag.