How To Block WordPress XML-RPC "Pingback" DDoS Attacks With NGINX

A WordPress XML-RPC attack is a type of HTTP layer 7 DDoS attack that abuses the XML-RPC API of WordPress based websites to send HTTP GET requests to a victim's web server in order to overload and crash it. This type of application layer attack is a relatively common part of layer 7 attacks, because a lot of people who run WordPress websites keep Pingback and Trackback features enabled, which ensures the bad guys always have enough vulnerable WordPress servers available to initiate this type of attack against an unprotected victim.

This article will guide you on how to "fix" your WordPress installation to ensure that it can't be used as a part of an XML-RPC attack, show you how the xmlrpc.php exploit works and also how to protect yourself from it with NGINX, if you're the victim of such a layer 7 Distributed Denial of Service attack.

Table of Contents

  1. A Close Look at the WordPress XML-RPC Attack
  2. The Forged Pingback Request
  3. The Malicious Pingback Response
  4. Fixing Your WordPress Website
  5. Using NGINX to Block the WordPress XML-RPC Attack

A Close Look at the WordPress XML-RPC Attack

A so-called Pingback is the attempt to notify a 3rd party site that you link to it. This is normally to get some exposure and hope that the 3rd party site will link back to your website in return. While this may be a semi useful way of gaining a few backlinks, this feature can easily be abused to hammer a site with Pingback requests by forging the part of the Pingback request that tells the 3rd party site which website initiated the Pingback request.

This is possible because no verification on the network level happens, that could determine the IP address the request came from and if it's the same the request will go back to. Forging the sender of a request/packet to make badly designed remote services send back responses to an IP/services that never asked for them in the first place is generally called a "reflection attack". A WordPress XML-RPC DDoS attack is a reflection attack (DrDoS) on application layer (layer 7 of the OSI model).

The Forged Pingback Request

Basically the attacker only has to send a POST request to an exploitable WordPress domain. In this example we'll use cURL to do that. The below command will exploit http://vulnerablewordpress.com/xmlrpc.php to send a malicious Pingback response to http://victim.com/hello-world/.

curl http://vulnerablewordpress.com/xmlrpc.php -d '<?xml version="1.0" encoding="iso-8859-1"?><methodCall><methodName>pingback.ping</methodName><params><param><value><string>http://victim.com/hello-world/</string></value></param><param><value><string>http://vulnerablewordpress.com/hello-world/</string></value></param></params></methodCall>'

curl -d - The "-d" option is short for "--data" and tells cURL to send a POST request containing a payload

http://vulnerablewordpress.com/ - This is the URL of a WordPress website that has Pingbacks via xmlrpc.php enabled and is therefore vulnerable to this kind of request forgery

http://victim.com/hello-world/ - This is the victim URL to which the response to the forged Pingback request will be sent to

http://vulnerablewordpress.com/hello-world/ - This is the URL to a valid blog post on the vulnerable WordPress website

The Malicious Pingback Response

The above cURL command will result in a HTTP GET request to http://victim.com/hello-world/. While a few of such requests are not harmful and are in fact very similar to what happens when a visitor opens a blog post, this method can be used to generate hundreds and thousands of such requests per second and that will most definitely bring down most websites. Below is an example of how the response to our malicious cURL request would look like in the access logs of the victim's web server:

192.168.0.2 - - [20/Jul/2015:14:12:08 0200] "GET /hello-world HTTP/1.0" 200 2812 "" "WordPress/3.5.1; http://vulnerablewordpress.com/hello-world"

Enough theory, let's move on to the practical part of this paper.

Fixing Your WordPress Website

If you run a WordPress website and want to make sure that it can't be used as a zombie participating in a DDoS attack, there are a few different approaches to ensure that.

Disable Pingbacks and Trackbacks (Recommended)

The most easy and intuitive way to make sure that your WordPress website can't be abused for DDoS attacks is to untick "Allow link notifications from other blogs (pingbacks and trackbacks)" under "Discussion Settings".

Rename or Delete xmlrpc.php

Probably a bold way of resolving this issue, but a very safe one. Simply delete the file called xmlrpc.php in your WordPress root directory. Instead of deleting it, you can also rename it to say xmlrpc.php-nono.

Use a WordPress Plugin

Instead of editing or changing any setting manually, you can install a WordPress plugin to disable the XML-RPC API, which will have a similar effect as the above methods.

Using NGINX to Block the WordPress XML-RPC Attack

block xml-rpc attacks with nginx

JavaPipe provides advanced "always-on" DDoS protection solutions that you can't find anywhere else! View DDoS Mitigation Solutions

Now to the interesting part. If you've become the target of a WordPress pingback attack, how do you protect yourself without the help of a professional DDoS protection service? While JavaPipe offers remote DDoS protection for websites that will definitely keep you safe from XML-RPC attacks amongst any others, you can also put NGINX as a local reverse proxy in-front of your web server (likely Apache) and block this type of attack in a reliable way with NGINX. I'm not going to show you how to setup NGINX as a reverse proxy, as that's not the topic of this paper.

Open Your NGINX vHost File

First you have to open the NGINX vHost file of the domain that is under attack. If you installed NGINX from a repository (RPM or DEB package), the vHost path is likely /etc/nginx/conf.d/. If you use WHM/cPanel on your server, you can install the plugin NginxCP (NGINX Admin) to get NGINX working as a reverse proxy in-front of your Apache web server.

With NginxCP the vHosts are located in /etc/nginx/vhosts/. Once you've found and opened the vHost file of the target domain that's being attacked or that you want to secure, you have to add the following within your server {} configuration block.

server {
...
if ($http_user_agent ~ WordPress) { return 444; }
...
}

What this rule does is match any HTTP requests that use WordPress in the user agent string, which all WordPress sites do by default. We've seen this pattern in the response to our forged cURL pingback request (see "The Malicious Pingback Reponse"). Then, if the condition is true (ie. the request contains "WordPress" in its user agent string), the rule will return a 444 status.

A successful HTTP response has the status code 200 and, something you likely have seen already, an URL that doesn't exist will give 404 status response. Now the 444 status response is something specific to NGINX. The 444 status will cause NGINX to close the connection immediately and not send any response, no error page no nothing.

I've seen a lot of guides suggesting to send similar malicious requests to 403 ("Forbidden") error pages, but that forces NGINX to process the HTTP request and send a response. If you expect many malicious requests, which is obviously the case during a layer 7 DDoS attack such as the XML-RPC one, you don't want that as it will only waste traffic and resources.

Instead we don't bother with those requests at all and immediately drop them by returning a 444 status, which doesn't actually return anything but just closes the connection. That's a great feature of NGINX that everyone working with it should be aware of.

Conclusion

With the instructions found in this article you can easily secure your website from this type of HTTP flood while ensuring the best possible performance even when under attack. You can proactively apply this rule to your NGINX setup if you want to be safe from XML-RPC attacks. If you run a WordPress website yourself, make sure to follow the instructions on how to disable Pingbacks, to help take away the firepower of the bad guys and contribute to a (at least slightly) safer online world.

PS: If you want to protect your Linux server from network layer DDoS attacks, check out our guide on DDoS protection with iptables!