Forensicseasy
Portion 2 (Around The World)
by Pavel Knespl (capyplivl)
About two hours of one workstation's cleartext HTTP traffic. Most is ordinary browsing; one host is an Ares C2 beacon disguised as CDN telemetry. Recover its repeating-key XOR key from known plaintext, read the config, and follow the staged manifest URL to the flag.
Solve
- Triage the capture. The workstation is
10.10.13.37, everything is HTTP. A steady ~60 s beacon goes totelemetry-edge-eu.cdnflare-stat.net(185.93.187.42): manyGET /api/5f3a9c11d4e84b2a/idle, onePOST .../hello, a fewPOST .../result.cdnflare-stat.netis a Cloudflare typo-squat, the tell.tshark -r portion2.pcap -q -z conv,ip tshark -r portion2.pcap -Y http.request -T fields -e ip.dst -e http.host -e http.request.uri - POST bodies carry
cfg=<b64>(registration) anddata=<b64>(beacons). Base64-decoding gives high-entropy bytes with a shared prefix, pointing at repeating-key XOR. The bot id5f3a9c11d4e84b2ais in both URL and body, so XOR the guessed prefix{"id":"5f3a9c11d4e84b2a"against the ciphertext to recover the 8-byte keyAr3s_C2!(Ares C2). - Decrypt the registration
cfg(base64-decode, then XORAr3s_C2!):import base64 key = b"Ar3s_C2!" raw = base64.b64decode(cfg_b64) print(bytes(c ^ key[i % 8] for i, c in enumerate(raw)).decode()){"id":"5f3a9c11d4e84b2a","campaign":"RAVENGLASS","host":"WIN-DSK-FIN03", "user":"j.dvorak","c2":"http://ctfchallenge.on-forge.com","interval":60, "stage":"http://ctfchallenge.on-forge.com:80/update/manifest.json", "note":"key reused for stage manifest"} - The beacons only say
{"r":"idle"}/{"r":"ok"}and every reply is{"status":"ok","task":null}, so the flag is not in the capture. The config points at a staged manifest that reuses the same key. Thechart.jshex comments,collectr.io/px?cid=pixels, and fake.webp/.woff2blobs are decoy cover noise. - Fetch the staged manifest and apply the reused key:
curl -sL "http://ctfchallenge.on-forge.com/update/manifest.json" -o manifest.rawimport base64 key = b"Ar3s_C2!" raw = base64.b64decode(open("manifest.raw").read().strip()) print(bytes(c ^ key[i % 8] for i, c in enumerate(raw)).decode()){"campaign":"RAVENGLASS","build":"4.2.1","tasks":[], "flag":"SVIUSCG{b34c0n_4r0unD_th3_w0rLd}"}
Flag: SVIUSCG{b34c0n_4r0unD_th3_w0rLd}