From 708829a0ab4e1de84b6ec099d5d38c0007f0e823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C5=BEe=20=C5=BDitnik?= <anze.zitnik@xlab.si> Date: Tue, 18 Feb 2020 12:50:12 +0100 Subject: [PATCH] Configuration parsing from JSON config file. Using Ubuntu 18.04 base image. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit bccedf5c278490f6befcb0f4f37db7e588f6901d Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Tue Feb 18 12:42:54 2020 +0100 CI... commit 5a7f5b4e03fd857683aa110da4f4d31c2fee03a5 Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Tue Feb 18 12:36:57 2020 +0100 CI... commit 39f9ec5bd410280afb2e856a44ce5ac5b390668d Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Tue Feb 18 10:41:58 2020 +0100 CI... commit cf807354e8a65d7ca2c5af7c73c16ae1b04c6f0e Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Tue Feb 18 10:22:59 2020 +0100 CI... commit a44ccefa3d2bb34016db540c3728375437f4f043 Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Tue Feb 18 10:19:20 2020 +0100 CI... commit 7fd21692f7f3629c94b8e7c4ff495a9740984439 Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Tue Feb 18 10:17:54 2020 +0100 CI... commit 8fdec3c7db52bf7b00f33de350df975a23496701 Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Tue Feb 18 10:14:32 2020 +0100 CI... commit e2ed633df6ec245edd62b7c6fb049730abe25db7 Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Fri Feb 14 19:00:43 2020 +0100 CI test update commit 650c02745260ed1e6f434aea8ab1d0d89cc648f7 Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Fri Feb 14 18:57:47 2020 +0100 CI test update commit a3f71bb2f249479dad74b1b6596399699c09ed4f Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Fri Feb 14 18:43:20 2020 +0100 CI test update commit 9a85e5b849eb99a6e8811c859bfe6458f2c1aea0 Author: Anže Žitnik <anze.zitnik@xlab.si> Date: Fri Feb 14 18:31:29 2020 +0100 Configuration parsing from JSON config file. Using Ubuntu 18.04 base image. --- .gitlab-ci.yml | 7 +++++- Dockerfile | 4 ++-- MANIFEST | 2 +- Makefile | 12 ++++++---- README.md | 30 ++++++++++++++++++++++++- config-example.json | 13 +++++++++++ configure.py | 55 +++++++++++++++++++++++++++++++++++++++++++++ install.sh | 3 ++- run-cscan.sh | 16 ++++--------- 9 files changed, 120 insertions(+), 22 deletions(-) create mode 100644 config-example.json create mode 100644 configure.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ccc06cf..b7ad452 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,10 +16,15 @@ build: test: stage: test script: - - docker run -e "TARGET=http://10.10.43.182" -v /tmp/:/mnt/output registry-gitlab.xlab.si/cyberwiser/$SERVICE:$VERSION + - docker network create test-genscan + - docker run --rm -d --network=test-genscan --name dvwa vulnerables/web-dvwa + - cp "${CI_PROJECT_DIR}/config-example.json" /tmp + - docker run --rm --network=test-genscan -v /tmp/config-example.json:/root/config.json:ro -v /tmp/:/mnt/output registry-gitlab.xlab.si/cyberwiser/$SERVICE:$VERSION - grep -q "W3af" /tmp/genscan-out.json - grep -q "OWASP ZAP" /tmp/genscan-out.json after_script: + - docker kill dvwa || docker network rm test-genscan + - docker network rm test-genscan - rm /tmp/genscan-out.json push: diff --git a/Dockerfile b/Dockerfile index 029efa0..0286dbf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 -COPY install.sh zap-plugin.patch w3af-plugin.patch w3af_output_fix.patch w3af-lz4.patch cscan-config.py run-cscan.sh requirements.txt /tmp/ +COPY install.sh zap-plugin.patch w3af-plugin.patch w3af_output_fix.patch w3af-lz4.patch cscan-config.py run-cscan.sh requirements.txt configure.py /tmp/ COPY wiser-wcs-reports /root/wiser-wcs-reports/ RUN chmod +x /tmp/install.sh /tmp/run-cscan.sh && \ diff --git a/MANIFEST b/MANIFEST index c5a6540..88a0ffd 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,3 +1,3 @@ -VERSION=v1.0.5 +VERSION=v1.1.0 SERVICE=vat-genscan diff --git a/Makefile b/Makefile index 6a20cde..6180a56 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ SERVICE = $(shell grep SERVICE MANIFEST | cut -d '=' -f2) VERSION = $(shell grep VERSION MANIFEST | cut -d '=' -f2) -TARGET ?= http://10.10.43.182 +CONFIG ?= $(shell pwd)/config-example.json TEST_DIR = /tmp/test-$(SERVICE)-$(VERSION)-$(shell date +%s)/ @@ -13,15 +13,19 @@ build: docker build -t registry-gitlab.xlab.si/cyberwiser/$(SERVICE):$(VERSION) . test: + docker network create test-genscan + docker run --rm -d --network=test-genscan --name dvwa vulnerables/web-dvwa mkdir $(TEST_DIR) - docker run -e "TARGET=$(TARGET)" -v $(TEST_DIR):/mnt/output/ registry-gitlab.xlab.si/cyberwiser/$(SERVICE):$(VERSION) + docker run --rm --network=test-genscan -v $(CONFIG):/root/config.json -v $(TEST_DIR):/mnt/output/ registry-gitlab.xlab.si/cyberwiser/$(SERVICE):$(VERSION) + docker kill dvwa + docker network rm test-genscan grep -q "W3af" $(TEST_DIR)genscan-out.json grep -q "OWASP ZAP" $(TEST_DIR)genscan-out.json start: ifdef OUTPUT_DIR - docker run -e "TARGET=$(TARGET)" -v $(OUTPUT_DIR):/mnt/output/ registry-gitlab.xlab.si/cyberwiser/$(SERVICE):$(VERSION) + docker run -v $(CONFIG):/root/config.json -v $(OUTPUT_DIR):/mnt/output/ registry-gitlab.xlab.si/cyberwiser/$(SERVICE):$(VERSION) else - docker run -e "TARGET=$(TARGET)" registry-gitlab.xlab.si/cyberwiser/$(SERVICE):$(VERSION) + docker run -v $(CONFIG):/root/config.json registry-gitlab.xlab.si/cyberwiser/$(SERVICE):$(VERSION) endif diff --git a/README.md b/README.md index b29f700..b674d0e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ Currently supports only basic (fast) scans without any configuration. ### Usage: Build: `make build` -Run `vat-genscan` Docker image and pass target URL as `TARGET` environment variable. +Run `vat-genscan` Docker image and pass configuration in JSON file, mounted as `/root/config.json`. + If a directory is mounted to `/mnt/output`, genscan copies the JSON output file to `/mnt/output/genscan-out.json. If output directory is not mounted, JSON output is sent to stdout (last line). @@ -13,9 +14,36 @@ Example: also `make TARGET="http://10.10.43.182" OUTPUT_DIR="/tmp/genscan-out/" start` or `make start` (default TARGET=http://10.10.43.182, OUTPUT_DIR none). +### Configuration: +Supported scanners and their profiles: + +* `w3af` + * `fast_scan`: no parameters +* `zap` + * `basic`: no parameters + +Example JSON config file: + +``` +{ + "target": { + "url": "https://172.17.0.1/webapp/path/", + "ip": "172.17.0.1" + }, + "config": { + "w3af": { + "profile": "fast_scan" + }, + "zap": { + "profile": "basic" + } + } +} +``` ### TODOs and FIXMEs: +* use latest w3af and zap (now fetching static, old commits) * use cscan from Faraday repo (newer?) * include some configuration options (at least authenticated scans for w3af) diff --git a/config-example.json b/config-example.json new file mode 100644 index 0000000..fed87a2 --- /dev/null +++ b/config-example.json @@ -0,0 +1,13 @@ +{ + "target": { + "url": "http://dvwa/" + }, + "config": { + "w3af": { + "profile": "fast_scan" + }, + "zap": { + "profile": "basic" + } + } +} diff --git a/configure.py b/configure.py new file mode 100644 index 0000000..0ea290b --- /dev/null +++ b/configure.py @@ -0,0 +1,55 @@ +import os +import json + +''' +Supported scanners: + - w3af +''' + + +def main(): + with open("/root/config.json", "r") as f_conf: + config = json.load(f_conf) + + # configure cscan target + target = config["target"] + if "url" in target: + f_t = open("/root/cscan/websites.txt", "w") + f_t.write(target["url"]) + f_t.write(os.linesep) + f_t.close() + if "ip" in target: + f_t = open("/root/cscan/ips.txt", "w") + f_t.write(target["ip"]) + f_t.write(os.linesep) + f_t.close() + + # configure scanners + cscan_config = {} + for scanner in config["config"]: + profile = config["config"][scanner]["profile"] + if scanner == "w3af": + cscan_config["CS_W3AF"] = "/root/w3af/w3af_api" + if profile == "fast_scan": + cscan_config["CS_W3AF_PROFILE"] = "/root/w3af/profiles/fast_scan.pw3af" + else: + raise UnsupportedProfileException() + # params = config["config"][scanner]["parameters"] + elif scanner == "zap": + cscan_config["CS_ZAP"] = "/root/ZAP_2.7.0/zap.sh" + if profile != "basic": + raise UnsupportedProfileException() + else: + raise UnsupportedScannerException() + + with open("/root/cscan/config.py", "w") as f_csconf: + f_csconf.write("config = %s\n" % cscan_config) + +class UnsupportedProfileException(Exception): + pass + +class UnsupportedScannerException(Exception): + pass + +if __name__ == "__main__": + main() diff --git a/install.sh b/install.sh index 38aed7d..7877270 100644 --- a/install.sh +++ b/install.sh @@ -15,7 +15,6 @@ pip install -r /tmp/requirements.txt && pip install git+git://github.com/hay/xml2json.git@3a674efad91e0f1e978babc41a72f297d5e5144b && #node and retire apt install -y npm && -ln -s /usr/bin/nodejs /usr/bin/node && npm install -g retire && #W3AF apt install -y libffi-dev libsqlite3-dev libyaml-dev && @@ -45,7 +44,9 @@ patch /root/cscan/plugin/zap.py /tmp/zap-plugin.patch && patch /root/cscan/plugin/w3af.py /tmp/w3af-plugin.patch && cp /tmp/cscan-config.py /root/cscan/config.py && echo "" > /root/cscan/ips.txt && +echo "" > /root/cscan/websites.txt && cp /tmp/run-cscan.sh /root/ && +cp /tmp/configure.py /root/ && #cleanup rm -r /tmp/* && diff --git a/run-cscan.sh b/run-cscan.sh index 8c4d6c0..d444f25 100644 --- a/run-cscan.sh +++ b/run-cscan.sh @@ -1,16 +1,9 @@ #!/bin/bash -#TARGET=$1 - -if [ -z "${TARGET}" ]; then - echo "TARGET variable not set. Exiting." - exit 1 -fi - -curl -k "${TARGET}" &> /dev/null -if [ $? -ne 0 ]; then - echo "Target inaccessible. Exiting." - exit 2 +python configure.py +RESULT=$? +if [ $RESULT -ne 0 ]; then + exit $RESULT fi #mounting random to urandom to prevent blocking because lack of entropy (ZAP certificate creation) @@ -19,7 +12,6 @@ ln -s /dev/urandom /dev/random cd /root/cscan rm output/* -echo "${TARGET}" > websites.txt python cscan.py 2>&1 | tee /root/cscan-log.txt RESULT=$? if [ $RESULT -ne 0 ]; then -- GitLab