← Back to all posts
September 16, 2026
•

Hacked WordPress Site Recovery: The Exact Process a Specialist Follows

Red padlock on a black computer keyboard, illustrating hacked WordPress site recovery

Your site is redirecting visitors to a pharmacy page, Google Search Console has flagged it for deceptive content, or your host has suspended the account because it was sending spam. That is the moment most owners go looking for a hacked WordPress site recovery specialist, and the honest answer to “what will they actually do?” is: follow a fixed process, in a fixed order, and refuse to skip steps. This article walks through that process exactly as we run it for clients through our hacked WordPress site recovery service.

It is written for the business owner or CTO who has to decide today whether to clean the site in-house or bring someone in. If you have SSH access and a developer who is comfortable on the command line, you can run most of this yourself. If you do not, you will at least know what a competent specialist is doing, why it takes the time it takes, and why a “malware scan” button in a plugin is not the same thing as recovery.

what a hacked WordPress site recovery specialist does in the first hour

The first hour is about containment and evidence, not cleaning. Every time we have seen a recovery fail, it was because someone started deleting files before they understood the breach, and the attacker walked back in through the same door a week later.

take the site out of the line of fire

Put a static holding page in front of WordPress so visitors stop being served malware and Google stops crawling it. On Nginx that is a single return 503 in the server block with a Retry-After header; on Apache it is a couple of lines in .htaccess. Do not use a WordPress maintenance plugin for this: it runs inside the compromised PHP application, so it proves nothing.

snapshot everything before you touch it

Archive the web root and dump the database to a location outside the web root. This is your forensic copy. It is also the only way to answer the question “what did they change?” once you start replacing files.

cd /var/www
tar -czf /root/forensics/site-$(date +%F).tar.gz example.com/
wp db export /root/forensics/db-$(date +%F).sql --path=/var/www/example.com
cp /var/log/nginx/access.log* /root/forensics/

rotate every credential

Assume everything stored on the server is known to the attacker. That means all WordPress administrator passwords, the database password in wp-config.php, SFTP and SSH keys, the authentication salts, any API keys stored in wp_options (payment gateways, SMTP, CRM connectors) and the hosting control panel login. Generate new salts with wp config shuffle-salts, which also invalidates every existing login cookie.

finding the entry point

A clean-up without a root cause is a temporary clean-up. This is the part of the job that separates a hacked WordPress site recovery specialist from a scanner. There are four places we look, in this order.

file integrity

WordPress core and every plugin from wordpress.org ship with published checksums. WP-CLI compares your files against them, and a couple of find commands catch what checksums cannot see:

wp core verify-checksums
wp plugin verify-checksums --all
find . -type f -name "*.php" -mtime -14 -not -path "./wp-includes/*" -not -path "./wp-admin/*"
find wp-content/uploads -type f ( -name "*.php" -o -name "*.phtml" -o -name "*.php5" -o -name "*.ico" ) -size +1k

Then grep for the usual obfuscation patterns. Real malware is rarely clever; it is usually eval(base64_decode(...)), gzinflate, str_rot13, a long hex string, or a file named wp-cache.php sitting somewhere core never puts one.

grep -rlE 'eval(base64_decode|gzinflate(|str_rot13(|$_(POST|GET|REQUEST)[' wp-content wp-config.php index.php
ls -la wp-content/mu-plugins/
cat .htaccess

the database

Attackers who cannot keep a file on disk keep a foothold in the database instead. Check wp_users for accounts you did not create, wp_options for changed siteurl and home values or unknown entries in active_plugins, the serialized cron option for scheduled events that re-download the payload, and wp_posts for injected script tags.

SELECT ID, user_login, user_email, user_registered FROM wp_users ORDER BY user_registered DESC LIMIT 20;
SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl','home','active_plugins','default_role','users_can_register');
SELECT ID, post_title, post_type FROM wp_posts WHERE post_content LIKE '%<script%' AND post_type IN ('post','page') LIMIT 50;
SELECT option_name FROM wp_options WHERE option_value LIKE '%base64_decode%' OR option_value LIKE '%eval(%';

the access logs

This is where the actual answer usually is. Find the first request to the malicious file, then look at what the same IP did before that request. Typical findings: a POST to a plugin upload handler that had a public CVE, a successful login on wp-login.php after a few thousand attempts, or an unauthenticated REST or admin-ajax.php route from a plugin that had not been updated in years.

the environment

Sometimes the site was not the target. Shared hosting with a compromised neighbour, a password reused from another breach, or a developer laptop with an infected FTP client will all put files on your server without any WordPress vulnerability at all. A specialist asks about these; a scanner cannot.

cleaning without destroying the site

The principle is simple: keep nothing you cannot verify. Every file on the server is either a pristine copy from a trusted source, an upload you can identify (images, PDFs), or it goes.

  1. Replace core. wp core download --force --skip-content --version=$(wp core version) overwrites wp-admin, wp-includes and the root PHP files with a clean copy.
  2. Reinstall every plugin and theme. For wordpress.org plugins, wp plugin install <slug> --force. For premium plugins, a fresh zip from the vendor account. If a plugin is abandoned and has a known vulnerability, it does not go back on the site.
  3. Purge what should not exist. Unknown files in wp-content/uploads, anything in mu-plugins you did not put there, extra index.php files in random directories, and rewrite rules in .htaccess you cannot explain.
  4. Clean the database. Remove rogue administrator users, restore siteurl and home, delete unknown cron hooks, and strip injected scripts from post_content. For simple injections, wp search-replace with the exact string works; for anything that varies per post, a short PHP script over get_posts() is safer than a regex in SQL.
  5. Rebuild wp-config.php by hand from a fresh copy. Attackers love a single require line at the bottom of this file.

A common question is whether to restore from backup instead. If you have a backup that pre-dates the compromise and you know the entry point, a restore plus patch is faster. If you do not know when the breach happened, restoring blindly just resurrects the back door. We covered how to build a backup you can actually trust in Automated WordPress Backup System Setup: Offsite, Versioned and Actually Tested.

Clean in place Restore from backup
Best when No trusted pre-breach backup, or the breach date is unknown Breach date is known and a clean backup exists before it
Main risk Missing a hidden file or a database foothold Restoring the vulnerability along with the site; losing recent content or orders
Typical time 4-12 hours 1-3 hours plus patching

closing the door so it stays closed

Once the site is clean, the entry point gets fixed and the general attack surface gets smaller. The specific fix depends on what you found in the logs; the hardening list below is what we apply on every recovery regardless.

  • Update the vulnerable plugin or replace it. If the site is stuck on an old release because the newer version needs a newer PHP, that is a separate job and we treat it as one; see upgrading to PHP 8 without downtime or our PHP version compatibility fix service.
  • Block PHP execution in uploads at the web server, not in a plugin.
  • Set DISALLOW_FILE_EDIT and, on production, DISALLOW_FILE_MODS in wp-config.php so plugins are deployed by a person with server access, not through the dashboard.
  • Correct permissions: directories 755, files 644, wp-config.php 440, owned by a user that PHP-FPM does not run as, where the host allows it.
  • Two-factor authentication on every administrator account, login rate limiting, and xmlrpc.php disabled unless something genuinely uses it.
  • A web application firewall in front of the origin (Cloudflare WAF rules or a server-level ruleset), so the next zero-day is blocked before it reaches PHP.
# Nginx: never execute PHP from uploads
location ~* /wp-content/uploads/.*.(php|phtml|php5|phar)$ {
    deny all;
}

# wp-config.php
define( 'DISALLOW_FILE_EDIT', true );
define( 'DISALLOW_FILE_MODS', true );
define( 'FORCE_SSL_ADMIN', true );

getting the warnings removed

A clean site that still shows a red interstitial in Chrome is not recovered from the business point of view. This part is slower than the technical work and mostly involves waiting.

  • Google Search Console: open the Security Issues report, then request a review with a short, factual description of what was found and fixed. Reviews typically clear in one to three days when the site is genuinely clean; if any injected URL is still reachable the request is rejected and the clock restarts.
  • Safe Browsing and third-party blacklists: check Google Safe Browsing, Sucuri SiteCheck and VirusTotal. Most delist automatically after a re-scan; some need a manual request.
  • Mail blacklists: if the server was sending spam, check the IP against Spamhaus and similar lists and request delisting once the outbound queue is confirmed empty.
  • The host: most hosts reinstate a suspended account when you show them the clean checksum output and the hardening applied.

verifying the recovery and watching for a return

Recovery is verified, not assumed. We re-run the checksum verification and the grep sweep from a clean shell, load every template type through a proxy with a mobile and a Googlebot user agent to check for conditional redirects (attackers often only redirect mobile or search-engine traffic), and confirm that no new cron events or users have appeared over 72 hours.

After that, monitoring: a daily wp core verify-checksums and wp plugin verify-checksums --all in cron that emails on any diff, file-change monitoring on wp-content, uptime checks that also assert on page content, and access logs retained for at least 90 days so the next investigation has data. This belongs in an ongoing website maintenance and support arrangement rather than a one-off, because update discipline is what actually prevents the next incident.

# /etc/cron.d/wp-integrity
15 3 * * * www-data cd /var/www/example.com && (wp core verify-checksums; wp plugin verify-checksums --all) 2>&1 | grep -v "^Success" | mail -E -s "Integrity diff: example.com" [email protected]

when to do this yourself vs hire a specialist

Do it yourself if the site is small, you have SSH and WP-CLI, you found the entry point in the logs within an hour, and you can afford the site being down for a day while you work carefully. The steps above are complete enough to follow.

Hire a hacked WordPress site recovery specialist if any of the following are true: the site takes orders or holds customer data; the host has already suspended it; you cannot find the entry point; the infection has come back once already; or nobody on your team has shell access. The cost of a professional recovery is usually a fraction of a day of lost sales, and the real value is the root-cause finding, not the file deletion.

get your site back, with the hole closed

If you are dealing with this right now, send us the domain and whatever your host or Search Console has told you. Within 24 hours you will know what it costs and how long it takes, as a fixed scope and fixed price in writing, and the senior engineer who scopes it is the one who does the work. Start with our hacked WordPress site recovery specialist service or contact us directly, and include the word “urgent” if the site is currently down.

Share this post

keep reading

Portable external hard drive connected to a laptop, illustrating an automated WordPress backup system
September 22, 2026
•

Automated WordPress Backup System Setup: Offsite, Versioned and Actually Tested

Automated WordPress backup system setup done properly: offsite S3 storage, versioned retention, write-only credentials, hourly store backups, tested restores.

Read more
Page speed test results on a monitor, illustrating Core Web Vitals optimization for WordPress
September 20, 2026
•

Core Web Vitals Optimization for WordPress: LCP, INP and CLS Fixes That Actually Work

Core Web Vitals optimization for WordPress, metric by metric: the LCP, INP and CLS fixes in theme, plugins and server that move…

Read more
Glass cloud icon with data layers above a padlock, illustrating AWS hosting migration for WordPress
September 18, 2026
•

AWS Hosting Migration for WordPress: Lightsail vs EC2 vs Managed Hosting

AWS hosting migration for WordPress compared: Lightsail vs EC2 with RDS vs managed hosting, the migration steps we run, and what breaks…

Read more

want this kind of thinking on your project?

Tell us what you are building and we'll come back with a straight answer on scope, timeline and cost within 24 hours.
start a project