# 2. Download the archive (the original link no longer works, but the file # is available in the CTF’s public release repository) wget https://example-ctf.org/files/kkmoom_pc.rar -O pc.rar
int __cdecl main() { char buf[0x100]; DWORD bytes; GetStdHandle(STD_OUTPUT_HANDLE); VirtualAlloc(0, 0x2000, MEM_COMMIT, PAGE_READWRITE); // Decrypt loop: for (i = 0; i < 0x100; ++i) buf[i] = encrypted[i] ^ key[i % keylen]; // WriteFile to stdout WriteFile(hStdOut, buf, 0x100, &bytes, 0); // Compare with expected value if (memcmp(buf, "FLAG", 5) == 0) puts(buf); else puts("Try again!"); return 0; www kkmoom com pc rar
import subprocess, os, struct, sys, pathlib Second‑Stage PE – The Real Target file payload
dd if=pc.exe bs=1 skip=$((0x00120000)) count=$((0x00002000)) \ of=payload.packed Using the disassembled LZ‑type routine we can implement a re‑creation of the algorithm in Python (the routine uses a 12‑bit sliding window with a flag byte controlling literal vs. copy). // WriteFile to stdout WriteFile(hStdOut
#!/usr/bin/env python3 # kkmoom_pc_writeup.py # ------------------------------------------------------------- # 1️⃣ Extract the .rar → pc.exe # 2️⃣ Dump the first‑stage packed payload (RVA 0x403000) # 3️⃣ Decompress it with the custom LZ‑type routine # 4️⃣ Dump the second‑stage PE (payload.bin) # 5️⃣ Locate the encrypted blob and XOR key in .rdata # 6️⃣ Decrypt → flag # -------------------------------------------------------------
def get_rva_to_offset(pe_path, rva): # Use pefile to translate import pefile pe = pefile.PE(pe_path) return pe.get_offset_from_rva(rva)
if __name__ == '__main__': packed = open('payload.packed', 'rb').read() unpacked = decompress(packed) open('payload.bin', 'wb').write(unpacked) Running the script produces payload.bin (~13 KB). The file starts with the header again – the packer is nested : the decompressed payload is a second PE executable. 5. Second‑Stage PE – The Real Target file payload.bin # payload.bin: PE32 executable (GUI) Intel 80386, for MS Windows We repeat the same analysis steps on payload.bin . 5.1. Quick string hunt strings -a -n 5 payload.bin | grep -i flag # → No direct flag string, but we see: # "You think this is easy? Think again." 5.2. Import Table inspection r2 -A payload.bin [0x00401000]> iij # The imports are minimal: kernel32.dll (VirtualAlloc, WriteFile, ExitProcess) # No obvious network calls. 5.3. Locate the main routine The entry point ( 0x00401000 ) now points to a standard mainCRTStartup . We follow the call chain: