WordPress application hacked 2/4 – How to recover the platform

8 January 2024 | IT and Hosting

In the previous post WordPress application hacked 1/4 – Immediate damage control, I explained what to do immediately after a security breach is detected. In this article we’ll be looking specifically at the wordpress platform and the quickest way to get it healthy and operational again.

Wordpress application hacked - How to recover the platform



There was tight coordination with our customer to fulfill their needs as best possible. For the actual platform recovery a substantial amount of the (technical) workload fell on my plate. However, if there are things the customer knows better, let them do it and don’t figure it all out yourself. As an example, the platform described here has a lot of specific functionality and thus functional testing was best done by the application maintainers on their end. This combined effort speeds up the recovery and thereby re-enabling their services sooner.



One tip before we dive in: If you cannot establish with 100% certainty that a component used during recovery is clean of any malicious infection, assume it is not. When for example you use a backup of a compromised system. What you restore from that backup will thus restore to a compromised situation still.

For completeness, these are the steps you should at least perform for a full platform recovery. As a reminder, this was about a WordPress platform, so these are somewhat tailored to that:

  • Review user accounts
  • Review strange and dated plugins and themes
  • Get to a clean base WordPress installation
  • Assert that your code is clean
  • Review and check all content files

NB: As stated in a previous article. If your platform holds credentials to for instance external API services, reset those passwords or keys as well.

After shutting down the service and isolating it from the public, there’s steps you should take on a higher level first. These are things like reviewing user accounts and checking themes and plugins. After that you need to clean out the files and possibly the database. Although the latter is not always at risk, there are known cases out there that describe risks therein as well. Via an external (or internal code) trigger, malicious code can be pulled from the database, placed back in memory or file. This can re-open a backdoor for the hackers. Your mileage may vary, but better safe than sorry.


Review user accounts

In coordination with the customer we checked all the user accounts. Consider the following steps to go through:

  • Remove all suspicious accounts
  • Remove any dated accounts
  • For the ones still in use, force a password reset

In case of needing more forensic evidence you could also check if access rights were changed based on previous user access roles (assuming you have those stored somewhere).

Note: Always use email accounts on your company’s domain name. This way you always have control of the mailboxes (for e.g. password reset emails). When email or accounts are hacked that are on a personal email address, there’s now way of knowing whether certain security policies are enforced and if such accounts are hacked. It is by all means not called a personal email address for nothing.


Strange plugins or themes

Looking at strange themes and plugins is one of the ‘higher level’ assessments you can do. Check and compare them possibly with a recent backup, or better yet and acceptance or test environment, to see if they were previously there. Mind you some hacks could be already in your platform for a while but under the radar. So make sure you assert that anything pulled from a backup is absolutely free from malicious code.

$ wp plugin list
| name                                    | status    | update                       | version   |
| acf-customizer                          | active    | none                         | 0.3.0     |
| advanced-custom-fields-pro              | active    | available                    | 6.0.7     |
| disable-application-passwords           | active    | available                    | 1.7       |
| google-analytics-dashboard-for-wp       | active    | available                    | 7.20.0    |
| wp-optimize                             | active    | available                    | 3.2.19    |

Note: The WP CLI command requires SSH access to where the website is hosted.

This output from the WP CLI command lists al the plugins and their state. You can of course check this via wp-admin as well. To be certain you should also compare this list with the plugin directores found in “./wp-content/plugins/”. Review this for your website and look for suspicious items and cleanup while you’re at it. Check for:

  • Weird plugin names (verify them with the vendor or on wordpress.org)
  • Plugins without a version
  • Disable and remove plugins if you don’t use them
  • Remove all disabled plugins since they weren’t used anyway

You can also do this with your themes. There should be just two themes installed. Your active theme obviously. I also advise you to have latest original wordpress theme installed. This is for testing things on any regular day when you’re troubleshooting issues. Make sure to remove all the others.


A clean WP installation

There’s a major trade off to consider when aiming for a quick recovery. If you can quickly assert that your files are clean you can leave them in place. Otherwise a wipe and reinstall of WordPress also does the trick and is often faster. Then you know for certain the installation is clean, and you can start to rebuild from there. The main goal is to focus on the result and how to get there quickly.

However, to satisfy my curiosity, I wanted to know if any wordpress files were infected. The simplest way to check this is to use the WP CLI command again to check the integrity of the installation.

# wp core verify-checksums
Warning: File doesn't verify against checksum: wp-includes/cron.php
Warning: File doesn't verify against checksum: wp-includes/plugin.php
Warning: File doesn't verify against checksum: wp-includes/blocks/file/view.min.js
-- SNIP --
Warning: File should not exist: wp-includes/js/thickbox/themes.php
Warning: File should not exist: wp-includes/js/thickbox/.htaccess
Warning: File should not exist: wp-includes/js/dist/server-side-mh.js
Warning: File should not exist: wp-includes/js/crop/.htaccess
Error: WordPress installation doesn't verify against checksums.


This gives you an immediate summary whether or not all files belonging to WordPress are clean or not. As you can see a lot of files were added and changed so starting with a clean installation definitely was the viable option in this case.


Cleanup your custom code

If you run an extensive custom code base on top of your WordPress installation as was the case, you need a way to establish your code is clean. A quick way to do that is to store checksums of your files after any update you deploy to perform an immediate scan. However, something like that belongs more under a nightly check as part of an IDS (intrusion detection system). A better option is versioning your code with github.com or similar. Of course any code development should run a versioning scheme nowadays. That way you can safely wipe everything (besides digital content) and simply redeploy the latest stable version you have deployed on your live system.

If there’s no way to get back to a clean code base the only route is to scan and examine your code thoroughly and look for weird code or symptoms. A good option for this is PHPCS (PHP Code Sniffer), but that’s something for another article.

This article is part of the series WordPress application hacked (and how to recover!).

Over Gerard

Gerard Petersen is oprichter en eigenaar van CAP5. Hij heeft meer dan 35 jaar ICT ervaring en 10+ jaar ervaring in ondernemerslandschap. Gerard wordt gedreven door de optimale combinatie tussen mens en techniek en gaat voor het maken van maatschappelijke impact. Gerard is vanuit CAP5 actief als adviseur voor ICT operatie en management. 

Meer over Gerard

Open chat
Hulp nodig?
Scan the code
Hi 👋 ... kan ik je helpen?