diff --git a/Dockerfile b/Dockerfile index b31dcdb..42a6260 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,18 @@ -FROM ubuntu:16.04 +FROM ubuntu:19.04 MAINTAINER james@gauntlt.org ARG ARACHNI_VERSION=arachni-1.5.1-0.5.12 +WORKDIR /opt -# Install Ruby and other OS stuff -RUN apt-get update && \ - apt-get install -y build-essential \ +# Install Ruby, Gauntlt and everything needing build-essential +RUN apt update && \ + apt install -y build-essential \ bzip2 \ ca-certificates \ curl \ gcc \ git \ - libcurl3 \ + libcurl4 \ libcurl4-openssl-dev \ wget \ zlib1g-dev \ @@ -20,64 +21,121 @@ RUN apt-get update && \ libxslt1-dev \ make \ python-pip \ + xmlstarlet \ python2.7 \ python2.7-dev \ ruby \ ruby-dev \ + openjdk-8-jre \ ruby-bundler && \ - rm -rf /var/lib/apt/lists/* + gem install rake && \ + gem install ffi -v 1.9.24 && \ + wget -O dirb.tar.gz https://downloads.sourceforge.net/project/dirb/dirb/2.22/dirb222.tar.gz && \ + tar xvf dirb.tar.gz && \ + rm dirb.tar.gz && \ + cd dirb222 && \ + chmod 755 ./configure && \ + ./configure && \ + make && \ + ln -s /opt/dirb222/dirb /usr/local/bin/dirb && \ + gem install gauntlt --no-rdoc --no-ri && \ + apt remove -y \ + ruby-dev \ + python2.7-dev \ + libxml2-dev \ + libxslt1-dev \ + build-essential \ + libcurl4-openssl-dev \ + zlib1g-dev && \ + pip install sslyze==1.3.4 && \ + gem install zapr && \ + rm -rf /var/lib/apt/lists/* && \ + apt autoremove -y && \ + apt clean -# Install Gauntlt -RUN gem install rake -RUN gem install ffi -v 1.9.18 -RUN gem install gauntlt --no-rdoc --no-ri -# Install Attack tools -WORKDIR /opt +# Install remaining Attack tools # arachni RUN wget https://github.com/Arachni/arachni/releases/download/v1.5.1/${ARACHNI_VERSION}-linux-x86_64.tar.gz && \ tar xzvf ${ARACHNI_VERSION}-linux-x86_64.tar.gz > /dev/null && \ mv ${ARACHNI_VERSION} /usr/local && \ + rm ${ARACHNI_VERSION}-linux-x86_64.tar.gz && \ ln -s /usr/local/${ARACHNI_VERSION}/bin/* /usr/local/bin/ # Nikto RUN apt-get update && \ apt-get install -y libtimedate-perl \ libnet-ssleay-perl && \ - rm -rf /var/lib/apt/lists/* - -RUN git clone --depth=1 https://github.com/sullo/nikto.git && \ + git clone --depth=1 https://github.com/sullo/nikto.git && \ cd nikto/program && \ echo "EXECDIR=/opt/nikto/program" >> nikto.conf && \ ln -s /opt/nikto/program/nikto.conf /etc/nikto.conf && \ chmod +x nikto.pl && \ - ln -s /opt/nikto/program/nikto.pl /usr/local/bin/nikto + ln -s /opt/nikto/program/nikto.pl /usr/local/bin/nikto && \ + rm -rf /var/lib/apt/lists/* && \ + apt autoremove -y && \ + apt clean # sqlmap -WORKDIR /opt ENV SQLMAP_PATH /opt/sqlmap/sqlmap.py RUN git clone --depth=1 https://github.com/sqlmapproject/sqlmap.git -# dirb -COPY vendor/dirb222.tar.gz dirb222.tar.gz - -RUN tar xvfz dirb222.tar.gz > /dev/null && \ - cd dirb222 && \ - chmod 755 ./configure && \ - ./configure && \ - make && \ - ln -s /opt/dirb222/dirb /usr/local/bin/dirb - +# dirdb is installed with stuff needing build esentials ENV DIRB_WORDLISTS /opt/dirb222/wordlists # nmap -RUN apt-get update && \ - apt-get install -y nmap && \ - rm -rf /var/lib/apt/lists/* +RUN apt update && \ + apt install -y nmap && \ + apt clean && \ + rm -rf /var/lib/apt/lists/* && \ + apt clean -# sslyze -RUN pip install sslyze==1.3.4 +# sslyze is installed with stuff needing build esentials ENV SSLYZE_PATH /usr/local/bin/sslyze +# Heartbleed +RUN apt update && \ + apt install -y golang && \ + export GOPATH=/go && \ + go get github.com/FiloSottile/Heartbleed && \ + go install github.com/FiloSottile/Heartbleed && \ + mv /go/bin/Heartbleed /usr/local/bin/ && \ + rm -rf /go && \ + apt remove -y golang && \ + apt autoremove -y && \ + apt clean && \ + rm -rf /var/lib/apt/lists/* && \ + apt clean + +# Garmr +RUN pip install beautifulsoup && \ + git clone https://github.com/freddyb/Garmr.git && \ + cd Garmr && \ + python setup.py install + +# owasp-zap adapted from https://github.com/zaproxy/zaproxy/blob/develop/docker/Dockerfile-stable +RUN curl -s https://raw.githubusercontent.com/zaproxy/zap-admin/master/ZapVersions.xml | xmlstarlet sel -t -v //url |grep -i Linux | wget -nv --content-disposition -i - -O - | tar zxv && \ + mv ZAP* zap &&\ + cd zap && \ + # Setup Webswing + curl -s -L https://bitbucket.org/meszarv/webswing/downloads/webswing-2.5.10.zip > webswing.zip && \ + unzip webswing.zip && \ + rm webswing.zip && \ + mv webswing-* webswing && \ + # Remove Webswing demos + rm -Rf webswing/demo/ && \ + # Accept ZAP license + touch AcceptedLicense && \ + pip install zapcli python-owasp-zap-v2.4 + + +ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ +ENV PATH $JAVA_HOME/bin:/opt/zap/:$PATH +ENV ZAP_PATH /opt/zap/zap.sh + +VOLUME [ "/attacks" ] + ENTRYPOINT [ "/usr/local/bin/gauntlt" ] + +CMD ["/attacks/*"] diff --git a/Makefile b/Makefile index f173cf4..6da1ba1 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,9 @@ install-stub: @echo "installing gauntlt-docker to /usr/local/bin" @cp ./bin/gauntlt-docker /usr/local/bin +runexamples: + @echo "Running all examples" + @docker run --rm -it -v ${CURDIR}/examples:/attacks gauntlt help: @echo "the help menu" @echo " make build" @@ -27,5 +30,6 @@ help: @echo " make help" @echo " make install-stub" @echo " make interactive" + @echo " make runexamples" .PHONY: build clean diff --git a/examples/dirb.attack b/examples/dirb.attack new file mode 100644 index 0000000..2f19034 --- /dev/null +++ b/examples/dirb.attack @@ -0,0 +1,18 @@ +@slow +Feature: Run dirb scan on a URL + +Scenario: Use dirb to scan a website for basic security requirements and the DIRB_WORDLISTS environment variable must be set in your path. You can use different wordlists by changing the environment variable. + Given "dirb" is installed + And the following profile: + | name | value | + | hostname | http://scanme.nmap.org | + | dirb_wordlists_path | Overwritten by $DIRB_WORDLISTS | + | wordlist | vulns/tests.txt | + When I launch a "dirb" attack with: + """ + dirb / -wf + """ + Then the output should contain: + """ + FOUND: 0 + """ diff --git a/examples/garmr.attack b/examples/garmr.attack new file mode 100644 index 0000000..6de4d52 --- /dev/null +++ b/examples/garmr.attack @@ -0,0 +1,18 @@ +Feature: Run garmr scan on a URL + +Scenario: Use Garmr to scan a website for the Mozilla opioniated security requirements + Given "garmr" is installed + And the following profile: + | name | value | + | target_url | http://scanme.nmap.org | + When I launch a "garmr" attack with: + """ + garmr -u -o my_garmr_output.xml + """ + Then it should pass with: + """ + [Garmr.corechecks.Http200Check] Pass The request returned an HTTP 200 response. + """ + And the file "my_garmr_output.xml" should not contain XML: + | css | + | testcase[name="Http200Check"] failure | diff --git a/examples/heartbleed.attack b/examples/heartbleed.attack new file mode 100644 index 0000000..219473d --- /dev/null +++ b/examples/heartbleed.attack @@ -0,0 +1,14 @@ +@slow +Feature: Test for the Heartbleed vulnerability + +Scenario: Test my website for the Heartbleed vulnerability (see heartbleed.com for more info) + + Given "Heartbleed" is installed + And the following profile: + | name | value | + | domain | www.google.com | + When I launch a "Heartbleed" attack with: + """ + Heartbleed :443 + """ + Then the output should contain "SAFE" diff --git a/examples/nmap.attack b/examples/nmap.attack new file mode 100644 index 0000000..3f824c6 --- /dev/null +++ b/examples/nmap.attack @@ -0,0 +1,48 @@ +@slow + +Feature: nmap attacks for scanme.nmap.org and to use this for your tests, change the value in the profile + Background: + Given "nmap" is installed + And the following profile: + | name | value | + | hostname | scanme.nmap.org | + | host | scanme.nmap.org | + | tcp_ping_ports | 22,25,80,443 | + + Scenario: Verify server is open on expected set of ports using the nmap-fast attack step + When I launch a "nmap-fast" attack + Then the output should match /80.tcp\s+open/ + + Scenario: Verify server is open on expected set of ports using the nmap fast flag + When I launch an "nmap" attack with: + """ + nmap -F + """ + Then the output should match: + """ + 80/tcp\s+open + """ + + Scenario: Verify that there are no unexpected ports open + When I launch an "nmap" attack with: + """ + nmap -F + """ + Then the output should not contain: + """ + 22/tcp + 25/tcp + """ + + Scenario: Output to XML + When I launch an "nmap" attack with: + """ + nmap -p 80,443 -oX foo.xml + """ + And the file "foo.xml" should contain XML: + | css | + | ports port[protocol="tcp"][portid="80"] state[state="open"] | + And the file "foo.xml" should not contain XML: + | css | + | ports port[protocol="tcp"][portid="123"] state[state="open"] | + | ports port[protocol="tcp"][portid="443"] state[state="open"] | diff --git a/examples/sqlmap.attack b/examples/sqlmap.attack new file mode 100644 index 0000000..e469587 --- /dev/null +++ b/examples/sqlmap.attack @@ -0,0 +1,14 @@ +@slow + +Feature: Run sqlmap against a target + +Scenario: Identify SQL injection vulnerabilities + Given "sqlmap" is installed + And the following profile: + | name | value | + | target_url | http://scanme.nmap.org/?id=test | + When I launch a "sqlmap" attack with: + """ + python -u --dbms sqlite --batch -v 0 --tables + """ + Then the output should contain "all tested parameters do not appear to be injectable" diff --git a/examples/sslyze.attack b/examples/sslyze.attack new file mode 100644 index 0000000..4f8c1bb --- /dev/null +++ b/examples/sslyze.attack @@ -0,0 +1,17 @@ +Feature: Run sslyze against a target + +Background: + Given "sslyze" is installed + And the following profile: + | name | value | + | hostname | google.com | + +Scenario: Ensure no anonymous certificates + When I launch an "sslyze" attack with: + """ + python :443 + """ + Then the output should not contain: + """ + Anon + """ \ No newline at end of file diff --git a/examples/verbs.attack b/examples/verbs.attack new file mode 100644 index 0000000..010f5ab --- /dev/null +++ b/examples/verbs.attack @@ -0,0 +1,22 @@ +@slow +Feature: Evaluate responses to various HTTP methods. + +Background: + Given "curl" is installed + And the following profile: + | name | value | + | hostname | scanme.nmap.org | + +Scenario Outline: Verify server responds correctly to various HTTP methods + When I launch a "curl" attack with: + """ + curl -i -X + """ + Then the output should contain "" + Examples: + | method | response | + | delete | HTTP/1.1 501 Not Implemented | + | patch | HTTP/1.1 501 Not Implemented | + | trace | HTTP/1.1 501 Not Implemented | + | track | HTTP/1.1 501 Not Implemented | + | bogus | HTTP/1.1 501 Not Implemented | diff --git a/examples/xss.attack b/examples/xss.attack index 9e3e1c3..d71b48d 100644 --- a/examples/xss.attack +++ b/examples/xss.attack @@ -1,4 +1,5 @@ -@slow +@reallyslow + Feature: Look for cross site scripting (xss) using arachni against scanme.nmap.org Scenario: Using arachni, look for cross site scripting and verify no issues are found @@ -10,4 +11,4 @@ Scenario: Using arachni, look for cross site scripting and verify no issues are """ arachni --checks=xss --scope-directory-depth-limit=1 """ - Then the output should contain "0 issues were detected." + Then the output should contain "With issues: 0" diff --git a/examples/zap-xss.attack b/examples/zap-xss.attack new file mode 100644 index 0000000..caa7c22 --- /dev/null +++ b/examples/zap-xss.attack @@ -0,0 +1,15 @@ +@reallyslow +Feature: Look for common vulnerabilities using owasp-zap + +# Adapted from https://github.com/devopstf/gauntlt-zap/blob/master/attacks/xss/zap-xss.attack +Background: + Given the following profile: + | name | value | + | url | http://scanme.nmap.org | + +Scenario: Using owasp-zap, look for common vulnerabilities via passive scan + When I launch a "generic" attack with: + """ + zap-cli quick-scan -sc -o "-config api.disablekey=true --self-contained -config scanner.attackOnStart=true -config view.mode=attack -config connection.dnsTtlSuccessfulQueries=-1 -config api.addrs.addr.name=.* -config api.addrs.addr.regex=true" -s xss,sqli --spider --recursive + """ + Then the output should contain "Issues found: 0" diff --git a/vendor/dirb222.tar.gz b/vendor/dirb222.tar.gz deleted file mode 100644 index 6a8322c..0000000 Binary files a/vendor/dirb222.tar.gz and /dev/null differ