A Javascript-based DDoS Attack as seen by Safe Browsing
Posted by Niels Provos, Distinguished Engineer, Security Team
To protect users from malicious content, Safe Browsing’s infrastructure analyzes web pages with web browsers running in virtual machines. This allows us to determine if a page contains malicious content, such as Javascript meant to exploit user machines. While machine learning algorithms select which web pages to inspect, we analyze millions of web pages every day and achieve good coverage of the web in general.
In the middle of March, several sources reported a large Distributed Denial-of-Service attack against the censorship monitoring organization GreatFire. Researchers have extensively analyzed this DoS attack and found it novel because it was conducted by a network operator that intercepted benign web content to inject malicious Javascript. In this particular case, Javascript and HTML resources hosted on baidu.com were replaced with Javascript that would repeatedly request resources from the attacked domains.
While Safe Browsing does not observe traffic at the network level, it affords good visibility at the HTTP protocol level. As such our infrastructure picked up this attack, too. Using Safe Browsing data, we can provide a more complete timeline of the attack and shed light on what injections occurred when.
For this blog post, we analyzed data from March 1st to April 15th 2015. Safe Browsing first noticed injected content against baidu.com domains on March 3rd, 2015. The last time we observed injections during our measurement period was on April 7th, 2015. This is visible in the graph below, which plots the number of injections over time as a percentage of all injections observed:
We noticed that the attack was carried out in multiple phases. The first phase appeared to be a testing stage and was conducted from March 3rd to March 6th. The initial test target was 114.113.156.119:56789 and the number of requests was artificially limited. From March 4rd to March 6th, the request limitations were removed.
The next phase was conducted between March 10th and 13th and targeted the following IP address at first: 203.90.242.126. Passive DNS places hosts under the sinajs.cn domain at this IP address. On March 13th, the attack was extended to include d1gztyvw1gvkdq.cloudfront.net. At first, requests were made over HTTP and then upgraded to to use HTTPS. On March 14th, the attack started for real and targeted d3rkfw22xppori.cloudfront.net both via HTTP as well as HTTPS. Attacks against this specific host were carried out until March 17th.
On March 18th, the number of hosts under attack was increased to include the following: d117ucqx7my6vj.cloudfront.net, d14qqseh1jha6e.cloudfront.net, d18yee9du95yb4.cloudfront.net, d19r410x06nzy6.cloudfront.net, d1blw6ybvy6vm2.cloudfront.net. This is also the first time we find truncated injections in which the Javascript is cut-off and non functional. At some point during this phase of the attack, the cloudfront hosts started serving 302 redirects to greatfire.org as well as other domains. Substitution of Javascript ceased completely on March 20th but injections into HTML pages continued. Whereas Javascript replacement breaks the functionality of the original content, injection into HTML does not. Here HTML is modified to include both a reference to the original content as well as the attack Javascript as shown below:
<html>
<head>
<meta name=”referrer” content=”never”/>
<title> </title>
</head>
<body>
<iframe src=”http://pan.baidu.com/s/1i3[…]?t=Zmh4cXpXJApHIDFMcjZa” style=”position:absolute; left:0; top:0; height:100%; width:100%; border:0px;” scrolling=”yes”></iframe>
</body>
<script type=”text/javascript”>
[… regular attack Javascript …]
In this technique, the web browser fetches the same HTML page twice but due to the presence of the query parameter t, no injection happens on the second request. The attacked domains also changed and now consisted of: dyzem5oho3umy.cloudfront.net, d25wg9b8djob8m.cloudfront.net and d28d0hakfq6b4n.cloudfront.net. About 10 hours after this new phase started, we see 302 redirects to a different domain served from the targeted servers.
The attack against the cloudfront hosts stops on March 25th. Instead, resources hosted on github.com were now under attack. The first new target was github.com/greatfire/wiki/wiki/nyt/ and was quickly followed by github.com/greatfire/ as well as github.com/greatfire/wiki/wiki/dw/.
On March 26th, a packed and obfuscated attack Javascript replaced the plain version and started targeting the following resources: github.com/greatfire/ and github.com/cn-nytimes/. Here we also observed some truncated injections. The attack against github seems to have stopped on April 7th, 2015 and marks the last time we saw injections during our measurement period.
From the beginning of March until the attacks stopped in April, we saw 19 unique Javascript replacement payloads as represented by their MD5 sum in the pie chart below.
For the HTML injections, the payloads were unique due to the injected URL so we are not showing their respective MD5 sums. However, the injected Javascript was very similar to the payloads referenced above.
Our systems saw injected content on the following eight baidu.com domains and corresponding IP addresses:
- cbjs.baidu.com (123.125.65.120)
- eclick.baidu.com (123.125.115.164)
- hm.baidu.com (61.135.185.140)
- pos.baidu.com (115.239.210.141)
- cpro.baidu.com (115.239.211.17)
- bdimg.share.baidu.com (211.90.25.48)
- pan.baidu.com (180.149.132.99)
- wapbaike.baidu.com (123.125.114.15)
The sizes of the injected Javascript payloads ranged from 995 to 1325 bytes.
We hope this report helps to round out the overall facts known about this attack. It also demonstrates that collectively there is a lot of visibility into what happens on the web. At the HTTP level seen by Safe Browsing, we cannot confidently attribute this attack to anyone. However, it makes it clear that hiding such attacks from detailed analysis after the fact is difficult.
Had the entire web already moved to encrypted traffic via TLS, such an injection attack would not have been possible. This provides further motivation for transitioning the web to encrypted and integrity-protected communication. Unfortunately, defending against such an attack is not easy for website operators. In this case, the attack Javascript requests web resources sequentially and slowing down responses might have helped with reducing the overall attack traffic. Another hope is that the external visibility of this attack will serve as a deterrent in the future.