WordPress Malware Removal: Complete Step-by-Step Guide
Follow this comprehensive guide to identify, remove, and prevent WordPress malware infections with proven cleanup procedures.
Introduction
Discovering malware on your WordPress site requires immediate, systematic action. This guide walks through the complete cleanup process from identification to prevention.
Signs of Malware Infection
Common indicators your site is compromised:
- Google Safe Browsing warnings
- Unexpected redirects to other sites
- Strange admin users you did not create
- Modified core files
- Spam content appearing in posts
- Slow site performance
- Hosting provider suspension notice
Step 1: Backup Everything First
# Create full backup before cleanup
# This preserves evidence and allows recovery if needed
# Backup database
mysqldump -u username -p database_name > backup_infected_$(date +%Y%m%d).sql
# Backup files
tar -czf backup_infected_$(date +%Y%m%d).tar.gz /path/to/wordpress/
# Store backups offsite - do not keep on same server
Step 2: Take Site Offline
// Add to wp-config.php temporarily
define('WP_MAINTENANCE_MODE', true);
// Or create maintenance.php in root
<?php
header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Retry-After: 3600');
die('Site is undergoing maintenance. Please check back soon.');
?>
Step 3: Scan and Identify Malware
Scan your files for these common malware indicators:
- Obfuscation functions - eval(), base64_decode(), gzinflate(), str_rot13()
- Code execution - preg_replace with /e modifier, assert(), create_function()
- Shell access - shell_exec(), passthru(), system(), exec()
- User input handling - Direct access to $_GET, $_POST, $_REQUEST
- File operations - file_put_contents() with user input, move_uploaded_file()
- Encoding tricks - Hex encoded strings, chr() encoding
Use a recursive directory scanner to check all PHP and JS files for these patterns. Log the file path, matched pattern, and line number for each finding.
Step 4: Check WordPress Core Files
Verify WordPress core file integrity:
- Get official checksums - Query api.wordpress.org for your version's checksums
- Compare file hashes - MD5 hash each core file and compare against official values
- Identify modifications - Flag any files with mismatched hashes as potentially compromised
- Find missing files - Note any expected core files that are missing
- Detect extra files - Look for unexpected files in wp-admin and wp-includes directories
Any modified, missing, or extra files in core directories should be investigated and replaced with clean versions.
Step 5: Clean Infected Files
# Replace WordPress core with fresh download
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
# Replace wp-admin and wp-includes (keep wp-content)
rsync -av wordpress/wp-admin/ /path/to/site/wp-admin/
rsync -av wordpress/wp-includes/ /path/to/site/wp-includes/
# Replace root PHP files except wp-config.php
cp wordpress/*.php /path/to/site/
# Do NOT copy wp-config.php - it contains your settings
Step 6: Clean Database
-- Find suspicious content in posts
SELECT ID, post_title, post_date
FROM wp_posts
WHERE post_content LIKE '%<script%'
OR post_content LIKE '%eval(%'
OR post_content LIKE '%base64_decode%'
OR post_content LIKE '%document.write%';
-- Check for rogue admin users
SELECT ID, user_login, user_email, user_registered
FROM wp_users
WHERE ID IN (
SELECT user_id FROM wp_usermeta
WHERE meta_key = 'wp_capabilities'
AND meta_value LIKE '%administrator%'
);
-- Find suspicious options
SELECT option_name, LEFT(option_value, 100)
FROM wp_options
WHERE option_value LIKE '%eval%'
OR option_value LIKE '%base64_decode%'
OR option_name LIKE '%hack%'
OR option_name LIKE '%backdoor%';
-- Check for scheduled backdoors
SELECT * FROM wp_options WHERE option_name = 'cron';
Step 7: Reset All Credentials
Reset all passwords and secrets after a compromise:
- Force user password resets - Invalidate all user sessions and require new passwords
- Regenerate security keys - Visit api.wordpress.org/secret-key/1.1/salt/ for new keys
- Update wp-config.php - Replace AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY and salts
- Change database password - Update MySQL password and wp-config.php
- Update FTP/SFTP passwords - Change all file transfer credentials
- Change hosting panel password - Update cPanel, Plesk, or other control panel access
Step 8: Reinstall Plugins and Themes
# Delete and reinstall all plugins from fresh sources
wp plugin deactivate --all
rm -rf wp-content/plugins/*
wp plugin install plugin-name --activate
# Delete and reinstall theme
rm -rf wp-content/themes/theme-name
wp theme install theme-name --activate
# Do NOT restore from backup - redownload from source
Step 9: Implement Prevention
- Install security plugin with firewall
- Enable two-factor authentication
- Set up file integrity monitoring
- Configure automatic updates
- Implement regular backups
Conclusion
Malware removal requires systematic identification, thorough cleaning, and credential resets. Follow each step carefully and implement prevention measures to avoid reinfection.
Written by Sarah Chen
WP Folder Shield Team