arrow_backUS Cyber Games 2026
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

  1. Triage the capture. The workstation is 10.10.13.37, everything is HTTP. A steady ~60 s beacon goes to telemetry-edge-eu.cdnflare-stat.net (185.93.187.42): many GET /api/5f3a9c11d4e84b2a/idle, one POST .../hello, a few POST .../result. cdnflare-stat.net is 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
    
  2. POST bodies carry cfg=<b64> (registration) and data=<b64> (beacons). Base64-decoding gives high-entropy bytes with a shared prefix, pointing at repeating-key XOR. The bot id 5f3a9c11d4e84b2a is in both URL and body, so XOR the guessed prefix {"id":"5f3a9c11d4e84b2a" against the ciphertext to recover the 8-byte key Ar3s_C2! (Ares C2).
  3. Decrypt the registration cfg (base64-decode, then XOR Ar3s_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"}
    
  4. 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. The chart.js hex comments, collectr.io/px?cid= pixels, and fake .webp/.woff2 blobs are decoy cover noise.
  5. Fetch the staged manifest and apply the reused key:
    curl -sL "http://ctfchallenge.on-forge.com/update/manifest.json" -o manifest.raw
    
    import 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}