← Back to Writeups
CUSTOMEasyReversing

task4 (patch4)

XESXOR9/2/20263 min read
#reversing#custom#easy#keystream_decryption#rc4_ksa_prga_recognition#signed_modulo_idiom_recognitio#static_disassembly

task4 (patch4)

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

Summary

Walkthrough of the CUSTOM Reversing task4 (patch4). Task: Windows C crackme that prints a secret only after 10 correct answers, then RC4-decrypts an embedded blob. Solution: recognize the two helper functions as RC4 KSA/PRGA with key 'iloveassembler',

Description

task4.exe — PE32 console crackme. Answer the prompts correctly to reveal the secret.

A 32-bit MSVC C binary asks "Enter num:" ten times. If all ten answers are correct it decrypts and prints a hidden secret string. The goal is to recover that secret.

Binary: https://rev-kids20.forkbomb.ru/files/rev/re7/task4.exe

Analysis

main() @ 0x401400:

  1. Sets a "remaining" counter var_2ch = 10, loops i = 0..9.
  2. Each iteration prints Enter num: and scanf("%d", &var_30h).
  3. Computes i % 2 using MSVC's signed-modulo idiom: and eax, 0x80000001 followed by sign correction (jns / dec / or 0xfffffffe / inc). Net result = i % 2 (0 for even index, 1 for odd index).
  4. If var_30h == (i % 2) it prints Yes and decrements the counter; otherwise prints Noo.
  5. After the loop, if (var_2ch == 0) (all 10 answers correct) the jne at 0x4014a1 is not taken and the reward block runs. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

So the input check is trivial — enter the alternating sequence 0 1 0 1 0 1 0 1 0 1.

Reward block = RC4 decryption

  • fcn.00401280 = RC4 KSA: builds a 256-byte S-box at 0x41e910 (S[i]=i), then runs the key-schedule swap loop using key "iloveassembler" (string @ 0x417188, length 0xe). Uses the signed-modulo idiom (and 0x800000ff + idiv) for the j index / key index.
  • fcn.00401330 = RC4 PRGA: generates 25 (0x19) keystream bytes S[(S[i]+S[j])&0xff] into a stack buffer.
  • main then XORs the 25-byte ciphertext at 0x41e000 with the keystream and puts() the result. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Ciphertext (25 bytes) @ 0x41e000:

8c a5 59 d7 78 30 77 65 28 af 43 46 13 7c 1b cc 57 76 3b e4 c1 b7 c1 0f 7f

Solution

Two paths:

  • Interactive / patch: enter 0 1 0 1 0 1 0 1 0 1, or patch the jne at 0x4014a1 to always take the reward branch.
  • Static: extract the ciphertext and key and decrypt offline with RC4.
python
#!/usr/bin/env python3
# RC4 decrypt of the embedded blob from task4.exe
data = bytes([0x8c,0xa5,0x59,0xd7,0x78,0x30,0x77,0x65,0x28,0xaf,0x43,0x46,
              0x13,0x7c,0x1b,0xcc,0x57,0x76,0x3b,0xe4,0xc1,0xb7,0xc1,0x0f,0x7f])
key = b"iloveassembler"
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

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]

i = j = 0; out = bytearray()
for b in data:                             # PRGA + XOR
    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])

print(out.decode())   # REDACTED

The output REDACTED is a transliteration of the Russian poem line "Однажды в студёную зимнюю пору". ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Key Takeaways / Lessons

  • Mastering keystream_decryption, rc4_ksa_prga_recognition, signed_modulo_idiom_recognition, static_disassembly was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-06-25 • CUSTOM • task4 (patch4) • Difficulty: Easy