LSN โ€” Local Sovereign Network

๐Ÿ‘ป HIGH โ€” Azure Botnet Checking Pre-Planted WordPress Backdoors at Scale

TI-2026-046B โ€” The WordPress Ghosts โ€” Azure Empty-UA Shell Checker Fleet

AS8075 ยท MICROSOFT-CORP-MSN-AS-BLOCK โ€” 269 Azure IPs with empty user-agents systematically checking for pre-planted webshells across WordPress installations. Not exploiting. Harvesting from previous compromises.
Webshell Callback Post-Compromise Empty User-Agent โ˜๏ธ Microsoft Azure WordPress Targeting Dual-Vector (HTTP+SSH) 269 IPs / 41K Requests Botnet-as-a-Service

๐Ÿ“– 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:

  1. The Exploiter โ€” finds a WordPress vulnerability, exploits it, plants a webshell (a PHP file that gives remote command access)
  2. The List Seller โ€” collects thousands of compromised URLs, sells lists of "active shells" on dark markets
  3. The Checker โ€” buys/receives the list, systematically verifies which shells still work
  4. 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:

269 / 308
Empty-UA IPs from AS8075 (Microsoft Azure) โ€” 87% of all empty-UA traffic

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:

DateIPsRequestsIntent
June 106493shell_upload
June 115561shell_upload
June 1291,098shell_upload
June 148562shell_upload
June 158749shell_upload
June 205344shell_upload
June 237598shell_upload
June 2612941shell_upload
TOTAL605,346All 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 RequestedIPsHitsWhat It Really Is
/wp-content/plugins/hellopress/wp_filemanager.php248472๐ŸŽฏ File manager shell disguised as plugin
/this_is_a_new_hello_world.phpโ€”12+๐ŸŽฏ Marker file โ€” confirms compromise to checker
/wp-blog.php101160Fake 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.php65137Fake WP core (disguised shell)
/wp-temp.php63112Fake WP core (disguised shell)
/wp-good.php62107Fake WP core (disguised shell)
/wp-access.php6389Fake WP core (disguised shell)
/wp-content/admin.php66186Shell in uploads/content directory
/wp-admin/css/colour.php66104Shell hidden in admin CSS folder
/wp-includes/ID3/about.php6295Shell 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 PathWhat It Confirms
/wp-includes/js/jquery/jquery.min.js?ver=3.7.1WordPress present + jQuery version
/wp-includes/js/wp-emoji-release.min.js?ver=7.0WordPress version 7.0 specifically
/wp-content/themes/legacy-news/assets/css/blocks.min.cssSpecific theme installed
/wp-login.phpLogin 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:

269 / 269
Azure ghost fleet IPs ALSO found in SSH honeypot

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

RegionIPsRequestsShareAzure Region Likely
๐Ÿ‡บ๐Ÿ‡ธ United States19433,45172%East US / West US / Central US
๐Ÿ‡ฌ๐Ÿ‡ง United Kingdom223,2348%UK South / UK West
๐Ÿ‡ธ๐Ÿ‡ฌ Singapore51,4962%Southeast Asia
๐Ÿ‡ง๐Ÿ‡ท Brazil56192%Brazil South
+ temporal bursts60+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

Metric046A: .env Harvesters (Google)046B: WordPress Ghosts (Azure)
Total IPs54269+
Total Requests6,31341,384
User-AgentRotated (7+ per IP)Empty (no attempt)
SSH Honeypot Overlap0% (specialist)~100% (generalist)
IP ReuseZero (daily burn)Multi-day persistence
Stealth LevelHigh (rotation, UA spoofing)None (empty UA)
Target Type.env files (credentials)Pre-planted shells (access)
Economy RoleCredential theft โ†’ saleAccess 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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
โš  Personal capacity. Research published independently โ€” not reflecting employer views. Derived from passive observation of attacks against personal infrastructure. Full disclaimer โ†’
โ† Previous The Web Siege โ€” 2 / 5 Next โ†’