Fighting the Hackers

I spent most of yesterday fighting with the hackers.

One of the websites I take care of was getting hammered with brute force password attacks. It’s a WordPress site. This is nothing out of the ordinary. But the scale of it was something I hadn’t seen before. Not on my little sites.

In the course of less than 24 hours, they attempted to guess a not-existent user’s password over 4600 times.

On the one hand, it’s kind of nice knowing that overall the site handled it pretty well. On the other hand, having the site email me with notices every minute or so to tell me that yet another IP (internet address) had been blocked was getting pretty annoying.

My first attempt to cut these password cracking attempts was to block access to the site’s login script for all IPs except mine. It’s pretty easy to do, and you can find the following code on lots of sites. Just add this to the beginning of your .htaccess file in WordPress root directory if you’re on an Apache server:

<FilesMatch wp-login.php>
    order deny, allow
    deny from all
    #Add list of IPs that you want to be able to log in
    allow xxx.xxx.xxx.xxx
    allow yyy.yyy.yyy.yyy
</FilesMatch>

But to no avail. The attacks kept coming.

At the end of the day, I got on the line with the hosting company (it’s a shared hosting situation where I don’t have direct access to the server logs) and asked if they could tell me anything about what they were seeing on their end. That’s when they told me that there had been 4600+ hits on the site’s xmlrpc.php script.

WordPress uses xmlrpc to allow connections from mobile devices to upload posts among other things. Turns out, there’s been a lot of hacking activity around it lately.

One of the hacks is to send an authenticated request by xmlrpc in order to get into the system’s routers (presumably to then be able to route spam and other nefarious stuff through your serve). So it was the xmlrpc that was the gateway the hackers were trying to break down, not the login screen.

The solution was just as simple as the first bit of code. After the code above, just add this to disable the xmlrpc (if you never connect to update your site via mobile anyway):

<Files xmlrpc.php>
    order deny, allow
    deny from all
</Files>

If you need a less drastic approach (say you need to be able to enable mobile update access while you’re on a trip) there’s also a handy plug-in by Mark Kaplun that gives you the option to enable or disable xmlrpc from your WordPress dashboard. You can find it here.