RevealTheme logo
Back to Blog

A WordPress Compromise: How It Was Caught and Recovered

A WordPress Compromise: How It Was Caught and Recovered
The RevealTheme Team

By

·

A WordPress compromise rarely announces itself with a dramatic defacement. Far more often it sits quietly: a few injected spam links in the footer, a cloaked redirect that only fires for mobile visitors arriving from Google, a stray PHP file in your uploads folder phoning home to a botnet. The site looks fine to you while it slowly poisons your search rankings and gets your domain blacklisted. This article walks through how these compromises actually get caught, and then through the recovery sequence that gets the site clean and keeps it that way.

The single most important thing to internalize up front: removing the malware is the easy part. The real work is finding how the attacker got in and proving there's no persistence left behind. Skip that, and you'll be cleaning the same site again in a week.

How a compromise gets caught

Most site owners don't discover a hack by noticing it themselves. They get told. The channels that usually fire first:

  • Google Search Console "Security issues." When Google's crawler detects injected spam or a malicious redirect, it flags the site under Security Issues and may show a "This site may be hacked" label in search results. This is frequently the earliest warning because Google crawls constantly.
  • Browser interstitials. Chrome, Safari, and Firefox all consume Google Safe Browsing data. A bright red "Deceptive site ahead" screen in front of your homepage is a brutal but unambiguous signal.
  • Host suspension or abuse notices. Hosts like SiteGround, Kinsta, and Cloudways run their own scanners. If your site starts sending outbound spam or eating CPU, they'll email you or suspend the account.
  • Security plugin alerts. Wordfence, Sucuri, and MalCare email you on file changes, new admin users, or signature matches from their scheduled scans.

If you want to catch problems before Google does the catching for you, there are a few checks worth running yourself when something feels off:

  • Run site:yourdomain.com in Google. Scroll the results for pages you never created — pharma keywords, gambling, or garbled "Japanese keyword hack" titles are classic. These pages are often cloaked, so they're invisible when you browse the site normally but plainly visible to Googlebot.
  • Test as a search-engine bot. Visit your site after clicking through from a Google result, and try it on mobile. Many redirect hacks fire only for that specific referrer or user-agent, which is exactly why owners miss them.
  • Run wp core verify-checksums with WP-CLI. This compares your core files against the official WordPress.org checksums and reports any that have been modified or added. It's one of the fastest ways to spot tampering in wp-admin and wp-includes.
  • Watch for new admin users and unexplained traffic. An admin account you don't recognize, or a sudden CPU/bandwidth spike with no marketing campaign behind it, both point at a backdoor doing work in the background.

Isolate before you touch anything

Once you've confirmed a compromise, resist the urge to start deleting files immediately. Two things come first.

Put the site into maintenance mode so visitors aren't exposed to the malicious payload and Google doesn't keep re-flagging it while you work. Then take a snapshot of the compromised state — a full file and database backup, clearly labelled as infected. You are not going to restore this; you're keeping it as evidence so you can study the attacker's footprint and confirm later that you removed all of it. Cleaning blind, without a reference copy, is how people miss the second backdoor.

The two recovery paths

There are two legitimate ways to get clean, and the choice is a genuine trade-off.

Path one: restore from a known-clean backup

If you have a backup from before the breach — and you can be reasonably sure of when the breach happened — restoring it is the fastest route to a trustworthy file system. The catches are real, though. You lose any legitimate content, orders, or comments created since that backup. And critically, a restore does nothing about the entry vector. If the attacker came in through a vulnerable plugin and you restore a copy that still has that vulnerable plugin, you'll be reinfected by the same botnet scan within hours. A backup that post-dates the breach is worse than useless: it just reinstalls the malware.

Path two: manual cleanup

When backups are missing, stale, or possibly already infected, you clean in place:

  1. Replace core. Run wp core download --force (or delete and reupload wp-admin and wp-includes from a fresh download). Never trust the existing core files.
  2. Reinstall plugins and themes from clean sources. Delete them entirely and reinstall from the WordPress.org repository or the developer's official package — don't just deactivate. Drop any plugin you can't account for or no longer use.
  3. Scan wp-content/uploads for PHP. Your uploads directory should contain images and documents, never executable PHP. A .php file in there is almost always a backdoor.

Hunting the indicators of compromise

This is the part that separates a real cleanup from a cosmetic one. Attackers hide persistence in predictable places, so check each one deliberately:

  • Obfuscated code. Grep your files for base64_decode, eval(, gzinflate, str_rot13, and assec/create_function patterns. Long unreadable strings being decoded and executed are the signature of injected malware.
  • Modified critical files. Inspect wp-config.php, .htaccess (look for injected redirect rules), and your active theme's functions.php. These are the favourite hiding spots because they load on every request, and automated scanners sometimes miss small, hand-placed additions here.
  • Rogue admin users. Delete any administrator account you didn't create. Attackers often pick legitimate-sounding names like "support" or "admin2" to blend in.
  • Malicious scheduled tasks. Check wp-cron entries (wp cron event list) for jobs that re-download the payload. This is a common persistence trick — you clean the files, and the next cron run quietly restores them.

Close the door and rotate everything

Now the step people skip. Find and patch the entry vector. In the large majority of WordPress compromises it's a known vulnerability in an outdated plugin or theme. Cross-reference your installed plugins against the WPScan vulnerability database or Wordfence Intelligence, find the one with a recently published CVE, and update or remove it. Until that hole is closed, nothing else you've done matters.

Then invalidate everything the attacker might hold:

  • Reset all administrator passwords, plus the database user password and your hosting/SFTP credentials.
  • Regenerate the salts and secret keys in wp-config.php using the WordPress salt generator. Changing these forcibly logs out every existing session, which kills any cookie the attacker still has even after a password change.

Clear the blacklist and decide when to call for help

With the site verified clean, run a final scan from scratch, lift maintenance mode, and submit a review request in Google Search Console under the Security Issues report. Reviews typically take anywhere from a day to a couple of weeks; the red interstitial stays up until Google reconfirms the site is clean, so don't request the review until you're genuinely confident.

And know your limit. If you find layered backdoors, a database stuffed with injected content, or the infection keeps returning after you thought you'd cleaned it, hand it to a professional service like Sucuri or Wordfence Care. A guaranteed cleanup costs roughly a couple hundred dollars a year and includes blacklist removal — cheap insurance against a reinfection loop you can't break.

The throughline worth remembering: detection is mostly about listening to the right channels, and recovery is mostly about discipline — snapshot first, hunt persistence thoroughly, and never, ever finish without closing the door the attacker walked through.