2012年2月19日日曜日

BackTrack 5 R1でGUIログイン

意外とぐぐっても引っかからないのでメモメモ。。。

# apt-get install gdm
# vi /etc/rc.local
 exit 0
 の上に
  /usr/sbin/gdm&
 追加
# reboot

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()以外の問題についても書かれています。

戻ってきました。

はてなダイアリープラスの1ヶ月無料お試し期間過ぎたので、戻ってきました。
さっそくセキュリティネタ1本書きます。