Signal 02 was the hunt: an odd packet on the wire that said “Meow.” This is the blue-team ending — turning that 2003 DCOM/RPC exploit (CVE-2003-0352 / MS03-026, the Blaster hole) into a detection you could ship. The exploit left three things it couldn't hide. You key on all three.
A DCOM activation that carries this exploit has to be well-formed enough for the RPC service to parse it — and that well-formedness is the tell. Four byte-patterns survive every string-edit and mass-rooter variant:
000001a0-…-c000-…-46 appears on the wire little-endian as a0 01 00 00 … c0 00 00 00 00 00 00 46. Legitimate RemoteCreateInstance traffic to 135 is rare on most hosts — this GUID narrows the field hard.4d 41 52 42 (“MARB”) marshals the interface pointer; 4d 45 4f 57 (“MEOW”) prefixes every encoded object reference. MEOW is in all object-bearing RPC — so on its own it's weak. It's a confirmer, not a trigger.\\server\share path, UTF-16LE on the wire: 5c 00 5c 00 then a name far past 32 bytes. Length + location is the real signal.90 90 90… padding the landing zone before the jump. A sled inside a path field has no legitimate reason to exist — a near-certain giveaway.A reconstructed MSRPC request to TCP 135. Pick a sample, then run the signature: it scans the bytes for the four fingerprints, highlights each where it lands, and emits the alerts a sensor would. The benign RPC bind should come back clean — that's the part that keeps you from paging the on-call at 3am over normal traffic.
The scan above is these rules, by hand. A two-stage Suricata signature keys the cheap, specific thing first (the GUID bind) and confirms with the payload shape, so the expensive content match only runs on traffic already headed for the RPC activator:
# stage 1 — the targeted interface bind (cheap, specific) alert tcp any any -> $HOME_NET 135 ( \ msg:"DCERPC ISystemActivator bind (MS03-026 attack surface)"; \ flow:to_server,established; \ content:"|05 00 0b|"; depth:3; ; RPC v5 bind \ content:"|a0 01 00 00 00 00 00 00 c0 00 00 00 00 00 00 46|"; distance:0; \ reference:cve,2003-0352; classtype:attempted-admin; sid:1000026; rev:1; ) # stage 2 — the payload shape: MEOW object ref + UNC path + NOP sled alert tcp any any -> $HOME_NET 135 ( \ msg:"DCERPC RemoteCreateInstance long UNC + NOP sled (Blaster/MS03-026)"; \ flow:to_server,established; \ content:"MEOW"; \ content:"|5c 00 5c 00|"; distance:0; ; \\ in UTF-16LE \ content:"|90 90 90 90 90 90 90 90|"; ; sled in the path \ reference:cve,2003-0352; classtype:attempted-admin; sid:1000027; rev:1; )
And the Zeek equivalent, for the same GUID on the same port — Zeek then logs the connection so the match carries its own evidence:
signature dcom_isystemactivator { ip-proto == tcp dst-port == 135 payload /\x05\x00\x0b.{0,64}\xa0\x01\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46/ event "DCOM ISystemActivator bind (MS03-026 surface)" }
This exact rule was real in 2003, and it would miss plenty today. That's the lesson, not a flaw:
content match drifts. NFR watched this happen in real time as mass-rooters rolled in — which is why they moved from "find the shellcode" to tracking connection state.ISystemActivator bind, then confirmation the server accepted it, then the suspicious path in a follow-up — so it fired on real exploitation and stayed quiet on rejected or garbage traffic. Flow state is what kept the false-positive rate survivable.Next: Lab 6 — memory forensics: the sled landed somewhere, and the one place an implant must become real is RAM.