The Same Scanners Phone Home
In Part 1, 216 sources crossed the line between our IT and our OT decoys. Here we take the ones that hit the most decoys and ask a simpler question: who are they, and are they connected? Most of them turned out to be scanners — but the exposed databases they surfaced in are genuinely compromised.
How we did it
From Part 1 we had a ranked list of the sources that crossed the IT/OT line, ordered by how many distinct decoys each one touched. Before doing anything with it, we scrubbed it. First we removed our own internal artifacts, the fleet's management and self-test traffic, which is exactly the kind of thing that inflates a count if you do not catch it. Then we set aside two addresses on a single hosting block that belong to a legitimate internet-measurement company, plus one lone SSH box that did not match anything else.
The arithmetic is worth stating plainly. Of the 216 crossers, we worked from the most prolific by decoy count, which came to thirteen external addresses once our own artifacts were removed. Setting aside the two research scanners and the one outlier just described left ten. We looked each of the ten up in Shodan, to see what services it runs and what it connects to, and VirusTotal, for independent reputation. Every one of the ten is flagged malicious by multiple security vendors. Nine of them appeared to resolve into one operation. The tenth advertised itself as something else, and it turned out to be the key to re-reading the other nine; we come back to it below.
What we found: two compromised datastores, and a roster we could not read
The nine split across two cheap-hosting providers: four on Amazon's cloud in the US-East region, and five on Linode, now Akamai Connected Cloud. Both groups surfaced in the client lists of the same exposed datastores, which is what first made them look like one fleet. They are not one fleet.
The Amazon nodes speak Redis. Each shows up in the connected-clients list of a large population of exposed Redis servers, databases left open to the internet on port 6379 with no password. Those Redis servers share a common profile: they run on Windows, using the same widely-circulated unofficial Windows build. Redis has no official Windows port, so nearly everyone who runs it on Windows pulls the same prebuilt binary, which is why they carry an identical redis_build_id a4f7a6e86f2d60b3. That uniformity is expected rather than remarkable, and we do not lean on it as evidence. What it gives us is a clean way to size the pool: a Shodan search for that build returns more than thirteen hundred internet-exposed instances, concentrated in China, South Korea, the United States, Iran, and Vietnam. That is the botnet's hunting ground, not its membership.

The tell that a given box has actually been conscripted is not the shared build, it is the two keys sitting in its keyspace that have no business in a cache: c2_startup and c2_ssh_key. That pattern is consistent with the long-known open-Redis takeover technique, where an attacker connects to an unauthenticated Redis instance and uses it to write an SSH key onto the host, turning the database into a foothold and a staging point. The scanners are not just probing these boxes, they are wiring them into a back end. Everything we describe about these servers, the build, the keys, and the connected-client lists, comes from Shodan's published banner data; we did not connect to any of them ourselves.
The Linode nodes speak ZooKeeper. Alongside Redis, the Linode cluster appears as clients in exposed Apache ZooKeeper instances on port 2181. ZooKeeper is a coordination service, the kind of thing a distributed system uses to keep its nodes in sync, and an internet-exposed one with no authentication is both a target and a ready-made control channel. The same handful of Linode addresses recur across ZooKeeper servers on Google Cloud, Aliyun, DigitalOcean, and others.
Why the two halves looked like one operation. The apparent tell was the overlap: the Linode nodes appear in both the Redis and the ZooKeeper client lists. A node that connects to the botnet's Redis staging boxes and to its ZooKeeper coordination boxes looked like more than coincidence. What that reasoning missed is that a scanner sweeping port 6379 and port 2181 produces exactly the same overlap, for entirely mundane reasons. The overlap is real; the conclusion we drew from it was not. The shared Redis build fingerprint across the victim population is still a genuine signature — but it describes the pool being preyed on, not the parties doing it.
Bigger than we caught
Here is the part that pays off Part 1's argument. Our decoys caught nine addresses that all turned up in the client lists of the same compromised datastores. Checked against our own sensor logs, every single one announces itself as a scanner: four send the user-agent visionheight.com/scan, five send zgrab. The compromised servers are real and the exposure is real. The membership list is the part a client list cannot give you.
The numbers make the point. Each exposed ZooKeeper server we looked at was showing dozens of connected clients at once. We pulled the client lists from just two of them and counted the distinct source addresses: fifty-four. Of those fifty-four, exactly five are nodes our own decoys had flagged as crossers. The other forty-nine never touched a single one of our sensors, and we cannot say what they are. They may be fleet nodes, other scanners, or researchers — a client list does not distinguish them. There are hundreds more exposed ZooKeeper and Redis instances carrying the same client fingerprints.
So the honeypots gave us nine addresses and a direction. The exposed infrastructure gave us the staging ground.
The gray zone: scanners you cannot tell from bots
The honest counterweight is that not everything crossing our IT/OT line is a botnet, and the hard part is telling the difference. The clearest case was easy. Two addresses sharing one hosting block belong to an internet-measurement company. They show up not in Redis or ZooKeeper but in the recent-connections of NTP servers around the world, which is what wide-area research scanning looks like. Their traffic reached our decoys the same way an attacker's would, but calling them botnet nodes would have been wrong, so we set them aside.
The genuinely difficult case is the tenth address, the one that advertised itself as something else. It was, in Part 1, the single widest crosser on our whole fleet. Its scanning hosts share a reverse-DNS suffix that ties them to a single operator, a self-described "ethical internet scanning" program whose public site says it collects only banners, TLS certificates, and protocol versions, with no authentication attempts and no exploitation. Taken at face value, that is a research scanner like Censys or Shodan.
Three things sit uneasily with the face value. It carries tens of thousands of abuse reports from over a thousand independent sources and is flagged malicious by multiple VirusTotal vendors. Defenders log it in the same breath as Censys and Shadowserver, but also alongside pure nuisance scanners. And on our own fleet it did not behave like a banner-grabber: it spoke Modbus and other industrial protocols to our OT decoys, and it appears in the connected-client lists of the very same exposed-Redis population the botnet uses.
From the packets alone, a gray-area scanner and a botnet node are the same thing. The only difference is a claimed intent, published on a website, that the traffic cannot confirm.
That is why we set it aside rather than counting it as hostile: not because its behavior was cleaner than the others, but because it asserts a research purpose we can neither verify nor disprove. And that ambiguity is itself a finding. A growing class of self-described "ethical" scanners now sweep the entire internet, industrial and OT services included, from cloud IP space, rack up heavy abuse records, and are operationally indistinguishable from the botnets they claim to be studying. When intent does not travel in the packets, "aggressive research" and "reconnaissance for a campaign" look identical on your sensors. One last address, a lone SSH-only box on a US host, matched none of the clusters, and we left it as an honest outlier rather than force it into the story.
This is the point of classification. Deception catches everything that touches a decoy, which is its strength, but "touched a decoy" is not the same as "is malicious," and a fleet that cannot separate a coordinated C2 client from a research scanner, or admit when it cannot tell them apart, is not producing intelligence, it is producing noise.
The map
| Group | Addresses we caught | Hosting | Phones home to | Independent verdict |
|---|---|---|---|---|
| Gray-zone scanner | 5 | Amazon, US-East | Exposed Redis (6379) client lists; self-describes as "ethical" scanning | Sends visionheight.com/scan to our sensors; heavily abuse-reported; intent unverifiable |
| Measurement scanner | 5 | Linode / Akamai Connected Cloud | Exposed ZooKeeper (2181) and Redis client lists | Sends zgrab to our sensors; wide-area enumeration |
| Research scanner | 2 | One hosting /24 (measurement firm) | NTP servers worldwide | Benign scanning, set aside |
| Outlier | 1 | US host, SSH only | Nothing matching | Unexplained, left out |
Indicators
Indicators of compromise: exposed-datastore abuse, observed July 2026 # Behavioral indicators (the durable ones, and the only ones we publish) Redis build id a4f7a6e86f2d60b3 (the common unofficial Windows Redis build) Redis keys c2_startup, c2_ssh_key Ports 6379/tcp Redis (staging) 2181/tcp Apache ZooKeeper (coordination) # Notes Source addresses are deliberately not published. Every address we caught resolved to a scanner; see the correction note at the end of this post. Exposed Redis and ZooKeeper servers are third-party victims and are deliberately not listed here. Presence in a compromised server's client list is not evidence of operating it.
What defenders should take from this
- Your exposed Redis or ZooKeeper is not just at risk, it is recruitable. An internet-facing datastore with no authentication does not just leak, it can become a coordination point for someone else's botnet. If you run Redis, ZooKeeper, or similar on a routable interface, put it behind authentication and a firewall today, and assume anything already exposed has been touched.
- The scanner on your edge is usually a node, not the operation. The address hitting your firewall is often one rented box in a fleet you cannot see from a single log. That is not a reason to panic, it is a reason to correlate, because the fleet is the thing worth understanding.
- Catching is not classifying. Deception gives you a clean, high-confidence signal that something hostile touched a decoy. Turning that into intelligence means asking who, and being willing to conclude that one was a research scanner. The willingness to exclude is what makes the inclusions trustworthy.
Honest framing and limits
We are fingerprinting infrastructure by behavior, not attributing it to a named actor, and we are deliberately not publishing our own node identities or exact decoy names. Shodan is a point-in-time view, so the specific exposed servers and client lists will drift. The Redis c2_* keys and the shared build fingerprint are strong signals of a single coordinated operation, but "one operation" is an inference from correlation, not a claim about who runs it. The exposed Redis and ZooKeeper servers described here in aggregate are victims, not the attacker, and they are already visible to anyone with a Shodan account.
Sources & notes
Deception Check honeypot fleet, July 2026 (first-party): the crosser ranking and IT/OT correlation from Part 1, scrubbed of our own management and self-test traffic before analysis. Third-party enrichment (public OSINT, July 2026): Shodan host and search data for services, connected-client lists, and build fingerprints; VirusTotal for independent reputation. Source addresses are not published at all; only behavioral indicators appear in the box above. Exposed-server populations are described in aggregate and their addresses are not published, since those hosts are victims rather than attackers.
Correction — 28 July 2026
This post originally published a list of nine source addresses under the heading “confirmed botnet nodes,” and described them as a rented fleet. That attribution was wrong and the list has been removed.
The compromised datastores are real. What we could not do is name the operator from their client lists — because those lists are full of scanners. Of the nine addresses we initially flagged, every one turned out to announce itself as a scanner on our own sensors: four as visionheight.com/scan, five as zgrab. The lesson generalises: co-presence in a victim’s client list is not membership in the operation.
The behavioral indicators are unaffected and remain the recommended detection surface. We are leaving this note in place rather than editing silently, because the original list was public for a day and may have been copied.
