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アプリケーションの作り方(いわゆる徳丸本)
などを購入して見ると良いのではないかと思います。


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

mixiの脆弱性報告制度の総括記事を書こうと思い、報告した脆弱性の評価が確定するのを待っていたのだが、最後の一件の評価がなかなか戻って来ないため問い合わせたところ、修正方法を含め時間がかかる、との事だった。

そのため、一件評価が未確定のものが残ってはいるが、評価が出るのを待っていたら遅くなりそうなので、先に今回の脆弱性報告制度に参加した感想を書いてしまおうと思う。

報酬

報告した脆弱性:15件
評価された脆弱性:4件
(評価が確定していないものが1件残っている)

いただいた報酬:現時点までの合計 ¥475,000(Amazonギフト)

感想

よかった点
・報酬が高額
・「mixi」という大手企業の色々なサービスを思う存分検査できた点。超楽しかった。ずっと続けたいぐらい。

悪かった点
・参加者への応対
・脆弱性の評価の判断基準の不明瞭さ

mixiさんの制度運用について思うこと

私が以前書いた記事のせいもあって、mixiさんに批判が集まる形になっているが、とりあえず参加者として思うところを少し述べてみようと思う。

私が報酬を頂いた脆弱性を発見したサイトは、mixiアンケート、youbride、YYC、ショッパーズアイだが、サイトの規模に関わらず、mixiさんからは高額な報酬(10~12.5万円のAmazonギフト)をいただくことができた。

特に、「ショッパーズアイ」というサイトはmixi本体と比べるとかなり参加者の少ない小規模なサイトだと思うが、このサイトのXSSであっても、特にケチるようなそぶりもなく、公式ルールの「脆弱性と報酬額の例」のXSSの場合の金額、12.5万円(Amazonギフト)が支払われた。

mixiさんが本当にできる限り報酬をケチりたいなら、「このサイトはユーザー数がmixi本体と比べるとかなり少なく、影響範囲も小さいので、報酬は1万円で」みたいなケチり方もできたと思うし、そのほうが批判の対象にもなりにくく、スマートだったと思う。
でもそれをしなかったので、運営側は必ずしも「何が何でも賞金をケチりたい」というのではなかったように思う。

しかし、超高額報酬が出てしまった際には、賞金支払いをケチっているかのように見える挙動があり、疑念を打ち消すような判断基準の情報開示もなかったので、炎上して叩かれてしまったように見える。

やはり、この手の脆弱性発見コンテストでは「企業側の評価基準の透明化」が絶対的に必要なのだろうと思う。
下手に「自社の基準で」でやってしまうと、どうしても「有益な脆弱性報告をただ取りされた」的なトラブルが起こってしまう気がする。

サイボウズの脆弱性発見コンテストでは、 脆弱性はCVSS v2 を用いて評価となっていた。例えばこのように客観的な指標を導入するのも手なのではないかと思った)


あと、別件で指摘したいのが、「脆弱性に賞金を出す制度」というのは、本来、クラッカーが発見した脆弱性を悪用したりその手のマーケットで販売したりするのを防ぐために企業が脆弱性情報をクラッカーから買い取るという趣旨があるものだが、今回、私の発見した例の脆弱性にしろ、このブログの方の発見した脆弱性にしろ、すごい危険性がある状態を発見し、それを悪用せずに企業に情報を渡したのに、企業側が「悪用しなかった」ということに対する対価を払わなかった(ように見えた)。この点は良くなかったと思う。

危険な脆弱性を発見して報告しても正当な対価がもらえないなら、今後は報告なんかせずに見つけた脆弱性を直接悪用するか、ブラックマーケットに売った方がいいや、となってしまうのでよろしくないと思う。(私は逮捕されたくないので仮に全く利益が得られなくてもIPAとかに報告してしまうと思いますが、一般論として)

既知であろうが同様の脆弱性が他にあろうが、「脆弱性を悪用しなかった」という点に対しての報酬はいくばくか払った方が良かったように思う。

まとめ:「次回に期待」

mixiさんの脆弱性報告制度は、自社および子会社の運営するサイトの本番環境を脆弱性検査希望者に全公開するという「こんなに緩くていいんですか??」という荒っぽさがあり、たぶん「攻撃なんて毎日腐るほど来ているのだから、脆弱性コンテストに本番環境使っても大丈夫やろ」というノリの豪胆な人がmixiの中にいたのだと思う。

それで、そういうノリでとりあえず開始してみたところ、起こる事態の想定なども甘いままボロが出てしまった、というところがあったのではないかと思う。(例えば対応人員足りなくて評価に時間かかったり)

ただ、その大雑把さのおかげで私としてはmixiという大手企業が運営する多数のサイト(本番運用中)をブロックや通報を恐れずに検査することができ、普通に脆弱性検査の体験学習として面白かったし、ためになった。

mixiさんの試みは、試み自体としては非常に良い試みだと思ったし、今後どんどんほかの企業も同じような試みをやってほしいと思った。

私としては、あまり国内でやられていない「高額賞金の脆弱性報告制度」という冒険を、本番環境で「えいや」でやってしまったmixiさんの男気は評価されるべきだと思う。

ただちょっと運用面では色々まずかったようにも思うので、次回やるときはそのあたりを改善してほしいと思う。

余談:Amazonギフトについて

今回のmixiの脆弱性報告制度の賞金はAmazonギフトで支払われた。

些末な事ながら、Amazonギフトは1~数万円程度の報酬には向くと思うが、それ以上の高額賞金には全く向かないと思う。
大きな理由としてはAmazonギフトには有効期限があり(一年間 有効期限はギフト券の券種によって一~三年のものがあるようだが、今回mixiさんが賞金の支払いに使ったのは有効期限一年の券種だった)、その間に使い切らないと無効になってしまうからだ。

高額になればなるほど、その一年縛りがきつくなるため、大金もらったのに素直に喜べず、一年以内に使い切るために何を買えばいいのかで悩まないといけないという、ジョジョのどこかのシーンみたいなことになってしまい、大金いただいたことはありがたいのに、一年縛りのせいで悩みが発生してしまう。(頂き物にたいして文句を付けるのは勇気がいるが、たぶん今回mixiさんに高額賞金もらった人はみんなこれで悩んでると思う)
この手のコンテストの賞金は、2~3万円以上の額になる場合は現金で支払った方が良いのではと思った。


※5/17追記:
Amazonギフトの有効期限は延長できるという噂を聞いたので、Amazonカスタマーサービスに電話してAmazonギフトの仕様について聞いてみた。
ネット上の情報では申請すれば簡単に期限を延長できるという感じだったが、実際にサポートに聞いてみると、あくまでも特例措置で、必ずしもホイホイやってくれるようなものでもないようだ。
オペレーターの方によると、

・Amazonギフト券の残高がある状態で有効期限を迎えてしまうと残高も無効になる
・ギフト券の有効期限の延長は、お客様の事情をお伺いして、上司の判断を仰ぐ必要がある。通常のサービスではなく特例的な対応のため、申請していただいても確実に延長が約束できるわけではない
・延長が可能だった場合でも原則として一年しか延長できない(それ以上延長できるケースがあるかどうかは不明)

とのことだった。
というわけでやはりAmazonギフトは、原則として有効期限内に使い切らないといけないものであるようだ。

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