Wednesday, December 15, 2010

Performing DDoS attacks with HTML5 Cross Origin Requests & WebWorkers

Update: Shellex has performed detailed performance analysis of this technique.

DDoS attacks are the rage this year, atleast in the latter part of the year. There have been numerous instances of successful DDoS attacks just in the past few months. Some of the current DoS/DDoS options seem to be LOIC, HTTP POST DoS and Jester's unreleased XerXes.

This post is about a DDoS technique I spoke about at BlackHat Abu Dhabi that uses two HTML5 features - WebWorkers and Cross Origin Requests. It is a very simple yet effective technique - start a WebWorker that would fire multiple Cross Origin Requests at the target. This is possible since Cross Origin Requests that use the GET method can be sent to any website, the restriction is only on reading the response which is anyway not of interest in this case. Sending a cross domain GET request is nothing new, you can even do that by embedding a remote URL in the IMG or the SCRIPT tag but the interesting part here is performance. My tests on Safari and Chrome showed that both the browsers were able to send more than 10,000 Cross Origin Requests in one minute.

So simply by getting someone to visit a URL you can get them to send 10,000 HTTP requests/minute to a target of your choice. Now if you pick a juicy target URL, one that would make the server do some heavy processing then just 10,000 requests/minute might overwhelm it. Lets scale this a little, say 60 people visit the URL containing the DoS JavaScript, that is 10,000 requests/second at the target. With just 6000 visitors to this URL we can send around 1 million requests/second to the target. Getting 6000 Chrome and Safari users to visit a particular URL is no big deal really.

Maybe its not that simple, there are few things to consider here. When you send the first request to a particular page and the response does not contain the 'Access-Control-Allow-Origin' header with a suitable value then the browser refuses to send more requests to the same URL. This however can be easily bypassed by making every request unique by adding a dummy query-string parameter with changing values. The number of requests/minute is also a variable. The browser sends a certain number of requests and when it receives the responses for those it sends in the next set of requests and so on. So as the server slows down the browser's requests/minute rating would also slow down. The figure 10,000 requests/minute was clocked against a server located in the internal network, against a target in the Internet it would realistically be between 3000-4000 requests/minute. If the attacker is planning to target an internal server by getting the employees of that company to visit this malicious URL then the 10,000 requests/minute rating would apply.

I am not going to release any PoC as this might probably be a bad time to do that but it shouldn't be very difficult to put together something for testing once you understand how it works. It should be relatively easy to block this attack at the WAF since all Cross Origin Requests contain the 'Origin' header, that way you can differentiate between legitimate and malicious requests.


  1. LAVA,

    Do you think these are the type of attacks they are using in the Assange attacks? i.e. Mastercard. Or just standard DDOS I haven't seen any data yet.


  2. @don

    The ones being used against Mastercard make use of LOIC, it's an app that must be downloaded and run from the machine. They do have a JavaScript variant as well called as JS LOIC but the method it uses is less effective than the one discussed here. More info -

  3. Hi, I wrote two javascript recipets. One use WebWorker and fire COR 20000 times in it. Another one create 20000 Image in a loop.

    Both of them cause high CPU load and for about half a minute.

    And here is some analysis base on my nginx access log.

    $ cat stat
    Summary [XHR]
    During: 2010-12-21 16:41:02 - 2010-12-21 16:41:35
    Cost: 33 sec
    Packets: 5767
    Rate: 174.000000 packets/sec
    Summary [IMG]
    During: 2010-12-21 16:40:12 - 2010-12-21 16:40:45
    Cost: 33 sec
    Packets: 6193
    Rate: 187.000000 packets/sec

    It seems the performance of XHR+Worker is not very good...

    are there any aspects that I haven't consider?

    Thank you.

  4. @shellex
    You numbers using XHR are comparable to mine which is ~10,000 requests/minute. Please note when I say 'requests' I only mean the outbound GET request and not the response.

    It is interesting to note that you got better figures with the img technique. If you don't mind sharing your code for the img technique I can do some comparisons locally and let you know.

  5. @lava

    Hi Lava, thank you for your quick response~

    I have send my test code to your email. and I am eager to know your implement if possible.

    P.S In my code, not all request was sent successfully, because i cannot control the speed of creating XHR/Image. Although 20,000 Objects were created, nginx only log 5k~6k requests.