rev02
rev02
Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: check_constant_extraction, rc4_ksa_prga_reimplementation, self_reading_binary, key_concatenation_recovery, tail_ciphertext_carving
Summary
Walkthrough of the CUSTOM Reversing rev02. Task: 64-bit non-stripped PIE ELF that asks for train-route fields, concatenates them into an RC4 key, and decrypts a flag appended to its own file. Solution: extract the expected field values from ea
Description
Hello! In order to complete the challenge you need to fill some info about path to flag Enter value of <field> field please: Now concatenate all data you entered and place here as key Enter key: Decrypting flag and second part Flag: %s
A 64-bit x86-64 PIE ELF (rev_0_2, not stripped) presents a series of
prompts asking you to fill in fields describing a "path to flag" (a train/route
record). It then asks you to concatenate everything you typed into a single
"key" which is used to decrypt the flag. The flag is submitted via POST to the
flag endpoint on rev-kids20.forkbomb.ru.
Analysis
The binary is a self-decrypting RC4 challenge. Relevant functions (symbols are present because the binary is not stripped):
read_user/read_train/read_station/read_path+create_*— build a nested struct hierarchy:path -> train -> user, twostations, and a travel duration.check_pathand its helperscheck_path_begin_0,check_path_end_0,check_path_train_0,check_train_driver_0— each entered field is validated against a hardcoded constant. Those constants ARE the intended field values; reversing the comparisons recovers every value directly.prepare_key@0x1382— RC4 KSA (key scheduling).rc4@0x1497— RC4 PRGA.drop_flag@0x1695— opens the program's own binary file (fopen(argv[0], "rb")), reads the last 4 bytes as a little-endian ciphertext length (44), reads the ciphertext atfilesize - 4 - 44, and runs the custom RC4 keyed by the raw user-typed key string. The plaintext is a 4-byte little-endian length prefix followed by the flag.strtoupper@0x15c5— exists in the binary but is NOT applied to the key (an intentional red herring; the key stays mixed-case).
Key insight: the RC4 key is the concatenation of ALL entered field values in entry/read order with no separator and no case change.
Recovered field values (from the check_*_0 validators)
| Field | Value |
|---|---|
| rate | 4 |
| train_number | S146 |
| age | 60 |
| name | Sebastiano Riese |
| country | Rohan |
| price | 2306 |
| passengers_count | 955 |
| begin station city / f2 / f3 | 72 / Mona / Mosapsa |
| end station city / f2 / f3 | 87 / Isontol / Hrotiecka |
| travel_time | 9912 |
| |
Concatenated key (entry order, no separator):
4S14660Sebastiano RieseRohan230695572MonaMosapsa87IsontolHrotiecka9912
Solution
Two equivalent paths were used:
(a) Dynamic replay — run the binary under Docker ubuntu:22.04 (amd64),
enter exactly the expected field values, then at Enter key: paste the full
concatenation and read Flag: ....
(b) Static offline — carve the 44-byte ciphertext from the tail of the
binary (filesize - 4 - 44) and reproduce the custom RC4 (standard KSA + PRGA)
against it, then strip the 4-byte length prefix.
python read-only • copy allowed#!/usr/bin/env python3 import struct def rc4(key, ct): key = key.encode() if isinstance(key, str) else key S = list(range(256)); j = 0 for i in range(256): j = (j + S[i] + key[i % len(key)]) & 0xff S[i], S[j] = S[j], S[i] i = j = 0; out = bytearray() for b in ct: i = (i + 1) & 0xff; j = (j + S[i]) & 0xff S[i], S[j] = S[j], S[i] out.append(b ^ S[(S[i] + S[j]) & 0xff]) return bytes(out) data = open("rev_0_2", "rb").read() n = len(data) clen = struct.unpack("<I", data[n-4:n])[0] # 44 ct = data[n-4-clen : n-4] # tail ciphertext key = "4S14660Sebastiano RieseRohan230695572MonaMosapsa87IsontolHrotiecka9912" pt = rc4(key, ct) inner_len = struct.unpack("<I", pt[:4])[0] # 40 print(pt[4:4+inner_len].decode()) # spbctf{REDACTED}
Both paths yield the same flag. The inner value
REDACTED is the MD5 of the empty string — a nice
sanity-check tell that the key concatenation and RC4 reproduction were correct.
Key Takeaways / Lessons
- Mastering check_constant_extraction, rc4_ksa_prga_reimplementation, self_reading_binary, key_concatenation_recovery, tail_ciphertext_carving was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-06-15 • CUSTOM • rev02 • Difficulty: Medium