Programming

How to Stop a Brute Force xmlrpc.php Attack on Bitnami WordPress

WordPress Inspiration (oxymoron).

I was trying to access my site the other day and noticed it took fucking forever for anything to load. I thought something was broken: server out of memory from a recurring CRON job, or maybe I had royally fucked over my WordPress ecosystem by accident. Who knows? It's WordPress after all...

Are you experiencing any of these symptoms? Then read on...

  • Perpetually waiting for a response from while your browser displays a white page?
  • When your website does manage to load, clicking any links could make the entire application stop responding..
  • Seeing an abnormally high AWS charge for a small instance? Blame Amazon for expensive cloud computing first...

Being the curious programmer here, I tried to look for the issue. PRO TIP: Always look at your Apache or NGINX logs. My god. Fuck this guy. Spamming my site with pointless brute-force password attempts on a file called xmlrpc.php. Eventually, you'll never succeed because the password is a million fucking digits long. Realistically, however, I'll probably be so pissed off at the AWS charge, that I would cancel the EC2 instance before giving into my blog's new commander.

Check out some of these logs from streaming the Apache logs:

$ tail -1000f /opt/bitnami/apache2/logs/access_log

185.188.204.7 - - [21/Nov/2017:08:07:19 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:18 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:17 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:20 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:18 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:19 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:21 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:19 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:20 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370
185.188.204.7 - - [21/Nov/2017:08:07:22 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370

Great, my server is being spammed by a Russian bot every few milliseconds. WordPress, why the hell are these requests succeeding from an external source? At least this explains why my site has been unresponsive - someone else is using its resources.

Let's block his ass. The best way to do this is on the intermediary Apache server. We're going to write an Apache policy to prevent access to the xmlrpc.php file.

One thing to note before we continue here is that Bitnami automatically disables .htaccess files by default for performance reasons. So to write any Apache configurations at all, we'll have to edit the customized .conf file under:

$ vi /opt/bitnami/apps/wordpress/conf/htaccess.conf

// Now add these lines at the end of the file, please learn VIM to complete the edit

<FilesMatch "xmlrpc.php">
  Order Deny,Allow
  Deny from all
  Allow from 192.0.64.0/18
  Satisfy All
  ErrorDocument 403 http://127.0.0.1/
</FilesMatch>

Once we have edited the htaccess.conf file, we are going to restart the Apache server for the changes to take place:

$ sudo /opt/bitnami/ctlscript.sh restart apache

We can verify this works by trying to access the file via GET or POST on the file, http://dasun.us/xmlrpc.php, it should redirect. The policy above effectively redirects all external users to their localhost, while allowing traffic internally from WordPress. This allows certain plugins, such as JetPack, to correctly function. Let's look at the access logs now:

185.188.204.7 - - [21/Nov/2017:08:41:24 +0000] "POST /xmlrpc.php HTTP/1.0" 302 201
185.188.204.7 - - [21/Nov/2017:08:41:24 +0000] "POST /xmlrpc.php HTTP/1.0" 302 201
185.188.204.7 - - [21/Nov/2017:08:41:25 +0000] "POST /xmlrpc.php HTTP/1.0" 302 201
185.188.204.7 - - [21/Nov/2017:08:41:29 +0000] "POST /xmlrpc.php HTTP/1.0" 302 201
185.188.204.7 - - [21/Nov/2017:08:41:31 +0000] "POST /xmlrpc.php HTTP/1.0" 302 201
185.188.204.7 - - [21/Nov/2017:08:41:31 +0000] "POST /xmlrpc.php HTTP/1.0" 302 201
185.188.204.7 - - [21/Nov/2017:08:41:31 +0000] "POST /xmlrpc.php HTTP/1.0" 302 201

Ahhh success, and a breath of go annoy someone else now. The 302 is a redirection status which means they are now trying to access their own localhost rather than wasting resources on your WordPress website. Cheers, hope this helps!

Standard