Blocking WordPress Pingback DDoS attacks with Nginx and Apache

Posted on November 16, 2014 Comments

A security researcher at SANS Technology Institute put out an advisory around 8 months ago when he discovered that WordPress’s “pingback” functionality contains an exploit allowing it to request a result from any server that an attacker wishes. This vulnerability means that there are thousands of WordPress installations that can be effectively weaponized to conduct floods against any target site of someone’s desire. This particular attack is dangerous because many servers can be overwhelmed with only 200 blogs “pingbacking” their site, clogging up their limited connections and/or resources.

While there are many options for dealing with this to prevent wordpress from being used in an attack, this is a difficult situation to be in if you’re the attack receiver. A client of mine experienced a WordPress Pingback DDoS attack against his site recently, and it overwhelmed his server. In analyzing the attack there were ~1,500 blogs that participated.  I had the opportunity of dealing with this fun attack live! The first thing I did was to check the logs, finding them full of requests like this:

192.241.x.x – – [09/Nov/2014:22:50:08 -0800] “GET /index.php HTTP/1.0″ 200 “-” “WordPress/3.9.2; http://www.x.x; verifying pingback from 69.30.x.x” “-“

Thousands of hits coming from WordPress blog. I knew this had to either be fake or a hole/exploit in WordPress. At the time, neither mattered, I was just focused on trying to keep it from falling over.

Blocking the blog IP addresses was one obvious way to prevent this, but there were too many – and new ones were constantly appearing. That simply was not an effective option during the time of the attack.  Immediately, I noticed that all of the WordPress pingback attacks were easy to find. The user agent was stamped with the WordPress version from where they came from, and what IP Address requested it. The best way to begin with blocking any type of attack is to look for a pattern, and this was an easy one. I decided to block all requests from “WordPress” at the web server level.

To handle HTTP floods, you need a web server that is resilient and efficient with handling thousands of concurrent connections. For this I recommend nginx. The purpose of it is to act as a layer between your main web server (apache) and attack traffic. Using nginx’s conditionals (which are awesome) I wrote this and put it in the server block. You need to have it outside of any “location /” blocks for it to apply to all incoming connections.

Congratulations, now none of the requests will actually make it to your web server or application! Nginx will forcibly deny WordPress blogs from making any requests to your site.

However, you will need to be sure to increase nginx’s worker_connections to something high – like 2,000-3,000 or more, depending on what your resources can handle. Even though Nginx is denying the attempts now, there is still a resource cost to accept the bad request and deny it. This is a good starting point, but you may have to go higher based on the frequency of requests and number of blogs that are flooding you:

Depending on the sheer volume of the attack, this may not cut it and you will need to seek other resources.

If you are unable to set up an nginx server instance, in a pinch, it is possible to block WordPress requests in Apache using this configuration:

Apache is not suited for dealing with DDoS traffic so I don’t recommend doing this unless you absolutely have to (and DON’T do it in an .htaccess file – add it to the core config).

In the aftermath of the attack, after researching it and finding out how it was done, I took a hard look at the log results to see how many machines were involved and how many requests each made. The results were interesting. Some were used multiple times, while others were used only 3-5 times. To calculate all of this I wrote a script in PHP to analyze requests from the WordPress user agent.

To get a dump of an access log’s WordPress pingback requests:

To analyize the dump, run this script:

The above will print out the top offending IP addresses from greatest to least, and provide an iptables firewall line to copy and paste to IP block directly.

I used this to comb through and wall off every single server that had attacked my client, so that they would not be a risk again.

Unfortunately this will be a problem for the foreseeable future because the pingback functionality is enabled by default in WordPress and without it, some bloggers lose a lot of benefits. I am not currently using any of them on this blog, so for now I have removed pingback functionality altogether. There are a variety of other blogs and security site offering advice if you want to secure yours, but the focus of this post was attack receivers like my client who have nothing to do with WordPress or blogging.

It’s worth noting (even though I am not a fan of CloudFlare, but that will be for another post) that CDN service CloudFlare has an option in their protection that protects sites against WordPress pingbacks. It works quite well if you are in a jam as well and cannot use any of the above options.

Comments

  1. Keep in mind that the CloudFlare protection you’re refering to only protects a WordPress website of sending out the pingbacks. It does not, however, protect a website that is under attack (what your blog post is actually about). Or I’m mistaken?

    • They seem to imply that it does if you use the second option.

      “So whether your blog is used to attack others or to be attacked itself, our WAF can help. ”

      They have two options circled, pingback blocker and numbers botnet. I don’t have a lot of experience with CloudFlare though so I am unsure if that’s the case, but it’s probably pretty decent. However there’s still nothing quite like blocking the user agent outright.

Leave a Reply