← Back to Writeups
CUSTOMEasyReversing

patch6

XESXOR9/2/20263 min read
#reversing#custom#easy#keystream_xor#rc4_ksa_prga_recognition#static_reimplementation

patch6

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: keystream_xor, rc4_ksa_prga_recognition, static_reimplementation

Summary

Walkthrough of the CUSTOM Reversing patch6. Task: PE32 x86 C crackme that prints a flag computed at runtime via an embedded RC4 cipher with no user input. Solution: recognize the RC4 KSA/PRGA in disassembly, reimplement it in Python with key 'Y

Description

task6.exe — rev category (rev-kids20 / forkbomb.ru). Binary: https://rev-kids20.forkbomb.ru/files/rev/re7/task6.exe

A PE32 x86 Windows console executable that prints Printing flag and then prints a flag generated at runtime. There is no user input and no check to bypass — the flag is produced by an embedded RC4 stream cipher.

Analysis

The binary is a small C program. main at 0x00401470:

  1. Stack canary setup (xor ebp with 0x419018 cookie), prints "Printing flag\n" (string at 0x412160).
  2. Calls fcn.004012e0(S_buffer, "Yahhooo", 7) — the RC4 Key Scheduling Algorithm (KSA):
    • S[256] initialized to 0..255
    • j = 0; for i in 0..256: j = (j + S[i] + key[i % keylen]) & 0xff; swap(S[i], S[j])
    • key = "Yahhooo" (string at 0x412170), keylen = 7
  3. Calls fcn.00401390(S_buffer, out_buffer, 0x14=20) — the RC4 PRGA producing 20 keystream bytes. It writes S[(S[i]+S[j]) % 256] into out[k] — pure keystream, no plaintext XOR inside this function.
  4. Loop at 0x004014c7..0x00401503: for i in 0..20: out[i] = out[i] XOR data[0x419000 + i], where .rdata at 0x419000 holds 20 bytes: 50 3d 70 28 89 90 89 00 ac 10 98 5f 61 d6 fb 21 76 b5 99 30.
  5. Null-terminates and prints the result. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

fcn.00401260 is a signed-modulo helper backing the % 256 operations.

The patch in the task name is a red herring — no patching is needed; the flag is computed and printed unconditionally.

How RC4 was recognized

  • A loop initializing a 256-entry array with 0..255 (the S-box).
  • A second loop accumulating j with j = (j + S[i] + key[...]) & 0xff and swapping S[i]/S[j] — the unmistakable KSA pattern.
  • A generation loop incrementing i, accumulating j += S[i], swapping, and emitting S[(S[i]+S[j]) % 256] — the PRGA. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

Recover the flag statically: reimplement RC4 in Python (no need to run a Windows binary on a non-Windows host), generate 20 keystream bytes with key "Yahhooo", and XOR against the hardcoded .rdata blob.

python
#!/usr/bin/env python3
key = b"Yahhooo"

# RC4 KSA
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]

# RC4 PRGA — 20 keystream bytes
ks = []
i = j = 0
for _ in range(20):
    i = (i + 1) & 0xff
    j = (j + S[i]) & 0xff
    S[i], S[j] = S[j], S[i]
    ks.append(S[(S[i] + S[j]) & 0xff])
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

data = bytes([0x50,0x3d,0x70,0x28,0x89,0x90,0x89,0x00,0xac,0x10,
              0x98,0x5f,0x61,0xd6,0xfb,0x21,0x76,0xb5,0x99,0x30])
flag = bytes(k ^ d for k, d in zip(ks, data))
print("keystream =", bytes(ks).hex())
print(flag.decode())  # REDACTED

Output:

keystream = 1651114fe8e2ed69d97dc7190db79c4819c6ea51
REDACTED

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Key Takeaways / Lessons

  • Mastering keystream_xor, rc4_ksa_prga_recognition, static_reimplementation was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-06-25 • CUSTOM • patch6 • Difficulty: Easy