[この記事は Security Team Engineer である Niels Provos による Online Security Blog の記事 "A Javascript-based DDoS Attack as seen by Safe Browsing" を元に、山口が翻訳・加筆したものです。詳しくは元記事をご覧ください。]

ユーザーを悪質なコンテンツから守るため、セーフ ブラウジングのインフラでは、仮想マシン上のウェブブラウザを使ってウェブページを分析しています。この分析により、ユーザーのコンピューターを悪用しようとする JavaScript など、悪質なコンテンツがページに含まれていないかどうかを判定できます。機械学習アルゴリズムによって検査対象を選択しながら、毎日数百万のウェブページを分析することで、全体的にはウェブのかなりの部分を網羅的にチェックできています。

3 月中旬、中国の検閲状況をモニタリングする GreatFire に対して大規模な DDoS (分散型サービス拒否) 攻撃があったことがさまざまなサイトで報じられました。研究者による徹底的な分析の結果、この DDoS 攻撃は、害のないウェブ コンテンツをインターセプトした通信事業者によって実行されており、そのコンテンツから悪質な JavaScript のインジェクションが行われるという新しい形であることが明らかになりました。今回のケースでは、baidu.com でホストされていた JavaScript と HTML リソースが、攻撃対象のドメインのリソースに対して繰り返しリクエストを行う JavaScript に置き換えられていました。

セーフ ブラウジングではネットワーク レベルでトラフィックをチェックすることはできませんが、HTTP プロトコル レベルのトランザクションは確認できます。そのため、セーフ ブラウジングのインフラでもこの攻撃は確認されていました。セーフ ブラウジングのデータから、この攻撃の詳しい経緯を突き止め、どのようなインジェクションがいつ行われたのかを明らかにできます。

今回、このブログポストに際し分析したのは、2015 年 3 月 1 日から 4 月 15 日までのデータです。セーフ ブラウジングで baidu.com ドメインに対するコンテンツのインジェクションがはじめて観察されたのは、2015 年 3 月 3 日です。対象期間内で最後にインジェクションが確認されたのは 2015 年 4 月 7 日となっています。この状況は、下記のグラフでも確認できます。このグラフでは、時間の経過にともなうインジェクション数の推移を、観察された全回数に対する割合 (%) で示しています。
攻撃は、いくつかの段階を踏んで実行されていることがわかります。第 1 段階はテスト段階のようで、3 月 3 日から 6 日まで実行されています。最初のテストの標的は 114.113.156.119:56789 で、リクエスト数は意図的に制限されています。3 月 4 日から 6 日にかけてリクエスト数の制限が外されています。

次の段階は 10 日から 13 日にかけてで、まず標的となった IP アドレスは、203.90.242.126 で、パッシブ DNS では、sinajs.cn ドメインのホストにこの IP アドレスが割り当てられています。13 日には攻撃対象が拡大され、d1gztyvw1gvkdq.cloudfront.net も標的となります。当初は HTTP リクエストだけが使用されていますが、アップグレードされて HTTPS も使用されるようになっています。14 日になると攻撃が本格化しはじめ、HTTP と HTTPS の両方を使って d3rkfw22xppori.cloudfront.net を狙っています。このホストに対する攻撃は 17 日まで続きます。

18 日には攻撃対象のホストが増え、以下のホストが標的となっています。d117ucqx7my6vj.cloudfront.net, d14qqseh1jha6e.cloudfront.net, d18yee9du95yb4.cloudfront.net, d19r410x06nzy6.cloudfront.net, d1blw6ybvy6vm2.cloudfront.net.また、ここではじめて、トランケートされるインジェクションが見つかっています。これは、JavaScript の一部が切り捨てられて機能しないものです。この段階の攻撃の途中で、CloudFront のホストが greatfire.org をはじめとするドメインに対して 302 リダイレクトの送信を開始します。JavaScript の置き換えは 3 月 20 日には完全に終了していますが、HTML ページへのインジェクションは続いています。JavaScript の置き換えでは元のコンテンツの機能が損なわれますが、HTML へのインジェクションはそうではありません。このケースでは、次のように、元のコンテンツに加えて攻撃用の JavaScript にもアクセスするように HTML が変更されています。

<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 ...]


この場合、ウェブブラウザは同じ HTML ページを 2 回取得を試みますが、t というクエリ パラメータがあるため 2 回目のリクエストではインジェクションが発生しません。攻撃対象のドメインも変更され、dyzem5oho3umy.cloudfront.netd25wg9b8djob8m.cloudfront.netd28d0hakfq6b4n.cloudfront.net が狙われています。この段階が始まってからおよそ 10 時間後に、標的となったサーバーからほかのドメインに対して 302 リダイレクトが返されます。

CloudFront のホストに対する攻撃は 3 月 25 日に終了しています。代わって github.com でホストされているリソースが標的となります。最初に新たな標的となったのは github.com/greatfire/wiki/wiki/nyt/ で、すぐに github.com/greatfire/github.com/greatfire/wiki/wiki/dw/ もこれに加わります。

3 月 26 日には、それまで難読化されていなかったスクリプトが、packer で難読化された攻撃用 JavaScript に置き換えられ、github.com/greatfire/github.com/cn-nytimes/ が新たな標的となります。ここでも、トランケートされるインジェクションが見つかっています。GitHub に対する攻撃は 2015 年 4 月 7 日で終了したようで、この対象期間中で最後のインジェクションが観察されています。

3 月初めから 4 月に入って攻撃が終了するまでに、JavaScript のペイロードの置き換えが 19 種類確認されています。それぞれを MD5 チェックサムに置き換えて、その割合を円グラフにしたのが下の図です。
HTML インジェクションの場合、挿入先の URL によってペイロードが異なるため、対応する MD5 チェックサムはここに記載しません。ただし、挿入された JavaScript は上記のペイロードとほぼ同様のものです。

セーフ ブラウジングでは、以下の 8 つの baidu.com ドメインとそれに対応する IP アドレスでコンテンツのインジェクションを検出しました。
  • 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)
挿入された JavaScript のペイロードのサイズは 995~1325 バイトとばらつきがありました。

本記事が、今回の攻撃について明らかになった事実をもとにその全体像を理解する助けとなれば幸いです。また、総合的な分析によって、ウェブ上で何が起きているのかがかなりはっきりとわかることもご紹介しました。セーフ ブラウジングで確認できる HTTP のレベルでは、この攻撃の犯人を特定することはできません。それでも、攻撃が起こった後に詳細な分析を行えば、攻撃自体を隠ぺいするのは困難だということは明らかです。

もしもウェブ上のトラフィックがすべて TLS で暗号化されていたら、このようなインジェクション攻撃はそもそも不可能だったでしょう。今回の騒動は、通信の暗号化や完全性保護を重視する方向へとウェブを向かわせる契機のひとつとなるでしょう。とはいえ、このような攻撃に対する防御策を講じるのはウェブ オペレーターにとって簡単なことではありません。今回のケースでは、攻撃用 JavaScript はシーケンシャルにウェブリソースへのリクエストを送信しているため、レスポンスの速度を落としていれば、全体的な攻撃のトラフィック量を抑えることができた可能性もあります。また、このような攻撃が外部から把握されうるという事実が、今後は抑止力として働くことが期待されます。

Posted by Yoshifumi Yamaguchi - Developer Relations Team