やっつけ不定記

好きなときに好きなことをちゃっちゃと書いてます

OWASP ZAP Automation FrameworkでActive Scanしてみた

しばらく前からOWASP ZAPのCUI実行を探っていました。
いわゆるシフトレフトの実現に役立つのではないかなと思った次第です。

zap.shのコマンドヘルプやググって出てきたオンラインドキュメント(★)
https://www.zaproxy.org/docs/desktop/addons/quick-start/cmdline/
からして、-quickxxxなオプションを-cmdもしくは-daemonオプションと
組み合わせて実行すればいいのだなと認識したのですが、いざ診断してみると、
Passive Scan(非破壊検査)しかやっていないように見受けられました。
やりたいのはActive Scanです。
話を簡単にするため、入力した値をそのまま表示するPHP(明らかにXSSがある)を
適当に拾ってきて、それで試してみても同様。

他にもオプションを探ってみたり、zap-cli
https://github.com/Grunny/zap-cli
というプロジェクトも眺めてはみたのですが、最終更新日が数年前。
情報が古そうな印象でしっくりこない。

あーだこーだ悩んでは、Twitterで実況していると海外の方から
Automation Framework(☆)
https://www.zaproxy.org/docs/automate/automation-framework/
を見てみるべしとのメンションを頂戴しました。
こういうときのアウトプットって本当に重要ですね。
アドバイスを踏まえて改めて調査してみると、もともと見ていた★は、
自動実行のドキュメント
https://www.zaproxy.org/docs/automate/
のごく一部にすぎず、
「Quick Start command line - quick and easy, but only suitable for simple scans」
とのこと。
zap-cliに至ってはサードパーティモジュールの扱いで、ZAP公式としては
Automation Frameworkを推奨しているようです。

以下、Automation Frameworkを使ってCUIからActive Scanをやってみたのですが、
このフレームワーク自体がアドオンだったり、設定ファイル書いたりでなかなかの暴れ馬。
忘れないうちにズシャーっとメモしておきます。
使ったOWASP ZAPのバージョンは、これを書いている時点の最新版の2.10です。
zap.shベースで書いていますが、Windowsだとzap.batでも同様と思います。

【診断実行までの流れ】
(初回のみ)アドオン導入

ZAPの設定

診断用YAMLファイル作成

診断実行

(1)アドオン導入
GUIでもCUIでもかまわないので、Automation Frameworkを導入する。
これにより、CUIではオプションとして-autorun,-autogenmin,
-autogenmax,-autogenconfが追加される。

GUIの場合
ZAP起動→ヘルプ→アップデートのチェック→マーケットプレイス
→Automation Frameworkにチェックを入れる→選択済みをインストール

CUIの場合

$ cd [ZAPのディレクトリ]
$ ./zap.sh -cmd -addoninstall automation

(2)ZAPの設定
ZAPを起動して、診断対象URLへのクロールやコンテキストの設定など、
普通に診断用の設定を行ったうえでセッションをファイルに保存する。

(3)診断用YAMLファイル作成
-autogenconfで現在の状態を生成し、これを-autogenminや-autogenmaxで
生成したサンプルや上記☆のドキュメントと照らし合わしながら、
やりたい診断内容に合わせて調整する。

・最大構成のYAMLサンプル生成

$ ./zap.sh -cmd -autogenmax [任意のディレクトリ]/[ファイル名].yaml

・最小構成のYAMLサンプル生成

$ ./zap.sh -cmd -autogenmin [任意のディレクトリ]/[ファイル名].yaml

・現在の状態をYAMLで生成した後、中身を調整

$ ./zap.sh -cmd -autogenconf [任意のディレクトリ]/[ファイル名].yaml
$ vi [任意のディレクトリ]/[ファイル名].yaml

とりあえずlocalhost:3080上のPHPにPassive ScanとActive Scanだけ動かした場合の
YAMLはこんな感じ。
追加アドオンの組み合わせ次第では、さらにいろんなことができるかもしれません。

--- # OWASP ZAP automation configuration file, for more details see https://www.zaproxy.com/docs/(TBA)
env:                                   # The environment, mandatory
  contexts :                           # List of 1 or more contexts, mandatory
    - name: test                       # Name to be used to refer to this context in other jobs, mandatory
      url: http://localhost:3080/      # The top level url, mandatory, everything under this will be included
      includePaths:                    # TBA: An optional list of regexes to include
      excludePaths:                    # TBA: An optional list of regexes to exclude
      authentication:                  # TBA: In time to cover all auth configs
  parameters:
    failOnError: true                  # If set exit on an error         
    failOnWarning: false               # If set exit on a warning
    progressToStdout: true             # If set will write job progress to stdout

jobs:
  - type: addOns
    name: addOns
    parameters:
      updateAddOns: true
    install:                           # A list of non standard add-ons to install from the ZAP Marketplace
    uninstall:                         # A list of standard add-ons to uninstall

  - type: passiveScan-config
    name: passiveScan-config
    parameters:
      maxAlertsPerRule: 0
      maxBodySizeInBytesToScan: 0
      scanFuzzerMessages: false
      scanOnlyInScope: false

  - type: passiveScan-wait
    name: passiveScan-wait
    parameters:
      maxDuration: 0

  - type: activeScan
    name: activeScan
    parameters:
      addQueryParam: false
      context: 
      defaultPolicy: 
      delayInMs: 0
      handleAntiCSRFTokens: false
      injectPluginIdInHeader: false
      maxRuleDurationInMins: 0
      maxScanDurationInMins: 0
      scanHeadersAllRequests: false
      threadPerHost: 2

(4)診断実行
作成した材料を使って診断を実行する。ここではアドオン周りを常に最新の状態にする
-addonupdateオプションと、最新の診断結果をHTML出力する-last_scan_report
オプションを追加しています。
Active Scanを実行すると、Passive Scanの結果に追記されてレポーティングされます。
この辺りはGUIで診断したときと同じですね。

$ ./zap.sh -cmd -addonupdate -session [セッション保存先]/[セッションファイル名].yaml -autorun [設定ファイル保存先]/[設定ファイル名].yaml -last_scan_report [結果保存先]/[レポートファイル名].html

・Passive Scanのみのレポートイメージ f:id:chocopurin:20210606150932j:plain

・Active Scan実行のレポートイメージ f:id:chocopurin:20210606150928j:plain

Active Scanではガチで攻撃を行います。ヘタすると、診断によってWebアプリが
再起不能になる恐れもあります。バックアップと復元手順の確立は必須です。
先に★で触れたオプションなし状態での文言
「Quick Start command line~」
には、そういう背景も含んでいる気がしています。

今回診断したのはDBを使っていない非常に単純なものですが、DBアクセスが入ってくると、
SQLインジェクションの診断も実行されるため、DBデータの並びをどうするかなど、
診断発生都度、攻撃されるアプリ側の方でテストデータの仕様決めや
データ投入(もしくは洗い替え)作業が発生します。

この辺りも含めて考えると、仮にCIの中でActive Scanを実行するとなると、
確実にCI渋滞が発生しそうな気がします。
世のZAPでCIやってる方々って、どういう運用でやっているのかなあ。
そもそも、Active Scanは開発フェーズではCIではなく手動で行って、
運用フェーズにおいて時間駆動で動かすのがカタいのでしょうか。