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.
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<<<https://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.
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.
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.
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.
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.
The last one isn’t a flaw. Consider sites without pretty permalinks enabled, i.e.
index.php?p=123
. Query strings are important and shouldn’t be ignored. 🙂As for the rest, patches welcome. *hint hint* 😉
It is a feature, I agree, a good point of course, non-rewritten links would not work without that. Thanks for dropping by and commenting, very much appreciated, Alex. Tickets and patches coming soon, hopefully.
[…] by Twitter, users flee to WordPress.com and self-hosted blogs, yey! My brother Gennady crafted a pingback attack which he was able to use to bring my blog down, […]
You didn’t exactly give us a lot of time to discuss it internally or send you an initial follow-up. We respond to all reports within a reasonable amount of time and operate under what’s called “responsible disclosure” — you waited less than a day before publishing this.
I stayed up for two nights straight experimenting with the concepts, so fatigue + excitement + disappointment + the nature of the “vulnerability” + my irresponsibility and lack of concern and patience took their toll, for which I sincerely apologize.
However, “responsible disclosure” is a very debatable topic. I was quite sure that 24 hours would be enough for anyone to come forth and say “Stop” or even simply acknowledge the fact that it was under review, ask questions maybe, if it was worthy of attention. More than 10 different people viewed the private page stated in the mailing list. And yes, the FAQ does state to “not publish”, was expecting some action/reaction either way, sorry, guilty.
When small people like me send off reports, etc. they are generally disregarded without any response whatsoever. I could have waited for ages, who knows. This is something I got used to. I would have gladly taken this publication down, and will be glad to take it down right now if it is indeed a serious issue and threat, and your comment is not just a friendly reminder on “responsible disclosure”.
Again, I apologize for the inconvenience and many thanks for your concern. I can imagine how busy the team is, I will send a link to a patch and proposal in a couple of hours directly your way (I imagine security issues are not be published in public Trac then, too), if it can ever make up for the “damage” (if any) already done.
[…] have been part of the WordPress since the very beginning. One of my previous articles, titled WordPress Pingback Attacks explores two types of denial-of-service attacks that leverage Pingback request processing in […]
[…] upozornenà (pingbacks) vo WordPress. Na tento problém ale už bolo upozornené oveľa skôr, WordPress Pingback Attack a WordPress DoSnet. Je to dobre známa funkcionalita využÃvaná mnohými blogermi. Spätné […]