Writing a Suricata rule for the double-letter alliterative C2 URL pattern

Following up on the Gamaredon URL-pattern observation from November — turning it into an actually-shippable Suricata rule, with false-positive notes.

Following up on the November post about UAC-0010 / Gamaredon’s bare-IP plain-HTTP beacon URL pattern, I spent a couple of January evenings tightening up a Suricata rule that catches the shape of the path without hard-coding the operator’s specific verb list. Here’s the writeup.

The pattern, restated

Pterodo HTML / VBS implants from late-2024 onwards beacon to URLs of the form:

http://<bare-IPv4>/<verb><suffix>?-<DD>-<MM>

Where:

The rule

alert http any any -> any any (
    msg:"GAMAREDON Pterodo bare-IP beacon URL (alliterative path + DD-MM date)";
    flow:established,to_server;
    http.method; content:"GET";
    http.host; pcre:"/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:80)?$/";
    http.uri; pcre:"/^\/[A-Z][A-Za-z]{2,7}-\d{2}-\d{2}\/?$/";
    classtype:trojan-activity;
    sid:9001502;
    rev:2;
    metadata:mitre T1071.001 T1568.002;
    reference:url,cert.gov.ua/article/...;
)

The two pcre clauses are the meaty bit:

I deliberately did NOT enumerate the specific verb list (Svvr, SSsr, etc.) — operators rotate verbs across campaigns, and a rule keyed on a fixed list would fail closed on the next rotation. Better to match the path shape and accept some false-positive volume.

False-positive notes

Things this rule will fire on that aren’t Pterodo:

Tuning

In my home-lab (the Suricata-elk-lab Docker-Compose I shipped with my BSc thesis support repo), the rule fires on:

So in a low-noise environment, false positives look like zero. In a real SOC the actual answer depends on your environment — please tune before deploying.

Coverage gaps

Things this rule misses:

Usefulness in context

For a small SOC (Brights-sized, ~50 staff) the rule is essentially free to run. The bare-IP HTTP outbound is rare enough in modern enterprise that it’s a high-confidence alert on its own; combining with the URI regex makes it specific to the Pterodo shape. Cumulative behavioural scoring makes this stronger — if a workstation also recently downloaded an HTML attachment with a Scan_X_Y_Z_NNNN name, you have a high-confidence Gamaredon detonation.

(Caveat: I’m a junior. This is rule-writing as a learning exercise, not as production guidance from someone with a decade of detection engineering. Run any rule through your own tuning loop before trusting it in alerts.)

Thanks

To Florian Roth’s signature-base project for being the canonical example of “how to structure a public-facing detection rule”. Most of the formatting choices here are imitations of his.