2012/11/07

OperaのEUC-TWに存在した潜在的にXSSが可能な問題

安定版Opera 12.10で修正されているのを確認したので書きます。
ベンダは悪用は難しいとして、これをノーマルバグとして扱いましたが、修正前はcharset指定がないページやEUC-TWエンコーディングのページでXSSを引き起こす可能性がありました。


これを見つけた経緯から話すと、僕は以前から、ブラウザがサポートするエンコーディングのページで、「0x22」「0x26」「0x27」「0x3C」「0x3E」「0x5C」("&'<>\)などの特殊な文字がマップされているバイト値を除いた上で、ランダムにバイト列を表示させて、別のバイト列で「"&'<>\」が現れないかチェックするというような、ブラウザのセキュリティバグを発見するためのテストを行っていました。これにより、OperaのEUC-TWで「"<>」などを検出し、この問題を発見しました。

実はこの手法で他のブラウザでもいくつかの問題を検出していました。(この詳細はタイミングをみてまた今度書きます) それらはどれも、ある固定のバイト列で、現れてはいけない文字が現れてしまうというもので、僕もそれを想定してやってた訳なんですが、このOperaのEUC-TWだけは、検出後に同じバイト列を使って再現させようとしてもなぜか一度は検出したはずの文字が現れず、うまくいきませんでした。

調査を続けていくと、どうも特定のバイト列が、時折文字を変えつつ、ほぼランダムな文字を返してくるということがわかりました。
そのバイト列周辺を並べたのがベンダへの報告時にも使った以下のページです。

 http://l0.cm/o_euc-tw_a1xx

ここの、0xA181-A1A0によくわからない値がくるのです。
0xA181-A1A0 はEUC-TWにおいて本来は使われないバイト列であるみたいなんですが、どうも処理が狂っているようです。(12.10では不正であるとしてU+FFFDが2つ現れます。)

さらにみていくと、たまに目に見えて意味のある文字列が返ってきていることに気が付きました。





これだけでどうみてもバグってるし、場所もはっきりしたのでもう十分バグ報告してもいいんですが、何度か「"&'<>\」を検出してる訳なので、セキュリティ上の脅威になるかどうかをちゃんと調べようと思ってさらにみていきました。
すると、バイト列には、たまに、自分が表示しようとしているHTMLの内容を含んでいる場合があるということにも気が付きました。ページ下部に「<」(0x3C)を大量に並べたところ、以下のようになったことがありました。





この時点で、このバイト列に、認証を済ましたページで表示された文字が含まれるなどすれば、情報が漏洩しうることになるので、セキュリティバグと言えるでしょう。ただ、僕はXSSがしたいのでまだ続けます。

ここで得られた文字から考えると、0x00 0x3C 0x00 0x3C....と書いておけば「<」が得られそうです。実際何度かそのようにして試していると「<」が得られました。
この方法で確かにXSSができることは確認しました。ただ、たまに「<」のような問題のある文字を現れさせることはできても、確実に出現させる方法がわかりませんでした。また、このバイト列に一度「"&'<>\」などが現れても、何かの拍子に中身が変更されてしまう場合が頻繁にあることなどから、安定して攻撃に使う方法を見つけられずにいました。

EUC-TWは、他のメジャーブラウザでもほとんどサポートされていないエンコーディングなので、ウェブページの表示にはまず使われていないのではないかと思います。そんな重箱の隅をつついて何の意味があるんだと思うかもしれませんが、Operaには、charset指定のないページをフレームに埋め込むと、親フレームの文字コード指定をクロスドメインでも継承するという挙動があるため、看過できません。(これはめんどうくさいWebセキュリティのp281にも書いてあります。Opera 12.02でこのページを見るとフレーム中にiso-2022-jpと表示されるはずです。この挙動は12.10では修正されているように思いますが、@masa141421356さんによるとまだ条件によっては継承するみたいです。) これを利用すれば、EUC-TWで見ることを想定していないcharset指定がないページでも、ある程度バイト列を自由に出力できるなら、問題のバイト列を挿入してXSSを起こすことができます。

攻撃は安定的にはできないものの、一応情報も漏洩するしXSSも可能なので、まぁセキュリティバグだろうと、このフレームによる継承の手法も含めて報告しました。が、Operaのベンダ的にはノーマルバグだそうです。
Operaの脆弱性のCVE番号をゲットすれば、「5大ブラウザのCVE番号をゲットする」のアチーブメントをアンロックできるんですけど、なかなか難しいですね。また挑戦します。

0 件のコメント:

コメントを投稿