Miscmedium
Up to Date
by Pavel Knespl (capyplivl)
A Zen-C source file is split into 5 stride chunks, wrapped in a tiny TCP-style protocol, mixed with noise packets, shuffled, and hex-encoded into output.txt. A genuine packet is the only one whose payload starts with its own sequence id, so that rule filters the noise. The recovered source XORs a byte array with 0x42 to print the flag.
Solve
- A valid packet is
[ZN][seq:1][len:1][payload:len]where the payload begins withstr(seq). Noise is either a bad magic orZNwith a payload that does not start with its seq. Scan forZN, keep packets whereseq < 5andpayload[0] == str(seq), then de-stride withzenc[j] = chunk[j % 5][j // 5].
data = bytes.fromhex(open("output.txt").read().strip())
chunks = {}
for i in range(len(data) - 4):
if data[i:i+2] != b"ZN":
continue
seq, ln = data[i+2], data[i+3]
payload = data[i+4:i+4+ln]
if len(payload) == ln and seq < 5 and payload[:1] == str(seq).encode():
chunks.setdefault(seq, payload[1:].decode("utf-8", "replace"))
out = []
for idx in range(max(len(c) for c in chunks.values())):
for s in range(5):
if idx < len(chunks[s]):
out.append(chunks[s][idx])
print("".join(out))
- The reconstructed source is:
fn main() -> void {
let code = [0x11, 0x14, 0x0b, 0x00, 0x05, 0x10, 0x39, 0x38, 0x71, 0x2c,
0x1d, 0x21, 0x1d, 0x34, 0x73, 0x20, 0x71, 0x1d, 0x26, 0x23,
0x75, 0x23, 0x1d, 0x25, 0x30, 0x76, 0x2f, 0x3f];
let key = 0x42;
for b in code { print(char(b ^ key)); }
}
- XOR each byte with 0x42:
code = [0x11,0x14,0x0b,0x00,0x05,0x10,0x39,0x38,0x71,0x2c,0x1d,0x21,0x1d,0x34,
0x73,0x20,0x71,0x1d,0x26,0x23,0x75,0x23,0x1d,0x25,0x30,0x76,0x2f,0x3f]
print("".join(chr(b ^ 0x42) for b in code))
Flag: SVIBGR{z3n_c_v1b3_da7a_gr4m}