Project

General

Profile

Actions

Unhacking a WordPress site » History » Revision 2

« Previous | Revision 2/3 (diff) | Next »
Manu Mei-Singh, 02/14/2024 10:50 PM


Unhacking a WordPress site

This is an INCOMPLETE guide, but a good starting point! It doesn't cover removing malicious code inserted into the database, for instance.

WordPress gets hacked - a lot. And the correct solution is to restore your database and filesystem from backup. However, sometimes we deal with sites that weren't responsibly managed, and that's not an option. Here's a guide on what to do.

First - if it IS an option, delete your WordPress filesystem and restore from known good files. There's just too many ways to obfuscate a hack, so these approaches are necessarily incomplete.

  • Search for suspicious PHP commands:
    grep -r gzuncompress *
    grep -r base64_decode *
    grep -r eval( *
    grep -r str_rev *
    

Not every instance of these commands is malicious! However, a hacked site will often use these, so look at what comes after them. If it's a long base64 block, that's bad news.

Note that there are MANY ways to obscure the commands above. Here are some example strings you can also search for

"base" . "64_decode" 
eval/*

That last one's tricky. It found this command: eval/*boguscomment*/('malicious_command').

  • Check for this:
    <?php eval(get_option("\x72\x65\x6e\x64\x65\x72")); ?>
    

That evaluates to:

<?php eval(get_option("render")); ?>

This indicates that there's malicious code in your database, and this minimal change allows the code to render.

Here's the commands I used to remove that from my entire codebase:

find -name \*php -exec sed -i 's/<?php eval(get_option("\\x72\\x65\\x6e\\x64\\x65\\x72")); ?>//g' {} \;
find -name \*.html -exec sed -i 's/<?php eval(get_option("\\x72\\x65\\x6e\\x64\\x65\\x72")); ?>//g' {} \;

  • Look for function names you discovered with the last command and grep for those. I found commands like "ruburat" and "ukonabuh" which I then searched for.
  • Use git reset --hard HEAD, if you're using git.
  • Don't assume git will remove everything! I found php files in places not checked by git. E.g. in the .git folder, to wp-config.php and civicrm.settings.php, wp-content/uploads. Here are some commands to help you find php files where they don't belong (run from webroot):
    find .git -name \*php
    find wp-content/uploads -name \*php
    

From when Highlander was hacked:

If the site is hacked (note that I wrote these fast and before my vacation... they should probably be updated and my guess is this process can be refined)

  1. Confirm that the site is hacked or being actively attacked
    • There maybe bogus data created or the site is no loading or something else
  2. If it being is compromised ssh into the site
  3. go to the web root directory
  4. vim .htaccess
  5. uncomment line 94 and change it with your ip so it should be something like
    Require ip your.ip.goes.here  another.ip.goes.here
  6. save it. and confirm that only the folks from those ips can access the site
  7. Login into the site with Manu's user name, password
  8. goto plugins
  9. activate Wordfence Security and run the malware scan
    1. this may take some time to complete.
    2. there will be some red herrings as well because of files not updated
  10. If you find something confirm that the it's a hacked file...
    1. When you ssh into the root directory, run git status to see if any files have been changed.
    2. If the same file pops up, the site might be compromised.
  11. If the site is indeed compromised. clean up up the bad files.
  12. Check the database for compromised data.
  13. First I check if there were new users created:
      wp user list --role=administrator --format=table 
    • The above command produces a table that you can review and look for out of the ordinary users with wired emails and recent user_registered time stamps
  14. If there bogus users, you'll need to delete them either through the wp cli or through web admin panel.
  15. Check for bogus post data
    •   wp db query 'SELECT * FROM `wp1_posts` ORDER BY `wp1_posts`.`post_date_gmt` DESC LIMIT 10;'  >> ~/last_post.txt 
    • I use the above command to see if the last 10 post entires seem out of the ordinary. I then save it to a file
  16. If there is bogus data it's probably best to go into updraft plus and revert to the last back-up
  17. you may want to change passwords at this point for users.
  18. If that worked you can change the .htaccess file back by commenting out line 94
  19. confirm that the site is working for all.
  20. monitor for a few days

Updated by Manu Mei-Singh 9 months ago · 2 revisions

Also available in: PDF HTML TXT

Go to top