More on WordPress xmlrpc denial of service attacks

disable-xmlrpcThe attacks on WordPress using xmlrpc.php service are rather common. I already mentioned that you could filter out unwanted user-agents using the redirect capability of Apache. That would, however, take care only of obvious cases, where you see that this particular user-agent could not possibly be your reader. What do we do if the user-agent looks normal?

Well, if you do not need your xmlrpc services, you could block it off completely with mod_rewrite for all access:

<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteCond %{REQUEST_URI} ^/xmlrpc.php.*$
 RewriteRule .* - [F,L]
 </IfModule>

This will return a 403 for all requests. It is basically equivalent to what you did with “files” directive where you specify “Deny all” for a file path. This will block all access to xmlrpc completely though, for all purposes, so you will not be able to use the service at all. Which is not always acceptable.

But the good news is that the set of rules is extensible with other conditions and you could block only the requests with particular user-agent again now. For example:

<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteCond %{REQUEST_URI} ^/xmlrpc.php.*$
 RewriteCond %{HTTP_USER_AGENT} ^.*NET CLR.*$ [OR]
 RewriteCond %{HTTP_USER_AGENT} ^.*Mozilla/5.0.*Windows.*NT.*6.*$
 RewriteRule .* - [F,L]
 </IfModule>

And so this becomes an extensible list of rules. You check your logs, see suspicious requests and add them to the list of rules. Stack the additional rules with [OR] flag at the end of the condition line.

Now we have a set of rules that blocks some of the accesses to the xmlrpc based on the user-agent reported by the attacker. We could also add filtering by referrer or IP ranges and so on. The arms race, you get the picture.

Mitigating Denial of Service attacks to WordPress xmlrpc

Distributed Denial of Service attackI have attracted attention, apparently. My website is under a Distributed Denial of Service (DDOS) attack by a botnet for the last week. I am flattered, of course, but I could live without a DDOS, frankly.

The requests go to xmlrpc.php every second or two from a different IP address from around the world:

POST /xmlrpc.php HTTP/1.1

At first I could not understand what was going on but it turns out that that request can be really expensive and the database basically gets overloaded with requests bringing the database server to a screeching halt after a while.

After trying to blackhole the IP addresses and finding out that the botnet is fairly large, I simply denied all access to xmlrpc.php. That is a simple and effective solution but it breaks some functionality that is expected of a WordPress site. I don’t like that. So I was looking for a way to block the attackers without crippling the site.

I noticed that all of the requests have a particular HTTP request user agent:

"Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)"

So I redirect the requests with that user agent in .htaccess all back to themselves (you could also redirect it to 127.0.0.1 with the same effect):

# Block attackers by agents
 <IfModule mod_rewrite.c>
 RewriteCond %{HTTP_USER_AGENT} ^.*WinHttp.WinHttpRequest.5.*$
 RewriteRule .* http://%{REMOTE_ADDR}/ [R,L]
 </IfModule>

It seems to have mitigated the attacks by that particular botnet software while allowing access from all other browsers and sites. I hope it stays that way. I don’t think my site is really worthy of this kind of attention anyway.