PHP Backdoors in WordPress: How Attackers Stay Hidden
By WP Vanguard Team
When attackers compromise a WordPress site, the malware you see is not the real problem. The real problem is the backdoor they leave behind.
A backdoor is a hidden piece of code that gives the attacker persistent access to your site even after you clean the visible infection, update your plugins, and change your passwords. It is the reason hacked sites get reinfected within days of cleanup.
Understanding how backdoors work is the key to actually getting rid of them.
What PHP Backdoors Do
A PHP backdoor accepts instructions from the attacker and executes them on your server. At its simplest, it takes input (via a URL parameter, POST data, or a cookie), decodes it, and runs it as PHP code.
This gives the attacker the ability to:
- Read any file on your server (including wp-config.php with database credentials)
- Write new files or modify existing ones
- Execute database queries (read customer data, inject spam, create admin accounts)
- Send email from your server (spam campaigns)
- Download and install additional malware
- Pivot to other sites on the same server
All of this happens through a single small PHP file that looks unremarkable in a directory full of legitimate WordPress code.
Where Attackers Hide Backdoors
Disguised as Core Files
Attackers create files with names that look like they belong to WordPress:
wp-xmlrpc.php(real file is xmlrpc.php in the root)class-wp-cache.phpin wp-includeswp-tmp.phporwp-feed.phpin the root directoryadmin-ajax-handler.phpin wp-admin
These files survive manual cleanup because administrators assume they are legitimate. Unless you compare every file against a fresh WordPress download, you will miss them.
In the Uploads Directory
The wp-content/uploads/ directory should contain only media files (images, PDFs, videos). There is no legitimate reason for PHP files to exist here. But attackers place backdoors here because:
- Upload directories are writable by the web server (necessary for media uploads)
- Nobody manually checks the uploads directory - it contains thousands of files organized by year/month
- Some backup and security plugins skip the uploads directory during scans
A backdoor at wp-content/uploads/2024/03/thumbnail-cache.php can sit there indefinitely.
In Must-Use Plugins
The wp-content/mu-plugins/ directory is a favorite hiding spot. Must-use plugins:
- Load automatically on every page request
- Cannot be deactivated from the WordPress admin panel
- Do not appear in the regular plugins list (they have a separate, less-visited tab)
- Many site owners do not even know this directory exists
A file like mu-plugins/loader.php or mu-plugins/health-check.php looks legitimate but could be a full-featured backdoor.
Inside Legitimate Plugin Files
Rather than creating new files, sophisticated attackers inject backdoor code into existing plugin or theme files. They add a few lines at the top or bottom of a legitimate PHP file, making it invisible to scans that only look for new or unknown files.
Common targets:
- Theme's functions.php (already contains custom code, a few extra lines blend in)
- Plugin bootstrap files (plugin-name.php)
- Rarely edited files deep in plugin directories
In the Database
Some backdoors live entirely in the database, stored in wp_options or as content in wp_posts. They get pulled from the database and executed by a small trigger in the filesystem. This two-part approach means cleaning just the files or just the database leaves half the backdoor intact.
Common Obfuscation Techniques
Backdoor code is almost never readable. Attackers use multiple layers of encoding to hide what the code actually does.
String Encoding
The most common technique chains encoding functions together. The inner layer is a base64-encoded string. The outer layer decodes it and passes the result to a function that executes it as code. Some backdoors chain three or four encoding layers deep.
String Concatenation
Instead of using function names directly (which scanners can detect), attackers build function names from individual characters or string fragments that are concatenated at runtime. The assembled string is then used as a variable function call.
Variable Functions
PHP allows calling functions using variables. An attacker stores a dangerous function name in a variable, then calls it indirectly. Static analysis tools that search for specific function names in source code will miss the call because the function name only exists at runtime.
Alternative Execution Methods
Beyond the obvious code execution functions, PHP offers several less-known ways to execute strings as code:
- The
preg_replacefunction with the/emodifier (deprecated but still works on older PHP versions) create_function(deprecated in PHP 7.2)assertwith string arguments (changed in PHP 7.0)- Callback-based functions like
array_map,array_filter, andusortwhere the callback is a code execution function register_shutdown_functionandregister_tick_function
Timestamped and Conditional Execution
Advanced backdoors include conditions that control when they activate:
- Only execute on certain days of the week
- Only execute if a specific cookie or header is present
- Sleep for a set period after installation before activating (to avoid detection during the initial security response)
- Only execute if the request comes from a specific IP range
This means a security scan during the wrong time window may not trigger the backdoor at all.
How to Find Backdoors
File Integrity Checking
Compare every file on your server against known clean versions. WordPress core files should match the official distribution exactly. Plugin and theme files should match the versions available from wordpress.org or the vendor.
Any file that does not match, or any file that exists but should not, is suspicious.
PHP Files Where They Should Not Be
Run a search for PHP files in directories that should only contain media:
Check wp-content/uploads/ for any .php files. Check the wp-includes/ directory for files that are not part of the standard WordPress distribution. Check the root directory for files that are not part of WordPress core.
Obfuscation Pattern Detection
Search your codebase for common obfuscation indicators:
- Long strings of encoded characters (base64 patterns)
- Nested decoding function calls
- PHP files with high ratios of encoded vs. readable code
- Very long single lines (obfuscated code often compresses into one line)
- Hex-encoded strings and character code arrays
Timestamp Analysis
Check file modification dates. If a file was last modified at 3:00 AM when nobody was working, or all legitimate files were modified on deployment day but one file has a different timestamp, investigate.
Automated Scanning
Manual checking is thorough but not practical for sites with thousands of files. The WP Vanguard deep scan automates this process via SSH, checking:
- Every PHP file against known clean versions (core, plugins, themes)
- All directories for files that should not exist
- Obfuscated code patterns across the entire file system
- Database entries containing executable code
- User accounts and application passwords for signs of compromise
- Cron jobs for scheduled malicious tasks
The deep scan costs $1 and examines your server at the file system level, catching backdoors that external scanners cannot see.
After Finding a Backdoor
Finding the backdoor is only half the job. You also need to:
-
Identify how it got there. Check your plugin versions against vulnerability databases. If a plugin had a known file upload or code execution vulnerability, that is likely the entry point.
-
Check for additional backdoors. Attackers rarely install just one. If you found a backdoor in mu-plugins, also check uploads, themes, and legitimate plugin files.
-
Verify the database. Check wp_options and wp_posts for injected code that might reinstall the file-based backdoor.
-
Reset all credentials. The backdoor may have been used to read wp-config.php, which means your database credentials are compromised.
-
Regenerate security salts. This invalidates all existing sessions, including any the attacker may hold.
If the infection is complex or you find multiple backdoors, the WP Vanguard cleanup service handles full removal for $49. First cleanup is free. The team traces the full infection chain, removes every component, and closes the entry point.
The Bottom Line
Backdoors are what make WordPress malware persistent. You can clean the visible symptoms all day, but if the backdoor survives, the attacker returns. Server-level scanning that checks file integrity, detects obfuscation, and examines every directory is the only reliable way to find them all.
Scan your site to check for known vulnerabilities and signs of compromise. If a deeper look is needed, the $1 deep scan examines your server at the level where backdoors actually hide.
Related reading
Check Your WordPress Site Security
Free scan, no login required. Find vulnerabilities before attackers do.
Scan Your Site FreeGet weekly WordPress security tips
Vulnerability alerts, plugin updates, and security guides. No spam. Unsubscribe any time.