TI-2026-046B โ The WordPress Ghosts โ Azure Empty-UA Shell Checker Fleet
๐ Series: The Web Siege โ Letter B
In Letter A, we documented a professional credential harvesting operation โ 54 Google Cloud IPs scanning for .env files with military-grade OPSEC. Zero SSH overlap. Daily rotation. A specialist.
Letter B is the opposite. This is a blunt instrument. A horde.
269 Microsoft Azure IPs. Empty user-agents. No stealth whatsoever. And they're not looking for vulnerabilities to exploit โ they're looking for backdoors that are already there. Someone else planted the shells. This fleet just checks which ones still work.
Welcome to the supply chain of web exploitation.
โ ๏ธ What You Need to Understand First
In the criminal web exploitation economy, there are layers:
- The Exploiter โ finds a WordPress vulnerability, exploits it, plants a webshell (a PHP file that gives remote command access)
- The List Seller โ collects thousands of compromised URLs, sells lists of "active shells" on dark markets
- The Checker โ buys/receives the list, systematically verifies which shells still work
- The Operator โ uses verified shells for spam, crypto mining, DDoS, phishing hosting, or further lateral movement
The Azure fleet documented here is Layer 3 โ The Checker. It doesn't plant shells. It doesn't use them. It just verifies they exist. The paths it requests are not WordPress core files โ they are specific backdoor filenames that were planted by someone else, probably months ago.
๐ฏ The Signal: 41,384 Ghost Requests
The detection was immediate. Empty user-agent is the most basic fingerprint in web security โ no browser, no crawler, no legitimate tool sends requests without identifying itself. Yet here were 308 IPs doing exactly that, generating 41,384 requests to 1,437 unique paths across our infrastructure.
When we filtered by ASN, one provider dominated everything:
Not Google this time. Not DigitalOcean. Not some obscure bulletproof hoster. Microsoft Azure โ the second-largest cloud platform on Earth โ hosting a botnet that makes no attempt to hide itself.
๐ The Campaign Structure: Steady Drumbeat + Bursts
Unlike the .env harvesters (Letter A) which appeared in discrete daily bursts, the Azure ghost fleet operates in two modes simultaneously:
Mode 1: Persistent Background (194+ IPs)
Continuous low-frequency checking from the empty-UA cluster. IPs operate for days or weeks, making steady requests. Not bursty โ persistent presence.
Mode 2: Temporal Bursts (60 IPs across 8 campaigns)
Coordinated bursts where 5-12 IPs appear simultaneously, all probing shell_upload paths. Same day, same targets, then quiet. Fresh lists being checked.
Shell Upload Burst Timeline:
| Date | IPs | Requests | Intent | |
|---|---|---|---|---|
| June 10 | 6 | 493 | shell_upload | |
| June 11 | 5 | 561 | shell_upload | |
| June 12 | 9 | 1,098 | shell_upload | |
| June 14 | 8 | 562 | shell_upload | |
| June 15 | 8 | 749 | shell_upload | |
| June 20 | 5 | 344 | shell_upload | |
| June 23 | 7 | 598 | shell_upload | |
| June 26 | 12 | 941 | shell_upload | |
| TOTAL | 60 | 5,346 | All AS8075, all empty UA | |
Additionally: 3 CMS detection campaigns (21 IPs, 2,711 requests) performing WordPress fingerprinting before shell checks.
๐ The Wordlist: A Ghost Dictionary
This is the key to understanding the operation. None of these files exist in a legitimate WordPress installation. Every single path below is a known webshell filename or backdoor marker:
| Path Requested | IPs | Hits | What It Really Is |
|---|---|---|---|
/wp-content/plugins/hellopress/wp_filemanager.php | 248 | 472 | ๐ฏ File manager shell disguised as plugin |
/this_is_a_new_hello_world.php | โ | 12+ | ๐ฏ Marker file โ confirms compromise to checker |
/wp-blog.php | 101 | 160 | Fake WP core file (no such file in WP) |
/x.php | โ | 13+ | Minimalist webshell (single-character name) |
/dx.php | โ | 15+ | Minimalist webshell variant |
/ppp.php | โ | 12+ | Webshell (nonsense name to avoid detection) |
/aaf.php | โ | 12+ | Webshell (random name) |
/1.php | โ | 8+ | Numeric webshell โ very common in wild |
/wp-the.php | 65 | 137 | Fake WP core (disguised shell) |
/wp-temp.php | 63 | 112 | Fake WP core (disguised shell) |
/wp-good.php | 62 | 107 | Fake WP core (disguised shell) |
/wp-access.php | 63 | 89 | Fake WP core (disguised shell) |
/wp-content/admin.php | 66 | 186 | Shell in uploads/content directory |
/wp-admin/css/colour.php | 66 | 104 | Shell hidden in admin CSS folder |
/wp-includes/ID3/about.php | 62 | 95 | Shell hidden in media library |
/atomlib.php | โ | 8+ | Webshell (fake library name) |
/like.php | โ | 9+ | Webshell (social feature disguise) |
/xxx.php | โ | 7+ | Webshell (obvious test name) |
The naming patterns reveal three strategies:
- WordPress disguise โ
wp-blog.php,wp-the.php,wp-temp.php,wp-good.phpโ look like WordPress core files but aren't - Minimalist naming โ
x.php,1.php,dx.php,ppp.phpโ tiny names that blend into directories with many PHP files - Marker/callback โ
this_is_a_new_hello_world.php,hellopress/wp_filemanager.phpโ unique identifiers that confirm "yes, our shell was installed here"
๐ The Two-Phase Attack: Fingerprint Then Harvest
The operation is not blind. Before checking for shells, a reconnaissance subset of 21 IPs first confirms the target runs WordPress:
| Phase 1: CMS Detection Path | What It Confirms |
|---|---|
/wp-includes/js/jquery/jquery.min.js?ver=3.7.1 | WordPress present + jQuery version |
/wp-includes/js/wp-emoji-release.min.js?ver=7.0 | WordPress version 7.0 specifically |
/wp-content/themes/legacy-news/assets/css/blocks.min.css | Specific theme installed |
/wp-login.php | Login page accessible (not hardened) |
Only after confirming WordPress does the full shell-checking fleet engage. This is an efficiency optimization โ why waste 50+ requests checking for WordPress shells on a server running Nginx + Node.js?
The version-specific checks (jQuery 3.7.1, WordPress 7.0) suggest the shell planter exploited a vulnerability in that specific version. The checker only visits targets running the vulnerable version because only those could have been compromised.
โ๏ธ Dual-Vector: The Ghost Fleet Also Attacks SSH
Remember Letter A's key finding? The Google Cloud .env fleet had zero SSH honeypot overlap โ proving a specialist. The Azure ghost fleet is the opposite:
Every. Single. One. The same machines that check for WordPress backdoors over HTTP are simultaneously brute-forcing SSH logins on every server they can find.
This tells us exactly what we're dealing with:
- This is a commodity botnet โ it runs every available attack module against every target
- The operator does not value stealth โ volume over precision
- The Azure instances are likely compromised themselves โ running botnet agents installed via stolen credentials or supply chain compromise
- Contrast: The Google .env operator (Letter A) would NEVER expose their infrastructure to SSH blacklists. Different operator, different tier, different market.
๐ Geographic Distribution: Global Reach
| Region | IPs | Requests | Share | Azure Region Likely |
|---|---|---|---|---|
| ๐บ๐ธ United States | 194 | 33,451 | 72% | East US / West US / Central US |
| ๐ฌ๐ง United Kingdom | 22 | 3,234 | 8% | UK South / UK West |
| ๐ธ๐ฌ Singapore | 5 | 1,496 | 2% | Southeast Asia |
| ๐ง๐ท Brazil | 5 | 619 | 2% | Brazil South |
| + temporal bursts | 60+ | 5,346 | โ | Various |
The geographic spread matches Azure's datacenter layout. The operator likely provisions VMs in multiple regions either for geolocation-based scanning or to distribute load across Azure's abuse detection systems.
๐ Scale Comparison: Azure Ghost Fleet vs Competitors
| Metric | 046A: .env Harvesters (Google) | 046B: WordPress Ghosts (Azure) |
|---|---|---|
| Total IPs | 54 | 269+ |
| Total Requests | 6,313 | 41,384 |
| User-Agent | Rotated (7+ per IP) | Empty (no attempt) |
| SSH Honeypot Overlap | 0% (specialist) | ~100% (generalist) |
| IP Reuse | Zero (daily burn) | Multi-day persistence |
| Stealth Level | High (rotation, UA spoofing) | None (empty UA) |
| Target Type | .env files (credentials) | Pre-planted shells (access) |
| Economy Role | Credential theft โ sale | Access verification โ resale |
Two completely different operational philosophies attacking the same target. One is a scalpel. The other is a battering ram.
๐ What This Means for WordPress Administrators
If the Azure ghost fleet finds one of these files on your server, it means you were already compromised. The shell was planted days, weeks, or months ago by a different attacker. The ghost fleet is just the latest visitor to your already-open back door.
The terrifying implication: If any of these paths return HTTP 200 on your server, an attacker already has full command execution on your machine. They can:
- Read your
wp-config.php(database credentials) - Upload additional malware (crypto miners, spam relays)
- Modify your WordPress content (SEO spam injection, redirect chains)
- Use your server as a proxy for further attacks
- Exfiltrate your users' data (emails, passwords, PII)
- Pivot to other services on the same network
If you run WordPress: Check RIGHT NOW whether any of the files listed in this dossier exist in your installation. If they do, you've been compromised and need immediate incident response โ not just file deletion, but full forensic investigation of what was accessed.
๐ต๏ธ Historical Context: Azure in Our Threat Intelligence
This is not the first time AS8075 has appeared in our investigations:
- 501 known threat IPs from AS8075 in our honeypot threat intelligence database
- 99 Azure IPs with threat_score โฅ 70 actively attacking SSH honeypot
- 3 IPs confirmed planting SSH backdoors (documented in earlier investigations)
- Outlaw botnet has been observed using compromised Azure instances as infrastructure nodes
- TI-2026-025J ("The Victims") documented Microsoft Azure as a major attack source
Microsoft Azure isn't a malicious actor โ it's being abused. But the scale of abuse (269 IPs for a single botnet, 501 known threats total) raises serious questions about the effectiveness of Azure's automated abuse prevention. For comparison: Google Cloud had 54 IPs in the .env fleet and nobody stopped that either.
๐ Methodology & Data Sources
Primary: Traefik access logs โ Loki โ web_threats PostgreSQL (automated pipeline)
Campaign Detection: empty_ua_asn_cluster (groups IPs by empty UA + same ASN + country) and temporal_burst (โฅ5 IPs, same intent, 1-hour window)
Cross-Reference: SSH honeypot (threat_intel DB, 8,000+ IPs) โ confirmed 100% overlap for Azure fleet
OSINT Library: Entity crosslinks (Qdrant, 15,392 edges) โ AS8075 documented across multiple prior investigations with 501 known threat IPs
Historical: TI-2026-025J (Azure as attack source), Outlaw botnet Azure connections, SSH backdoor planting incidents
Period: June 4 โ 27, 2026 (23 days) | Confidence: HIGH
๐ Conclusions
- This is a post-compromise verification operation. The Azure fleet does not exploit โ it checks. The filenames it probes are pre-planted backdoors from previous attacks. This represents Layer 3 in the criminal supply chain: access verification before resale.
- The two-phase operation (CMS detect โ shell check) proves coordination. A reconnaissance subset confirms WordPress before the main fleet engages. This is not blind scanning โ it's targeted harvesting with an efficiency optimization layer.
- 100% SSH overlap reveals a commodity botnet. Unlike the specialized Google .env fleet (Letter A, 0% overlap), this is a general-purpose attack tool running every module against every target. Volume over precision.
- Empty user-agent is a deliberate choice, not laziness. At 41,384 requests with no UA, the operator either does not care about detection (because targets lack WAFs) or uses empty UA as a primitive authentication mechanism for the planted shells.
- Microsoft Azure's abuse response is failing. 269 IPs, 23+ days, 41K+ requests, trivially detectable pattern (empty UA). Either Azure's automated detection cannot handle this volume, or abuse reports are being deprioritized for this activity class.
- The attack economy has clear specialization layers. Letter A showed the credential thieves (specialists). Letter B shows the access verifiers (commodity). Different actors, different infrastructure, different operational philosophies โ but all feeding the same underground market.
๐ The Web Siege โ Series Navigation
๐ You are here: Letter B โ The WordPress Ghosts
- ๐ธ๏ธ A: The .env Harvesters โ Google Cloud credential scanning fleet
- ๐ป B: The WordPress Ghosts โ Azure empty-UA shell checker fleet (this article)
- ๐ญ C: The Reconnaissance Industrial Complex โ Palo Alto, LeakIX, DeepSeek
- โ๏ธ D: The Multi-Vector Operators โ 1,751 IPs in both SSH + HTTP
- โ๏ธ E: The Cloud Mercenaries โ Cloud providers as attack platforms