
🌐 Also available in: Deutsch · Français · Español
A few days ago, “wp2shell” made the rounds — an unauthenticated RCE chain in WordPress, cobbled together from a SQL injection (CVE-2026-60137) and a validation bypass in the REST batch
endpoint (CVE-2026-63030). 🩸 Every WordPress ≥6.8 was
exposed, upstream finally fixed it in 7.0.2. For a
nail-biting couple of days, this very blog was running an emergency
nginx block on /wp-json/batch/v1 because the patched
Docker image simply refused to exist yet. Classic. 🙃 So naturally, once the fire was out, I did what any self-respecting
homelab nerd does at 2am: I went spelunking through my own ingress
logs. 🕵️♂️ Turns out the internet does not care that you patched.
The internet keeps knocking anyway.🔍 Receipts From the Access Log
First pass through the logs, I thought I had a tidy little handful of hits. Then I went back with a better grep (turns out nginx’s plain access-log lines don’t repeat the hostname, so my first domain filter was quietly eating real hits — even homelab nerds have off days 🤦) and found out it was way more than a handful.- 🌊 The opening flood, 18–19 July — the
day the CVE dropped, my logs lit up with dozens of hits, almost all
from the same wonderfully unsubtle User-Agent,
wp2shell.com scanner, cycling through a small army of Cloudflare-fronted IPs, mostly landing 207 (processed, pre-mitigation). Basically the internet’s security researchers (or “researchers” 🧐) doing a synchronized victory lap the moment the disclosure went public. - 😂 Repeat performance from the same scanner UA on 20 July: 403, blocked by my emergency rule. 💪 Then again on 21 July, rule happened to be off for a moment: 207, sailed right through. 🎯 (Core CVE was already patched by then, so — anticlimactic for both of us.)
- 🕵️ My personal favorite: an EC2 box in AWS
Tokyo (
ec2-*.ap-northeast-1.compute.amazonaws.com, yes I did the reverse-DNS lookup, yes I felt very smart) wearing a fake Chrome User-Agent like a cheap Halloween costume. 🎭 It requested/, waited exactly one (1) second, then went straight for the exploit endpoint. No CSS. No JS. No favicon. No human being browses like that — real Chrome loads a small novel’s worth of assets per pageview. Nice try, robot. 🤖 - 🆕 Update while I was still writing this post: a
fresh one landed from Google Cloud (
*.bc.googleusercontent.com), two requests, one second apart, both 207 — and this one bothered to tag itself with its own tracking parameter,&_w2s=347b2f52/&_w2s=b58fad1b. Somebody’s scan tool is apparently numbering its own attempts now. Efficiency! 📊 Third different major cloud provider spotted so far (Cloudflare-fronted, AWS, now GCP) — this thing has friends everywhere.
🤔 Okay, But Who’s Actually Doing This?
Fair question, and worth spelling out for anyone who doesn’t stare at server logs for fun: not everyone poking at a known vulnerability is a criminal. There’s a real spectrum here, and the tells matter. 🔬- 😇 Good-faith end: security research outfits and
scanning services (think Shodan, Censys, GreyNoise-style projects)
constantly sweep the internet for known CVEs — sometimes to
build public threat-intel feeds, sometimes so affected site owners
can look themselves up and go “oh no.” A tool that literally calls
itself
wp2shell.com scannerin its own User-Agent fits this profile well: it has no reason to hide, and being loud about who you are is exactly what legitimate scanners do (and often what responsible-disclosure norms expect). - 😈 Bad-faith end: attackers running the exact same kind of check, except the goal isn’t “tell someone,” it’s “find a door I can still walk through” — to drop a webshell, a spam injector, a cryptominer, or just add the box to a botnet. These are the ones with every incentive to blend in.
curl tests — the ones I ran to confirm the block
actually worked — are sitting in that same log file, repeatedly,
because apparently I couldn’t just check once. 😅 So technically I’m
also “an IP address probing the vulnerable endpoint.” Guilty as
charged, Your Honor. 👨⚖️ Not just me being paranoid, by the way: Golem.de covered this exact
wave of ongoing exploitation attempts too — “Lücken in WordPress: Laufende Schadcode-Attacken gefährden Millionen von Websites” — so this isn’t some isolated homelab-blog conspiracy theory. 📰
It’s a genuinely internet-wide thing.🕸️ Bonus Round: The Scrapers Wearing a Trenchcoat
While I was down in the log mines looking for wp2shell, I tripped over something way bigger and, honestly, more interesting: 765 different IP addresses, spread across at least 530 distinct /16 network blocks (so: everywhere, not one datacenter), each one showing up to make exactly one or two requests and then vanishing forever. 👻 Every single one of them presented a perfectly normal-looking desktop browser UA — Chrome or Edge, Windows or Mac, the works. Nothing you’d flag on sight. But line them all up and the mask slips immediately: they only ever hit my ~31 tag/category/date archive pages (/tag/ansible, /category/devsecops, /2025/05, and so on),
methodically working through the list — and not one of them ever
fetched a single CSS file, JS file, or image afterwards. 🖼️🚫 A real
Chrome tab loads two dozen assets per pageview without you lifting a
finger. These didn’t load any. That’s the signature of a residential-proxy scraping
botnet: instead of hammering the site from one IP (which gets
you rate-limited or banned in about four seconds), you rent a few
hundred thousand real residential IPs and fire exactly one polite,
totally-a-real-person-honest request from each. Death by a thousand
paper cuts, except the paper cuts are indistinguishable from actual
readers unless you zoom out far enough to see the pattern. 🔎 Given the
target (systematically walking every archive page, i.e. the entire
content index of the site, not just the homepage), my money’s on
large-scale content scraping — could be good old SEO content
theft, could be someone building an AI training set. Either way: 765
“visitors” who read zero words and loaded zero fonts were never
visitors. 🤖🕶️🎬 Takeaway
The actual hole has been patched for a while now (running7.0.2 since day one of this being possible). But
scanning for a freshly-announced CVE doesn’t stop just because
someone, somewhere, shipped a fix. 📡 The scanning bots do not read
changelogs. If you run public-facing WordPress, this kind of traffic
is just background radiation — a good excuse to actually glance
at your access logs once in a while instead of assuming “patched ==
done.” 🛡️






