Unhacking a WordPress site » History » Version 1
Jon Goldberg, 07/22/2016 01:52 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> |