§ SC

Silent Ransom Group Went Fast Flux. The Detection Trips Over Akamai Before It Finds the Botnet

Silent Ransom Group’s current operations are a phone call, not a payload — though the crew did deploy LOCKBIT.BLACK ransomware back in 2022 before pivoting to data-theft-and-extortion only. Tracked as Luna Moth, Chatty Spider, and UNC3753 depending on whose feed you read, the group has run callback phishing against US law firms since spring 2023, and the FBI’s FLASH advisory on May 26, 2026 spelled out the playbook again: an invoice-themed email, a phone number, a friendly voice claiming to be IT, and a few minutes later someone in billing has installed a legitimate RMM tool and handed over a screen-share. In recent Mandiant-tracked cases the data search, staging, and theft begins inside an hour, and the extortion email often lands within 30 minutes of the operator backing out. There is no malware to hash, no exploit to patch, nothing for the EDR to chew on until the remote-access session is already live.

So when Resecurity reported in early June 2026 that SRG had moved its staging and leak-site infrastructure onto DNS fast flux, the interesting question for a SOC isn’t how do I stop the phone call — you don’t, not at the DNS layer. It’s whether you can catch the tail of the operation: the leak-site and staging infrastructure the group now hides behind rotating residential IPs. The honest answer is yes, partially — and with a hard limit worth stating up front. SRG exfiltrates through legitimate channels (WinSCP, Rclone, Google Drive, OneDrive, browser uploads, sometimes removable media), so this analytic surfaces resolution of SRG’s leak-site and staging domains, not the initial RMM session and not the cloud-storage exfil path itself. The detection that does it is one of the easiest analytics to write and one of the hardest to actually run without burying your analysts.

In Resecurity’s own tracked dataset, law firms accounted for almost a quarter of ransomware-related incidents in Q1 2026 — which by their count would put legal fourth among targeted verticals. Treat that as a vendor dataset, not an industry-wide census; the denominator isn’t published. The measurement that matters for detection is Resecurity’s own: they traced SRG’s rotation across more than twenty compromised consumer hosts spanning 18 countries and 22 ISPs, with two domains, ep6pheij[.]com and business-data-leaks[.]com, cycling their A records through that pool. No datacenter IPs. Every node a residential or small-ISP address. That last detail is the whole ballgame for detection, and I’ll come back to it.

Single flux, double flux, and why this one is annoying

Fast flux is old. MITRE files it under T1568.001 (Dynamic Resolution: Fast Flux DNS), and NSA, CISA, the FBI, and partners in Australia, Canada, and New Zealand put out joint advisory AA25-093A in April 2025 calling it a national-security-grade defensive gap in many networks — a polite way of saying a lot of shops can’t see it at all.

The mechanism is simple. A single domain resolves to a large, rotating set of IP addresses, each backed by a compromised host acting as a reverse proxy to the real server. Single flux rotates the A records: same domain, new IPs every few minutes, TTLs often pushed down under 300 seconds so resolvers don’t cache. Double flux adds rotation at the NS layer too, so the authoritative name servers themselves move, which makes takedown and sinkholing genuinely painful because there’s no stable anchor to seize.

What makes the SRG case annoying specifically is the residential sourcing. A botnet built on datacenter VPS instances is comparatively easy to spot — the IPs all land in a handful of hosting ASNs you can score on reputation. SRG’s nodes are spread across consumer broadband across two dozen ISPs on five continents. That degrades geofencing and IP-reputation controls, and slips past them entirely when a node lands in a geography you already allow — a related but distinct problem from ORB (operational relay box) egress, which is its own layer and its own post. Naive IP reputation fails too, because residential space is mostly “unknown/clean” in commercial feeds. You’re not going to block your way out of this with a threat-intel list. The novel domains won’t be on one until somebody reports them, and by then the rotation has moved.

What it looks like in the DNS logs

The detection signal lives in resolver telemetry, and the quality of your answer is capped by where you collect it. Best case you have Zeek dns.log off a tap (Corelight or rolled yourself), which gives you query and the answers array per response. Otherwise it’s Windows DNS Analytical logging via the Microsoft-Windows-DNS-Server/Analytical ETW channel (off by default — you have to enable it on Server 2012 R2 or later before it logs a thing), or your protective-DNS vendor’s export (Umbrella, Infoblox BloxOne, DNSFilter), or PAN DNS Security logs, which carry the DNS transaction detail you need — plain traffic logs are session records (even scoped to app=dns) and won’t reliably give you the full answer set, and URL-filtering logs won’t carry it at all. Each is messier than the last.

The core analytic is a per-domain aggregation over a rolling window: how many distinct IPs did this name resolve to, and — the part that matters — how many distinct ASNs do those IPs belong to. In Splunk against a Zeek sourcetype it’s roughly:

sourcetype=zeek:dns rcode_name=NOERROR (qtype_name=A OR qtype_name=AAAA) answers=*
| eval q=lower(rtrim(query,"."))
| bin _time span=24h
| mvexpand answers
| where match(answers,"^\d{1,3}(\.\d{1,3}){3}$") OR match(answers,":")
| lookup asn_lookup ip AS answers OUTPUT autonomous_system AS asn
| stats dc(answers) as ip_count dc(asn) as asn_count values(asn) as asns by q, _time
| where asn_count > 8 AND ip_count > 12

A few things in there earn their keep. bin _time span=24h makes the window explicit — don’t lean on the Splunk time picker for a reusable detection, or the threshold means something different on every search. eval q=lower(rtrim(query,".")) normalizes case and the trailing dot so Example.COM. and example.com don’t split into separate groups. Gating on rcode_name=NOERROR with qtype_name=A/AAAA keeps SERVFAIL/NXDOMAIN noise and cached CNAME chains out of the counts. The where match(...) line drops any non-address record that still slips through before enrichment, and the ASN comes from a lookup table (MaxMind ASN, ip2asn, whatever you maintain) — not from iplocation, which only gives you geo. The thresholds are illustrative, not gospel — asn_count > 8 over a 24-hour window is a reasonable starting line for an enterprise resolver, and you will move it. Low TTL is a supporting signal, not the trigger; flag responses with A-record TTLs under ~300 seconds as a contributing feature, but don’t gate on it, because plenty of legitimate infrastructure runs aggressive TTLs. One portability note: this SPL is Zeek-shaped. Windows DNS Analytical logs carry the same facts, but pulling the answer set and TTLs out of them is materially messier, and the query won’t port cleanly without reshaping that extraction.

If you trigger on TTL and raw IP count alone, here’s what you get on day one.

Noise. A wall of it.

The CDN problem, which is where most of these rules die

Akamai can resolve to dozens of IPs with a short TTL, and plenty of other large services behave similarly — Fastly, CloudFront, Google, Microsoft 365, ad exchanges, telemetry endpoints, your own GeoDNS load balancers — though the answer-set size and TTL vary by provider (a Cloudflare-proxied record, for one, often returns a small stable set, not an Akamai-style rotating wall). By the dumb metric — many IPs, short TTL — a lot of them look exactly like fast flux. A first-pass rule built on those two features alone will hand your tier-1 a few hundred “fast flux” hits a day, all of them *.akamaiedge.net and *.cloudfront.net, and the rule will be muted by Thursday. That’s the failure mode, and it’s nearly universal the first time someone builds this.

The discriminator that actually separates a CDN from a botnet is ASN dispersion against ASN type. A CDN returns many IPs, but they all sit inside a small, stable set of that provider’s own networks: Cloudflare is AS13335, Akamai is AS20940 and friends, Amazon is AS16509/AS14618, Google AS15169, Fastly AS54113, Microsoft AS8075. Many addresses, few ASNs, and all of them hosting/CDN ASNs. SRG’s pool is the inverse — a comparable IP count smeared across twenty-plus unrelated eyeball ASNs: a Brazilian cable provider, an Argentine telco, a Bulgarian broadband ISP, all answering for the same domain. That pattern is rare in legitimate service delivery: a domain answering across unrelated residential eyeball ASNs with no CDN chain behind it is high-signal. Legitimate services don’t spread one name across a Brazilian cable provider and a Croatian DSL pool without a CDN in the path.

So the tuning that makes the rule usable is two lookups and a chain walk, not one:

  • A CDN/cloud ASN allowlist you suppress on. Maintain it as a lookup table, seed it from the obvious dozen, and expect to add to it for a couple of weeks as new SaaS shows up.
  • An ASN-type enrichment so you can score whether the dispersed ASNs are hosting/CDN networks (probably fine) or consumer/broadband networks (the SRG tell). Note that the ASN number and org name come from MaxMind/ip2asn, but the type — hosting versus eyeball — does not; you build that classification yourself from PeeringDB, CAIDA’s AS Rank, or a curated overlay, and it’s a data-prep step in its own right. The reverse-DNS strings help here too; residential PTRs are full of dsl, dynamic, broadband, cable, and the IP embedded in the hostname.
  • A CNAME-chain walk before you score. Resolve to the terminal A/AAAA and suppress when the chain lands on a known CDN parent — akamaiedge.net, cloudfront.net, fastly.net, trafficmanager.net, azureedge.net. This catches the one case the ASN logic alone misses: Akamai and Google embed caches inside ISP eyeball networks, so their serving IPs can land in consumer ASNs and look dispersed. The CNAME is what gives them away when the ASN doesn’t. Treat the chain walk as one suppression feature, not a definitive CDN oracle: it misses apex-domain CNAME flattening / ALIAS records, HTTPS/SVCB answers, partial chains served from cache, and vendor logs that don’t preserve the full chain.

Layer domain age on top if you have it — a freshly registered domain resolving across scattered eyeball ASNs is about as high-signal as this gets — but don’t lean on it as decisive. Resecurity’s WHOIS shows the two named SRG domains were registered back in early 2024, so by the time this campaign surfaced they were well over a year old; “newly registered” would not have flagged them. And treat absence from the Tranco/Umbrella top-1M as FP-reduction only. A domain not being popular is not evidence of anything; SRG’s domains won’t be on the list, but neither will half your legitimate long-tail.

Even after all that, you will still chew through false positives from a few specific sources: dual-stack CDNs that haven’t made your allowlist, dynamic-DNS services your developers use (DuckDNS and friends rotate aggressively and legitimately), NTP pool members, and peer-to-peer clients if anyone’s running them. Budget the first week for carving those out. In my experience a clean enterprise tends to settle into the low single digits per day after tuning — but that’s field anecdote, not a benchmark; your real floor depends on your CDN footprint and how clean your asset tagging is. Most of what survives should be worth a look.

Where the visibility actually breaks

Here’s the part the vendor demos skip. The analytic above only sees DNS that traverses a resolver you log. In 2026 that’s a shrinking fraction of the traffic.

Endpoints doing DoH or DoT straight to 1.1.1.1 or 8.8.8.8 are invisible to it. Firefox turns DoH on by default in some regions (it still honors the use-application-dns.net canary domain and enterprise policy), Chrome will use it opportunistically, and any malware author who isn’t asleep is resolving over HTTPS to bypass exactly this telemetry. If you haven’t blocked outbound 853 and forced DoH through your own resolver — or at least denied known public DoH endpoints at the egress firewall — your fast flux analytic has a hole in it the size of the actual threat. That’s an SC-7 boundary problem you have to solve before the SI-4 detection means anything. Most shops have it half-closed: 53/udp is forced to the internal resolver, but 853 (DoT) and DoH-over-443 are not. Check yours. Grep your egress rules for a port-853 deny — and confirm the denylist of known public DoH endpoints on 443 actually exists, because a port block alone never catches DoH, which rides 443 alongside everything else. Better still, bias toward an allow-only egress model — resolution permitted to your own resolvers and denied everywhere else — rather than chasing a denylist, because Encrypted Client Hello increasingly conceals the SNI that any 443-based block depends on.

Then there’s volume. A mid-size enterprise resolver does tens of millions of queries a day, and you cannot ASN-enrich that firehose at ingest on a normal Splunk license without lighting your indexing budget on fire. The workable architecture is a scheduled summary search: roll up distinct-IP-and-ASN-per-domain on, say, a 15-minute or hourly cadence into a summary index, enrich only the candidate domains that clear a coarse pre-filter, and keep 90 days of those rollups while raw DNS stays hot for maybe 7 to 14. Trying to retain raw resolver logs hot for 90 days to support this is how you end up explaining a license overage.

Minor, but it bites: if you’re correlating IP rotation across a window, host clock skew between your resolver and your indexers will smear the window edges. Use the resolver’s event time, not index time, for the aggregation, or a domain that rotates right at a bucket boundary will split across two windows and under-count.

What it maps to, and what it doesn’t catch

For the control narrative, this lands across a predictable set of families. SI-4 owns the anomaly detection itself. AU-12 and AU-6 are the prerequisite and the follow-through: DNS query logging has to be generating the events, and somebody has to review what the analytic surfaces. SC-7 is the egress control that closes the DoH bypass and forces resolution through monitored infrastructure. SC-20 through SC-22 cover the secure-name-resolution architecture — trusted recursive resolvers, DNSSEC where it applies, the resolver design that gives you a single chokepoint to instrument in the first place. CA-7 if you’re folding it into continuous monitoring, IR-4 and IR-5 once a hit turns into pivot-and-contain, RA-5 if you’re scoring the exposure.

But map it honestly. Fast flux detection is a tail control. It catches SRG’s leak-site and C2 infrastructure after a human already installed the remote-access tool, which means the front door — the callback-phishing vector — closed behind the attacker an hour before your DNS analytic has anything to say. The high-value outcome isn’t prevention; it’s catching the rotating-domain beacon during the dwell window, blocking the exfil and extortion channel, and pivoting from one flagged domain to every host that resolved it. That’s a real win. It is not the same as stopping the breach, and anyone selling fast flux detection as front-line ransomware prevention is selling the wrong control for this actor.

CISA called on protective-DNS providers to build better fast flux analytics because, as of that advisory, they mostly hadn’t. Don’t assume your PDNS vendor catches the novel domain. Build the ASN-dispersion analytic yourself, tune it against your own CDN footprint, and treat the vendor feed as the floor, not the ceiling.

Sources