ラベル セキュリティ の投稿を表示しています。 すべての投稿を表示
ラベル セキュリティ の投稿を表示しています。 すべての投稿を表示

2013年3月10日日曜日

サーブレットのgetRequestURI()が取扱い注意な件 - その3(CVE-2012-0077)

OracleからCritical Patch Updatesが出て1年以上経ち、そろそろ時効かと思いますので書いておきます。

サーブレットのgetRequestURI()が取扱い注意な件で書いた、URLのパス中にスクリプト等を仕込める問題ですが、例で上げたものはすべてApache Tomcatで確認しています。
当然これらはサーブレットエンジンの実装の問題であることが考えられるので、WebLogic、WebSphere、GlassFish等でも確認してみました。
その結果、一部バグと思われる動作をしたものもありましたが、ほぼすべてTomcatと同じ動きであることが確認できました。

ところでこれらの製品、管理用のアプリケーションが用意されていますが、当然同じサーブレットエンジン上で動いていることが予想されます。この問題はアプリケーションの作り方によって発生しますので、ひょっとしたらこれらの管理アプリが誤った使い方をしていてXSS等があるかもしれません。

Tomcatも含め、4つの製品で試したところWebLogicがまんまとこの問題にひっかかっていました。これがCVE-2012-0077(JVNDB-2012-000007)です。



まだPatchをあてていないところもあるかもしれないので、一応URLは伏せておきます(って画面から推測できますが)。onMouseOverでalert出すようにしたところ、いたるリンクで出てしまい結構うざかったです。

まだPatchをあてていないならすぐ対応しましょう。
 Oracle Critical Patch Update Advisory - January 2012

2013年2月10日日曜日

とある雑誌のWriteupのさらなる別解

Google Chromeで http://23.20.185.226/ATAST/web200/ にアクセス後、 「ツール」「デベロッパーツール」で「Sources」タブ選択、右のメニューの「Event Listener Breakpoints」で「Mouse」をチェックし、イメージをクリックしてパズルをスタートさせます。すると、


はい、復元されたコード中でブレークすることができました。

このATAST CTF 2012 WEB 200のように、難読化されたJavaScriptを復元してevalで実行するタイプで、その復元されたコードを読めば何とかなる問題の場合、ChromeのDeveloper Toolsを使い実行コード中でブレークするのがもっとも手っ取り早そうです。

2012年2月2日木曜日

サーブレットのgetRequestURI()が取扱い注意な件 - その2

先のブログ記事「サーブレットのgetRequestURIが取扱い注意な件」で書いた、URLのパス中にスクリプト等を仕込める問題は当然サーブレットだけの問題だと思っていました。

ところがGoogleの複数のサービスに、同様にパス中のセミコロン以降を無視するものが多くありました。その中の幾つかは、同じサービス内へのリンクにわざわざそれらを引き継いでいたり、JavaScriptに渡しているものがありました。
正規化されたURLと同じように「"<>」等はエンコードされていましたが、「'」はそのままだったので、シングルクォーテーションで囲まれている部分についてXSSできました。

以前晒したスクリーンショットですが、特にURLを短くできたものについてリクエストURL付きで再度晒します。

2010年12月のBlog Searchは、JavaScriptに仕込めたのでページ表示時に発動しました。


2011年05月のMapsの再発したものはリンクのHREFです。qパラメータのイコールはエンコードされましたが、URL中のパスのイコールは放置でした。


合計で5ページをGoogleのセキュリティチームに報告し、$3,000の報奨金を頂きました。

他にも同様の問題を持っていた製品等がありましたが、また今度にします。
おそらく半年後くらいに「その3」を書くと思います。

2012年2月1日水曜日

サーブレットのgetRequestURI()が取扱い注意な件

いきなり本題ですが、

サーブレットのURLのパス中にセミコロンでつなげられた文字列は、サーブレットの呼び出しについては無視されますが、HttpServletRequest#getRequestURI()の戻り値には含まれます。

どうゆうことかというと、以下のようなサーブレットにアクセスするためのURLがあったとします。
http://www.acchi.jp/kocchi/OneServlet?hoge=moge
 これは以下のようにアクセスしても正常に呼び出されます。
 http://www.acchi.jp/kocchi/OneServlet;(-_-;)?hoge=moge
 このときgetRequestURI()の戻り値には、セミコロンで追加された文字列も含まれます。
/kocchi/OneServlet;(-_-;)
セッション管理が必要な携帯サイトをサーブレットで構築した方ならご存知と思いますが、URLリライティングによりURLのパスの後ろ、パラメータの前にセミコロンでつなげてセッションIDが埋め込まれます。
http://www.acchi.jp/kocchi/OneServlet;jsessionid=...?hoge=moge
過去に、同様に別のパラメータを追加できないか試したのと、そのアプリで独自のアクセスログを実装、URLの取得に最初getRequestURI()を使っていたことで、経験的にこのことを知っていました。

これは何か?

RFC3986 - Uniform Resource Identifier (URI): Generic Syntax の3.3.Pathによると、パスの後ろに追加するのではなく、パスセグメント(上の例のパス/kocchi/OneServletでいえば、kocchiと OneServlet)に付加情報を追加するための機能のようです。確かにTomcatをインストールした直後のExamplesで試してみると、サンプルのサーブレット、
 http://localhost:8080/examples/servlets/servlet/HelloWorldExample
は以下のようにしても正常に呼び出されます。
http://localhost:8080/examples;orz/servlets;o.rz/servlet;o..rz/HelloWorldExample;o...rz
一方、海外のサイトではこのような追加パラメータをPath Parameterと呼び、ファイル名の後ろにつけるもの、と説明しているものもあります。日本語で「パスパラメータ」で検索しても、それらしいものは見つかりません。

何が問題か?

開発者が意図しない文字列をパス中に挿入できるわけですから、 もし開発者が「正常にサーブレットが呼び出されたのだから、getRequestURI()の戻り値に不正な文字が含まれていることはない」という前提でコーディングをしていれば、Webアプリの脆弱性につながる場合もあるでしょう。そのままDBに保存すればSQLインジェクション、そのまま画面上に表示すればXSSされる可能性があります。

特にサーブレットの場合はweb.xmlファイルの中で<url-pattern>を指定するので、正常に呼び出されたサーブレットやJSPの パス中に、SQL文やJavaScriptが埋め込まれるはずなどないと思いがちでしょう。ところが上のサンプルサーブレットはweb.xmlで以下のように登録されています。

<servlet>
  <servlet-name>HelloWorldExample</servlet-name>
  <servlet-class>HelloWorldExample</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>HelloWorldExample</servlet-name>
  <url-pattern>/servlets/servlet/HelloWorldExample</url-pattern>
</servlet-mapping>

このように、<url-pattern>でPATHを固定に設定していても、上記の方法で任意の文字を挿入することができてしまいます。またweb.xmlに登録されていないJSPファイルについても同様に、
http://localhost:8080/index.jsp;(-_-;)
 というリクエストで通常どおり表示されてしまいます。


 どういった文字が挿入可能か

Servlet APIのHttpServletrequest#getRequestURI()の説明によればHTTPリクエストをデコードしない、とあるので、リクエストの送り手に依存することになります。
次のようなリクエスト、
http://localhost:8080/test.jsp;!"$&'()*+,-.:<=>@[\]^_`{|}~
 を各ブラウザで試した結果は以下のとおりでした。
FireFox(9.0.1) on Windows7
 /test.jsp;!%22$&%27()*+,-.:%3C=%3E@%5B%5C%5D%5E_%60%7B|%7D~
 IE(8) on Windows7(スラッシュに変換されてしまうので、バックスラッシュは除く)
 /test.jsp;!%22$&'()*+,-.:%3C=%3E@[]%5E_%60%7B%7C%7D~
 telnet直入力
 /test.jsp;!"$&'()*+,-.:<=>@[\]^_`{|}~
インターネットに公開しているサービスなどでは、フロントエンドにApacheを立てて、mod_proxy_ajp等を経由する構成が一般的でしょう。このような構成の場合、デフォルトではmod_proxyはURLを正規化します。その結果エンコードされる文字、デコードされる文字については過去にこのブログに書い たので、そちらを参照してください。FireFoxでアクセスした結果は次のようになりました。
mod_proxy
 /test.jsp;!%22$&'()*+,-.:%3C=%3E@%5B%5C%5D%5E_%60%7B%7C%7D~
mod_proxy経由で正規化された場合は、ブラウザに依存することなく「!$&'()*+,-.:;=@_~」がそのまま挿入可能になります。

どの程度危険か

サーブレットコンテナ直接接続の場合、SQLインジェクションのような直接攻撃(という言い方でいい?)については、telnetでほぼすべての特殊文字が利用可能になります。XSSのような間接攻撃(?)は利用者(被害者)の使用するブラウザに依存することになります。

mod_proxy 経由の場合、シングルクォーテーションが入力できることからSQLインジェクションが可能で、XSSについてもタグ内やJavaScript内でシングルクォーテーションで囲まれていればXSS可能になります。いずれの場合も挿入可能な文字種「!$&'()*+,-.:;=@_~」からすると、かなりのことができそうです。

対策

当たり前のことですが、getRequestURI()からの戻りはクライアントから送られてくるものなので、基本疑ってかかる。これに尽きると思います。適切にエスケープ、エンコード処理を行うべきでしょう。

参考

http://www.springsource.com/security/cve-2010-3700
CVE-2010-3700ではパス中のセミコロン以降に文字列を追加することでSpring Securityの制限がバイパスされてしまう問題を報告しています。

https://superevr.com/blog/2011/three-semicolon-vulnerabilities/
どうしてもこの件書けない事情があり、書けるようになるまで待ってたら、去年の11月に先に書かれたw
getRequestURI()以外の問題についても書かれています。

2011年8月4日木曜日

mod_proxyでエンコード・デコードされる文字

技術メモ。のちのち参照の可能性アリ。
apache2.2.17のap_proxy_canonencから(modules/proxy/proxy_util.cの153〜238行目)

  • /とエンコードされた/(%2F)はそのまま。
  • ~$-_.+!*'(),;:@&=(%7E%24%2D%5F%2E%2B%21%2A%27%28%29%2C%2B%2A%40%26%3D)はデコードされる。
  • 英数字でもなく上記の文字でもないものはエンコードされる。

以上の処理が行われた後、バックエンドに渡される。

2011年7月13日水曜日

XSS in Google Maps (again)

おそらくは前回のXSSのあとで機能追加されたリンクだと思う。
cnnでWeb検索してからMapsに移動すると、「Search the web for cnn」というリンクが左側に表示される。
このリンクのhrefがシングルクォート(')でくくられていた。
しかも前回見つけた「必要なのかどうかわからない機能」がこのリンクで発動していた。
前回は同じサービス内のリンクでのみ発動したので、なんでここだけ?と不思議に思ったが同じ手口であっさり通った。


成功して報告したあとに気づいたが、このリンク実は普通にqパラメータにシングルクォート入れるだけでhrefを終わらせることができていた。しかしへんな文字を入れるとすぐにこのリンク自体が表示されなくなってしまう。

がんばれば普通にXSSできるのではないか?と思ってORでつなげたりしてみたが、残念ながらイコール(=)がエンコード(%3D)されてしまった。


ひょっとしてこれ、気づいている人はたくさんいて、攻めあぐねていたんじゃないだろうか?

2011年2月1日火曜日

グーグル脆弱性報奨プログラム(まとめ) - グーグルからお金をもらう

今回は「ですます」調で。

日本語のセキュリティのページに書かれていないので、日本では気付いている人が少ないのかもしれません。
Googleでは昨年の11月から脆弱性報奨プログラム(Vulnerability Reward Program)というのをやっていて、同社のサービスに脆弱性を見つけて報告すると、報奨として$500から$3,133.7もらえます。

今後続く方のために、私がXSSを見つけた時の経緯を書いておきます。

最初、ショッピングにXSSを見つけて、すぐにSecurity Team(security@google.com)にメールしました。最初に見つけたものは、ページ表示後ユーザの操作によってスクリプトが動くものでしたが、その後同じサービス内の別のページで、ページ表示時点ですぐにスクリプトが動くものを見つけました。
この時点ではまだ、バグの管理番号が割り振られていませんでしたが、その後他のサービスで同じバグを見つけ、そのとき初めてちゃんとしたリストを作成し、管理番号の入ったサブジェクトのメールに返信しました。
これがちょっとしたトラブルの元になったようです。どうやら共通のバグであっても、サービス毎に管理しているようで、ショッピング以外のバグが見落とされそうになったそうです。

現に私の見つけたXSSは複数のサービスに共通にありましたが、報奨については別のバグとしてカウントされました。
しかも、共通で使われているフレームワークに元々の問題がありそうなので、すべてのサービスで共通に対応するだろうと思っていましたが、直し方はサービス毎にばらばらでした。

ですので、共通に存在するバグを見つけても、サービス毎に別のバグとして報告したほうがよさそうです。また一度報告してしまえば開発者は同じサービス内のその他の部分に気付くでしょうから、同じサービスをひと通り調べてから報告したほうが、とりっぱくれを少なくできると思います。彼らとしてもちまちま報告されるよりは、ある程度まとめてからの方が助かるでしょう。

報奨を受け取るには、
1.USDを受け取れる銀行に口座を持つ。
2.Googleのページでサプライヤ登録する。
3.W8-BEN form(米国源泉税を免除してもらうための書類)を作成、提出する。
ことが必要になります。これらはすべてメールで指示してもらえます。

1.については私の場合、もともとソニー銀行に口座を持っていたので、ここに振りこんでもらいました。
振りこんでもらうにあたり、銀行から被仕向送金手数料を取られます。ソニー銀行の場合$25なので、もし最低額の$500だと5%を取られることになります。私の場合2回に分けて振り込まれましたが、初回は被仕向手数料無料キャンペーン中だったので、1%で済みました。

2.は書くべき項目をメールで教えてもらえますが、受け取り口座は自分で調べて書く必要があります。私の場合不備があったようで、メールで足りない情報を確認されました。
受け取り銀行のSWIFTコード、中継銀行がある場合は中継銀行のSWIFTコードも必須のようです。ソニー銀行の場合、必要な情報はこのページに書いてあります。


3.は、ぐぐればフォーマットのPDFや書き込み例が出てきますので、特に問題ないと思います。


そして、バグが修正されて振込み手続きがひと通り完了したら、バグ情報をBlogに書いたりつぶやいていいそうです。
また、Google Security Hall of Fameページ(セキュリティの殿堂ページ?)に名前が載ります。どう書くか、どこにリンクさせるかは指定した通りにやってもらえました。

報奨を受け取られた他の方のご意見おまちしております。
 

2011年1月27日木曜日

Google Vulnerability Reward Program: XSS in Google Shopping, Maps and Blogs

There was a common XSS bug in Google Shopping, Maps and Blogs.
I don't describe it in detail because I think many web applications have same bug.

Shopping.
Maps.
Blogs.

I got $2,500 in total. Thanks Google.

2011年1月26日水曜日

グーグル脆弱性報奨プログラム(その3) - XSS in Google Blogs

これで最後、ブログ検索。
Shopping、Maps、Blogsで合計$2,500頂いた。
そろそろ新しいネタ探さないと。

2011年1月21日金曜日

グーグル脆弱性報奨プログラム(その2) - XSS in Google Maps

前回のShoppingと同じ手口。
「次へ」とかページ番号のリンクにonMouseOverで。
これで$500。㌧クス。>Google

2011年1月17日月曜日

グーグル脆弱性報奨プログラム(その1) - XSS in Google Shopping

昨年12月の始め、最近日本でサービスが開始されたグーグル・ショッピングにXSSを見つけた。商品リスト(/products)にはイベント駆動(onなんとか)でスクリプティング可能なものが1つ。商品情報(/products/catalog)では、ページ表示時点で可能なものが1つ、イベント駆動で可能なものが2つあった。

まずは商品リストから。
 画面上URLが短めだが、これはスクリプティングによって遷移先のURLが途中で切られてしまったことによる。ダイアログ表示後、表示されているURLに遷移している。

次、商品情報で遷移一発ででるもの。
 aikoで検索後、URL入力欄にスクリプトを仕込んだ。

続いて、 商品情報イベント駆動もの。

ダイアログすぐ上にある、「ショップ数」のリンクに細工をしてある。このリンクはUSのページにはないので、日本語のページで説明したところ、最初Security Teamは見つけられなかったらしい。UKのページにもあったので、これで説明した。

そして次は、逆にUSのページにしか見つけられなかったもの。

「Similar Items」のリンクに細工をしてある。

これらは共通のバグによって発生していて、個人的には「フレームワークの設計ミス」によるものだと考えている。
同じような問題を持つサイトがかなりあると思われるので、ここでは詳細については書かない。

実はこれと同じ問題は複数のサービスにあって、次回以降にレポートする予定だが、そのなかで「ヒント」くらいは出すかもしれない。

と、ここまでで$1,500頂いだ。ごっちゃんです。>Google