前の投稿 次の投稿

OWASP ZAPの基本的な使い方(手動診断編)

12月から業務として脆弱性診断を毎日やっており、診断にはOWASP ZAPとFiddlerを利用しているのですが、ほぼ一月使ってみてZAPの使い方や便利さが分かってきたので、自分の把握したZAPの使い方をシェアすることにします。

はじめに・診断対象サイトについての注意

OWASP ZAPでの診断は自分の管理下にあるサイトか、診断許可をもらっているサイトに対してのみ行ってください。(アクセス数によっては途中のインフラにも気をつける必要があります)
許可をもらっていないサーバへZAPの診断を走らせるのは、不正アクセスと解釈される可能性が高く、また実際に対象サーバに危害を与えてしまう可能性もありうるので大変危険です。


OWASP ZAPの基本的な使い方 手動診断編

OWASP ZAPのダウンロード・インストール

各環境用(win,mac,linux版がある)のOWASP ZAPをこのサイトからダウンロードしてインストールします。インストール方法は割愛します。ZAPの実行にはJREなどのJAVA実行環境が必要です。
本記事では、Windows版ZAPの執筆時点最新バージョン2.3.1に基づいて解説します。

ZAPでブラウザの通信を中継(&覗き見)する手順

1.OWASP ZAPを起動し、特定のポート(デフォルトは8080ポート)で待ち受けを開始させる
ZAPは起動すると設定されたポートでローカルプロキシとして待ち受けを始めます。何も設定していなければ、ローカルホストのデフォルト8080ポートがZAPが待ち受けるポートになっています。

※8080ポートは他のツールとかぶりやすいので、もし8080ポートで問題がある場合はZAPメニューの「ツール」-「オプション」で起動したオプション画面の「ローカルプロキシ」の設定画面で、ポートを空いてる任意のポート番号に設定します。


2.ブラウザのプロキシ設定をhttp,httpsの場合にZAPのポート(デフォルトなら8080)を通すように設定する

各ブラウザでのプロキシ設定方法を以下に記載します。
・IE11では設定-インターネットオプションの「接続」タブから「LANの設定」-プロキシサーバーのところでプロキシを使うにチェックを入れてlocalhost、8080ポートを設定。
・Firefoxでは「ツール-オプション-ネットワーク-接続設定」でHTTPとSSLにlocalhost、8080ポートを設定。
・Chromeでは「設定-詳細設定-ネットワーク-プロキシ設定の変更」でインターネットオプションのネットワーク設定画面が出てくるので、あとはIE同様に設定します。


3.プロキシ設定したブラウザで任意のサイトを見る(非SSL)
プロキシ設定したブラウザで、https~でないアドレスの任意のサイトにアクセスし、ZAPの「サイト」ウィンドウ(画面左)や画面下部の「履歴」タブのところに通信ログが出ればOKです。

(例としてIPAのサイトにアクセスしたところ。別にIPAのサイトを攻撃対象にするわけではありません)

SSLサイトの通信を中継するには:

上記の設定で、SSLを使っているサイトにアクセスすると、証明書が安全でないというエラーが出ます。
これはZAPがブラウザと当該サーバの間に入って通信を中継しているせいです。

ここで、この警告を無視してアクセスする選択(「セキュリティ例外として承認」ボタンなど)がある状態であれば、そのまま承認ボタンを押して接続することも可能ですが、Googleなど一部のサイトでは警告を無視して進むオプションが出てこないことがあります。

その場合、上の設定に加え、以下の手順を行ってください。
(SSLエラーが無視できるサイトの場合でも、都度エラーを出して例外を許可するのは手順が煩雑になるため、SSLが使われているサイト検査時には下記手順を行っておいたほうが検査がスムーズに行くと思われます)

4. ZAPのダイナミックSSL証明書をブラウザにインストールする

ZAPメニューの「ツール」-「オプション」で起動したオプション画面の「ダイナミックSSL証明書」の設定画面で、「保存」を押下します。



するとファイル保存ダイアログが表示され、OWASP ZAPが生成したルートCA証明書(デフォルトファイル名「owasp_zap_root_ca.cer」)をどこに保存するか聞かれるので、デスクトップなど、見失わないところに保存します。
このファイルをブラウザにルートCA証明書としてインポートすれば、ZAPでSSL通信を中継した時にSSLエラーが出なくなります。
(これはもちろん、正規のルートCA証明書ではなく、ZAPが勝手に作成したオレオレルートCA証明書です。)

各ブラウザへの証明書のインポート方法を以下に記載します。
・IE11では、設定-インターネットオプションの「コンテンツ」タブから「証明書」-「信頼されたルート証明機関」で「インポート」を押すと証明書インポートウィザードが開始されるので、「ファイル名」でさきほど保存した「owasp_zap_root_ca.cer」を選び「次へ」、証明書ストアで「証明書をすべて次のストアに配置する:信頼されたルート証明機関」になっていたら「次へ」で、確認画面が出るので「完了」、証明書ストアに証明書をインポートすることに対するセキュリティ警告が出るのでOKをすればインポートされます。

・Firefoxでは、「ツール」-「オプション」-「詳細」-「証明書」タブの「証明書を表示...」で、「認証局証明書」タブのところで「インポート」。ファイルダイアログが出るので「owasp_zap_root_ca.cer」を選ぶと、証明書のインポートというウィンドウが出てきて、この証明書が行う認証のうちWEB、メール、ソフトウェア製作者のどれを信頼するかという3択を聞かれるので「この認証局によるWEBサイトの識別を信頼する」にチェックを入れて「OK」を押すとインポートされます。

Chromeでは「設定」-「詳細設定」のところにある「HTTPS/SSL」セクションの「証明書の管理...」を押下すると、「証明書」というウィンドウが表示されますが、これはIE11の「インターネットオプション」-「コンテンツ」-「証明書」ボタン押下時に出てくるウィンドウとまったく一緒の画面なので、IE11同様の手順でインポートできます。


(※正式なものではないオレオレルートCA証明書をブラウザにインポートした状態はセキュリティ的にはあまり良くない状態のため、念のため「owasp_zap_root_ca.cer」ファイルはインポート後削除し、インポート済のZAPルートCA証明書も、使う期間が終わったらブラウザから削除しましょう。)

5.任意のSSLを使ったサイトにアクセス
警告が出ずにちゃんとアクセスでき、ZAP上に履歴が表示されればOKです。

ZAPでブラウザの通信を差し止めて改変する手順

1. リクエストにブレークポイントを設定

ZAPをブラウザのプロキシとして設定した後に、ZAPメニューアイコンの「→」(「全リクエストにブレークポイントセット」)ボタンを押下します。



この状態でブラウザからWEBサイトにアクセスすると、ブラウザが応答待ちの状態になり、ZAPの画面で上部右のウィンドウが「ブレーク」タブに自動的に切り替わり、GET/POSTリクエストが表示されます。
この状態になれば、ブラウザから発行されたリクエストがZAPによって差し止められています。

2. リクエストを書き換えて投げる

「ブレーク」タブに表示されたリクエストの任意の部分を書き換えてから、「→」ボタンを再度押してリクエストにブレークがかかる状態を解除した後に、右三角のボタン(「サブミットして次のブレークポイントへ移動」)を押下します。
(※次のブレークポイントは設定していないので、この操作で差し止めたリクエストをすべて送るという処理になります)



→書き換えられたリクエストがサーバに飛び、レスポンスが返ってきます。(リクエストの改変に成功)
ZAPの画面下部の「履歴」タブを確認すれば、どういうリクエストが投げられたかの確認ができます。
(履歴の行をダブルクリックで、「リクエスト」タブのところにリクエストが表示され、「レスポンス」タブを開くと、リクエストに応じたレスポンスが表示されます)

一度GET/POSTしたリクエストを再送信する手順


1. 履歴ウィンドウで履歴を選択し右クリックメニュー「再送信...」を選択



すると再送信用のウィンドウが立ち上がって、そのウィンドウから何度でも再送信が可能になります。そのウィンドウ上でリクエスト改変も可能です。


(再送信ウィンドウ。この画面でリクエストを改変して送信、が繰り返せる)

ファジングを行う手順


OWASP ZAPには、リクエストの一部をいろいろな文字列に置き換えてリクエストを自動で繰り返す「ファジング」を行う機能があります。
この機能をうまく使うと検査がかなり捗るのでおすすめです。

1.履歴ウィンドウで履歴を選択 → リクエストウィンドウの任意の文字列をドラッグし、右クリックメニュー「Fuzz...」を選択する

ZAPの履歴ウィンドウで履歴行をダブルクリックすると、ZAP右上のペインで「リクエスト」タブが自動的に有効になり、その履歴のリクエストが表示されます。そのリクエストの内容の一部をドラッグで選択し、その部分をファジング対象として指定することができます。



右クリックメニュー「Fuzz...」を選択すると、下図のように、ZAPに組み込まれているさまざまなFuzzカテゴリとFuzzリストが選択できます。



選択できるFuzzリストの中にどういう文字列が設定されているかは、Windows7の場合
C:\Program Files\OWASP\Zed Attack Proxy\lib\JBroFuzz.jar
これを解凍し、解凍ディレクトリ直下のfuzzers.jbrfというファイルをテキストエディタで開くと、文字列リストが書いてあります。
(fuzzers.jbrfに文字列リストが含まれていない「jbrofuzz/Zero Fuzzers」というカテゴリのFuzzerは、リクエストをただ単に繰り返すという特殊なFuzzerのためFuzz文字列リストがありません。)

自作の文字列リストでファジングを行う手順


1.ファジング用文字列ファイルを作成

ZAPのファジング用文字列ファイルは、一行に一文字列を記載する形式で自作することができます。

例えば、

aaa
bbb
ccc

このようなテキストファイルを作成し、任意のファイル名で保存します。(ここでは仮で「aaa.txt」とします。)

ファイル内にコメントを書きたい場合は、行頭を「#」から始めるとコメント行として読み飛ばされます。

2. ZAPの「Custom Fuzzers」に取り込む

ZAPメニューの「ツール」-「オプション」で起動したオプション画面の「Fuzzer」-「Add custom fuzz file:」で、自作のファジング用文字列ファイルをZAPに追加することができます。



例えばここで、さきほどの三行のファイルを「aaa.txt」としてZAPに登録すると、リクエストウィンドウ右クリック-「Fuzz...」で出てくるメニューのうち、「Custom Fuzzers」のfuzzリストに



のように出てくるようになります。

ここで登録したファイルの修正・削除メニューはZAPのUIにはないのですが、同名ファイルを登録すると上書きになり、削除は、登録したファイルがWindows7ではC:\Users\<ユーザー>\OWASP ZAP\fuzzers 下にあるので、ここから削除すると、ZAPの「Custom Fuzzers」のリストから消去されます。

ファジングの実行結果の見方


例として、さきほどのカスタムファザー「aaa.txt」でファジングを行うと、ZAPの「Fuzzer」タブが有効になり、下図のように、ファイルの三行に応じた3つのリクエストが飛びます。

(下図の例では、URLのGETパラメータ部分をファジング対象として指定したので、GETパラメータの変化が一覧に出てきており分かりやすいのですが、POSTの場合などはこの一覧には出てこないので「Fuzz」欄の値で何を試したか確認します)



ここで、ファジングの実行結果より、怪しい応答を見つけ出す方法を解説します。

ZAPのファジング実行結果ウィンドウで、任意の行をダブルクリックすれば、そのリクエストおよびレスポンスの詳細がZAPのリクエストタブ・レスポンスタブで確認できますが、ファジングは通常、大量の値を次々に試すので、一つ一つのレスポンスを開いて目検でチェックしていくのは大変です。

実際の診断時では、ここでは、何百件もあるようなファジング結果群から、何らかの異常が起こったレスポンスだけを見当をつけてチェックする必要があるのですが、ZAPのファジング実行結果ウィンドウはよくできていて、一覧上である程度、詳細を見るべきレスポンスがどれなのか判断が付くようになっています。

ZAPのファジング実行結果ウィンドウに表示される項目は

・メソッド・・・GET/POSTなど
・URI・・・リクエストURI
・Status・・・リクエストを行った結果のHTTPステータスコード
・Reason・・・HTTPステータスコードとセットのReason-Phrase
・RTT(ms)・・・レスポンスが戻ってくるまでの時間
・Size・・・レスポンスのContent-Length
・State・・・ファジング用文字列がレスポンスに含まれていたら「Reflected」、レスポンスが戻ってきたがファジング用文字列がレスポンスに含まれていなければ「Successful」、レスポンスが戻ってこなければ「エラー」

となります。

例えば、ファジングの実行の結果、下図のような結果が返ってきたとして、

一覧に表示された情報から、

・パラメータに「aaa」を指定したところ、レスポンスに「aaa」が含まれた結果が返ってきた
・パラメータに「bbb」を指定したところ、レスポンスに「bbb」は含まれていなかった
・パラメータに「ccc」を指定したところ、レスポンスが返ってこなかった
・パラメータに「ddd」を指定したところ、404になった

ということが分かります。(fiddlerで結果を操ってこういう結果を出したので、こんな変な挙動をするhtmlファイルは何なのか等は気にしないでください)

この例から分かる通り、

・ダブルクォートやタグなどのHTML特殊文字が「Reflected」になっていたら、値がエスケープされずに戻ってきているため、XSSの可能性あり
・特定の文字の時だけ、レスポンスサイズ・応答時間・ステータスが他リクエストと違うものがあれば、詳細を見る必要がある
(単なる記号ではなく何かしら意味のある文字として処理されている可能性がある)

のような判定が一覧を見ているだけで可能です。

また、ファジング結果判定に関するZAPの便利技として、二つのレスポンスの差分が、具体的にどこなのか目視でよく分からないときには、二つの行を選択して右クリック - 「Compare 2 Responces」を選択すると、二つのレスポンスの差分をグラフィカルに表示してくれるDiffウィンドウが開きます。(これはFuzzerウィンドウだけでなく履歴ウィンドウでも使えます)




CSRFチェックのあるページに対してファジングを行う手順


ZAPのファジング機能は便利ですが、CSRFチェックが入っているページに対してはそのままでは実行できません。
CSRFチェックが入っているページに対してファジングを行う場合は下記の設定が必要になります。

1.ZAPにCSRFチェック用のトークンを覚えさせる

ZAPメニューの「ツール」-「オプション」で起動したオプション画面の「Anti CSRF トークン」の「Add」ボタンで、CSRF防止用トークンの名前を登録します。



2.CSRFチェック用のトークンが発行されるページにアクセスする

登録したCSRFチェック用トークンが発行されるページにブラウザでアクセスします。
設定がうまくいっていれば、ZAPがトークンを認識し、履歴ウィンドウのTags欄に「AntiCSRF」 と出ます。



3.CSRFチェックがあって直接リクエストが送れないページに遷移して、ファジングを行う

CSRFトークンを受け取るページに遷移し、そのPOSTのレスポンスをZAP上で表示し、ファジングを行います。
Fuzzウィンドウは、そのページへのリクエストに「Anti CSRF トークン」に登録したトークンが含まれていると、CSRFチェック対応用のモードになります。
そのモードの場合、右クリック-Fuzz..で表示されるウィンドウに下図赤枠の項目が追加されます。
ここで「anti CSRFトークン利用」チェックボックスと、「トークン・リクエストの表示」にチェックを入れてください。

(下図は設定例です。トークン名は「samplecsrftoken」です。私の環境だと「トークン・リクエストの表示」という文字がチェックボックスにかかってしまって見にくいですが、これにチェックを入れることで、ZAPがトークンが発行されるページに都度アクセスしている履歴がFuzzerタブに出てくるようになります。)



ファジングを開始すると、ZAPが自動的に「トークンの発行されるページでトークンを取得してから当該のページにファジング」を行ってくれます。

下図は、「csrftest1.php」でトークン発行、「csrftest2.php」で受け取ったトークンが合っていたら200、合っていなければ404を返すプログラムで実験してみた結果です。
ここでファジング対象にしているのは「csrftest2.php」ですが、ZAPが1リクエストごとに「csrftest1.php」にトークンを取得しに行き、そのページで発行されたCSRFチェック用トークンで「csrftest2.php」にPOSTを行い、CSRFチェックに通る形でファジングを行っているのが分かります。


この、CSRFチェックを回避しながら自動的に検査を行う機能は、ファジングだけでなく動的スキャンのほうでも設定すれば使えます。そのあたりの解説は、後日公開予定の自動診断編で書きます。

→CSRFチェックを回避しながらの動的スキャンについては書けてませんが、続編書きました。


※本稿のOWASP ZAPでの手動診断の手順は、「脆弱性診断ええんやで」講師松本さんから教えてもらった内容をベースにして、自分で発見したテクニックを追加したものです。
https://security-testing.doorkeeper.jp/

Leave a Reply

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