…or how to build your own WordPress-powered denial-of-service network
Pingbacks 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 WordPress. If you do not know how Pingbacks work, I suggest taking a quick crash-course here.
One of the attacks is a Layer 7, direct denial-of-service attack, performed by a handful of machines targeted at a single WordPress XML-RPC server with pingbacks enabled. Its purpose is to deplete the server of memory resources by forcing it to download and parse a target URL, which is specifically crafted to heighten resource usage while parsing. Up to 6:1 peak-memory-usage-to-download-size ratios have been reliably reproduced. There’s a bug that allows 5 times as much usage (i.e. 30:1 inflation ratios) when setup properly (WordPress 3.4 will suffer from it as well).
The second attack is a Layer 4 (typically bandwidth-exhaustion), reflected distributed denial-of-service attack which utilizes publicly available WordPress sites on servers of any size and is the subject of this article. Buckle up, off we go.
The scope of the Pingback specification does not define or mention any particular guards for when the target URL is spoofed. WordPress does not “mind” receiving and processing Pingback requests on behalf of a third-party. The WordPress XML-RPC server, under readily-available circumstances, will request absolutely any valid target URL.
WordPress XML-RPC servers worldwide are ready to accept lightweight Pingback XML-RPC payloads (consisting of typically under 2 kilobytes of data; size depends on URL length), reflect them towards a single target, resulting in inflated input-to-output ratios and a denial-of-service attack, that can be distributed among tens of thousands of servers with little effort.
Such reflected/spoofed attacks have been lately heavily used by hacktivist groups to incapacitate some of the largest web resources on the Internet.
WordPress is currently deployed in an estimated 5 million instances globally (as per WordPress builtwith trends, and a drastically different 35 million instances reported by Yoast), and is the most-used CMS at the moment. By utilizing a very primitive home-made web spider, a little over 27,000 WordPress instances on different hosts have been added to a database of vulnerable WordPress XML-RPC servers in a matter of 24 hours.
In order to be eligible to “join the fun”, a WordPress installation had to be a WordPress installation (validated against readme.html), have Pingbacks enabled on any one of its pages and thus respond to a fake Pingback XML-RPC request with an expected error.
Among the hundreds of notable WordPress-powered sites that were found to be predisposed to the participation in a DoSnet, belonged to the following domains:
- edublogs.org blogs and blog.com blogs (I prevented the spider from going to WordPress.com, but that’s vulnerable territory, too)
- …and countless others, including my own blog (not that it’s notable)
I’m sure that many don’t know what Pingbacks are or don’t know that they are active on any of their endpoints. These were among the valid links at the time of exploit.
Mounting an attack
Armed with a rather high-quality database (as in low number false positives) of thousands of DoSnet agents (enpoints that are eligible to receive and process requrests), their XML-RPC and Pingback enabled content URLs, a semi-coordinated attack using several cheap boxes can be mounted. Simple PHP worker scripts feeding on agent data, selected at random from one or more databases, is enough.
The target host, has to have a page selected that would inflate to the maximum resource consumption possible, be it bandwidth or memory usage. Large files, dynamic and uncached pages, pages that request other pages, etc. are all good. The attack vector protocol is limited to HTTP(s) GETs. Requests are automatically terminated by the agent after 10 seconds (a hardcoded WordPress setting/guard against long-running requests).
sidenote: since there is, expectedly, no barriers stopping one from targeting any open TCP ports (the schema constraints mean nothing, obviously), turning it into a possible distributed attack at the application level is also possible, in cases where a public service (preferably one that persists a connection for as long as possible) is happy with any sort of data; crafting the request variables of the target URL can even result in all sorts of interesting and valid payloads which are applicable based on targeted remote service.
The request dispatchers query the database for several thousand agent records, and start forking themselves creating sockets that merely write and don’t bother to read to minimize traffic on dispatchers. A short delay between forks (~50-100ms) allows for a heavy, sustainable flow that does not overwhelm the Pingback dispatcher resource-wise.
Depending on the target server configuration and the type and size of target content requested, dispatch servers should send at least around 10 requests per second towards a reflecting agent to achieve an intense enough request flow by the agents to clog a typical target.
Proof of concept
A 5MB static file was requested from the target. The target was a dual-core 256MB Xen instance running nginx.
One XML-RPC request dispatcher was used to query a database of 27,000 valid WordPress hosts at random. The target was unable to process requests after several seconds, with over 1300 lingering connections at any single point in time. The dispatcher was a 2GB box.
None of the agents “feel” anything. Requests to an individual agent are rare enough to trigger absolutely nothing. Agent logs will contain access to `xmlrpc.php` and will not usually have access to the contents of the XML-RPC payload. Outgoing connection logs are seldom kept. All appears quiet for WordPress DoSnet agents.
Targets will obviously go down and logs will show IPs belonging to serious organizations around the world. The political side of the vulnerability should raise some concern, many high-profile websites can be forced into a DoSnet and compromised both legally and socially; news of US government allocated IPs attacking kremlin.ru (funny example; not so funny for other country pairs) will spread like wildfire; neither will be too happy, even after it turns out to be a little “misunderstanding” caused by the predisposition of WordPress to “bark up any tree” upon request.
- 19th March 2007 – https://secunia.com/advisories/24951/ Secunia advisory released, trac ticket #4137
- 14th March 2012 – my independent discovery and proof of concept mailed to WordPress security team, didn’t stumble upon the old advisories while investigating, sorry
- 17th March 2012 – patches (arguably perfect) for both types of attacks submitted, dismissed; core team representatives consider issue to be of low severity with “nothing [they] can really do about it”, which is arguable, unless I’ve missed something of key importance
- 3rd April 2012 – another report mailed with most of the contents in this article, evoked 2 responses – one pointing toward the 2007 report, and the other one pointing out that I used some incorrect terminology, thank you
Everyone has to disable Pingbacks (trollface). Impossible. None to date. Nothing usable in the core. Pity.
IP addresses and hostnames belonging to serious businesses are logged by the target webserver. Not only will targets be successfully attacked, but may also file abuse complaints against the participants of a DDoS. The attack is very scalable and can be prepared for and mounted in a matter of days without any special software or hardware prerequisites.
The participants of the attack cannot be filtered out via any firewall, since they come from thousands of different hosts from all around the world.
Inflation ratios are sky-high (2kb instruction to download up to 5Mb+ of data), meaning a single machine can potentially block out up to a couple of servers and keep them under constant pressure. With a dozen volunteering XML-RPC payload dispatch boxes – nearly anything can be taken down with enough boxes.
The DoS attack vector is primitive, but it appears to work and can pose a serious threat in today’s aggressive world of hacktivism, information security mania and online warfare. I’m surprised WordPress isn’t yet another convenient and powerful tool.
Almost any Pingback server is vulnerable to some extent, unless it prevents target URL spoofing. This probably includes other content-management systems and web application engines, the investigation of which is out of the scope of this article. Drupal, Joomla, have you looked at your code? Or can attackers add fingerprints for your engines, too?
Stay tuned, I have two more goodies queued up for this weekend and next week.