2013/11/30

MS13-037: エンコーディングの自動選択の強制によるXSS

2013年5月の月例パッチ、MS13-037で修正された、Internet Explorerでエンコーディングの自動選択を強制的に起こせたバグについて書きます。

http://technet.microsoft.com/ja-jp/security/bulletin/ms13-037
 このセキュリティ情報に組み込まれている多層防御についてマイクロソフトと協力してくださった Masato Kinugawa 氏

アドバイザリには問題に対する説明がありませんが、多層防御で修正されたのがこの問題です。

今回は、ざっと、報告書っぽく。
 --------------------------------------------


報告日:
2012年11月23日

問題の概要:

IEで特定の方法でページを表示しようとすると、ページのエンコーディングの指定にかかわらず、ページに含まれるバイト値からブラウザ側でエンコーディングを判断する、"エンコーディングの自動選択"が勝手に発生する。

ページのエンコーディングがユーザーにより切りかえられるとXSSが起きる場合があるという記事を以前書いた( http://masatokinugawa.l0.cm/2012/12/encoding-self-xss.html )ように、 この動作は、単なる表示上の問題だけでなく、XSSなどのセキュリティ上の問題を引き起こす場合があり、好ましくない。


発見したきっかけ:

IEでページを見ていた際に、適切にエンコーディングの指定がされているページで文字化けが発生したことから。



再現させた環境:

Windows Vista sp2 IE9(2012年11月までに提供されたパッチをすべて適用済み)


再現方法:

以下のように細工したページを用意することで、強制的に自動選択を起こすことができる。

<script>
function go(){
window.open("http://vulnerabledoma.in/r_slow?url=http://target/","x")//手順1
window.open("http://vulnerabledoma.in/h_back.html","x")//手順2
}
</script>
<button onlclick=go()>go</button>

手順は、

1. ターゲットのページに対して "少し細工をした300台のリダイレクト" を起こすページをwindow.openする
2. そのページに対してすぐに「戻る」操作だけが書かれたページ( <script>history.back()</script> )をwindow.openでかぶせる


これでターゲットのページに「戻ったとき」、文字化けが起こる。

1のリダイレクトの細工とは、リダイレクトが完了するまでに意図的に数秒の遅延を発生させるようにしてあること。 実際に http://vulnerabledoma.in/r_slow?url=https://www.google.com/ にアクセスしてみると、 リダイレクトするまでに時間がかかることがわかると思う。

このリダイレクトははさまなくても化かすことはできるのだが、  ターゲットのページが完全に読み込まれる前に「戻る」動作がされると問題が起こる挙動であったため、読み込みがはやいページでは、化かすのに失敗することがあった。遅延のあるリダイレクトをはさむと、読み込みがはやいページでも確実に問題を起こすことができる。

XSSで攻撃するときには、ターゲットのページの文字列を出力できる部分から、特定のエンコーディングの特徴的なバイト列を並べ、特定のエンコーディングで作られているように装えばよい。うまくいけば、IEは自動選択でそのエンコーディングを選択し、HTMLやJavaScriptもろとも構造を変えることができる。

--------------------------------------------


もちろん、前提条件として、ターゲットのページが特定のエンコーディングで表示されたとき、XSSが起きるような作りになっている必要があります。難しそうですが、できないこともありません。
実際に、GoogleのサービスでXSSが可能な箇所を複数確認しており、報告しています。(なお、この情報提供に対し、特別に$500を頂きました。)

これがそのときに報告したページの1つです。

https://docs.google.com/spreadsheet/embeddedform?formkey=dDBuQjhkWVozbV9JR1NSRDBHNHRHVWc6MQ
 
このページを先ほどの仕掛けにかけると、ページに含んだ [0x1B]$)C という特徴的なバイト列から、ISO-2022-KRが選択され、XSSが起きていました。

(※ただし、このGoogleの問題を再現させる場合、ページで右クリック→「文字コード」→「自動選択」のチェックが入っている必要があります。この設定はすべてのページで永続的に適用されます。この設定がオンになっていないと、システムロケールがエンコーディングの決定にかかわってきて、うまくISO-2022-KRが選択されません。)
 
なお、報告した11月から修正が発表された5月まで、細かい動作が変更されているかもしれないので、もし再現させてみようという方がいれば、2013年4月より、2012年11月までさかのぼった方が確実です。実際、僕が2月くらいにみたときはうまく動かなかった気がします。多分途中で、軽減策として自動選択で選択されるエンコーディングが制限されて、ISO-2022-KRなどが選択されなくなったのではと思います。

そこまで戻すのが面倒な人は、上のGoogleのページを開いて「エンコード」→「韓国語」で疑似体験ができます。

おまけの話として、パッチが提供された後、再現方法が少し違う文字化けの問題に対しても、パッチ後に問題が起きなくなったというWeb上の投稿があったりして( http://answers.microsoft.com/ja-jp/ie/forum/ie9-windows_7/%E6%88%BB%E3%82%8B%E3%83%9C%E3%82%BF%E3%83%B3/2b34b6ea-17f4-4499-ac07-aa8a007ac251 )、目に見える表示上の問題も直ってよかったなーと思いました。


そんなんでした。
エンコーディングの記事は基本人気がない気がしますが、次もエンコーディングの記事を書く予定です!