※ご注意
他社および他組織のWebサイトなどへのポートスキャンおよびデータの取得などの行為で得た情報を侵入などに悪用するか、または同じ目的を持つ第三者に提供した時点で違法となります。ご注意ください。
本稿の内容を検証する場合は、必ず影響を及ぼさない限られた環境下で行って下さい。
また、本稿を利用した行為による問題に関しましては、筆者および株式会社アットマーク・アイティは一切責任を負いかねます。ご了承ください。
完璧なアプリケーションをいきなり作り上げられる人はまずいないだろう。多くの人はアプリケーション中にデバッグ用のメッセージやコメントを残しながら開発を進めていくことになる。またユーザーにとって重要なのがエラーメッセージである。エラーメッセージを頼りにアプリケーションを利用していく。しかし、ユーザーにとって有用な情報なのだが、同様に攻撃者にも有用な情報を与えてしまうことにもなることがある。今回は、開発者として知っておいてほしい攻撃者に悪用されないためのいくつかの例を紹介する。
エラーメッセージの危険性
次のような画面を見たことがあるだろうか。
これは、ODBCを使ってデータベースにアクセスしたとき、何らかのエラーが発生して表示された画面だ。攻撃者はさまざまな手法を使って、エラー画面を表示させようとするだろう。
攻撃者にとってこのエラー画面に、どのような魅力があるというのだろうか。エラーメッセージをよく見ると、[Microsoft][ODBC SQL Server Driver][SQL Server]という記述がある。つまりこのサイトでは、Microsoft SQL Serverを使っていることが分かる。さらに、SQL文にエラーが発生したためにこのエラーメッセージが出力されたことから、SQL Injection(「第2回 顧客データがすべて盗まれる?!」参照)ができる可能性が高いということも分かる。
おそらくこのパラメータは、
〜 WHERE ***=<nameパラメータ> AND users.role = 1 〜
といったSQL文で使われているのではないかと想像できる。それならば、
name=0 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--
とするとどうなるだろうか。
エラーメッセージが変わり、
Syntax error converting the nvarchar value 'Customers' to a column of data type int.
となった。この結果から
〜 WHERE ***=0 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES-- AND users.role = 1 〜
というコマンドが実行されたはずだ。上記の「UNION SELECT 〜 INFORMATION_SCHEMA.TABLE」の部分は、SQLサーバを含むすべてのテーブルから先頭の1つを抜き出すためのSQLコマンドだ。ここでは、Customersという名前のテーブルが該当したため、SQL文全体では、
〜 WHERE ***=0 Customers AND users.role = 1 〜
という意味のコマンドになっている。そのため、0の後ろにCustomersが来るのは構文的におかしい、ということでエラーメッセージが表示された。これにより攻撃者は、「Customers」という名前のテーブルがあることを知るだろう。同じような攻撃を繰り返すことにより、ほかのテーブル名を1つずつ、テーブル名が分かった後はカラム名を1つずつ、そしてテーブル名とカラム名が分かった後はデータベースのデータを1つずつ取得することができる。つまりエラー画面を使ってデータベースの全データを抜き出すことができてしまう。
これは最悪のケースで、エラー画面が表示されたからといって必ずしもデータベースの全データが漏えいするわけではないだろう。しかしデータの漏えいだけを気にしていればいいわけではない。エラーメッセージ自体には何の情報も含まれていないとしても、攻撃者にとっては有用となるケースもある。
例えば、パラメータ値に「'」(シングルクオート)を入れると、次のようなエラー画面が表示されたとしよう。
この画面は、Webアプリケーションが異常終了した場合にApacheが表示するデフォルトのエラー画面だ。エラーメッセージには、「管理者に連絡してくれ」などとあるが、決まり文句で何の有用な情報も含まれない。攻撃者にとってはこの画面が表示されたこと自体が有用なのだ。
攻撃者はさまざまなエラーメッセージを収集するために何回もアクセスをしてきて、その後本格的な攻撃を行うはずだ。エラーメッセージが頻繁に表示されていることをIDSなどで検知して対策を施すことも考えられるが、2、3個のエラーメッセージを収集しただけで必要な情報が集まってしまうことも十分あり得る。時間的にはほんの数分なのでとても間に合うはずがない。プログラミングとテストの段階で、不正な入力値を徹底的に排除しておかねばならないだろう。
バックドアとなる可能性のあるデバッグモード
アプリケーションの開発にデバッグは欠かせない。そこで、デバッグのために必要な機能をアプリケーションに組み込んでおくことがある。例えば、
- パラメータにdebug=1とあったら、変数の値を画面に表示する。
- 特定のパスワードを入力すると、認証を回避できる。
- デバッグのための専用ページを用意してある。
などの機能が考えられる。エラーメッセージと同様、アプリケーションの開発時には便利な機能なのだが、実運用が始まったシステムではほとんどの場合必要ないはずだ。何らかの理由でやむを得ず必要な場合は、アクセス制御を行うなどして許可された人だけがその機能を使えるようにしておこう。
最近見つかった脆弱性
いままで紹介した脆弱性はどれも古くからある脆弱性だが、最近になって新たに見つかった脆弱性がある。それを紹介しよう。
●LDAPクエリーを操作する攻撃(LDAP Injection)
2003年7月29日にSPI LabsがLDAP Injection(http://www.spydynamics.com/whitepapers/LDAPinjection.pdf)というホワイトペーパーで発表した脆弱性だ。
基本的な考え方はSQL Injectionと同じだ。SQL InjectionではSQL文を操作したのに対して、これはLDAPクエリー(ディレクトリへの情報問い合わせ)を操作してしまおうという攻撃だ。例えば次のようなURLがあったとしよう。
http://www.example.com/cgi-bin/profile?name=kokubu
そしてこのアプリケーション内では、次のようなLDAPサーチフィルタ(検索条件)が発行される。
(uid=kokubu)
これに対して、
http://www.example.com/cgi-bin/profile?name=kokubu)(|(objectclass=*)
とアクセスすると、
(uid=kokubu)(|(objectclass=*))
というサーチフィルタが発行され、objectclass(RDBでいうところのカラム名のようなもの)の一覧が取得できてしまう。
また、
http://www.example.com/cgi-bin/profile?name=*
とアクセスすると、
(uid=*)
というサーチフィルタが発行され、すべてのLDAPレコードが該当することになる。
LDAPについて詳しく知らない人でも直感的に理解できると思う。いわれてみると当たり前で、難しい攻撃方法ではない。だから、こんな脆弱性を抱えたアプリケーションがあるはずないと思いたいが、SQL Injectionの問題を持つWebアプリケーションがあるのと同じ程度の割合でこの脆弱性を持ったWebアプリケーションがあると推察される。WebアプリケーションとLDAPを連携させているシステムでは、再確認しておいた方がよいだろう。
●Basic認証のIDとパスワードが漏えいするXST(Cross-Site Tracing)
WhiteHat Securityが2003年1月に発表した攻撃手法だ(http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf)。
この攻撃の大まかな流れはXSSと変わらない。XSSの詳細については、「特集:クロスサイトスクリプティング対策の基本」をご覧いただきたい。その記事で、XSSにより起きる主な被害としてCookieの盗難とページの改ざんを挙げた。しかしこのXSTという攻撃手法により、従来は XSSによって漏れることはないと思われていたBasic認証(IDとパスワードを用いて特定の人だけにWebサイトを見せることができる認証方式)のIDとパスワードが漏えいしてしまうことが分かった。
まず始めに、Cross-Site Tracingという名前の由来となっている、HTTPのTRACEメソッドについて説明しておく。TRACEメソッドはHTTP/1.1で導入されてもので、クライアントが自分が送信したリクエストメッセージがそのまま返ってくるメソッドだ。
$ telnet www.example.com 80 Trying 192.168.0.1... Connected to www.example.com Escape character is '^]'. TRACE / HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.2.1) Gecko/20030225 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1 Accept-Language: ja, en-us;q=0.66, en;q=0.33 Accept-Encoding: gzip, deflate, compress;q=0.9 Accept-Charset: Shift_JIS, utf-8;q=0.66, *;q=0.66 Keep-Alive: 300 Authorization: Basic a29rdWJ1Om1pY2hhaXlhLS0= Cookie: sessionid=5addd3c01848f941496720549ac9af8e Connection: Close HTTP/1.1 200 OK Date: Tue, 19 Aug 2003 14:17:36 GMT Server: Apache/2.0.40 (Red Hat Linux) Content-Length: 559 Connection: close Content-Type: message/http TRACE / HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.2.1) Gecko/20030225 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1 Accept-Language: ja, en-us;q=0.66, en;q=0.33 Accept-Encoding: gzip, deflate, compress;q=0.9 Accept-Charset: Shift_JIS, utf-8;q=0.66, *;q=0.66 Keep-Alive: 300 Authorization: Basic a29rdWJ1Om1pY2hhaXlhLS0= Cookie: sessionid=5addd3c01848f941496720549ac9af8e Connection: Close
最初に送信したリクエストメッセージが、完全な形でレスポンスメッセージに含まれているのが分かる。
攻撃者は、クライアントのブラウザがこのTRACEメソッドを発行するように仕向けてそのレスポンスを奪うことで、Basic認証のパスワードを盗むことができる、というものだ。
XSSの脆弱性を使うことで、攻撃者はユーザーに任意のスクリプトを実行させることができる。では、次のようなスクリプトが実行された場合はどうだろうか。
<script type="text/javascript"> var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlHttp.open("TRACE", "http://www.example.com/",false); xmlHttp.send(); xmlDoc=xmlHttp.responseText; alert(xmlDoc); </script>
FormからのアクションではTRACEメソッドを発生させることはできないのだが、スクリプトの中でIEのMicrosoft.XMLHTTPというActiveXコントロールやNetscapeのXMLDOMオブジェクトを使うことで、ブラウザからTRACEメソッドを発生させることができる。アラートボックスのメッセージを見てみると、Authorizationヘッダが含まれている。これがBasic認証のIDとパスワードをエンコードしたものだ。このスクリプトでは、TRACEリクエストの応答をアラートボックスに表示させているが、これを攻撃者のサイトに送信するようなスクリプトにすることも可能となる。
各サイトの管理者は、Cookieは使っておらずBasic認証を使っているからXSSの影響はないと思わずに注意が必要である。
これまで4回にわたってWebアプリケーションに潜む脆弱性と攻撃例を紹介してきた。 どの攻撃方法も高度な技術を要するものではなく少し考えれば思いつきそうな攻撃である、と思う。故にアプリケーションを作る側の立場からすると、ちょっと時間を掛けて考えれば対策が思いつく問題である、とも思う。
普段よりもほんの少し余計に考えることで、脆弱性が(もちろんセキュリティと関係ないバグも)激減するはずだ。人間のやっていることなのでミスや見落としはある程度仕方ない。それさえも許されないサイトでは、専門家に相談、あるいは診断してもらうとよいだろう。
次回は、Webアプリケーションの検査手法について紹介する。
←「第3回」へ
「第5回」へ→
著者紹介
国分裕(こくぶ ゆたか)
三井物産セキュアディレクション勤務。セキュリティコンサルタントとして、不正アクセス監視やセキュリティ検査などに従事している。金融機関、官公庁、大手製造業などへのセキュリティシ ステムの導入、セキュリティ 検査などの実績を持つ。
主に、不正アクセス監視サービス、セキュリティ検査、セキュリティポリシー策定支援などのサービス提供している。また、セキュリティに関する教育サービスも実施中。
- Webアプリケーションの脆弱性を総括する
- OSコマンドインジェクションを防ぐルールを作成する
- mod_securityのXSS対策ルールを作成する
- Webアプリケーションファイアウォールによる防御
- 安全なWebアプリケーション開発のススメ
- オンラインショッピングにおける脆弱性の注意点
- ロジック系の検査 〜 問い合わせ画面に含まれる脆弱性 〜
- Webアプリケーションの検査(3)〜 攻撃されないためのセッション管理の検査方法 〜
- Webアプリケーションの検査(2)〜 Webサイトのセッションまわりを調べる方法 〜
- Webアプリケーションの検査テクニック(1)
- エラーメッセージの危険性
- 気を付けたい貧弱なセッション管理
- 顧客データがすべて盗まれる?!〜OSやデータベースへの攻撃〜
- サーバのファイルが丸見え?!
Copyright © ITmedia, Inc. All Rights Reserved.