Project

General

Profile

Unhacking a WordPress site » History » Version 3

Manu Mei-Singh, 11/11/2024 04:46 PM

1 1 Jon Goldberg
h1. Unhacking a WordPress site
2
3
This is an INCOMPLETE guide, but a good starting point!  It doesn't cover removing malicious code inserted into the database, for instance.
4
5
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.
6
7
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.
8
9
* Search for suspicious PHP commands:
10
<pre>
11
grep -r gzuncompress *
12
grep -r base64_decode *
13
grep -r eval( *
14
grep -r str_rev *
15
</pre>
16
17
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.  
18
19
Note that there are MANY ways to obscure the commands above.  Here are some example strings you can also search for
20
<pre>
21
"base" . "64_decode"
22
eval/*
23
</pre>
24
25
That last one's tricky.  It found this command: @eval/*boguscomment*/('malicious_command')@.
26
27
28
29
* Check for this:
30
<pre>
31
<?php eval(get_option("\x72\x65\x6e\x64\x65\x72")); ?>
32
</pre>
33
34
That evaluates to:
35
<pre>
36
<?php eval(get_option("render")); ?>
37
</pre>
38
39
This indicates that there's malicious code in your database, and this minimal change allows the code to render.
40
41
Here's the commands I used to remove that from my entire codebase:
42
<pre>
43
find -name \*php -exec sed -i 's/<?php eval(get_option("\\x72\\x65\\x6e\\x64\\x65\\x72")); ?>//g' {} \;
44
find -name \*.html -exec sed -i 's/<?php eval(get_option("\\x72\\x65\\x6e\\x64\\x65\\x72")); ?>//g' {} \;
45
</pre>
46
47
* 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.
48
* Use @git reset --hard HEAD@, if you're using git.
49
* 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):
50
<pre>
51
find .git -name \*php
52
find wp-content/uploads -name \*php
53
</pre>
54 2 Manu Mei-Singh
55
56
From when Highlander was hacked: 
57
58
59
_*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)
60
61
# Confirm that the site is hacked or being actively attacked
62 3 Manu Mei-Singh
**  This "flow chart":https://drive.google.com/file/d/1Z3u9hyVwIzyhY4EJKp6ixBMEX47P9mBZ/view?usp=drive_link might be of assistance
63
# If the site is compromised, ssh into the site
64
# Go to the web root directory and vim .htaccess
65
# uncomment line 94 and change it with your ip so it should like this.
66 2 Manu Mei-Singh
<pre>Require ip your.ip.goes.here  another.ip.goes.here</pre>
67 3 Manu Mei-Singh
** Note that if it's a DOS or DDOS you'll need to set up some sort of firewall at the server level. 
68
# Save the htaccess file and confirm that only the required ips can access the site.
69
# Login into the site; you should be able to find login information via bitwarden.
70
# Goto plugins
71 2 Manu Mei-Singh
# activate Wordfence Security and run the malware scan
72
## this may take some time to complete.
73 3 Manu Mei-Singh
## there will be some red herrings, such as un updated files. 
74 2 Manu Mei-Singh
#  If you find something confirm that the it's a hacked file...
75 1 Jon Goldberg
## When you ssh into the root directory, run git status to see if any files have been changed.
76
## If the same file pops up, the site might be compromised. 
77 2 Manu Mei-Singh
# If the site is indeed compromised. clean up up the bad files. 
78
#  Check the database for compromised data. 
79 3 Manu Mei-Singh
# First check if there were new users created:
80 2 Manu Mei-Singh
<pre>  wp user list --role=administrator --format=table </pre>
81
** 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
82
# If there bogus users, you'll need to delete them either through the wp cli or through web admin panel.
83
# Check for bogus post data 
84
** <pre>  wp db query 'SELECT * FROM `wp1_posts` ORDER BY `wp1_posts`.`post_date_gmt` DESC LIMIT 10;'  >> ~/last_post.txt </pre> 
85 3 Manu Mei-Singh
** 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.
86
** If it's a different website you'll need to make sure table names match. 
87
# If there is bogus data it's best to go into updraft plus and revert to the last clean back-up 
88
# You may want to change passwords at this point for users. 
89 2 Manu Mei-Singh
# If that worked you can change the .htaccess file back by commenting out line 94
90 3 Manu Mei-Singh
# Confirm that the site is working for all.
91
# Continue to monitor the site for a few days
Go to top