This guide assumes you have confirmed the infection. If you have not, start with the five-minute check. If you have just found the problem, do the first-hour steps in How to Fix a Hacked WordPress Site first. They cover the backup, the offline decision and changing every credential, and you should not skip them.

Before you run anything: you need the infected backup from the fix guide, SSH or SFTP access, and ideally WP-CLI (most managed hosts include it). Run the commands from the WordPress folder, often public_html. Test them on a staging copy if you can, and put the live site in maintenance mode while you work.

Step 1: Make a quarantine folder

Move suspicious files out of the site instead of deleting them. A false positive is easy to restore, and a deleted file is not. Put the folder outside the web root:

mkdir -p ~/quarantine

Step 2: Replace WordPress core

Core folders should never contain hand-edited code, so replacing them is safe. Save the version number first, because you are about to remove the file that stores it:

VERSION=$(wp core version)
rm -rf wp-admin wp-includes
wp core download --force --skip-content --version=$VERSION
wp core verify-checksums

The download restores clean copies of the core folders and the root files such as index.php and wp-login.php. The last command should report that everything verifies. Any "File should not exist" line is a stray file hiding among core files. Move it to quarantine.

wp-config.php is not part of the download, so open it and read it. Look for code above the opening lines or below the last line, and for any eval, base64_decode, or include pointing at a file you do not recognize.

Step 3: Reinstall plugins and themes

Reinstall each plugin and theme from its original source instead of cleaning an infected copy. It is faster, and you will not miss a subtly changed file.

wp plugin list
wp plugin install PLUGIN-SLUG --force
wp theme install THEME-SLUG --force
wp plugin verify-checksums --all

Premium plugins and themes are not on wordpress.org, so download a fresh copy from the vendor and upload it. Remove anything you do not use or recognize, and delete it instead of only deactivating it. A deactivated plugin's files can still be run directly by anyone who knows the path:

wp plugin deactivate PLUGIN-SLUG
wp plugin delete PLUGIN-SLUG

Step 4: Check the usual hiding places

Malware rarely stays in one file. Check these places even after replacing core and plugins, because they sit outside what you just reinstalled.

grep -RIl --include="*.php" -E "eval\(|base64_decode\(|gzinflate\(|str_rot13\(" wp-content
find wp-content/uploads -name "*.php"
ls -la wp-content/mu-plugins
cat .htaccess
wp cron event list
  • The grep results. These functions also appear in legitimate code, so a match is a lead, not proof. Open each file and read it. Do not delete a plugin file because it matched.
  • wp-content/uploads. It should hold media only. Any PHP file here goes to quarantine.
  • wp-content/mu-plugins. Must-use plugins load automatically and do not appear in the normal plugin list. A file here that you did not add is a strong warning sign.
  • .htaccess. Compare it with the default WordPress rules. Injected redirect rules, especially ones that depend on the visitor's referrer or device, are a classic hack.
  • .user.ini and php.ini. Look for an auto_prepend_file line. It runs a file before every page, and is a favorite place to keep a backdoor.
  • Theme files. Open functions.php, header.php and footer.php in your active theme and look for code you did not write.
  • Scheduled tasks. A cron event that calls an unfamiliar function can recreate a backdoor after you delete it. Remove it with wp cron event delete HOOK-NAME.

For more on hidden login access, see How to Find a WordPress Backdoor.

Step 5: Clean the database

Malware often lives in the database, where a file scan never looks. Back it up first with wp db export. Your table prefix may not be wp_, so check it:

wp db prefix
wp db query "SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl','home');"
wp db query "SELECT ID, user_login, user_email, user_registered FROM wp_users ORDER BY user_registered DESC LIMIT 20;"
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%' OR post_content LIKE '%display:none%';"
wp db query "SELECT option_name FROM wp_options WHERE option_value LIKE '%<script%' LIMIT 50;"
  • siteurl and home. Both must be your own domain. A different value redirects the whole site without changing a file.
  • Recent users. Any administrator you did not create can be removed with wp user delete ID --reassign=ADMIN-ID.
  • Posts and options with script tags. Some contain legitimate analytics or embed code. Review each result, then clean only the injected part.

Step 6: Close the access the attacker used

If you have not changed every credential yet, do it now. The full order, from hosting access down to WordPress logins, is in Step 5 of the fix guide. Regenerate the security keys with wp config shuffle-salts so existing sessions end.

Step 7: Verify, then keep watching

wp core verify-checksums
wp plugin verify-checksums --all
find wp-content/uploads -name "*.php"

Clear any cache. Then visit the site from your phone on mobile data, arriving from a Google result, because redirect hacks often hide from direct visits. If Google flagged the site, request a review under Security issues in Search Console. Run the checks again after 24 hours and after a week. A file or admin account that returns means a backdoor or the entry point was missed.

If the malware comes back

A repeat infection almost always has one of two causes: a backdoor that was never found, or an entry point that was never closed. Re-check mu-plugins, .htaccess, .user.ini and scheduled tasks. Then work through Step 7 of the fix guide to find how the attacker got in: outdated or pirated plugins, stolen hosting credentials and server logs.

How SiftWP helps

SiftWP runs file-integrity, database and malware checks like these every week over SSH, with no plugin on your site. Flagged files are quarantined, never deleted outright. Low-risk fixes are applied automatically, and anything ambiguous stops and asks you first.

Start with free credits, no card needed