WordPress Pingback Attack

Yesterday I wrote a post titled On WordPress Pingbacks. While writing this I came to several conclusions that resulted in some interesting experiments and results.

WordPress Pingback Attacks

I was going to publish my results along with that post, however, I wanted to make sure that the WordPress Security mailinglist had nothing against my publishing such information. With no word from them (I guess I expected too much to be contacted back within 24 hours), I’ve decided to dedicate a whole article to the Pingback attack, its potential, its limitations and further considerations and concerns.

Prerequisites

PHP, WordPress (specifically on how WordPress Pingbacks work, both clientside and serverside) and basic understanding of HTTP.

Buckled up?

Journey to the darkside

A thought. Can a WordPress Pingback server be forced to run out of memory if the pinging page is too large? Everything is forced into the $linea variable, passed around via the pre_remote_source filter to who knows where, dozens of str_replace and regular expression functions, explode into an array, with even more processing… seems like a lot.

The pinging page is fetched using the wp_remote_fopen function. This calls wp_remote_get with a 10-second timeout.

10 seconds doesn’t sound like much. However, while the server is fetching the pinging page and processing it further, requests can further be directed towards it… even the same request, since the comment is added only after a request is processed (remember how it first checks whether a comment with the Pingback exists before doing anything?)… and the text doesn’t even have to have the specific link in it to avoid approval in the first place. Just feed it bogus requests for huge data you don’t even own… like something off of here

There’s a catch though, when a timeout occurs inside of wp_remote_get, a mere false is returned, so no memory is ever used up. This means that requests have to be under 10 seconds to have WordPress huff and puff a bit.

Let’s say the average network speed is 8Mbits/s, that’s 1MB/s x 10 = 10MB of data, cut that in half just in case and feed it a 5MB data package. Downloading that via the function inflates to around 2-3 times in memory, meaning at least double peak memory usage.

That’s quite a large chunk of data, and its going to be thrown around a lot. Adding in all the processing that goes on inside of the Pingback server we get a peak memory usage of around 32MB with bogus data. To further make WordPress work the data has to be carefully assembled, like maybe so:

printf '<a<<<http://whatever.com/2012/10/10/this-is-a-post-matching-the pingback-link?dos////>\n\n%.0s' {1..60000} > payload.html && echo '<title>title</title>' >> payload.html

This results in some nice content that WordPress will gladly sift through and try to match. I’m sure the regular expressions can be further stressed by providing more artfully crafted URLs. I don’t have the perfect combination for a large inflation ratio at the moment, a 6:1 ratio seems to be the limit for now. Meaning if you can push get it to download 10MB fast enough, around 60MB of memory are consumed. Actually a bit more, since there’s additional XML parsing, etc.

WordPress Out Of Memory

Naughty, naughty, are we not?

Most of the time is spent on downloading, so unfortunately, the more requests are made, the longer it takes to download the file resulting in misses (wp_remote_get returning false preventing further server load). However results can be achieved.

WordPress CPU Load

Also, having valid Pingbacks inside one domain means that if the remote server has a large file that is known of can speed up download times and increase memory consumption.

Accomplishable? Definitely. Difficult? No. With the right tools and the right amount of network power standard DOS attacks can be amplified by quite a lot.

WordPress Denial of Service

Yes, that’s one of my servers and it went down under in around 10-15 seconds. It’s not running the best possible configuration, and it’s not the most powerful machine, but a single shot of invalid Pingbacks took it down.

Reflected denial-of-service

Since there is no host or IP filtering, an attacker is able to send Pingback requests for other target URLs.

So how about a reflected denial-of-service attack, that’s popular now, isn’t it? Theoretically, making a list of a couple of hundred of WordPress blogs with RPC enabled and Pingbacks on a post (which is easy to spot), flooding them with requests for a target URL, and boom!, all at once, like a swarm of bees they go request the target page… fancy your own botnet?

This attack vector can potentially leverage thousands of WordPress servers, which willingly download any URL that is supplied (with a 10 second limit, of course).

Don’t do this at home, please.

Pingback flooding

Another minor flaw feature in the WordPress Pingback mechanism that can be exploited lies in the fact that there is no distinction between the same target URL with different request variables. This means that with some simple automation, a target URL can be repung thousands of times with a single-lined dynamic payload.

<?php echo '<a href="targetURL">This is a dynamic title '.$_GET['d'].'</a>'; ?>

The source URL would have an additional d variable with some random digits appended. Bad code example, btw.

And, of course, there’s comment flooding protection that gets triggered for Pingbacks as well – “You are posting comments too quickly. Slow down.” Nothing a nice proxy list of 30-60 peers can’t do.

WordPress Pingback Flooding

Absolutely no big deal, is there? Comment flooding has been around for ages, and lots of protection schemes have been devised. Alas, Pingbacks don’t offer any CAPTCHAs.

Protecting yourself

  • Disable Pingbacks altogether
  • Hook to the comment_flood_filter
  • Raise awareness in yourself and others
  • Spread the knowledge
  • Good server, updated software, good configs
  • Write patches
  • Do not harm others

…there’s even more

Check out the continuation to this article over at WordPress-powered denial-of-service botnet.