Skip to content

Automating ZAP running against a web application in Docker Containers

July 9, 2015

To start of, this has been a lot of fun learning experience for me. It had been a while since I did any sort of Bash/Python scripting so it definitely got me back on track. Also, there are some resources out there but nothing helped me as such for the particular case I was looking to solve. Lastly, I will try to convert this into a series of blog posts where I will try to get much deeper with ZAP scanning and reports, integration with CI build servers, etc. as and when time permits. And, btw, you would need to know the basics of working with Docker in order to understand this blog. Having said that, I will try to explain most of the commands I have in my scripts. So, lets begin.

TL;DR of this post:

1. You install Docker.

2. You run a custom bash script.

3. This bash script starts 2 Docker containers from 2 different images:

  • One is a sample web application. The name of the image from where this container is built is “training/webapp”. This can be found on Docker Hub.
  • The other container is built from a custom image which in turn is built on top of “owasp/zap2docker-stable” image found on Docker Hub.

4. Once, both the containers are started, ZAP runs against the web app. It does a very basic spidering and scanning. Once everything is done, the report is stored on the ZAP container.

5. The report is then transferred onto the host and all the containers are deleted.

So, basically, you ran ZAP against a web app and generated a XML report on your file system – all automated by just one script!

The main bash script (zaprun.sh) mentioned in point 2 above is as follows. I have left comments above each command so it should be self-explanatory. Try to understand this script and save it for now. We will run this later on:

#!/bin/bash

set -e

#Running the sample webapp and storing the ID in a variable

WEBCONTAINERID=$(docker run -d -P –name web training/webapp python app.py)

echo Container ID = $WEBCONTAINERID

#Inspecting the above container to gather its IP address and port that will be accessible to the ZAP container to run the scan against

WEBDOCKERIP=$(docker inspect $WEBCONTAINERID | grep -w IPAddress | sed ‘s/.*IPAddress”: “//’ | sed ‘s/”,$//’)

echo Webapp Docker IP = $WEBDOCKERIP

WEBDOCKERPORT=$(docker port $WEBCONTAINERID | sed ‘s/\/tcp.*//’)

echo Webapp Docker Port = $WEBDOCKERPORT

#Running the ZAP container. Notice that this container is named test and there is a custom python script runzap.py that is run. I will provide these later on. This is what I built on top of owasp/zap2docker-stable image

ZAPCONTAINERID=$(docker run -d –name zap test python /zap/ZAP_2.4.0/runzap.py http://$WEBDOCKERIP:$WEBDOCKERPORT)

echo ZAP Container ID = $ZAPCONTAINERID

#Inspecting the above container to see whether it is running or not. If it is not running, that means ZAP has finished the scan and the report is generated.

STATUS=$(docker inspect $ZAPCONTAINERID | grep Running | sed ‘s/”Running”://’ | sed ‘s/,//’)

flag=”1″

while [ “$flag” = “1” ]; do

if [ $STATUS == “true” ];

then 

sleep 5

echo ZAP is running..

flag=1

STATUS=$(docker inspect $ZAPCONTAINERID | grep Running | sed ‘s/”Running”://’ | sed ‘s/,//’)

else

sleep 5

echo ZAP has stopped

flag=0

STATUS=$(docker inspect $ZAPCONTAINERID | grep Running | sed ‘s/”Running”://’ | sed ‘s/,//’)

fi

done

#Copying the report to Host OS

echo Copying the report to host in the current directory with the name report.xml

docker cp $ZAPCONTAINERID:/zap/ZAP_2.4.0/report.xml .

#Deleting all the containers that were created as a result of this script

echo Deleting the ZAP Container

docker rm $ZAPCONTAINERID

if [ $? -eq 0 ]

then

echo Stopping the Webapp Container

docker stop $WEBCONTAINERID

fi

if [ $? -eq 0 ]

then

echo Deleting the Webapp Container

docker rm $WEBCONTAINERID

fi

Now, on your host OS, create a folder and paste the following 2 files in that folder:

  1. Dockerfile (self-explanatory)

FROM owasp/zap2docker-stable

MAINTAINER Anshuman Bhartiya <anshuman.bhartiya@gmail.com>

RUN apt-get update && apt-get install -y \

python-pip

RUN pip install python-owasp-zap-v2

ADD runzap.py /zap/ZAP_2.4.0/

2. runzap.py (This script is slightly modified from here. Credit also due here.)

#!/usr/bin/env python

import os

import subprocess

import time

import urllib

from pprint import pprint

from zapv2 import ZAPv2

import sys

#Starting ZAP as a daemon on port 8090

print ‘Starting ZAP …’

subprocess.Popen([“zap.sh”,”-daemon”,”-port 8090″,”-host 0.0.0.0″],stdout=open(os.devnull,’w’))

print ‘Waiting for ZAP to load, 10 seconds …’

time.sleep(10)

#Taking the IP address to scan against through the command line. This is where you will provide the value for http://$WEBDOCKERIP:$WEBDOCKERPORT in the above bash script

target = sys.argv[1]

print target

zap = ZAPv2()

print ‘Accessing target %s’ % target

zap.urlopen(target)

time.sleep(2)

#Spidering the target

print ‘Spidering target %s’ % target

zap.spider.scan(target)

time.sleep(2)

while (int(zap.spider.status) < 100):

    print ‘Spider progress %: ‘ + zap.spider.status

    time.sleep(2)

print ‘Spider completed’

time.sleep(5)

#Scanning the target

print ‘Scanning target %s’ % target

zap.ascan.scan(target)

while (int(zap.ascan.status) < 100):

    print ‘Scan progress %: ‘ + zap.ascan.status

    time.sleep(5)

print ‘Scan completed’

#Printing the XMLreport and saving it on the file system of the ZAP container at /zap/ZAP_2.4.0/report.xml which we will later copy to the Host OS

with open(“/zap/ZAP_2.4.0/report.xml”, “w”) as f:

f.write(zap.core.xmlreport)

f.close()

zap.core.shutdown()

That’s all you need pretty much. 3 files –

  1. The main bash script. I have uploaded this here as well.
  2. Dockerfile to build the custom image and container. I have uploaded this here as well.
  3. runzap.py script that is used to start the ZAP daemon and run it against an IP. I have uploaded this here as well.

Once you have all these files, navigate to the folder you created on your host OS and build the Dockerfile with the following command:

docker build -t test .

After this file is built, type:

docker images

you should now see the test image being listed in your repository.

And, to save some time, download the other container as well with the following command:

docker pull training/webapp

In the end, you should see 3 docker images in your repository:

  1. test
  2. owasp/zap2docker-stable
  3. training/webapp

You should be good to go now to run the main bash script. So, just enter:

bash zaprun.sh

Hopefully, everything goes fine and you will see the report.xml file in your current directory.

Cheers!!

Advertisements

From → DevOps, Security

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: