Cleaning A Hacked WordPress Site

While this is a Workshop, showing you and walking you through dehacking a WordPress site is hard to do in a setting like this. If I said 'everyone has to have a local install of WordPress in order to be here' it would scare off the people who need it most. So this is a Tutorialesque Workshop out of necessity. The people who are here without computers, who are worried that they're not technical ENOUGH to do this? Yes, you can too do this.

Have You Been Hacked?

Is your site really slow?

Do you get errors all over the place?

Are you using a lot of resources?

Do you have strange users?

Is your site defaced?

I thought about jumping right in with how you clean things up, but the truth is a lot of sites are hacked and the user NEVER NOTICES. So before you clean things up, you should know some common signs of a hacked site. Maybe you noticed that every time you publish a post, you get all sorts of errors and your site gets slow as dirt and your host keeps saying you're using a lot of resources. Maybe you're pretty sure you never added kidjones221@gmail.com to your site, and certainly not as an admin, but there he is... Or maybe it's the worst day you've had. You get an email from a client, or a friend tweets you, because ISIS or whatever silly noob with a script has hacked your site and defaced it.

Hacks are Serious Business

The FBI has published alerts warning us that plugins and themes can be vulnerable. Having your site remain hacked is a loss of money and reputation, but also it's just darn dangerous. I've been hacked once. Just once. I logged on to my site via FTP, not SFTP or SSH, on a non-virus protected Windows PC, AFTER I saw a weird popup when I went to a site. Now... I emailed the person who ran the website to alert THEM about the popup but it never once occurred to me that I might be the issue. Until I got a call from my webhost saying I was infected with a rootkit. A hundred bucks later, I disabled FTP and Telnet and burned that PC. But that was a rootkit, not WordPress.

Cleaning WordPress Is Easy

WordPress Is Just Files (and a DB)

Let me put you at ease with WordPress. It's SAFE to replace WordPress files. Let me say that again. It's SAFE to replace ALL of WordPress' core files. Safe. Safe Safe. You get the idea I hope. It's also generally safe to replace plugins and themes. All we're worried about are your files and your database for the most part. Yes, there are exceptions, but in generally there are only a few steps to doing this and they are (mostly) backing up, deleting, and replacing.

What You'll Need

A File Transfer App (SFTP ONLY!)

Access to your server

Access to your database

Access to all your plugins and theme's source

You'll want those tools. I like using Cyberduck or Transmit as my SFTP client. If you have that AND shell access, even better. Shell access (that's the command line, right?) is the best thing for this since you can type in commands and have an on-site backup. Your Database Access may vary. If you've got command line, great, we can do some things. If you don't, you'll need access via a tool like phpMyAdmin. MOST webhosts have that, but there's no saying what version. Access to the plugins and themes may also be tricky. If you have wp-cli on your server, and you might, then command line just got a WHOLE lot easier! You can type 'wp help' from the command line on your server to see if you have it.

Step One

Backup Your Files

$ cp -r public_html public_html_backup

Download all the files to your computer. It's that simple. If you've got SSH access, the CP command there is great. It gives you an immediate copy of it all locally, which will be faster than SFTP any day. No intermediary. In both cases, DOWNLOAD to your computer. You need this local. You want this local. No, you can't infect your computer with it.

Step Two

Backup Your Database

$ mysqldump -u DB_USER -p[DB_PASSWORD] [DB_NAME] > filename.sql

$ wp db export

Okay. This is a little harder. If you have phpMyAdmin there's an EXPORT feature. Click it, export ALL the tables (I like to save it as a zip) and save it to your computer. If you have command line, one of those commands might work. Since you've already made a backup of your files, pop open the file WP-CONFIG.PHP. You're looking for those values of DB_USER, DB_PASSWORD, and DB_NAME. In general they're at the top of the file. If you have WP-CLI, that second command grabs the info from the wp-config.php and runs that command for you. I love it.

Step Three

Make an Inventory

What plugins?

What theme(s)?

What else?

Are they all updated?

Are they safe?

Get a list of everything you have installed. Anything NOT WordPress that you have on the domain is going to need to be MANUALLY reviewed. Sorry. For WordPress, make a list of ALL the plugins you have on the site as well as all themes. You're going to need to download clean copies. If the plugin or theme is from WordPress.org, great, it's PROBABLY fine and it's certainly easy to get. If it's not, you will need to go to where ever you got it in the first place. As for the 'else,' all those things you were clever about and uploaded outside of WordPress? Make a note of them too. And here's the hard part. Check ALL of those things for hacks. I know you may not know how, so google 'plugin name vulnerability.' You may be surprised. Google "WordPress SEO Vulnerability" and you'll see there was a blind SQL injection issue in April. But you'll ALSO see that the latest version was patched. So as long as you upgrade, you will be okay.

Step Four

Delete (Almost) Everything

DO NOT DELETE THESE!

wp-config.php

.htaccess

wp-content/uploads/

wp-content/blogs.dir/

Don't panic! Okay? We're talking WordPress here. WordPress is JUST FILES. Say it out loud. WordPress is Just Files. We can delete them and be fine. Also, since we took a backup, it's okay to nuke it all, but we'd like to not have to copy everything back so let's be smart. If at any time your server narks at you and say it CANNOT delete a file, you will need root access and you've also probably found your hack. You may need to call your webhost for help if you don't have the access to root.

Step Five

Check What's Left

With the files that are left, we're looking for nutty things like those examples. If I see ANYTHING like that in any file, I tell the folks I work with "Don't stop, don't think, don't ask. Sing HAAAAAAAAACK and send it for a scan." Done. Period. But you? You want to clean it up. Look for any files that are .php in your wp-content folder. Remember, we've DELETED plugins and themes (and cache) so all you should have left are uploads. If there are ANY php files in there, be suspicious.

Step Five (B)

Command Line Is Our Friend

You can use any tool to search that you want. I find command line the best. I can do this on the files backed up to my hard drive as well, just make sure you're IN the folder for the domain. Again, if there's anything you can't read or can't delete, it's probably hacked (or broken). The first two commands search for files. We're looking for ANY PHP files and ANY .htaccess -- You want to open them all and read them. If they look weird, like the examples before, they're PROBABLY evil. The last one is a powerful command that looks for 'random characters' in PHP files. It's not perfect. But it'll get you closer when you've only got your uploads to sort through.

Step Six

Reinstall It Clean

https://wordpress.org/latest.zip

wp core download --force

wp plugin install [slug, url, zip]

This is easy, if time consuming. We're downloading WordPress again and reinstalling it. Since you didn't delete your wp-config.php, you're okay and everything will reconnect, but DO NOT log back in yet. Don't check your plugins or your theme. They won't work. If you do check them, you will accidentally disable them and have to set them all up again. We don't want that. Downloading and reinstalling is time consuming. There's no other way to do it, though. You have to go, get each one, download it, upload it. If you've got WP-CLI, again, life is easier. You can even install from a URL or a downloaded zip on your server. If not? Unzip 'em all.

Step Six (B)

Clean The Theme

wp theme install [slug, url, zip]

Why didn't I mention the theme? Well... If your theme is a NON EDITED version of a theme from WordPress.org, or a reputable theme vendor, awesome. Download and done. If you manually edited the theme, or made your own child theme, you've got two problems. If you edited their theme, you have to compare the original with your own changes and make sure you add in yours. If you made a child theme, it's a lot easier (and that's WHY we make child themes, they're awesome), but you still have to be the one to review ALL the code in that theme and check it. This is made more complex if your theme is based on an older version of a master or parent theme. Because yes, you've got to upgrade. Many times, a theme from a 3rd party is a lot harder to triage, and a lot harder to get update alerts from.

Generally speaking, the Database is RARELY infected by these hacks. Rarely. There is a fairly famous hack called the PHARMA hack which left weird entries in your database like the ones listed here on the slide. And yes, they're incredibly hard to find and remove. How hard? Well one of the better ways to find it was to look for the words "Levitra/Cialis/Viagra" spelled BACKWARDS in the database. Ouch. Why doesn't this kind of hack happen all the time? A couple reasons. DB injection attacks are harder to pull off, since not all themes will work the same way. They're reliant on specific themes to get to the level of phrama. Also after that hack, we all got WAY better about sanitizing our SQL input. AND your webhosts are working hard to prevent the injection from working at all, using firewalls and tools like fail2ban and mod_security. I worry about this less than I do file hacks.

Step Eight

So What Happened?

Technically that's outside the goal of this class, which is cleaning up a hacked site, but since you have that backup, you can start going through the files. That grep command I used before is AWESOME to help find the evil. I generally only bother running it on plugins and themes, since while my WP core files MIGHT have been hacked, the odds are they're not the source of it all. No, the odds are the hack was in a plugin or a theme, so really that's all I want to check. That command looks the same as the one I ran before, except I removed the check for PHP only and changed it to EXCLUDE images and .sql files. I also tossed in ttf files for fonts. So when I said you should do that inventory and make SURE all that code was safe? You've taken care of this. If the world doesn't know about a hack or vulnerability in there, you may not be able to find it either, so you have to trust. And upgrade. And since you have your handy backup, check what versions of the plugins you were using and see if they had a KNOWN hack. If they did, that's what happened most likely.

Step Nine

An Ounce of Prevention

Always Update. Always backup. Always be smart! That last one is hard. If you can NOT be stupid, you're unlikely to be hacked. Do you need plugins to protect you? I think no. I think if you pay attention to what you're installing on your site, if you ALWAYS upgrade promptly, and you take the time to research the plugin author a little, you're ahead of the game. After a hack, you will find yourself more cautious and concerned about what you're putting on your site, and that is GOOD. That time you spent doing the inventory back then has given you more information than you know. Use that information to be smarter. And remember: If you get a bad feeling, trust your gut. You're smart.

Resources - Software

What are my tools? Few. I do as much as I can on the command line because I like it and it's fast. I'm on a Mac so I like those tools, but I'm including my favorite Windows ones as well. I used to work on Windows. PuTTY is the best SSH tool for Windows. I used to use Putty Connection Manager, but it seems to have gone away in the few years since I've used Windows and the other similar tools seem abandoned, so I don't have one to recommend at the moment. Sorry. DeltaWalker, by the way, is multi-platform as well. That's what I use to compare two ZIP files so when I need to look at MY theme vs the original, I use that.

Resources - Command Line

What are my tools? Few. I do as much as I can on the command line because I like it and it's fast. WP-CLI is already on a lot of webhosts and more are adding it because it works and it works well and it's a WP developers best friend. Many other hosts let you install it yourself. ACK is a grep replacement that's even better than Grep (hence the URL) and is also on a lot of servers. You can install it on your own computer, Mac or Windows OR linux. If you're on a Mac, grab HomeBrew to quickly install things. Homebrew lets me type 'brew install ack' and have it installed.