How one scanning operation hid across 11,107 IPs on 147 networks | HoneyLabs blog
Look up<br>Dashboard<br>LookupExplore<br>CVEsPayloadsCampaignsAEI IndexPortsUser-agents<br>Integrations<br>OverviewMCPFeedsAPI / Enrich<br>DocsBlog
Dashboard
Blog · 2026-07-10<br>How one scanning operation hid across 11,107 IPs on 147 networks<br>In late June, 38 Google Cloud machines fired 1.87 million requests guessing the filenames of leaked database dumps. By IP and HTTP fingerprint they looked like 11,000 unrelated scanners; by TLS fingerprint they were a single operation. A field lesson in attributing coordinated cloud activity at the layer that actually holds.<br>In the last week of June, a single machine on Google Cloud opened one TLS connection to a HoneyLabs sensor and asked for more than 47,000 files without stopping: backup.sql.gz, then backup.tar.gz, then database.zip, then poetry.sql, straight down a list it never broke from. Thirty-seven other machines were working the same list at the same time.
None of it was an exploit. No CVE, no injection, no login attempt against /wp-admin. The operation was making one bet at industrial scale: that somewhere on the host sat a database dump or a source archive left in a web root, and that it could find it by guessing the filename.
Here is the part worth your attention. Depending on which field you group by, that traffic is either one operation or eleven thousand strangers.
Group the requests by source IP and you get 38 addresses scattered across fifteen countries, all inside Google Cloud, none of them on any blocklist. Group them by their HTTP client fingerprint and you get 11,107 addresses on 147 networks, indistinguishable from the general hum of the internet. Group them by their TLS fingerprint and the whole thing collapses to one operation: a single JA4, t13i1314h2_f57a46bbacb6_3b244d8fbcc8, on exactly 38 addresses and nowhere else in our data, tied to 1,871,175 requests . Same packets, three answers. Only the last one is the truth.
That gap is the whole story. Below is how each layer lies, and which one does not.
What it was after
First, what the operation actually wanted, because it explains the volume. Pull the requests apart and the wordlist is not a list. It is a product of three sets.
It takes a path prefix (/, /logs/, /var/, /backend/, and about thirty others), a basename, and an archive extension, and requests every combination. The basenames are the tell. Some are generic (backup, database, dump, www). Some are the names of package managers and frameworks, the strings a developer's own tooling produces: poetry, composer, node_modules, vendor, drupal, typo3, strapi. Some are words you would only pick if you were hunting secrets: .env, .aws, .ssh, credentials, tokens, keys.
Each basename is requested across fourteen archive and dump formats: .sql, .sql.gz, .sql.bz2, .tar.gz, .tgz, .tar.xz, .zip, .7z, .rar, .zst, and the rest. The fourteen extensions are exact, logged verbatim; the prefix and basename lists run to dozens each. Multiplied out, that is tens of thousands of candidate URLs per open port, replayed on every port and every host it reaches. It also folds in the older secret-grab we wrote about in June: .git/config under the same prefixes, plus /env and /api/credentials.json. The .git grab is the appetizer. This one wants the whole compressed database. One TLS connection carried more than 47,000 of these guesses back to back over four and a half hours, roughly nine megabytes on a single keep-alive socket.
That behavior, on its own, is not remarkable. Content-discovery scanning is old. What is worth writing down is that it is nearly impossible to see as one thing unless you fingerprint it correctly. So look at each layer.
The IP tells you nothing
Every one of the 38 addresses sat in Google Cloud, AS396982, spread across fifteen regions. The traffic arrives from India, the United States, Singapore, Germany, Australia, and a dozen more. Every address is clean, freshly assigned cloud space with no reputation history, and there are only 38 of them, far too few and too transient to blocklist your way out of. The one signal in the IPs is the coordination: at any given second one host is working the /logs/ prefix, another /tmp/, a third /var/, all stepping through the same basename list together. The wordlist was sharded across the fleet by path prefix, the way you split a job you want to finish fast. But you only notice that if you have already grouped the hosts together, and the IPs give you no way to do that.
The HTTP request tells you nothing
The obvious next move is to fingerprint the HTTP client. It fails here, and it fails for a reason worth understanding. The requests are deliberately plain: a bare GET, four headers, no cookies, no Accept-Language. That produces a JA4H of ge11nn0400_88d30a62b7ad, which in our data covers 4.6 million requests from 11,107 addresses across 147 networks , including Amazon, Microsoft, DigitalOcean, and Censys. A minimal request looks...