■前回までのあらすじ
part1~part3まではOWASP ZAPのStand Aloneスクリプトでディレクトリ一覧を出力し、各ディレクトリにOPTIONSメソッドのリクエストを実行するというサンプルを書きました。
Stand Aloneスクリプトは、動かし方が分かりやすいので「Hello World」を実行する程度であれば作成が楽なのですが、少し複雑なロジックを組もうとすると、全てをイチから実装しなければならず、かつ現状では情報もサンプルコードも少ないので作成が大変になり、急激に初心者向きではなくなってしまいます。
「各ディレクトリにOPTIONSメソッドのリクエストを実行して実行結果を見る」という処理を書きたいのであれば、Stand Aloneスクリプトで実現するよりも、Active Rulesなど他の種類のスクリプトで実現したほうが実装が容易で、かつ、Stand Aloneだとできなかった「アラートを上げる」ということも可能になるため、今回はActive Rulesのスクリプトとしてpart3のサンプルを書き直してみます。
■スクリプトの種類
まず、Active Rulesのスクリプトを作る前に、そもそも「Active Rulesのスクリプト」って何? というところから説明します。
OWASP ZAPに登録できるスクリプトには種類がいくつかあり、呼ばれるタイミングや実行方法などが違います。
OWASP ZAPの「ヘルプ」-「ユーザーガイド」の目次から「Add Ons」-「Scripts」の中に「Script types」という項目があり、ここでスクリプトの各タイプが解説されています。
英語なので訳してみます。(誤訳等あればお知らせください)
Script types
Different types of scripts are supported:
以下の種類のスクリプトがサポートされている:
Stand Alone - scripts that are self contained and are only run when your start them manually
Stand Alone - スクリプトは独立しており、手動で開始した時のみ実行される。
Active Rules - these run as part of the Active Scanner and can be individually enabled
Active Rules - これはActive Scannerの一部として動作し、個別に有効にすることができる。
Passive Rules - these run as part of the Passive Scanner and can be individually enabled
Passive Rules - これはPassive Scannerの一部として動作し、個別に有効にすることができる。
Proxy Rules - these run 'inline', can change every request and response and can be individually enabled. They can also trigger break points
Proxy Rules - スクリプトは'インライン'(「ZAPと一緒に」のような意味と思われる)で動作し、全てのリクエストおよびレスポンスを改変可能である。個別に有効にすることができる。またブレークポイントをtriggerすることもできる。
Targeted Rules - scripts that invoked with a target URL and are only run when your start them manually
Targeted Rules - スクリプトはターゲットとなるURLに対して起動する。手動で開始した時のみ実行される。
Authentication - scripts that invoked when authentication is performed for a Context. To be used, they need to be selected when configuring the Script-Based Authentication Method for a Context.
Authentication - スクリプトはコンテキストにおける認証処理の際に起動する。これを使うためには、コンテキストの「認証」が「Script-Based Authentication」である必要がある。
Script Input Vectors - scripts for defining exactly what ZAP should attack
Script Input Vectors - ZAPが攻撃すべき箇所を厳密に定義するスクリプト。
OWASP ZAPのカスタムスクリプトには上記の7種類のスクリプトがある、ということです。
(ZAPの実際のスクリプトの画面には、「Fuzzer HTTP Processor」など、もっと種類があり、ヘルプの記述が足りていない気がするので、何か情報見つけたら追記します)
■Active Rulesスクリプト編(1) まずは関数の動作を確認する
ではActive Rulesのスクリプトを作って動きを見てみます。
ZAP左上の「サイト」タブの隣の「Scripts」タブ(場合によっては「+」マークのタブになっているかもしれませんが、その場合はその「+」タブをクリックすると「Scripts」タブが出てきます)を選択し、Active Rulesを右クリックし、「新規スクリプト」を選ぶと、スクリプト用のダイアログが出てきます。
以下の設定で新規スクリプトを作成します。
Script名: script_test4
タイプ:Active Rules
Script engine:ECMA Script: Oracle Nashhorn
テンプレート:Active default template.js
開始時にロード:オン
「保存」を押下すると、こういうコードがScriptコンソールの上部のペインに現れます。
// The scanNode function will typically be called once for every page // The scan function will typically be called for every parameter in every URL and Form for every page // Note that new active scripts will initially be disabled // Right click the script in the Scripts tree and select "enable" function scanNode(as, msg) { // Debugging can be done using println like this println('scan called for url=' + msg.getRequestHeader().getURI().toString()); ・・・(略)・・・ } function scan(as, msg, param, value) { // Debugging can be done using println like this println('scan called for url=' + msg.getRequestHeader().getURI().toString() + ' param=' + param + ' value=' + value); ・・・(略)・・・ }
このソースにはscanNode()という関数とscan()関数が定義されています。
この関数は一体何か?
ソース冒頭の英文のコメントを読んでみると
// The scanNode function will typically be called once for every page
// The scan function will typically be called for every parameter in every URL and Form for every page
scanNode関数は一般的に全てのページに対し一度コールされる
scan関数は一般的に全てのページの全てのURLの全てのパラメーターおよびフォームに対しコールされる
という動きをするそうです。
この説明だけだとよく分からないので実際に動かして確認してみます。
まずはソースを以下のように修正します。
・function scanNode()の冒頭の「println」を「print」に修正
・function scanNode()の冒頭の「print」(もと「println」)で出力する文字列を "scan called for url=..." を "scannode called for url=..."に修正
・function scan()の冒頭の「println」を「print」に修正
次に、script_test4スクリプトを右クリックし「スクリプトを有効にします」を選択します。
Active Rulesに登録したカスタムスクリプトは、「スクリプトの種類」のところで翻訳した通り「Active Scannerの一部として動作」します。
Active Rules - these run as part of the Active Scanner and can be individually enabled
Active Rules - これはActive Scannerの一部として動作し、個別に有効にすることができる
具体的には「動的スキャン(Active Scan)」の実行時に、スキャンポリシーの「一般」カテゴリの「Script Active Scan Rules」が実施される際に登録したカスタムスクリプトが実行されます。
動的スキャンを実行するには、とりあえず動的スキャンを実施する対象サイトが必要なので、ZAPで診断しても問題のない自己管理下にあるWEBサイトを用意し、ZAPをプロキシに設定したブラウザを使ってアクセスし、ZAPにそのサイトのアクセス履歴を記録します。
ここでは、ZAPの動的スキャン対象のURLを、例として
http://localhost/zaptest/test.php?aaa=bbb
動的スキャンを実施するサイトの履歴を右クリックし「攻撃」-「動的スキャン」を選択し、「入力ベクトル」タブで「URL Query String」のみチェックを入れます。
「Script Active Scan Rules」だけを実行する形にしたいので、「ポリシー」タブを開いて全てのカテゴリのthresholdをいったんオフにし、「一般」の「Script Active Scan Rules」のthresholdだけを「既定」にします。
(ここで「入力ベクトル」タブや「ポリシー」タブなどが表示されていない場合、「Show advanced options」チェックボックスにチェックを入れてください)
これで「スキャンを開始」を押下し、動的スキャンを実施します。
(※もし、本ブログのStand Alone編からの続きで作業をしている場合、「Scriptコンソール」の「ほうき」の右横のボタンが押下された状態になっているかもしれませんが、Active Rulesスクリプトの場合、結果が一行ごとに消えてしまうような挙動になってしまうため、このボタンはオフにしてください。)
[スクリプトが実行時にエラーになった場合の注意点]
動的スキャンを実施して、シンタックスエラーなどでうまく動作しなかった場合、スクリプトが「無効」の状態に戻ってしまうので、エラー箇所の修正後、再度スクリプトを「有効」にします。
[スクリプト正常動作時]
スキャン対象に対して「Script Active Scan Rules」のみ有効の動的スキャンを実行してみると、Scriptコンソールの下のペインに、診断対象にしたURLに応じて
scannode called for url=http://localhost/zaptest/test.php?aaa=bbb
scan called for url=http://localhost/zaptest/test.php?aaa=bbb param=aaa value=bbb
というログが表示されたと思います。
このログからすると、scannode()とscan()がそれぞれ一度づつコールされたようです。
これでもまだ動作がよく分からないので、以下の手順でさらに詳しい挙動を確認してみます。
■テスト1:
スキャン対象を上位ディレクトリにしてみます。
「Scriptコンソール」の「ほうき」マークをクリックし、前回のスクリプトの実行時ログを消します。
それから、ノードツリー末端のtest.phpではなく、ルートノードである http://localhost/ を右クリックし、さきほどと同じ設定で動的スキャンを行ってみます。(動的スキャン「スコープ」タブの「再帰的」にチェックが付いていない場合は付けてから実行してください。)
実行結果:
scannode called for url=http://localhost/zaptest
scannode called for url=http://localhost
scannode called for url=http://localhost/zaptest/test.php?aaa=bbb
scan called for url=http://localhost/zaptest/test.php?aaa=bbb param=aaa value=bbb
順番は前後していますが、ノードツリーに含まれるノードの数(3つ)ぶんだけscannode()が呼ばれた事が分かります。
■テスト2:
動的スキャン対象URLのパラメーターを増やしてみます。
http://localhost/zaptest/test.php?aaa=bbb
↓
http://localhost/zaptest/test.php?aaa=bbb&ccc=ddd&eee=fff
前回の結果とごっちゃにならないよう、ZAPの「ファイル」-「新規セッション」でセッションをいったんリセットし、http://localhost/zaptest/test.php?aaa=bbb&ccc=ddd&eee=fff にアクセスをして、このURLに対して「Script Active Scan Rules」のみ有効の動的スキャンを実行すると出力はこのようになります。
実行結果(表示上改行を入れています):
scannode called for url=http://localhost/zaptest/test.php?aaa=bbb&ccc=ddd&eee=fff
scan called for url=http://localhost/zaptest/test.php?aaa=bbb&ccc=ddd&eee=fff
param=aaa value=bbb
scan called for url=http://localhost/zaptest/test.php?aaa=bbb&ccc=ddd&eee=fff
param=ccc value=ddd
scan called for url=http://localhost/zaptest/test.php?aaa=bbb&ccc=ddd&eee=fff
param=eee value=fff
URLに含まれるパラメーターのキーの数(ここではaaa,ccc,eee)だけscan()が呼ばれた事が分かります。
■テスト3:
動的スキャン対象URLをさきほどのURLパラメーターが3つ付いたものとし、動的スキャンの「入力ベクトル」から「URL Query String」を外し、例えば「Cookie Data」にチェックを入れて「Script Active Scan Rules」のみ有効の動的スキャンを実行してみます。
対象:
http://localhost/zaptest/test.php?aaa=bbb&ccc=ddd&eee=fff
実行結果:
scannode called for url=http://localhost/zaptest/test.php?aaa=bbb
(scan関数は呼ばれない)
テスト結果から分かった挙動をまとめると、Active RulesのスクリプトにおけるscanNode()関数とscan()関数の挙動としては、
・scannnode()関数は、対象となる範囲に含まれるノードに対して都度コールされる
(ノードが3つであれば、3回コールされる)
・scan()関数は、「入力ベクトル」で指定された攻撃ベクター(URL Query String / POST Data 等)に合致する項目ごとにコールされる
(例えばGETパラメーターが3つあり、「入力ベクトル」で「URL Query String」にチェックが入っていれば3回コールされる。また、コールされる際、引数に処理対象パラメーターのkeyとvalueがそれぞれ入る)
続きます。
次へ