TI-2026-095D โ The Equifax Ghost: One DigitalOcean Droplet per Host, Nine Years On
Classification: HIGH ยท Forensic threat intelligence ยท Web-threats vector ยท Series: Below the Noise Floor
In 2017 a single unpatched Apache Struts server let attackers walk out of Equifax with 147 million people's records. The flaw was CVE-2017-5638, it scored 9.8, it went straight onto every "patch this now" list on earth, and the security world moved on. Nine years later it is still being thrown โ not by a lone straggler, but by a coordinated fleet of 66 DigitalOcean droplets, one assigned to each host in a homelab's published estate, 59,318 times across two months. This is the story of a ghost: an exploit so old it has fallen below the attention floor, and a campaign that lives in exactly that blind spot.
1. A Different Kind of Hiding
The earlier entries in this series hid by rarity โ a single tunnel-scout session in a login flood, sixteen offensive edges in a 92,000-edge exposure map. This one is the opposite. It is loud: 66 source IPs, tens of thousands of requests, sustained for two months, sweeping an entire estate. And yet it hides just as effectively, because it hides along a different axis: age.
CVE-2017-5638 is nine years old. It is on the CISA Known Exploited Vulnerabilities catalog. It is patched in every supported release, it runs in no modern application, and any competent defender "knows" it is dead. That certainty is the cover. A scanner throwing a 2026 zero-day gets attention; a scanner throwing a 2017 Struts payload gets filed as background radiation โ the internet's ambient hum of ancient, harmless probes. The campaign in this dossier is built on the bet that nobody is really looking at the old stuff anymore. It is right often enough to be worth 66 rented droplets.
That is what "below the noise floor" means here. Not below the volume threshold โ this is well above it. Below the attention threshold: beneath the line where a defender bothers to look.
2. The Exploit โ Why It Still Matters
CVE-2017-5638 โ Apache Struts2 Jakarta Multipart parser OGNL RCE (S2-045). Struts 2's file-upload parser mishandles a malformed Content-Type (or Content-Disposition / Content-Length) header. Instead of rejecting it, the parser evaluates an OGNL expression embedded in the header โ and OGNL can reach java.lang.Runtime. So a single crafted HTTP header, unauthenticated, executes arbitrary commands on the server. The in-the-wild March-2017 payload wrapped a #cmd= string in the Content-Type; within days it was mass-exploited, and by September it was the confirmed entry point for the Equifax breach.
CWE-755 (improper handling of exceptional conditions). CVSS 9.8. On the CISA KEV list โ the government's canonical "being actively exploited, patch immediately" register. This is not an obscure bug; it is one of the most consequential web vulnerabilities of the decade.
And its age is precisely what keeps it economically alive for an attacker. The internet's installed base never fully patches. Somewhere out there are forgotten Struts apps behind forgotten load balancers, and a decade-old OGNL request costs the attacker nothing to fire. The expected value of throwing CVE-2017-5638 at ten thousand hosts is not zero โ it is one or two ancient boxes that still answer. The long tail of un-patching is what turns a "dead" CVE into a permanent, low-cost lottery ticket.
3. The Fleet โ 66 Nodes, One Provider
The web-threats CVE-correlation engine records the campaign in full. Queried through the platform's new per-CVE actors endpoint:
| Measure | Value |
|---|---|
| Distinct source IPs | 66 |
| Total exploit hits | 59,318 |
| Method | GET (Struts action endpoint, /login.action and variants) |
| Match score | 0.88 (path-derived, consistent across all 66) |
| Window | first seen 2026-06-05 โ last seen 2026-07-23 |
| Origin | 100% DigitalOcean (AS14061) |
Every single node is a DigitalOcean droplet. There is no spread across bulletproof hosting, no residential proxies, no geographic scatter to complicate attribution โ one mainstream, US-registered IaaS provider, rented by the hour. Verified on the heaviest thrower, 167.172.232.142: ASN AS14061 (DIGITALOCEAN-ASN, DigitalOcean, LLC, US), threat score 83, abuse 100, already MikroTik-banned and carrying 16 CrowdSec decisions, clustered by the platform into a "Burst 2026-06-23 AS14061" campaign. Its user-agent is l9scan/2.0 โ the string used by LeakIX, the internet-wide exposure scanner โ but the platform classes that identity unverifiable, and for good reason: a rented droplet can borrow a well-known scanner's user-agent for free, wearing benign-research colours over a hostile sweep. Whether this is LeakIX-style unsolicited scanning or an actor hiding behind its name, the behaviour against the estate is a broad exploit-path sweep, and CVE-2017-5638 is one signature in it.
The single-provider concentration is itself a finding, and it cuts two ways. It makes the campaign cheap to reconstitute โ burn a flagged droplet, spin up another in the same /20 โ but it also makes it maximally attributable and takedown-tractable: there is exactly one abuse desk to notify, and the nodes are already blocked locally. The operator traded attributability for elasticity, which is the standard economics of a commodity cloud sweep.
4. The Signature โ One Droplet per Host
The most telling detail is not the volume or the provider. It is the assignment.
Line up the 66 IPs against the hosts they hit, and a one-to-one map falls out. 142.93.143.8 โ turn.shuffle-on.com. 167.99.181.249 โ mail.sonatural.life. 138.68.82.23 โ lsn-pma.shuffle-on.com. 159.89.127.165 โ lsn-registry.shuffle-on.com. 167.172.158.128 โ lsn-nas1.direct.quickconnect.to. 143.244.168.161 โ lsn-nas2.... 165.227.84.14 โ portainer.shuffle-on.com. 206.81.24.74 โ lsn-vault.shuffle-on.com. 164.92.244.132 โ mcp.shuffle-on.com. And on, and on โ through lsn-qdrant, lsn-jupyter, lsn-storage, lsn-photos, lsn-ai, lsn-ragflow, lsn-trivy, lsn-wireguard, lsn-webmail, lsn-classroom, lsn-netdata, lsn-images, pastebin, peertube, registry, web-offline, shuffle-on.com itself โ essentially the entire published surface of the estate, one rented droplet per subdomain.
That pattern does not happen by accident. Sixty-six independent scanners hitting a target would pile up on the popular hosts and leave the obscure ones untouched; you would see overlap and skew, not a clean partition. A clean one-IP-per-host partition across dozens of subdomains means the target list was enumerated first and then distributed โ the operator discovered the estate's subdomains, split them across the fleet, and assigned each droplet its slice. The Burst 2026-06-23 AS14061 campaign tag is the platform's independent confirmation that these nodes fired as one.
So this is not ambient scanning. It is a list-driven, coordinated campaign, and the coordination is legible in the assignment map long before you read a single request header. The whole estate, methodically, one ghost per door.
5. What It Actually Hit โ and Didn't
Honesty about impact. These are attempts, not compromise. The LSN hosts are Traefik-fronted and Authelia-guarded, and not one of them runs Apache Struts โ the OGNL header lands on services that have never heard of it, and the 404/401 responses in the telemetry confirm nothing executed. A GET to /login.action on a homelab that runs no Java web stack is a knock on a door that isn't there.
But the finding is not "we were breached" โ it never claims that. The finding is the coordinated attempt: 59,318 exploit requests, aimed at real hosts, distributed across a rented fleet, sustained for two months, still arriving. It is a standing IOC set (66 IPโhost pairs), a demonstration that a decade-old KEV CVE still commands campaign-scale infrastructure, and a live example of the assignment tradecraft. The value is in reading the shape of the thing, not in a body count.
6. The Counter-Narrative
Steelman: "This is the most boring finding imaginable. It's LeakIX โ a legitimate research scanner โ hitting a nine-year-old CVE that nothing runs, getting 404s. Sixty-six DigitalOcean IPs throwing /login.action at the whole internet is Tuesday. There is no threat and barely a story."
Each clause has some truth, and the finding survives them:
- "It's just LeakIX." The user-agent says
l9scan; the platform says that identity is unverifiable. A benign scanner's UA is a free costume, and a hostile fleet wearing it is a documented pattern, not a paranoid one. More to the point, whether the label is real or borrowed does not change the shape โ a coordinated, list-driven, one-droplet-per-host sweep of a specific estate is not what an internet-wide research crawler produces; research scanners hit everyone's/, not each of your subdomains with a dedicated node. - "Nine-year-old CVE, nothing runs it." That is the thesis, not a rebuttal. The age is why it is viable: unattended, unmonitored, and occasionally landing on the one forgotten Struts box in ten thousand. A KEV CVE does not stop being exploited because you patched yours.
- "Just 404s." Correct, and stated plainly (ยง5). The claim is the coordinated attempt and its tradecraft, not a compromise. A campaign that fails against a hardened target is still a campaign, and its assignment pattern is intelligence regardless of outcome.
What is not claimed: attribution to a named operator (single-provider, UA unverifiable โ the anchor is DigitalOcean's abuse desk, not a person); that any host was compromised (none was); or that the fleet's only interest is Struts (its top-paths sweep spans /actuator/env, /.git/config, /.env, the Atlassian Jira pom.properties probe โ Struts2 is one signature among many in a broad exploit-path scan).
Confidence: HIGH that 66 DigitalOcean nodes ran a coordinated, one-droplet-per-host CVE-2017-5638 sweep of the LSN estate over JuneโJuly 2026; MEDIUM on operator identity and on the LeakIX label; impact is explicitly attempts, not compromise.
7. Defence Response
- Do not de-prioritise ancient KEV CVEs. The instinct to filter a 2017 Struts probe as noise is exactly the blind spot this campaign occupies. Age is not obsolescence for an attacker; the CISA KEV list is a "still being exploited" register, not a history book. Keep the old signatures live.
- Report the fleet โ it is one abuse desk. All 66 nodes are DigitalOcean (AS14061). A single abuse report to
abuse@digitalocean.comcovers the whole campaign, and the droplets are already MikroTik-banned and CrowdSec-listed locally. Single-provider origin is the defender's leverage here, not the attacker's. - Read the assignment, not just the request. The one-droplet-per-host map is a higher-order detection than any single
/login.actionGET. If your telemetry can group source IPs by the host each one exclusively targets, a clean partition of your subdomains across distinct IPs is a coordinated-campaign alarm that fires before you inspect payloads. - Front everything, run no Struts. The reason this landed on nothing is the reason it should: every host behind Traefik/Authelia, no legacy Java web framework exposed. The exploit is only dangerous to the box that still speaks OGNL โ so make sure none of yours does.
8. A Note on Method
This dossier was assembled entirely through the web-threats MCP layer, with no direct database access โ using a new per-CVE actors capability (wt_cve_actors / GET /api/web-threats/cves/{cve}) added to the platform this session, plus dossier_web_threats_intel for node enrichment. The honeypot and entity-graph CVE tools (honeypot_cve_actors, sec_intel_cve_dossier) return nothing for CVE-2017-5638 โ they cover SSH posture and the entity graph's promoted targets edges only, and Struts2 lives purely on the web (L7) vector. The gap that used to force a raw SQL query for "who is throwing CVE-X at us?" is now a first-class MCP tool, and this is its first published use.
9. Investigation Metadata
| Field | Value |
|---|---|
| Dossier ID | TI-2026-095D |
| Series | Below the Noise Floor (part 4) |
| CVE | CVE-2017-5638 โ Apache Struts2 S2-045 OGNL RCE ยท CVSS 9.8 ยท CISA KEV ยท the Equifax flaw |
| Fleet | 66 IPs, 100% DigitalOcean (AS14061); 59,318 hits; 2026-06-05 โ 2026-07-23 |
| Signature | One droplet per host โ the fleet partitions the entire LSN estate across distinct nodes |
| Targets | turn/mail.sonatural.life/lsn-pma/registry/lsn-nas1+2/portainer/lsn-vault/lsn-qdrant/mcp/peertube/lsn-webmail/โฆ (whole estate) |
| Identity | UA l9scan (LeakIX) โ classed unverifiable; MikroTik-banned, CrowdSec-listed, "Burst 2026-06-23 AS14061" |
| Impact | Attempts only โ hosts are Authelia-fronted and run no Struts (404/401) |
| Method | Built entirely via the web-threats MCP layer (new wt_cve_actors endpoint) โ no direct SQL |
| Cross-reference | TI-2026-095C (PHPUnit/Laravel/ThinkPHP weaponizers), TI-2026-095B (Tunnel Scout) |
| Confidence | HIGH (fleet, coordination, CVE); MEDIUM (operator identity, LeakIX label); impact = attempts, not compromise |
Cristian Liศneanu ยท shuffle-on.com ยท Threat Intelligence