ron (RE3_ron)
ron (RE3_ron)
Platform: rev_kids20 | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-06-15 | Status: Solved Techniques: hardcoded_key_extraction, rc4_keystream_recovery, stripped_disasm_idiom_recognition, symmetric_cipher_decryption
Summary
Task: stripped 64-bit PIE ELF that RC4-encrypts a 24-byte input with hardcoded key 'blood' and compares to an embedded ciphertext. Solution: recognize the RC4 KSA/PRGA idioms (the 'ron'=Ron Rivest pun), then exploit RC4 symmetry to recover the flag by running RC4(key='blood', ciphertext).
ron (RE3_ron) — rev_kids20
Description
RE3_ron (display name "ron"), category Shtrikh17/Reverse. Platform: rev-kids20.forkbomb.ru
A stripped 64-bit PIE ELF named ron. Running it prints Give me the key: ,
reads a line, and validates it. On success it prints Correct!. The goal is to
recover the accepted key, which is the flag.
Analysis
main is at 0x13ef. Behavior:
fgets(input, 0xff, stdin), strip trailing newline.- Require
strlen(input) == 0x18(24); otherwise printWrong lengthand exit. - Set pointer A =
.rodata 0x2023="blood"(the RC4 key), pointer B =0x2029= a 24-byte expected ciphertext blob. - Call
0x138f(rdi="blood", rsi=input, rdx=outbuf):0x1199— RC4 KSA: initialize a 256-byte state and mix it with the key usingkey[i % keylen].0x1272— RC4 PRGA: i/j pointer swaps, emit keystream byteS[(S[i] + S[j]) & 0xff], XOR overinputintooutbuf.- So
outbuf = RC4_encrypt(key="blood", input).
- Compare
outbufbyte-by-byte against the 24-byte blob at0x2029; if all equal ->Correct!.
The decisive clues:
- Task name "ron" = Ron Rivest, inventor of RC4.
- The two unmistakable RC4 idioms in the stripped disassembly:
- KSA: a 256-entry array filled
0..255, then a loopj = (j + S[i] + key[i % keylen]) & 0xff; swap(S[i], S[j]). - PRGA:
i = (i+1)&0xff; j = (j+S[i])&0xff; swap; out ^= S[(S[i]+S[j])&0xff].
- KSA: a 256-entry array filled
- The hardcoded key string
"blood"sits in.rodataimmediately before the ciphertext (0x2023then0x2029).
.rodata contents:
0x2023:"blood\0"0x2029: ciphertext =e7 eb 7f 68 13 fe d6 40 e3 d1 00 14 60 f0 64 9a 04 b8 59 72 79 38 ed 18(24 bytes)- strings:
"Give me the key: ","Wrong length","Wrong","Correct!"
Solution
RC4 is a symmetric stream cipher: encryption and decryption are the same
operation (XOR with the keystream). The program computes
RC4(key="blood", flag) == ciphertext. Therefore the flag is simply
RC4(key="blood", ciphertext) — no input brute force, no comparison oracle
needed.
python read-only • copy allowed#!/usr/bin/env python3 def rc4(key, data): S = list(range(256)); j = 0 for i in range(256): # KSA j = (j + S[i] + key[i % len(key)]) & 0xff S[i], S[j] = S[j], S[i] out = bytearray(); i = j = 0 for b in data: # PRGA 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) ct = bytes.fromhex("e7eb7f6813fed640e3d1001460f0649a04b8597279 38ed18".replace(" ", "")) print(rc4(b"blood", ct)) # -> b'spbctf{REDACTED}'
The result is 24 bytes, matching the 0x18 length gate. Feeding
spbctf{REDACTED} to the binary prints Correct!.