Skip to content
CH SCShop classwordpress · advanced · ~150 min · 7 steps

How to clean up a hacked WordPress site

Contain a compromised WordPress site, find and remove the malware and its backdoors, close the hole, and get off the blocklists.

August 10, 2026 · by Dane Petersen

This is the long portage: heavy for a stretch, then it opens up. Take it in order and don’t skip steps — the number one cause of reinfection is a cleanup that removed the malware but left the backdoor. You’ll need SSH access, WP-CLI set up, and a recent backup you trust. If you’re still in the first panicked hour, read the first-steps essay first, then come back here for the full job.

Contain first: passwords and a holding page

Before hunting anything, stop the bleeding. Change the hosting, SFTP, and database passwords, and reset every admin password:

wp user list --role=administrator --fields=ID,user_login,user_email
wp user update ADMIN_ID --user_pass="$(openssl rand -base64 18)"

Look hard at that admin list — an account you don’t recognize is the attacker’s, and it gets deleted, not just demoted. If the site is serving spam or malware to visitors, put up a maintenance page at the server level while you work.

Preserve the evidence

Take a full copy of the site as it stands — files and database — before you delete a single thing:

tar -czf ../evidence-$(date +%Y-%m-%d).tar.gz .
wp db export ../evidence-$(date +%Y-%m-%d).sql

This feels backwards. It isn’t. The infected copy tells you how they got in, and if you delete something the site needed, it’s your undo button.

Verify core and plugin checksums

Let WordPress.org tell you which files were modified:

wp core verify-checksums
wp plugin verify-checksums --all

Every file that fails is either infected or added. Reinstall core cleanly rather than editing infected files by hand:

wp core download --force --version=$(wp core version)

Then reinstall each flagged plugin from the repository the same way, with wp plugin install PLUGIN --force. Note that premium plugins can’t be checksummed — re-download those from the vendor.

Hunt the backdoors

Checksums don’t cover uploads, mu-plugins, or extra files the attacker dropped. PHP has no business living in your uploads folder:

find wp-content/uploads -name "*.php"
grep -rl "eval(base64_decode\|gzinflate(base64_decode\|str_rot13" wp-content/ --include="*.php"

Also list files changed in the last month (find . -name "*.php" -mtime -30) and read wp-config.php, the active theme’s functions.php, and everything in mu-plugins/ line by line. Anything obfuscated, anything you can’t explain, goes. Expect to find two or three backdoors — attackers plant spares.

Close the way in

A clean site with the original hole is a clean site for about a week. The usual doors, in order of likelihood: a vulnerable plugin or theme (update everything, remove anything abandoned), a stolen password, or a neighboring site on the same account. Your server’s access logs — see reading your error logs — often show the first malicious POST request, which names the entry point exactly.

Rotate the salts and every credential

Stolen cookies survive password changes; new salts kill every session on the site, including the attacker’s:

wp config shuffle-salts

Then rotate what’s left: the database password (in both MySQL and wp-config.php), API keys, SMTP credentials, and any reused passwords elsewhere. Assume everything in wp-config.php was read.

Request blocklist review and watch the logs

If Google flagged the site, open Search Console’s Security Issues report, confirm each issue is fixed, and request a review — it typically clears in a few days. Then verify your work: checksums pass clean, the uploads find comes back empty, no unexplained admins, and the site behaves logged-out in a private window. Watch the access logs daily for two weeks; a returning attacker probing their dead backdoor is loud and obvious. When it stays quiet, spend the next hour on hardening so you never run this tutorial twice.

That's the lesson. Back to the shop for more — or if this is the chore your organization never gets to,that's literally what we're for.