前の投稿 次の投稿

OWASP ZAPのスクリプトを作ってみる part9


前回のpart8ではCSRF対策でトークンチェックが入っている複数画面遷移を自動的に辿ることに成功しました。

今回は、
・複数画面遷をした後のページの自動スキャン
・複数画面遷移を行いながらのファジングおよび判定ロジックの実装
のやり方を書いてみます。

Zest編(5)複数画面遷移後の自動スキャン


part8で作成したCSRFチェックの入った複数画面遷移を突破するZestスクリプトをそのまま使います。

Zestスクリプトのcomplete.phpへのPOSTを右クリックし、「Zestアクションを追加します」-「Action - Scan」を選択します。



すると、なんかまたとてもシンプルな「Zest Actionを追加します」というタイトルの、「Target Parameter:」というプルダウンとボタン二つだけのダイアログが出てきます。


ここでスキャン対象のパラメーターを選択することができそうに見えるのですが、ここでパラメーターを設定してもしなくても挙動が変わらない(ように私には見える)ので、ターゲットを選ばないで「保存」します。(※何か挙動に変化がある条件があるのかもしれないので、今後情報が得られたら本件追記します)

すると、complete.phpへのPOSTの下に、炎マークの「Action - Scan()」というノードが追加されます。



ここで、実はもう設定は完了で、このZestスクリプトを実行すると、index.php → confirm.php → complete.php とCSRFチェックを突破しつつ遷移し、最後にcomplete.phpに対して動的スキャンが実行されます。

ここですぐにスクリプトを実行しても良いのですが、注意点として、「Zestスクリプトから実行する動的スキャンは中断できない」というのがあり(※)、Zestスクリプトのテスト目的で普通にスキャンを実行するとスキャン完了まで長時間待つ必要が発生します。

そのため、Zestスクリプトを実行する前に、テスト実行用のスキャンポリシーの作成と設定をまず行います。

※ Zestスクリプト自体の実行停止ボタンがZestスクリプト実行ボタンの隣にあるのは発見したのですが、Zestスクリプト内のスキャンに関してはこれを押してもまったく停止せず最後まで実行されてしまいます。(これの停止ボタンをご存じの方教えてください)

Zestスクリプトの「Action - Scan」で実行される動的スキャンは、そもそもスキャンポリシーなどの設定箇所がないので、何のポリシーに基づいて動くのか? と思って調べたところ、「ZAPに設定されたデフォルトポリシーによるスキャンが実行される」という挙動をするようです。

デフォルトポリシーはZAPの設定画面から設定できるので、これを利用して、Zestの「Action - Scan」で自動的に実行される動的スキャンのポリシーを設定することが可能です。

まずZestから実行される動的スキャン用のポリシーを作成します。ZAPのメニューの「ポリシー」-「スキャンポリシー」を選択し、表示された「Scan Policy Manager」で「追加」を選択します。

表示された「スキャンポリシー」ウィンドウで、全カテゴリのThresholdをいったんオフにした後に「インジェクション」の「クロスサイト・スクリプティング(反射型)」のThresholdを「既定」にしてポリシー名を付けて保存し、反射型XSSのスキャン項目だけが実行されるポリシーを作成します。
(本例では「zestscanpolicy」というポリシー名とします)



それから、ZAPの「ツール」-「オプション」-「動的スキャン」の「Default active scan policy:」で、登録済のスキャンポリシーがプルダウンリストで選べるようになっているので、さきほど作成したスキャンポリシー(本例では「zestscanpolicy」)を選択し「OK」を押下します。



これでデフォルトのスキャンポリシーがZestスキャン用のポリシーに設定できたので、さきほどのZestスクリプトを実行してみます。

Zestスクリプト下のどれかのノードを選択し、右のペインの「実行」を押下すると、3画面遷移した後に、動的スキャンが実行されます。本ブログで配布したサンプルサイトを対象にしている場合は、complete.phpに対する動的スキャンの結果、反射型XSSが検出されます。



注意事項

上記手順を見て、CSRFチェックのある画面遷移を経て最後の画面に動的スキャンが成功しているから、このやり方で各種サイトの複数画面遷移が必要なページへの自動診断可能になるのでは? という考えを持たれる方もおられるかもしれません。

しかしここにはちょっと条件があって、ここではサンプルサイトのcomplete.phpのCSRFチェックの実装が甘く作られているから自動スキャンが成功しています。

サンプルサイトのCSRFチェックの実装だと、チェックが終わった後もトークンをセッションから削除しないので、complete.php画面に関してはリロードで再ポストを行ってもCSRFエラーになりません。再ポストがエラーにならないので動的スキャンが可能となっています。

confirm.phpの画面だと、POSTされたトークンとセッションにあるトークンを比較した直後に次画面用のトークンを取得してセッションの値を更新するので、リロードで再POSTを行うと、POST値のトークンがセッションにあるものと食い違うため、CSRFチェックに引っかかり、エラーになります。

そのため、この画面に対してはZestによるスキャンをセットしても全てCSRFエラー画面となり、動的スキャンが有効に実施されません。
(confirm.phpの画面にもXSSが仕込んでありますが、検出されません)



通常は複数画面遷移後の重要処理は再POSTを受け付けず、エラーにするページが多いと思うので、上記のZestのやり方で自動画面遷移後の動的スキャンを実施するのは、成功するサイトもあるとは思いますが、通常は厳しいと思われます。

どうせならZestに、1診断項目につき複数画面遷移を一回行うような感じの、複数画面遷移込みで特定画面をスキャンしてくれるようなオプションがあれば良いのにと思うのですが、そのような機能はZestには組み込まれていないようです。

代替案として、1項目ごとに複数画面を遷移するファジングのような処理を書くことは可能です。そのやり方を解説します。

Zest編(6)複数画面遷移+ファジング


今回はファジングを行うので、まずファジング用のファイルを作成します。
aaa
111
<script>alert(1)</script>
この三行をテキストファイルとして任意の場所に保存します。本例では「zestfuzztest.txt」とします。

ここで、Zestに対してFuzzing用のファイルの保存場所をフルパスで指定する必要があるので、ファイルの保存場所はうっかり移動したり削除したりしないような場所にしておいたほうが良いと思います。

Fuzzing用ファイルが準備できたら、これまで使ってきたZestサンプルスクリプトから、Zest編(5)で追加した「Action - Scan」のノードをいったん削除し、3画面を遷移するだけの状態に戻します。

Zestサンプルスクリプトの下にある全てのノードをShiftキー複数選択で全て選択した状態で右クリック - 「Surround with...」-「Loop File」を選択します。



「Zest Loopを追加」というダイアログが出るので、「変数名」にZestスクリプト内で参照したい変数名(本例では「zestfuzztest」とします)、「File Location」に、さきほど作成したFuzzing用ファイルをフルパスで指定します。



「保存」を押下すると、複数選択していたノードが全て、新しく作成された「Loop For zestfuzztest in zestfuzztest.txt」というノードの配下に移動します。



次に、Zestスクリプト内のcomplete.phpへのPOSTをダブルクリックし、「Zest Request」というダイアログを表示します。そのリクエストのBodyにある「name=Test+Taro」を「name={{zestfuzztest}}」に書き換えて保存します。



それで最後に、Fuzzing結果の判定ロジックを組み込む必要があります。
Zestスクリプトのcomplete.phpへのPOSTを選択し、右クリック - 「Add Zest Condition」-「Regex」を選択します。



「Add Zest Condition」というウィンドウが出てくるので、変数名「response.body」(デフォルトのまま)、「Regex」に「<script>alert\(1\)</script>」(カッコが正規表現上の特殊文字になるためエスケープする必要があります)を入力し、「保存」を選択します。



すると、complete.phpへのPOSTの下に「IF:Regex」「THEN」「ELSE」という条件分岐を表すノードが3つ登場します。



これの「THEN」を右クリックし「Zest Actionを追加します」-「Action - Fail」を選択すると、



ZAPのアラートを上げるための「Zest Actionを追加します」というタイトルのウィンドウが表示されるので、「Message」に「XSS!!!!!」、「Priority」を「High」に設定し保存します。



ついでに「ELSE」のほうを右クリックし、「Zest Actionを追加します」-「Action - Print」で、適当に「Not XSS...」というメッセージを表示するように設定します。



ここまで設定できたら、Zestサンプルスクリプトを実行すると、Fuzzerのファイルに基づいて、1つのファジングの項目に対して3画面を遷移し最終画面にPOST、を3回繰り返し、3回目で「<script>alert(1)</script>」がレスポンスにあるので「XSS!!!!!」というアラートが上がるのが確認できます。



アラートタブ:


ここまでできれば、Zestスクリプトは割に直感的に作ることが可能なので、本サンプルの応用でいろいろな処理を組むことが可能になると思います。

Zestスクリプト編は以上です。

残件として、ZAPのスクリプトで複数画面遷移+動的スキャンができなかったのが心残りですが、とあるアドオンでできる可能性があるという情報を入手したので、今後時間ができたらそれについて調べて、できるようなら続きを書きます。

※当ブログの記事中で紹介したサンプルコードはなるべく間違いのないように心がけておりますが、無保証です。利用する場合は自己責任にて改めて検証の上ご利用ください。
(何かミスを見つけたらお知らせください)

Leave a Reply

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