前の投稿 次の投稿

脆弱性の見つけ方(初心者向け脆弱性検査入門)

EC-CUBEで脆弱性を見つけたり、mixiの脆弱性報告制度で成果を挙げたりしたせいか、「どうやって脆弱性を見つけてるんですか?」という質問をされることが時折あり、一応手順は説明するのですが、いつも口頭で細かくは説明できなくて申し訳ないので、自分のやり方をまとめてこのブログにアップしておきます。

標準的な脆弱性検査のやり方しか説明していないので、脆弱性検査のやり方を既に把握している人が読んでも得るものは少ないのではないかと思います。今回は脆弱性検査に興味があるが何をどうしたらいいか分からないような初心者向けコンテンツです。

●ウェブサイトの手動脆弱性検査の基本

ブラウザでウェブページを見る際、発生する通信はHTTPプロトコルの「HTTPリクエスト」と「HTTPレスポンス」の二種類のメッセージで成り立っています。

ウェブサーバにブラウザから要求(リクエスト)を出し、ウェブサーバから戻ってきた応答(レスポンス)をブラウザが解釈してウェブページを表示する、というのが、ブラウザでサイトを見た際に裏側で行われている処理です。

あるウェブアプリの脆弱性検査を行いたい場合で、ブラックボックステスト方式で検査を行う場合には、この「HTTPリクエスト」のいろいろな箇所にいろいろな値を入れてみて(手順A)、ウェブサーバから戻ってきた「HTTPレスポンス」の反応を解釈して、脆弱性を見つける(手順B)というのが基本の手順になります。(他、ソースコードを開示してもらい、解析して脆弱性を見つけ出す等のホワイトボックステスト的なやり方もありますがここでは解説しません)

この(A)(B)の手順は、ブラウザ単体でやろうとしても十全にはできないので、ブラウザ-WEBサーバ間の通信内容を見たり、一旦止めて修正してから送信できたりするローカルプロキシソフトを使うのが一般的です。

私が使っているローカルプロキシソフトはFiddlerというソフトですが、Burp Suiteというソフトを使っている人も多いようです。

Fiddlerの使い方は下記サイトが詳しいです。

実はFiddlerがすごすぎたので、機能まとめ紹介 - digital matter
Webセキュリティの小部屋 > Fiddler の簡単な使い方
Webセキュリティの小部屋 > Fiddler でリクエストパラメーターを改ざんする方法

Fiddler起動させておくと、ブラウザの設定が自動的に変わり、ブラウザからの通信がFiddlerを経由しての通信になります。

Fiddlerの機能で、ブラウザから送信されたリクエストを、いったんサーバーに実際に投げる前に一時停止して、編集できるようにするモードがあるので、そのモードにして、ブラウザから送信されるリクエストをいじくってからサーバーに投げます。そうして、いじくったリクエストに対するレスポンスに反応が出るか出ないか、異常な反応か正常な反応か、などを見ます。

●具体例

以下は私のローカルPC上のWEBサーバのページ(XAMPPトップページ)にアクセスした場合のFiddlerの画面キャプチャです。

検査対象のサイトに対して、Fiddlerを起動してブラウザからアクセスをすると、Fiddlerの左のウィンドウにアクセス結果(URL、結果ステータス等)が、右の上ペインに「HTTPリクエスト」、右の下ペインに「HTTPレスポンス」が表示されます。

(Inspectorsタブを選択し、リクエスト・レスポンス両方とも「Raw」を選択するようにしてください。本手順を確認するときは、インターネットの任意のサイトへの通信を覗く形で手元で確認できますが、外部のサイトを覗いて確認するときは、SSL利用のサイトだと通信を覗くのに設定を加えないといけないので、非SSLのサイトにアクセスして確認してください。また、注意事項ですが、公開サーバーへの攻撃とみなされる可能性がありますので、検査の許可をもらっていないサイトや自分が管理していないサイトへの通信は改変等はせず覗くだけにしましょう。



Fiddlerには、ブラウザからサイトにリクエストを投げる際に、いったんリクエストがFiddlerで差し止められ、Fiddler上でリクエストを編集することができるようになるモードがあります。

分かりづらいのですが、Fiddlerのステータスバーの左から三番目の区切りの箇所

を一度クリックすると こんな表示になり、この状態にすると、ブラウザからのリクエストをいったんFiddlerが差し止めるモードになります。

ここで、ブラウザからウェブサイトにアクセスすると、Fiddlerが通信を差し止めるので、ブラウザはレスポンス待ちの状態で止まります。
Fiddlerの画面を見ると、右上のリクエストを表示する欄でウェブサーバに投げるリクエストが表示されているので、内容を改変し、「Run to Completion」のボタンを押下すると、改変されたリクエストがウェブサーバに投げられ、そのレスポンスがFiddlerの右下のレスポンスを表示する欄に表示されつつ、ブラウザにもレスポンスが表示されます。

ここで、検査の際にどういう風に考えて値を改変していくかを簡単にやってみます。

ここで、「example.com」というサイトに対するGETリクエストを改変する場合を考えてみます。

例えば、GETリクエストの内容がこうだったとして、

GET http://example.com/?q=a HTTP/1.1
Host: example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Referer: http://example.com/ref
Cookie: uid=12345
Connection: keep-alive

脆弱性を探すための改変箇所として、パッと見でとりあえず色々試して反応を見たい箇所は
・GETパラメータ「q」の値
・Cookieの「uid」
だと思います。


・GETパラメータ「q」の値
は、まず「xxxxxyyyyyzzzzz」みたいな文字列にして、ここに指定した値がページ上にエコーバックされるかされないかを見ます。(文字列は何でも良いのですが、一目でわかるような特殊な文字列であればエコーバック箇所が見つけやすい)

それから、指定した値がエコーバックされる場合は「"」や「'」や「<」「>」などHTML的に特殊な意味を持つ文字を指定してみて、それらの文字がエスケープされて表示されるか否かを見ます(XSS狙い)。

それらの記号がエスケープされないで表示されるなら、ブラウザがHTMLを解釈(パース)する際に、ページのHTMLの構造をウェブサイト運営側が意図しない形で解釈させてスクリプトを動かしたり、ページの一部や全体を偽造したりすることが可能なので、XSS脆弱性の発見に成功したということになります。
(*細かくは記号がエコーバックできてもXSSできないケース等もあると思いますが、ここではざっくり例外を省いて解説しています)

・Cookieの「uid」
これはパラメータの名前や値の雰囲気からいって「ユーザーID」を示す値っぽいです。こういう値の場合には、SQL的に特殊な意味を持つ「'」などを指定してみてSQLインジェクション脆弱性がないか探すのも一手ですが、「12345」という値を「12344」のように、同じ形式の別の値にしてみることにより他人になりすませないか見るほうが期待値が高いです。

というのも、「'」のような特殊記号の混入には対策が取られていても、「適切な形式の値である」というチェックを通ったら、実際には他者のIDであっても正しい値として処理を通してしまう、というようなチェック処理の漏れを持つプログラムは割にあるからです。

(しかも、こういう処理漏れは脆弱性スキャナにエラーとして認識されないことが多々あります。ログイン者と違う氏名が表示されても画面遷移的には正常なので、脆弱性スキャナには異常と検知されない可能性が高いです)

こんな感じで、当たりをつけつつ、リクエストをいじくって、レスポンスの反応を確認し怪しい挙動があれば絞り込んでいく、みたいな作業を繰り返します。
(もちろん件のGETリクエストには上記以外にもいろいろリクエストをいじくって反応を見てみたい箇所はありますが、大まかな例です)

これが私のやっている脆弱性検査の基本的な手順です。おそらくこれは大抵の脆弱性検査者がやってる手順だと思います。

●検査に有用な知識

上述の作業において、脆弱性の当たりをつけたり、絞り込んでいったりするのに有用なのが、WEBアプリケーションの開発経験と脆弱性の知識です。(これは私の私見です)

WEBアプリケーションの開発経験は、「このあたりはこういう構造になっているのではないか」と内部構造を推測するのに役立ちます。

脆弱性の知識は、どれだけたくさん色々な脆弱性を把握しているかが、検査人としての腕前に直結するのではないかと思います。というのも、知識がないと危険な現象を見ても脆弱性に結びつけることができないからです。

例えば、「XSS」という脆弱性の原理を知らない開発者がもしいたとしたら、ユーザーが入力した「"」や「<」や「>」等がページにそのまま出力されてしまうことの危険性は分からないため、HTML上の特殊文字をそのままエコーバックするようなつくりにしてしまい、XSSを知っているクラッカーに脆弱性を突かれてしまいます。クラッカー側の目線から見ると、「XSS」というものを知っていることによって、「"」や「<」や「>」などの特殊記号がエコーバックされる危険性を想起することができたわけです。

検査人としても同様に、脆弱性の事例を知っていれば知っているほど、ウェブサイトの振る舞いから想起できる脆弱性の数が増えるので、知識は多いほうが良いです。
(私はこの点でまだまだ知識が足りません。勉強しなければ)

脆弱性についての知識は、たぶん無限に必要ですが、基本を抑えるならIPAの公式ドキュメントにある代表的な脆弱性の把握から始めれば良いのではないかと思います。

(IPA) 知っていますか?脆弱性 (ぜいじゃくせい)
http://www.ipa.go.jp/security/vuln/vuln_contents/index.html
(IPA) 安全なウェブサイトの作り方
https://www.ipa.go.jp/security/vuln/websecurity.html

●脆弱性検査の注意点

最後に重要なので再度注意書きを。

注意:脆弱性検査は検査許可をもらっているサイトか、自分の管理しているサイトに対してのみ行いましょう。

これは不正アクセス禁止法に触れるという以外に、検査行為によって対象サイトに実際の被害を発生させかねないからです。

参考:検査行為のおかげで対象サイトに害が発生しえた/害が発生した例
ockeghem(徳丸浩)の日記 2008-11-17 SQLインジェクション検査の危険性
とある診断員とSQLインジェクション

●参考書籍

また、この記事以上に脆弱性検査について学びたい方は
体系的に学ぶ安全なWEBアプリケーションの作り方(いわゆる徳丸本)
などを購入して見ると良いのではないかと思います。


以上、私のやってる脆弱性検査の方法をまとめてみました。

Leave a Reply

Powered by Blogger.
© WEB系情報セキュリティ学習メモ Suffusion theme by Sayontan Sinha. Converted by tmwwtw for LiteThemes.com.