備忘録/にわかエンジニアが好きなように書く

個人的にとりあえず仕組みを知るためにとりあえず動くまで構築や動作をみただけの単なる操作ログです。個人用の備忘録となり、最新の導入手順は個別に確認してください。 ※変な内容や間違いを書いているなどありましたらコメントやご指摘いただけると幸いです。

OWASP ZAP2.7(baseline)でのレポート出力

OWASP ZAP2.7(baseline)でのレポート出力

結果としてはレポート出力は可能だったが、Dockerコンテナ内のユーザや所有権と実行ホストのユーザとの関係について知識不足だった。

知識や理解がないため、もっと良い実施方法はありそうです。

 

 

公式ページのコマンドでレポート出力を実施

https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan

---- 抜粋 ----

If you use 'file' params then you need to mount the directory those file are in or will be generated in, eg

docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py \
    -t https://www.example.com -g gen.conf -r testreport.html

----------------

公式ページのコマンドでの実行結果

コマンド:docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py -t http://192.168.20.161 -r testreport.html

⇒Permission deniedでレポート出力ができない。

 ⇒コンテナ内でzapユーザで 権限のないディレクトリへアクセスしたため 

# docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py -t http://192.168.20.161 -r testreport.html
_XSERVTransmkdir: ERROR: euid != 0,directory /tmp/.X11-unix will not be created.
Dec 09, 2017 4:37:40 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Total of 74 URLs
PASS: Cookie Without Secure Flag [10011]
PASS: Incomplete or No Cache-control and Pragma HTTP Header Set [10015]

~~ 省略 ~~

WARN-NEW: Absence of Anti-CSRF Tokens [10202] x 17
http://192.168.20.161/
http://192.168.20.161/
http://192.168.20.161/sitemap.xml
http://192.168.20.161
http://192.168.20.161/archives/1
ERROR Permission denied
2017-12-09 04:38:18,862 I/O error(13): Permission denied
Traceback (most recent call last):
File "/zap/zap-baseline.py", line 388, in main
write_report(base_dir + report_html, zap.core.htmlreport())
File "/zap/zap_common.py", line 410, in write_report
with open(file_path, mode='wb') as f:
IOError: [Errno 13] Permission denied: '/zap/wrk/testreport.html'
Found Java version 1.8.0_151

~~ 省略 ~~

27942 [ZAP-SpiderInitThread-0] INFO org.zaproxy.zap.spider.Spider - Spider initializing...
27965 [ZAP-SpiderInitThread-0] INFO org.zaproxy.zap.spider.Spider - Starting spider...
30473 [ZAP-SpiderThreadPool-0-thread-1] WARN org.zaproxy.zap.spider.URLCanonicalizer - Host could not be reliably evaluated from: https://gravatar.com">Gravatar</a>?????????? (on base http://192.168.20.161/comments/feed)
32613 [ZAP-SpiderThreadPool-0-thread-1] WARN org.zaproxy.zap.spider.URLCanonicalizer - Host could not be reliably evaluated from: https://gravatar.com">Gravatar</a>?????????? (on base http://192.168.20.161/archives/1/feed)
36134 [ZAP-SpiderThreadPool-0-thread-1] INFO org.zaproxy.zap.spider.Spider - Spidering process is complete. Shutting down...
36143 [ZAP-SpiderShutdownThread-0] INFO org.zaproxy.zap.extension.spider.SpiderThread - Spider scanning complete: true
#

※コンテナのボリュームをホストにマウントしたディレクトリの所有権はどうなるの?

※コンテナへのアクセス時のユーザーIDやグループIDはどうなるの?

コンテナの所有権やユーザ確認

lsコマンドで"/zap/wrk/"ディレクトリの所有者確認

docker run の -u のオプションでユーザを指定する場合と指定しない場合で確認

■ユーザオプション無

# docker run --rm -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable ls -l
~~ 省略 ~~
drwxr-xr-x 3 root root 39 Dec 7 13:24 wrk
drwxr-xr-x 2 zap zap 4096 Dec 1 00:41 xml
-rw-r--r-- 6 zap zap 9518830 Nov 28 15:11 zap-2.7.0.jar
-rwxrwxr-x 5 root root 21301 Nov 28 13:53 zap-api-scan.py
-rwxrwxr-x 1 zap zap 16293 Nov 28 13:53 zap-baseline.py
-rwxrwxr-x 5 root root 18593 Nov 28 13:53 zap-full-scan.py
-rwxrwxr-x 1 zap zap 1916 Nov 28 13:53 zap-webswing.sh
-rwxrwxr-x 1 zap zap 117 Nov 28 13:51 zap-x.sh
-rw-r--r-- 6 zap zap 192 Nov 28 15:11 zap.bat
-rw-r--r-- 6 zap zap 123778 Nov 28 15:11 zap.ico
-rwxr-xr-x 6 zap zap 3834 Nov 28 15:11 zap.sh
-rw-rw-r-- 5 root root 14574 Nov 28 13:53 zap_common.py

 コンテナの中のディレクトリは"root"となる。 

 

 ■ユーザオプション有(zap)

# docker run --rm -u zap -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable ls -l
total 9532
~~ 省略 ~~
drwxr-xr-x 3 root root 39 Dec 7 13:24 wrk
~~ 省略 ~~
#

コンテナの中のディレクトリは"root"となり、ユーザオプションでは所有者を"zap"へ変更できない。

 

idコマンドでコンテナ内でのアカウント情報確認

■ユーザオプション無

■ユーザオプション無
# docker run --rm -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable id
uid=1000(zap) gid=1000(zap) groups=1000(zap)

コンテナの中のユーザは"zap"となる。 

  

■ユーザオプション有(root)

■ユーザオプション有(root)
# docker run --rm -u root -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable id
uid=0(root) gid=0(root) groups=0(root)

コンテナの中のユーザは"root"となっている。

 

実行できなかった推測

最初に実行したコマンドでは、ディレクトリが rootとなっているため"zap"ユーザではパーミッションがないため実行できなかった。

コンテナ内でもroot権限もったユーザ "root" として実行できたら/zap/wrk/配下にレポート出力が可能と思われる。

 

オプション "-u root" を付けてレポート出力した場合 

# docker run -v $(pwd):/zap/wrk/:rw -u root -t owasp/zap2docker-stable zap-baseline.py -t http://192.168.20.161 -r testreport_$(date +%Y%m%d).html

# docker run -v $(pwd):/zap/wrk/:rw -u root -t owasp/zap2docker-stable zap-baseline.py -t http://192.168.20.161 -r testreport_$(date +%Y%m%d).html
Dec 09, 2017 8:25:55 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Total of 74 URLs
PASS: Cookie Without Secure Flag [10011]
PASS: Incomplete or No Cache-control and Pragma HTTP Header Set [10015]
PASS: Cross-Domain JavaScript Source File Inclusion [10017]
PASS: Content-Type Header Missing [10019]

~~ 省略 ~~
http://192.168.20.161/wp-admin/admin-ajax.php
WARN-NEW: Absence of Anti-CSRF Tokens [10202] x 17
http://192.168.20.161/
http://192.168.20.161/
http://192.168.20.161/sitemap.xml
http://192.168.20.161
http://192.168.20.161/archives/1
FAIL-NEW: 0 FAIL-INPROG: 0 WARN-NEW: 6 WARN-INPROG: 0 INFO: 0 IGNORE: 0 PASS: 19
#
# ls -l testreport_*
-rw-r--r-- 1 root root 63475 12月 9 17:26 testreport_20171209.html
#

 

(補足)コマンド内の wrkというディレクトリについて

■出力ファイルを wrk/test.xml とした場合

# docker run --rm -u root -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable /zap/zap-baseline.py -t http://192.168.20.161 -x wrk/test.xml

⇒ディレクトリがないため実行できない

# docker run --rm -u root -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable /zap/zap-baseline.py -t http://192.168.20.161 -x wrk/test.xml
Dec 07, 2017 1:26:25 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Total of 74 URLs
PASS: Cookie Without Secure Flag [10011]
PASS: Incomplete or No Cache-control and Pragma HTTP Header Set [10015]

~~ 省略 ~~

WARN-NEW: Absence of Anti-CSRF Tokens [10202] x 17
http://192.168.20.161/
http://192.168.20.161/
http://192.168.20.161/sitemap.xml
http://192.168.20.161
http://192.168.20.161/archives/1
ERROR No such file or directory
2017-12-07 13:26:54,656 I/O error(2): No such file or directory
Traceback (most recent call last):
File "/zap/zap-baseline.py", line 400, in main
write_report(base_dir + report_xml, zap.core.xmlreport())
File "/zap/zap_common.py", line 410, in write_report
with open(file_path, mode='wb') as f:
IOError: [Errno 2] No such file or directory: '/zap/wrk/wrk/test.xml'
Found Java version 1.8.0_151
Available memory: 1823 MB
Setting jvm heap size: -Xmx455m
362 [main] INFO org.zaproxy.zap.DaemonBootstrap - OWASP ZAP 2.7.0 started 07/12/17 13:26:21 with home /root/.ZAP/
416 [main] INFO org.parosproxy.paros.common.AbstractParam - Setting config api.disablekey = true was null
416 [main] INFO org.parosproxy.paros.common.AbstractParam - Setting config api.addrs.addr.name = .* was null
416 [main] INFO org.parosproxy.paros.common.AbstractParam - Setting config api.addrs.addr.regex = true was null

~~ 省略 ~~

23344 [ZAP-SpiderThreadPool-0-thread-1] WARN org.zaproxy.zap.spider.URLCanonicalizer - Host could not be reliably evaluated from: https://gravatar.com">Gravatar</a>?????????? (on base http://192.168.20.161/archives/1/feed)
27125 [ZAP-SpiderThreadPool-0-thread-1] INFO org.zaproxy.zap.spider.Spider - Spidering process is complete. Shutting down...
27152 [ZAP-SpiderShutdownThread-0] INFO org.zaproxy.zap.extension.spider.SpiderThread - Spider scanning complete: true
#

■出力ファイルを test.xml とした場合

# docker run --rm -u root -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable /zap/zap-baseline.py -t http://192.168.20.161 -x test.xml

⇒問題なく実行可能

# docker run --rm -u root -t -v $PWD/report/:/zap/wrk owasp/zap2docker-stable /zap/zap-baseline.py -t http://192.168.20.161 -x test.xml
Dec 09, 2017 8:53:30 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Total of 74 URLs
PASS: Cookie Without Secure Flag [10011]
PASS: Incomplete or No Cache-control and Pragma HTTP Header Set [10015]
PASS: Cross-Domain JavaScript Source File Inclusion [10017]

~~ 省略 ~~

WARN-NEW: Absence of Anti-CSRF Tokens [10202] x 17
http://192.168.20.161/
http://192.168.20.161/
http://192.168.20.161/sitemap.xml
http://192.168.20.161
http://192.168.20.161/archives/1
FAIL-NEW: 0 FAIL-INPROG: 0 WARN-NEW: 6 WARN-INPROG: 0 INFO: 0 IGNORE: 0 PASS: 19
#
# ls -l report/test*
-rw-r--r-- 1 root root 32272 12月 9 17:54 report/test.xml
#

 

■マウント先をwrk から work へ変更し、出力ファイルを test.xml とした場合

# docker run --rm -u root -t -v $PWD/report/:/zap/work owasp/zap2docker-stable /zap/zap-baseline.py -t http://192.168.20.161 -x test.xml

コマンドが実行できない

[root@sv01 ~]# docker run --rm -u root -t -v $PWD/report/:/zap/work owasp/zap2docker-stable /zap/zap-baseline.py -t http://192.168.20.161 -x tes
t.xml
2017-12-09 08:59:20,447 A file based option has been specified but the directory '/zap/wrk' is not mounted
Usage: zap-baseline.py -t <target> [options]
-t target target URL including the protocol, eg https://www.example.com
Options:
-c config_file config file to use to INFO, IGNORE or FAIL warnings
-u config_url URL of config file to use to INFO, IGNORE or FAIL warnings
-g gen_file generate default config file (all rules set to WARN)
-m mins the number of minutes to spider for (default 1)
-r report_html file to write the full ZAP HTML report
-w report_md file to write the full ZAP Wiki (Markdown) report
-x report_xml file to write the full ZAP XML report
-J report_json file to write the full ZAP JSON document
-a include the alpha passive scan rules as well
-d show debug messages
-P specify listen port
-D delay in seconds to wait for passive scanning
-i default rules not in the config file to INFO
-j use the Ajax spider in addition to the traditional one
-l level minimum level to show: PASS, IGNORE, INFO, WARN or FAIL, use with -s to hide example URLs
-n context_file context file which will be loaded prior to spidering the target
-p progress_file progress file which specifies issues that are being addressed
-s short output format - dont show PASSes or example URLs
-T max time in minutes to wait for ZAP to start and the passive scan to run
-z zap_options ZAP command line options e.g. -z "-config aaa=bbb -config ccc=ddd"

For more details see https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan
[root@sv01 ~]#

 

 ※zap-baseline.pyで直接ディレクトリ先が指定されているようなので変更はできないため

 マウントする場合のパラメータとしては、"/zap/wrk"は固定値 となるようだ

 zap-baseline.py(204行目辺り)

if running_in_docker():
     base_dir = '/zap/wrk/'
     if config_file or generate or report_html or report_xml or report_json or progress_file or context_file:
          # Check directory has been mounted
          if not os.path.exists(base_dir):
               logging.warning('A file based option has been specified but the directory \'/zap/wrk\' is not mounted ')
               usage()
               sys.exit(3)