The scariest WordPress hacks are not the ones that deface your homepage with a skull and crossbones. The scariest hacks are the ones where the website looks completely fine.
At 2:20 AM last night, a client’s e-commerce site was targeted by a sophisticated automated attack. If you looked at the frontend, the products loaded perfectly. The checkout worked. Uptime monitoring tools reported 100% availability. The client, asleep, had absolutely no idea their digital storefront was being actively weaponized.
But beneath the surface, an attacker had gained access, bypassed standard security scanners, and was actively establishing deep persistence via a hidden WordPress backdoor.
This is a real world forensic breakdown of that exact incident. We will look at how the attacker used a compromised account to upload a fake plugin, why they utilized Must-Use (MU) plugins to evade detection, how they created a hidden “Ghost Admin,” and the exact workflow agencies must use for WordPress malware removal when standard tools fail.
What Happened in Less Than Six Minutes
Speed is the defining characteristic of modern botnet attacks. This was not a human clicking around a dashboard; it was a scripted execution sequence that established a complete backdoor in under six minutes.
Here is the exact timeline of the attack:
- 2:20:04 AM (The Breach): The attacker successfully logged in. They utilized a compromised administrator account belonging to a developer from a domain the client had migrated away from months ago. (A stark reminder to audit stale user accounts).
- 2:20:12 AM (The Delivery): The attacker uploaded a ZIP file containing the initial payload.
- 2:20:15 AM (The Evasion): Immediately after extraction, the attacker deleted the ZIP file to remove the most obvious evidence from the server.
- 2:20:18 AM (The Payload): A hidden plugin was activated.
- 2:20:25 AM (Persistence): Two new MU-plugins were written to the server to ensure the malware loaded before WordPress even booted.
- 2:20:30 AM (The Ghost Admin): A hidden administrator account was created in the database.
- 2:25:00 AM (The Mass Infection): 337 files across multiple legitimate plugins were modified simultaneously to insert tracking code and external references.
By 2:26 AM, the attacker had full, invisible control of the site.
The Fake Plugin That Started It
The initial entry point was a classic deception tactic. The attacker uploaded a plugin, but they disguised it to look legitimate.
The ZIP file uploaded was named social-1788468575.zip. However, once extracted into the wp-content/plugins directory, the folder and internal headers claimed the plugin was “Call to Action Block – WPPOOL”.
WPPOOL is a highly respected, legitimate WordPress development company. The attacker deliberately spoofed their branding in the plugin headers so that if an agency owner quickly glanced at the active plugins list, they would assume it was a benign, premium add-on.
When performing WordPress malware detection, you cannot trust plugin headers. You must compare the folder name, the zip name (if available in logs), and the actual code against known repository hashes.
The Plugin That Did Not Want to Be Seen
The fake WPPOOL plugin was just a dropper. Its primary job was to install the real malicious WordPress plugin, a directory named woocommerce-license-api.
This plugin was designed specifically for stealth. It contained code that hooked into the WordPress all_plugins filter. By intercepting this filter, the plugin actively removed itself from the list displayed on the wp-admin/plugins.php screen.
To a standard user logging into the dashboard, woocommerce-license-api simply did not exist. This highlights a critical flaw in manual auditing: you cannot clean what you cannot see. The code inside this hidden plugin was actively reaching out to a known Command and Control (C2) domain, cdn-id.biz, to download further instructions.
Why MU-Plugins Are Critical During Malware Investigations
Deleting the woocommerce-license-api folder via FTP would not have saved the site. The attacker had already established a deeper layer of persistence using Must-Use plugins.
What are MU-Plugins?
Must-Use plugins reside in a specific directory: wp-content/mu-plugins/. Unlike standard plugins, MU-plugins do not need to be activated in the WordPress dashboard. If a PHP file exists in this folder, WordPress executes it automatically, before standard plugins and themes are loaded. Furthermore, MU-plugins cannot be disabled from the standard WordPress interface; they must be deleted at the file level.
How the Attacker Abused Them
The attacker dropped two PHP files into the mu-plugins directory. Because these files execute first, they can intercept and manipulate the rest of the WordPress load sequence. This is a highly effective way to establish WordPress MU-plugin malware persistence. Even if a security scanner detects and deletes the standard malicious plugin, the MU-plugin will simply redownload and reinstall it on the next page load.
The Hidden Administrator (Ghost Admin)
The first MU-plugin had a singular, highly damaging purpose: to create and protect a hidden administrator account.
The attacker created a user named admindefault with full administrative privileges. To ensure this user remained a secret, the MU-plugin hooked into the pre_user_query filter.
Whenever a legitimate site owner navigated to the Users page in the dashboard, this malicious hook intercepted the database query. It instructed WordPress to exclude the ID associated with admindefault from the results and artificially adjusted the total user count.
This is often referred to as a “Ghost Admin.” Traditional security plugins often miss this because they rely on standard WordPress functions to list users, and the malware is actively lying to those functions.
337 Plugin Files Changed at Almost the Same Time
When investigating a WordPress hacked site, timestamps are your most valuable forensic evidence.
At exactly 2:25 AM, the modification timestamps on 337 separate files across various legitimate plugins (like WooCommerce and Elementor) changed.
A human developer cannot open, edit, and save 337 files in a single minute. A cluster of modifications this dense is a definitive forensic signal of an automated script or worm rapidly injecting code across the file system. In this incident, the malware was inserting tracking scripts and references back to their external C2 domain.
Finding the External Malware Reference
By analyzing the obfuscated code injected into those 337 files, we found heavily encoded base64 strings. When decoded, they revealed scripts attempting to load external resources from cdn-id.biz.
This domain is a known indicator of compromise. This specific attack pattern (hidden plugins, MU-plugin persistence, and specific C2 domains) strongly aligns with the tactics, techniques, and procedures (TTPs) of the massive “StopAndProtect” campaign, which security researchers noted hijacked over 2,000 WordPress sites in mid-2026. This campaign famously utilizes fake CAPTCHA prompts (ClickFix) to distribute malware.
How to Remove a Hidden WordPress Backdoor
If you discover indicators like this on a client site, you must follow a strict remediation workflow. Blindly deleting suspicious files without understanding the persistence mechanisms will only result in the site being re-infected hours later.
Here is the practical hidden WordPress malware removal workflow:
- Isolate the Compromised Site: Put the site in maintenance mode or block traffic at the Web Application Firewall (WAF) level to prevent further data exfiltration or visitor infection.
- Preserve Evidence: Take a complete backup of the infected state (files and database) and store it securely offline. You may need this for forensic analysis if the breach involves sensitive customer data.
- Identify Compromised Accounts: Review access logs to determine which account was used for the initial breach.
- Inspect
wp-content/mu-plugins/: Access the server via FTP or SSH. Look for any unfamiliar PHP files in this directory. Delete confirmed malicious MU-plugins immediately to break the persistence loop. - Identify Malicious Plugins: Review the
wp-content/plugins/directory. Look for plugins that do not match known repository checksums or were modified at suspicious times. - Investigate Database Persistence: Check the
wp_optionstable for suspicious, obfuscated JavaScript or hidden user ID markers (like_pre_user_id). Use SQL queries to find and delete Ghost Admin accounts directly. - Remove Confirmed Components: Delete the malicious plugin folders and clean the infected legitimate files (or replace them with fresh copies from the official repository).
- Rotate Credentials: Force a password reset for all administrative users and enforce Two-Factor Authentication (2FA). Update the database passwords and WordPress salts in
wp-config.php. - Update the Stack: Ensure WordPress core, themes, and all legitimate plugins are updated to patch the vulnerability that allowed the initial access.
- Verify the Clean: Perform a secondary, deep forensic scan to ensure no backdoors were missed.
What We Found With SiteOps
The timeline above is exact. But we did not discover these indicators by manually opening dozens of WordPress dashboards at 2:00 AM, hunting through FTP directories, and writing custom SQL queries.
Manual investigation of this depth is impossible at scale.
We utilize SiteOps, our autonomous WebOps platform. When the attack occurred, the SiteOps Emergency Scanner executed a deep forensic audit and caught the entire attack chain autonomously.
Here is exactly how the platform mapped the threat to a detection, and then provided the action to fix it:
| What We Found | What SiteOps Detected | Remediation Action |
|---|---|---|
Hidden Plugin (woocommerce-license-api) | Detected plugin folder bypassing all_plugins filter | 1-Click Delete via Dashboard |
Suspicious Admin (admindefault) | Detected Ghost Admin marker in database bypassing core queries | 1-Click Database User Purge |
| MU-Plugin Persistence | Detected unauthorized PHP execution in mu-plugins directory | 1-Click Quarantine |
| 337 File Modifications | Flagged massive timestamp cluster anomaly | File Replacement / Regex Clean |
| Suspicious Domain | Detected obfuscated strings pointing to cdn-id.biz | Quarantined infected files |
The most critical aspect of this remediation was that it occurred from a single, centralized dashboard. We did not need to open an FTP client. We did not need to log into phpMyAdmin. We clicked “Clean” on the specific database injections and “Delete” on the malicious plugin folders, neutralizing the threat in minutes.
The Bigger Problem for WordPress Agencies
This incident highlights a terrifying business lesson for agencies: A WordPress site does not need to be down to be compromised.
If you rely on basic HTTP uptime monitors or standard security plugins that only check public blacklists, a sophisticated attack like this will go completely unnoticed until your client’s customers start reporting fake CAPTCHA prompts and malware downloads.
For an agency managing 50 or 100 client sites, manually investigating every suspicious file change or checking every mu-plugins folder is simply not scalable. It destroys your profit margins.
When evaluating WordPress security for agencies, the real challenge isn’t simply, “Can I detect malware?”
The real challenge is: “Can I know what is happening deep inside the file system and database across my entire client portfolio, and can I fix it before the client discovers it?”
If you are relying on legacy tools, the answer is likely no.
Think your WordPress sites are clean? Test them.
SiteOps is built specifically for agencies managing multiple WordPress sites, providing deep forensic scanning, automated visual regression for updates, and 1-click malware remediation.
Connect your first 3 sites free and see exactly what SiteOps finds across your portfolio.
(Managing 5+ client sites? Join the SiteOps Founding Member Program for personal onboarding and early access to upcoming forensic capabilities).
