今朝、ブラウザで動作を試しながらECMA-262の仕様を読んでいたところ、IEの奇妙な動作を発見し、それがXSSフィルターのバイパスに使えることがわかりました。
完全なバイパスではありませんが、興味深いものなので共有します。
XSSフィルターは、単純な反射型のXSSに加えて、文字列リテラル中で起こるXSSも防止しようとします。自分の過去の資料で、文字列リテラルの文脈で遮断される文字列の一部を紹介していますので、以下に貼り付けます。
今回注目したいのがこの中の
valueOf=
です。この資料をまとめたとき、valueOf=
をなぜ遮断する必要があるのかよくわかりませんでした。確かに、あらかじめ定義された関数であれば、次のような形式で、フィルターが反応する
()
を使わずに関数呼び出しができます。https://vulnerabledoma.in/xss_js?q="%3BvalueOf=alert%3B~window//&xss=0
";valueOf=alert;~window//ただ、このくらい不自由な呼び出しは、以下のような、イベントへの代入が遮断されないことから、許容されていると考えていました。
https://vulnerabledoma.in/xss_js?q="%3Bonload=alert//
";onload=alert//ちなみに、この
valueOf=
は、Eduardoさん・Davidさん発見の以下のベクタとは無関係です。https://media.blackhat.com/bh-eu-10/presentations/Lindsay_Nava/BlackHat-EU-2010-Lindsay-Nava-IE8-XSS-Filters-slides.pdf#page=14
"+{valueOf:location, toString: [].join,0:'jav\x61script:alert\x280)',length:1}//ご覧の通り、お二人のベクタは
=
を使っていません。自分の資料の中には書いていないのですが、これらは、";{valueOf:
や";{toString:
といった文字列を遮断する別の正規表現が存在しており、そっちで遮断されます。valueOf=
の場合は、イベントへの代入の場合よりも呼び出しが許される関数が多く、例えば、特定要素へのclickなどのメソッド呼び出しがIE8以下のドキュメントモードのページに対してできるようなので、このあたりの手法を止めたいのかも、という風に勝手に解釈しました。(本当のところを知っている人はぜひ教えてください!)以下のページにIEでアクセスして、"go"ボタンを押すと、"important action"というボタンが
valueOf=opener.button.click
を経由してクリックされるのが確認できます。https://l0.cm/xssfilter_bypass/valueOf.html
このとき、
valueOf=
は遮断して、なぜtoString=
は遮断しないのだろうと思ったのですが、toStringに変えて試してみると動きませんでした。普通なら動くべきだと思いますが、IEならそういうおかしなことも起こるだろうと考えて今日まであまり気にしないできました。さて、ここから、今回のバイパスの話を始めます。
今朝、IEでも、
toString
への代入からclickなどのメソッド呼び出しができることを発見しました。なんと、IEは
toString=
では代入に失敗するのに、var toString=
だと成功するようなのです。こうすると、alertが呼ばれます。var toString=alert;~window
これを利用して、valueOfと同じ要領でclickを呼び出そうとすると、うまくいきました。
var toString=opener.button.click
を経由してクリックされるのが確認できます。https://l0.cm/xssfilter_bypass/toString.html
ほとんど使う場面はないかと思いますが、せっかく
toString=
の面白い動作に気付いたので、部分的でもフィルターのバイパスに繋がることを証明してみました。valueOf=
を止めている理由の推測が正しければ、こちらも本来なら遮断したい動作ではないかと思います。以上です!
脆弱性"&'<<>\ Advent Calendar 2016、明日は…、まだ登録されてないっぽいです!誰か書いてください!
0 件のコメント:
コメントを投稿