他社および他組織のWebサイトなどへのポートスキャンおよびデータの取得などの行為で得た情報を侵入などに悪用するか、または同じ目的を持つ第三者に提供した時点で違法となります。ご注意ください。
本稿の内容を検証する場合は、必ず影響を及ぼさない限られた環境下で行って下さい。
また、本稿を利用した行為による問題に関しましては、筆者および株式会社アットマーク・アイティは一切責任を負いかねます。ご了承ください。
前回まではさまざまなWebアプリケーションの脆弱性についての説明を行ってきたが、今回からは実際に検査を行う場合に必要となるテクニックについて説明する。
まず初めにWebアプリケーションの検査とはどういったものなのか、攻撃とどう違うのか、ということについて説明しておこう。
ここでいう検査とは、外部からWebアプリケーションに対してブラウザでアクセスする、いわゆる「ブラックボックステスト」のことをいう。
Webアプリケーションの検査は基本的に不正な文字列をアプリケーションに渡して、その反応を見る作業である。これらの不正入力が正しくフィルタリングされていない場合、アプリケーションは何らかの想定外の動作をする。同じ不正文字列でもアプリケーションの作り方によって、誤動作する場合としない場合があるため、さまざまなパターンの入力を行い、その反応を見る。これにより、アプリケーションがどの不正文字列に対しては安全であるかが分かる。
もちろん、ソースコードがどのようになっているかは外部からは見えないので、「OSコマンドインジェクションの脆弱性は100%存在しない」と断言することはできないが、攻撃者の立場から考えられる入力を数多く試してみることにより、検査対象アプリケーションの安全性は確かなものになる。
すなわち、Webアプリケーションの検査は、これまでに説明したさまざまな脆弱性が検査対象アプリケーションには存在しないということを確認する作業である。脆弱性を見つけることが目的ではない。
脆弱性を見つけるだけであれば、攻撃とあまり変わらない。攻撃者の立場に立って考えると、サイト全体のアプリケーションを片っ端から攻撃するのは非常に効率が悪い。また、アクセスログが残るため、サイト管理者に見つかってしまう可能性も高くなる。そのため、攻撃者は脆弱性がありそうな個所を見つけて、そこに対して適切な攻撃を仕掛ける。例えば、「ここはデータベースにアクセスしてるだろうから、SQLインジェクションを試してみるか」といった感じだ。このような方法ではSQLインジェクションの脆弱性は発見できるかもしれないが、OSコマンドインジェクションが存在しない、とはいうことができない(参照:「第2回 顧客データがすべて盗まれる?!- SQL Injection」)。
また、攻撃の場合は、簡単に脆弱性を見つけることができる。なぜなら脆弱と思われるサイトを探して攻撃すればいいからである。脆弱性があるかどうか分からないサイトを執拗に攻撃するより、脆弱かどうか簡単に確認できる方法で片っ端からサイトをチェックしていく方が楽だからだ。
以上簡単ではあるが、Webアプリケーションの検査とはどういうものなのか、お分かりいただけただろうか。
Webアプリケーションの検査は手間がかかる。詳しい手順などは後述するが、なるべく手間をかけずに行いたいと考えるのは当然である。そこで登場するのが、自動的に検査を行ってくれるツールだ。
検査ツールは大きく2種類に分けることができる。
前者は脆弱性の検査を行うには変わりないが、Webサーバプログラムと一緒にデフォルトでインストールされるCGIや、一般に広まっているフリー、もしくはシェアウェアのWebアプリケーションが対象となっている。また、Webアプリケーションだけでなく、一般的な名前のファイルやディレクトリの検索を行うものもある。これらのツールは、ネットワークレイヤの検査と一緒に行われることが多い。この種のツールは、フリーのスクリプトとしてインターネット上で入手可能だ。これらのツールの入手先URLを以下に示す。
後者は本稿が対象としている脆弱性検査を自動的に行うものである。この種のツールで使えるものとしては、フリーのものはまだなく、商用のもののみとなっている。自動検査ツールは主に次のような機能を持っている。
ほかにもいろいろと機能はあるが、上記2つがWebアプリケーションの検査にとって重要な機能である。自動検査ツールを使うとWebアプリケーションの検査が非常に楽になるが、当然ながら欠点もある。それを以下に説明する。
では、それぞれ順に詳しく説明しよう。
1.すべての画面を巡回できるとは限らない
自動検査ツールで一番重要なのは、自動巡回部分である。
静的コンテンツ(HTMLファイル)で構成されるWebサイトの巡回は非常に簡単である。なぜなら、取得したWebページに含まれるリンクをすべてたどっていけばいいだけだからだ。このような自動巡回を行うツールは、フリーのものがインターネット上で簡単に手に入る。
一方、動的コンテンツで構成されるWebサイトの場合、ただ単にリンクをたどっていけばいいわけではない。ユーザー登録、ログイン、ショッピングなど、それぞれの画面が提供する機能に従って、何らかのデータを入力して送信したりする必要がある。また、誤ってログアウトしてしまった場合、再度ログインする必要がある。ある画面を表示するには、特定の画面遷移をたどっていかなければならない場合もある。
このように、動的コンテンツで構成されるWebサイトの巡回は、アプリケーションごとに異なるため、いまのところこの機能を完全に自動化するのは不可能だろう。現在手に入る商用の検査ツールでは、フォームを送信する画面はユーザーの手を借りることでクリアしているが、同じフォームを送信する場合でも、場合によっては次の画面が異なるものとなる場合も考えられる。
また、すべての画面遷移がPOSTメソッドで行われているようなアプリケーションでは、自動巡回は不可能だ。
このように、自動検査ツールの巡回機能ではすべての画面を巡回できるとは限らない。
2.入力が複数画面にまたがる場合に対応していない
例えば、次のようなユーザー情報登録画面があったとする。
A ⇒ B ⇒ C
画面Aには名前や住所の入力フォームがある。このフォームを埋めて送信すると、画面Bが表示される。画面Bでは趣味などを入力するフォームがある。これを埋めて送信すると画面Cが表示される。画面Cでは「登録完了しました。ありがとうございました」と表示され、画面A、画面Bでの入力が確定する。
このような個所を検査する場合、まずは画面Aのフォーム内のすべてのパラメータの検査を行う(詳しい手順は別の回で説明するので、ここでは詳細は割愛させていただく)。この画面に対する検査は、手動による検査でも自動ツールによる検査でもそれほど違いはないだろう。問題は次だ。
次は画面Bの検査を行うのだが、自動検査ツールの場合は、画面Aでの入力が完了していることを前提とせずに直接画面Bの検査を行ってしまう。なぜか?
自動検査ツールの場合、自動巡回時にすべてのフォームに手動で入力させる。フォーム入力までは自動では難しいからだ。自動検査ツールはここでの手動による「正しい入力」によって生成されたリクエストを記録しておき、検査フェイズでこのリクエストをベースとして使う。
つまり、画面Bを単独で検査している。もし画面Bのフォーム送信が画面Aのフォームが送信済みであることを前提としている場合、画面Bで不正な入力を行ったとしても、
「画面Aのフォームが入力されていません」というエラーページが表示されるだけで、入力した不正文字列がまったく処理されない可能性がある。 このような検査はまったく意味がないものである。
3.すべてのステータスで検査できるとは限らない
上記2に関連することだが、自動検査ツールはアプリケーションの“ステータス”に関しては考慮されていない。常に同じ動作をするアプリケーションもあるが、中にはステータスによって動作が変わるものもある。例えば、次のような画面遷移をするアプリケーションがあったとする。
A ⇒ B ⇒ C ⇒ D
↑
E ⇒ F ⇒ G
画面AからB、C、Dと遷移するパターンと画面EからF、G、C、Dと遷移するパターンがある。
ここで、画面Cのフォーム送信は、2つのパターンで共通となっている。画面Cのフォームから送信されるデータがまったく同じであっても、画面の遷移順序によっては、違った動作をするかもしれない。
自動検査ツールがこのような画面遷移をまったく意識せずに、単にフォームがあるURL、フォームを構成するパラメータ、フォームの送信先だけでそのフォームが同じかどうか判断している場合、2つのパターンで共通となっている画面Cでの検査が1回で済まされてしまうかもしれない。
もし画面遷移によって動作が異なるのであれば、画面A、Bから遷移した後の画面C、画面E、F、Gから遷移した後の画面Cの検査を別々に行う必要がある。
4.すべての脆弱性を検査できるわけではない
Webアプリケーションの脆弱性は、「テクニカルエラー」と「ロジックエラー」の2つに分けることができる。
注:「テクニカルエラー」「ロジックエラー」、これらの言葉は筆者が独自に定義したものであるが、テクニカルエラーとは、主に入力チェック漏れのことをいい、ロジックエラーとは、アプリケーションのアルゴリズムやセッション管理などにおける脆弱性のことを指す。
自動検査ツールはテクニカルエラーを見つけるツールである。ロジックエラーに関しては、ほとんど脆弱性を見つけられないか、チェックすらしない場合もある。そのため、ロジックエラーについては必ず手動での検査が必要となってくる。
手動での検査では、基本的に自動検査ツールによる検査の長所、短所が逆になる。つまり、手動ではすべての検査を行うことができるが、非常に時間がかかり、効率が悪い。しかし、検査の正確性を重要視する場合は、自動検査ツールではなく、手動による検査を行うべきであろう。
次に、手動で検査を行う場合に役に立つツールを紹介しよう。
手動での検査といってもブラウザだけではちょっと無理なので、何らかの補助ツールが必要になってくる。検査に使えるツールとしては、以下のようなものがある。
この中から「Achilles」というツールを紹介しよう。Achillesは、クライアントPC(Windows)上で動作するプロキシサーバである。通常のプロキシはHTTP(S)通信を中継するだけであるが、このツールはMITM(Man In The Middle)攻撃(参照:PKI再入門 - 第4回 公開鍵に基づく信頼の図1)のように、途中でデータを書き換えることができる。
このツールの特徴を以下に挙げる。
ダウンロードしたzipファイルを解凍してできるexeファイルをダブルクリックするだけですぐに起動する。
HTTPSはSSLセッションを張ってからそのうえでHTTPの通信を行うため、その通信をプロキシでインターセプトして書き換えを行うことは不可能だと思われるかもしれない。もちろん、本当のプロキシの仕様では書き換えは不可能だ。しかし、このツールではそれが可能になっている。その理由は、SSLのセッションを2分割しているからである。
HTTPSを中継する部分をもう少し詳しく説明しよう。少々セキュリティとは話がそれるかもしれないが、Webアプリケーションの検査を行ううえでHTTP/HTTPSやプロキシの知識は必須なので、このあたりの話も理解しておいた方がいいと思う。
プロキシ経由でHTTPSの通信を行う場合、ブラウザは以下のようなHTTPリクエストを送信する。
CONNECT www.gtisec.net:443 HTTP/1.0
ここで、通常のプロキシの場合は、対象ホスト(www.gtisec.net:443)との間にTCPコネクションを張り、ブラウザに以下のレスポンスを返す。
HTTP/1.0 200 Connection established.
プロキシはそれ以降の通信をすべてTCPレベルで中継する。この後、クライアントがWebサーバとの間でSSLセッションを張ろうとすると、プロキシはSSLを意識せずにそのまま転送するため、Webサーバとブラウザの間でSSLセッションが確立される。
以上は通常のプロキシの動作だが、Achillesでは次のような動作をする。
ブラウザが以下のHTTPリクエストを送信する。
CONNECT www.gtisec.net:443 HTTP/1.0
プロキシは、対象サーバとの間でSSLセッションを張り、以下のレスポンスを返す。
HTTP/1.0 200 Connection established.
通常のプロキシでは、この後ブラウザとWebサーバ間でSSLセッションが確立されるが、Achillesは自分がWebサーバであるかのようにブラウザからのSSLセッション確立要求をそのまま受け入れて、ブラウザとプロキシの間でSSLセッションが確立される。これは、ブラウザに渡されたサーバ証明書を見ることで確認できる。接続しているWebサーバ(例えば、https://www.gtisec.net/)とは別のサーバ証明書が表示されるだろう。
ブラウザはSSLセッションが確立されると、通常のHTTPリクエストをそのセッション上に流す。あとは通常のプロキシと同じようにHTTPを中継する。
以上のような仕組みであるため、AchillesではHTTPSの通信のインターセプト、およびデータの書き換えが可能になっている。
achilles-0-27.zipをダウンロードして解凍したら、あとはAchilles.exeをダブルクリックすれば起動する。
画面を見れば理解できると思われるが、一応、設定方法を簡単に説明しておく。
1.ポート番号を指定する(デフォルトは5000番になっている)
ブラウザ側でこの番号に合わせるだけなので、特に変更する必要はないだろう。
2.「Ignore .jpg/.gif」「Intercept Server Data(text)」「Intercept Client Data」「Intercept mode ON」それぞれにチェックを入れる
Ignore .jpg/.gif | 画像ファイルの送受信をインターセプトしないようにするオプション |
---|---|
Intercept Server Data(text) | サーバからのHTTPレスポンスをインターセプトするオプション |
Intercept Client Data | クライアントから出力されるHTTPリクエストをインターセプトするオプション |
Intercept mode ON | 実際にインターセプトするかどうかのオプション |
3.左上の[Start Proxy]ボタンを押すとプロキシが起動する
起動すると左下のStatus欄が「Running」になる。
4.ブラウザのプロキシ設定を「localhost:5000」にする
以上でAchillesが使えるようになるだろう。
では早速使ってみよう。単にプロキシとしてではなく、リクエストの書き換えを行うので、外部のWebサーバではなく、ローカル環境の自分の管理下にあるWebサーバを使ってほしい。
基本的な流れは以下のとおりである。
ページ内に画像(jpg、gifなど)やJavaScriptファイル(js)やスタイルシート(css)が含まれる場合は、基本的にその数だけ1〜7の手順が繰り返される。
このようなHTTPリクエスト/レスポンスの書き換えができるツールは、Webアプリケーションの検査を行う上で必須である。このツールを使って、まずはブラウザとWebサーバ間でどのような通信が行われているのかじっくり見てみるといいだろう。
実際の検査手法については次回以降で詳しく説明する。
←「第4回」へ
「第6回」へ→
中村隆之(なかむらたかゆき)
三井物産セキュアディレクション勤務。 セキュリティコンサルタントとして主にWebアプリケーションのセキュリティ検査に従事しており、大手ポータルサイト、オンラインバンキングなどの数多くの 検査実績を持つ。また、セキュアネットワーク及び暗号関連の研究に携わり、大手製造、官公庁、金融機関へのセキュリティシステム導入など数多くの実績を持つ。
主に、不正アクセス監視サービス、セキュリティ検査、セキュリティポリシー策定支援などのサービス提供している。また、セキュリティに関する教育サービスも実施中。
Copyright © ITmedia, Inc. All Rights Reserved.