diff --git a/.gitignore b/.gitignore index 8409a05..0d48e99 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ /terraform/tf.plan __pycache__ build/ +tmp/ jmeter.log scan-xccdf-results.html scan-xccdf-results.xml diff --git a/Jenkinsfile b/Jenkinsfile index cd04adb..5a6db2b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -165,24 +165,27 @@ if (params.Run_Packer) { node { wrap.call({ unstash 'src' - sh ("./bin/pack.sh") - archive (includes: 'build/**') - publishHTML (target: [ - allowMissing: true, - alwaysLinkToLastBuild: false, - keepAll: true, - reportDir: 'build', - reportFiles: 'scan-xccdf-results.html', - reportName: "OpenSCAP Report" - ]) - publishHTML (target: [ - allowMissing: true, - alwaysLinkToLastBuild: false, - keepAll: true, - reportDir: 'build', - reportFiles: 'gauntlt-results.txt', - reportName: "Gauntlt Report" - ]) + try { + sh ("./bin/pack.sh") + } finally { + archiveArtifacts artifacts: 'build/**', fingerprint: true + publishHTML (target: [ + allowMissing: true, + alwaysLinkToLastBuild: false, + keepAll: true, + reportDir: 'build', + reportFiles: 'scan-xccdf-results.html', + reportName: "OpenSCAP Report" + ]) + publishHTML (target: [ + allowMissing: true, + alwaysLinkToLastBuild: false, + keepAll: true, + reportDir: 'build', + reportFiles: 'gauntlt-results.html', + reportName: "Gauntlt Report" + ]) + } }) } } diff --git a/Vagrantfile b/Vagrantfile index eeda2ac..54b2902 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,8 +1,8 @@ Vagrant.configure("2") do |config| config.vm.box = "bento/centos-7.5" config.vm.synced_folder ".", "/app" - config.vm.provision "shell", inline: "/app/bin/install-gauntlt.sh", upload_path: "/home/vagrant/install-gauntlt.sh" - config.vm.provision "shell", inline: "/app/bin/install-ansible.sh", upload_path: "/home/vagrant/install-ansible.sh" - config.vm.provision "shell", inline: "cd /app/ansible && ansible-playbook -l localhost bakery.yml app-AfterInstall.yml app-StartServer.yml", upload_path: "/home/vagrant/apl.sh" + config.vm.provision "shell", inline: "/app/bin/install-gauntlt.sh", upload_path: "/home/vagrant/install-gauntlt.sh", privileged: false + config.vm.provision "shell", inline: "/app/bin/install-ansible.sh", upload_path: "/home/vagrant/install-ansible.sh", privileged: false + config.vm.provision "shell", inline: "/app/bin/ansible.sh bakery.yml scan-openscap.yml scan-gauntlt.yml app-AfterInstall.yml app-StartServer.yml ", upload_path: "/home/vagrant/ansible.sh", privileged: false config.vm.network "forwarded_port", guest: 80, host: 6080, auto_correct: true end diff --git a/ansible/bakery.yml b/ansible/bakery.yml index c03607c..4282248 100644 --- a/ansible/bakery.yml +++ b/ansible/bakery.yml @@ -33,6 +33,8 @@ - nginxinc.nginx - prepare-web-content - prepare-codedeploy + vars: + nginx_start: false - name: Harden Server @@ -42,5 +44,3 @@ roles: - extra-cis-remediation #- MindPointGroup.RHEL7-CIS - - scan-openscap - - scan-gauntlt diff --git a/ansible/gauntlt-results.txt b/ansible/gauntlt-results.txt index fc25590..67d42c3 100644 --- a/ansible/gauntlt-results.txt +++ b/ansible/gauntlt-results.txt @@ -100,3 +100,207 @@ cucumber /app/gauntlt/simple-env-var.attack:16 # Scenario: Verify server is avai 6 scenarios (1 failed, 5 passed) 27 steps (1 failed, 2 skipped, 24 passed) 0m14.558s +Feature: OS detection + + Background: # /app/gauntlt/os_detection.attack:3 + Given "nmap" is installed # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:4 + And the following profile: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:9 + | name | value | + | hostname | scanme.nmap.org | + + @slow + Scenario: Detect OS # /app/gauntlt/os_detection.attack:10 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -sV -p80 -PN + """ + Then the output should contain: # aruba-0.7.4/lib/aruba/cucumber.rb:182 + """ + Apache + """ + +@slow +Feature: nmap attacks for scanme.nmap.org and to use this for your tests, change the value in the profile + + Background: # /app/gauntlt/nmap.attack:4 + Given "nmap" is installed # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:4 + And the following profile: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:9 + | 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 # /app/gauntlt/nmap.attack:12 +Checking nmap-fast and nmap-fastRunning a nmap-fast attack. This attack has this description: + This is a fast nmap scan that should run in 10 seconds or less on most networks. It looks for the most common ports and services. + When I launch a "nmap-fast" attack # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:12 + Then the output should match /80.tcp\s+open/ # aruba-0.7.4/lib/aruba/cucumber.rb:206 + + Scenario: Verify server is open on expected set of ports using the nmap fast flag # /app/gauntlt/nmap.attack:16 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -F + """ + Then the output should match: # aruba-0.7.4/lib/aruba/cucumber.rb:210 + """ + 80/tcp\s+open + """ + + Scenario: Verify that there are no unexpected ports open # /app/gauntlt/nmap.attack:26 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -F + """ + Then the output should not contain: # aruba-0.7.4/lib/aruba/cucumber.rb:186 + """ + 22/tcp + 25/tcp + """ + + Scenario: Output to XML # /app/gauntlt/nmap.attack:37 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -p 80,443 -oX foo.xml + """ + And the file "foo.xml" should contain XML: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:15 + | css | + | ports port[protocol="tcp"][portid="80"] state[state="open"] | + And the file "foo.xml" should not contain XML: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:21 + | css | + | ports port[protocol="tcp"][portid="123"] state[state="open"] | + | ports port[protocol="tcp"][portid="443"] state[state="open"] | + +@slow +Feature: simple nmap attack (sanity check) + + Background: # /app/gauntlt/simple-env-var.attack:4 + Given "nmap" is installed # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:4 + And the following environment variables: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:3 + | name | environment_variable_name | + | hostname | TEST_HOSTNAME | + And the following profile: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:9 + | name | value | + | https_port | 443 | + | http_port | 80 | + + Scenario: Verify server is available on standard web ports # /app/gauntlt/simple-env-var.attack:16 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -p , + """ + no implicit conversion of nil into String (TypeError) + /app/gauntlt/simple-env-var.attack:17:in `When I launch an "nmap" attack with:' + Then the output should match /80.tcp\s+open/ # aruba-0.7.4/lib/aruba/cucumber.rb:206 + And the output should not match: # aruba-0.7.4/lib/aruba/cucumber.rb:219 + """ + 443/tcp\s+open + """ + +Failing Scenarios: +cucumber /app/gauntlt/simple-env-var.attack:16 # Scenario: Verify server is available on standard web ports + +6 scenarios (1 failed, 5 passed) +27 steps (1 failed, 2 skipped, 24 passed) +0m17.076s +Feature: OS detection + + Background: # /app/gauntlt/os_detection.attack:3 + Given "nmap" is installed # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:4 + And the following profile: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:9 + | name | value | + | hostname | scanme.nmap.org | + + @slow + Scenario: Detect OS # /app/gauntlt/os_detection.attack:10 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -sV -p80 -PN + """ + Then the output should contain: # aruba-0.7.4/lib/aruba/cucumber.rb:182 + """ + Apache + """ + +@slow +Feature: nmap attacks for scanme.nmap.org and to use this for your tests, change the value in the profile + + Background: # /app/gauntlt/nmap.attack:4 + Given "nmap" is installed # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:4 + And the following profile: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:9 + | 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 # /app/gauntlt/nmap.attack:12 +Checking nmap-fast and nmap-fastRunning a nmap-fast attack. This attack has this description: + This is a fast nmap scan that should run in 10 seconds or less on most networks. It looks for the most common ports and services. + When I launch a "nmap-fast" attack # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:12 + Then the output should match /80.tcp\s+open/ # aruba-0.7.4/lib/aruba/cucumber.rb:206 + + Scenario: Verify server is open on expected set of ports using the nmap fast flag # /app/gauntlt/nmap.attack:16 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -F + """ + Then the output should match: # aruba-0.7.4/lib/aruba/cucumber.rb:210 + """ + 80/tcp\s+open + """ + + Scenario: Verify that there are no unexpected ports open # /app/gauntlt/nmap.attack:26 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -F + """ + Then the output should not contain: # aruba-0.7.4/lib/aruba/cucumber.rb:186 + """ + 22/tcp + 25/tcp + """ + + Scenario: Output to XML # /app/gauntlt/nmap.attack:37 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -p 80,443 -oX foo.xml + """ + And the file "foo.xml" should contain XML: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:15 + | css | + | ports port[protocol="tcp"][portid="80"] state[state="open"] | + And the file "foo.xml" should not contain XML: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:21 + | css | + | ports port[protocol="tcp"][portid="123"] state[state="open"] | + | ports port[protocol="tcp"][portid="443"] state[state="open"] | + +@slow +Feature: simple nmap attack (sanity check) + + Background: # /app/gauntlt/simple-env-var.attack:4 + Given "nmap" is installed # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:4 + And the following environment variables: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:3 + | name | environment_variable_name | + | hostname | TEST_HOSTNAME | + And the following profile: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/gauntlt.rb:9 + | name | value | + | https_port | 443 | + | http_port | 80 | + + Scenario: Verify server is available on standard web ports # /app/gauntlt/simple-env-var.attack:16 + When I launch an "nmap" attack with: # gauntlt-1.0.13/lib/gauntlt/attack_adapters/nmap.rb:8 + """ + nmap -p , + """ + no implicit conversion of nil into String (TypeError) + /app/gauntlt/simple-env-var.attack:17:in `When I launch an "nmap" attack with:' + Then the output should match /80.tcp\s+open/ # aruba-0.7.4/lib/aruba/cucumber.rb:206 + And the output should not match: # aruba-0.7.4/lib/aruba/cucumber.rb:219 + """ + 443/tcp\s+open + """ + +Failing Scenarios: +cucumber /app/gauntlt/simple-env-var.attack:16 # Scenario: Verify server is available on standard web ports + +6 scenarios (1 failed, 5 passed) +27 steps (1 failed, 2 skipped, 24 passed) +0m14.169s diff --git a/ansible/roles/scan-gauntlt/defaults/main.yml b/ansible/roles/scan-gauntlt/defaults/main.yml index fb0556f..aba7d8d 100644 --- a/ansible/roles/scan-gauntlt/defaults/main.yml +++ b/ansible/roles/scan-gauntlt/defaults/main.yml @@ -3,4 +3,4 @@ gauntlt_version: "1.0.8" build_dir: /app/build/ gauntlt_attacks: /app/gauntlt/*.attack -output_file_html: gauntlt-results.txt +output_file_html: /app/build/gauntlt-results.html diff --git a/ansible/roles/scan-gauntlt/tasks/main.yml b/ansible/roles/scan-gauntlt/tasks/main.yml index 2e1db5d..4ae3445 100644 --- a/ansible/roles/scan-gauntlt/tasks/main.yml +++ b/ansible/roles/scan-gauntlt/tasks/main.yml @@ -9,4 +9,4 @@ mode: 0775 - name: Scan using gauntlt - shell: gauntlt "{{ gauntlt_attacks }}" | cat >> "{{ build_dir}}""{{ output_file_html }}" + command: gauntlt -f html -o "{{ output_file_html }}" "{{ gauntlt_attacks }}" diff --git a/ansible/roles/scan-openscap/defaults/main.yml b/ansible/roles/scan-openscap/defaults/main.yml index d89ecc3..ed0b37a 100644 --- a/ansible/roles/scan-openscap/defaults/main.yml +++ b/ansible/roles/scan-openscap/defaults/main.yml @@ -1,7 +1,7 @@ --- # defaults file for scan-oscap build_dir: /app/build -output_file_html: scan-xccdf-results.html -output_file_xml: scan-xccdf-results.xml +output_file_html: /app/build/scan-xccdf-results.html +output_file_xml: /app/build/scan-xccdf-results.xml profile: C2S xccdf_file: /usr/share/xml/scap/ssg/content/ssg-centos7-xccdf.xml diff --git a/ansible/roles/scan-openscap/tasks/main.yml b/ansible/roles/scan-openscap/tasks/main.yml index 3cc27e1..f8bf305 100644 --- a/ansible/roles/scan-openscap/tasks/main.yml +++ b/ansible/roles/scan-openscap/tasks/main.yml @@ -14,8 +14,8 @@ - name: Scan with OpenSCAP shell: | - eet -euo pipefail - ed {{ build_dir }} + set -euo pipefail + cd {{ build_dir }} # This will have a non-zero exit if any of the scans fail, so do not fail immediately on that set +e oscap xccdf eval --fetch-remote-resources --profile {{ profile }} --results {{ output_file_xml }} {{ xccdf_file }} diff --git a/ansible/scan-gauntlt.yml b/ansible/scan-gauntlt.yml new file mode 100644 index 0000000..7b456b4 --- /dev/null +++ b/ansible/scan-gauntlt.yml @@ -0,0 +1,9 @@ +--- +# Thanks https://www.tricksofthetrades.net/2017/10/02/ansible-local-playbooks/ for +# the trick on installing locally using "hosts: 127.0.0.1" and "connection:local" + +- name: Scan Server with Gauntlt + hosts: 127.0.0.1 + connection: local + roles: + - scan-gauntlt diff --git a/ansible/scan.yml b/ansible/scan-openscap.yml similarity index 88% rename from ansible/scan.yml rename to ansible/scan-openscap.yml index 79c1165..e9c3edf 100644 --- a/ansible/scan.yml +++ b/ansible/scan-openscap.yml @@ -2,7 +2,7 @@ # Thanks https://www.tricksofthetrades.net/2017/10/02/ansible-local-playbooks/ for # the trick on installing locally using "hosts: 127.0.0.1" and "connection:local" -- name: Scan Server +- name: Scan Server with OpenSCAP hosts: 127.0.0.1 connection: local become: yes diff --git a/bin/activate-rvm.sh b/bin/activate-rvm.sh new file mode 100755 index 0000000..dc8a93e --- /dev/null +++ b/bin/activate-rvm.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Activate rvm +# Source this to activate RVM + +RVM_SH=${RVM_SH:-$HOME/.rvm/scripts/rvm} +RUBY_VERSION=${RUBY_VERSION:-2.6.3} + +# rvm hates the bash options -eu + +if [[ ! -f "$RVM_SH" ]]; then + echo "Error: $0: RVM_SH $RVM_SH not found" + exit 1 +fi +set +eu +#shellcheck disable=SC1091,SC1090 +. "$RVM_SH" +rvm reload +rvm install "$RUBY_VERSION" +rvm alias create default ruby-"$RUBY_VERSION" +rvm list +rvm use "$RUBY_VERSION" --default +# We don't reactivate -u because even doing a "cd" will invoke an rvm +# function in .rvm/scripts/cd that bombs with: +# .rvm/scripts/functions/environment: line 267: rvm_bash_nounset: unbound variable + +set -e +ruby --version + diff --git a/bin/ansible.sh b/bin/ansible.sh new file mode 100755 index 0000000..f5dee25 --- /dev/null +++ b/bin/ansible.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Run ansible +# +# Set bash unofficial strict mode http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail + +# Set DEBUG to true for enhanced debugging: run prefixed with "DEBUG=true" +${DEBUG:-false} && set -vx +# Credit to https://stackoverflow.com/a/17805088 +# and http://wiki.bash-hackers.org/scripting/debuggingtips +export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + +# Credit to http://stackoverflow.com/a/246128/424301 +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# shellcheck disable=SC1090 +. "$DIR/common.sh" +# shellcheck disable=SC1090 +. "$DIR/activate-rvm.sh" + +ensure_not_root + +cd "$DIR/../ansible" +ansible-playbook -l localhost "$@" diff --git a/bin/common.sh b/bin/common.sh index 5baddf6..57cb52f 100755 --- a/bin/common.sh +++ b/bin/common.sh @@ -85,3 +85,31 @@ function get_docker_shellcheck() { echo "docker run --rm -i ${USE_TTY} -v $(pwd):/mnt koalaman/shellcheck" } +function ensure_root () { + # Thanks Unix Stack Exchange https://unix.stackexchange.com/a/389407 + if ((EUID != 0)); then + echo >&2 "Error: script not running as root or with sudo! Exiting..." + exit 1 + fi +} + +function ensure_not_root () { + # Thanks Unix Stack Exchange https://unix.stackexchange.com/a/389407 + if ((EUID == 0)); then + echo >&2 "Error: do not run script as root or with sudo! Exiting..." + exit 1 + fi +} + + +function quick_yum_install() { + declare package + package=${1?"You must specify a package to install"} + local sudo_maybe='' + ((EUID != 0)) && sudo_maybe='sudo' + if ! rpm -q "$package" > /dev/null; then + $sudo_maybe yum -y -q install "$package" + else + echo "$package already installed, skipping" >&2 + fi +} diff --git a/bin/install-ansible.sh b/bin/install-ansible.sh index 585ae0c..0e8c04c 100755 --- a/bin/install-ansible.sh +++ b/bin/install-ansible.sh @@ -11,13 +11,13 @@ ${DEBUG:-false} && set -vx # and http://wiki.bash-hackers.org/scripting/debuggingtips export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' -function quick_yum_install() { - declare package - package=${1?"You must specify a package to install"} - if ! rpm -q "$package" > /dev/null; then - sudo yum -y -q install "$package" - fi -} +# Credit to http://stackoverflow.com/a/246128/424301 +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +#shellcheck disable=SC1090 +. "$DIR/common.sh" + +ensure_not_root + quick_yum_install epel-release quick_yum_install ansible quick_yum_install git diff --git a/bin/install-gauntlt.sh b/bin/install-gauntlt.sh index 843d51c..7e91256 100755 --- a/bin/install-gauntlt.sh +++ b/bin/install-gauntlt.sh @@ -16,50 +16,65 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #shellcheck disable=SC1090 . "$DIR/common.sh" -function quick_yum_install() { - declare package - package=${1?"You must specify a package to install"} - if ! rpm -q "$package" > /dev/null; then - sudo yum -y -q install "$package" - else - echo "$package already installed, skipping" - fi -} +ensure_not_root -quick_yum_install ruby-devel -quick_yum_install nmap +RUBY_VERSION=2.6.3 +export RUBY_VERSION +RVM_SH="$HOME/.rvm/scripts/rvm" -if [[ ! -f /etc/profile.d/rvm.sh ]]; then +PACKAGES='nmap +ruby-devel +autoconf +automake +bison +gcc-c++ +libffi-devel +libtool +patch +readline-devel +sqlite-devel +zlib-devel +glibc-headers +glibc-devel +openssl-devel +requirements_centos_libs_install +patch +autoconf +automake +bison +gcc-c++ +libffi-devel +libtool +patch +readline-devel +sqlite-devel +zlib-devel +glibc-headers +glibc-devel +openssl-devel' + +#shellcheck disable=SC2086 +sudo yum -q install -y $PACKAGES + +if [[ ! -f "$RVM_SH" ]]; then curl -sSL https://rvm.io/mpapis.asc | gpg2 --import - curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import - curl -L get.rvm.io | bash -s stable # rvm hates the bash options -eu set +eu - #shellcheck disable=SC1091 - source /etc/profile.d/rvm.sh + #shellcheck disable=SC1091,SC1090 + . "$RVM_SH" rvm reload rvm requirements run + set -eu else - echo "rvm already installed" -fi -# rvm hates the bash options -eu -set +eu -#shellcheck disable=SC1091 -source /etc/profile.d/rvm.sh -rvm reload -rvm install 2.6.0 -rvm alias create default ruby-2.6.0 -rvm list -rvm use 2.6 --default -set -eu -if is_ec2; then - usermod -a -G rvm centos -else - usermod -a -G rvm vagrant + echo "rvm already installed" >&2 fi -ruby --version + +#shellcheck disable=SC1090 +. "$DIR/activate-rvm.sh" if ! (gem list gauntlt | grep gauntlt > /dev/null); then echo 'gem: --no-rdoc --no-ri' > ~/.gemrc - gem install gauntlt + gem install gauntlt syntax fi diff --git a/bin/pack.sh b/bin/pack.sh index 25743ab..ad6bf93 100755 --- a/bin/pack.sh +++ b/bin/pack.sh @@ -18,6 +18,14 @@ export BASE_DIR # shellcheck disable=SC1090 . "$DIR/common.sh" +function finish() { + pwd + ls -l "$BASE_DIR" "$BASE_DIR/build" build +} + +trap finish EXIT + DOCKER_PACKER=$(get_docker_packer) $DOCKER_PACKER validate app/packer/machines/web-server.json $DOCKER_PACKER build app/packer/machines/web-server.json +find "$BASE_DIR" -name '*.html' | grep -E 'gauntlt|scan' diff --git a/bin/scan.sh b/bin/scan.sh index 00716a3..60329eb 100755 --- a/bin/scan.sh +++ b/bin/scan.sh @@ -15,7 +15,7 @@ mkdir -p build cd build # This will have a non-zero exit if any of the scans fail, so do not fail immediately on that set +e -sudo oscap xccdf eval --profile C2S --results scan-xccdf-results.xml /usr/share/xml/scap/ssg/content/ssg-centos7-xccdf.xml +sudo oscap xccdf eval --profile C2S --results scan-xccdf-results.xml --fetch-remote-resources /usr/share/xml/scap/ssg/content/ssg-centos7-xccdf.xml set -e oscap xccdf generate report scan-xccdf-results.xml > scan-xccdf-results.html diff --git a/gauntlt/nmap.attack b/gauntlt/nmap.attack index d463db0..6467c14 100644 --- a/gauntlt/nmap.attack +++ b/gauntlt/nmap.attack @@ -1,17 +1,17 @@ @slow -Feature: nmap attacks for scanme.nmap.org and to use this for your tests, change the value in the profile +Feature: nmap attacks for localhost 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 | + | hostname | localhost | + | host | localhost | | 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/ + Then the output should match /22.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: @@ -20,7 +20,7 @@ Feature: nmap attacks for scanme.nmap.org and to use this for your tests, change """ Then the output should match: """ - 80/tcp\s+open + 22/tcp\s+open """ Scenario: Verify that there are no unexpected ports open @@ -30,20 +30,19 @@ Feature: nmap attacks for scanme.nmap.org and to use this for your tests, change """ Then the output should not contain: """ - 22/tcp - 25/tcp + 443/tcp """ Scenario: Output to XML When I launch an "nmap" attack with: """ - nmap -p 80,443 -oX foo.xml + nmap -p 22,80,443 -oX foo.xml """ And the file "foo.xml" should contain XML: | css | - | ports port[protocol="tcp"][portid="80"] state[state="open"] | + | ports port[protocol="tcp"][portid="22"] 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="80"] state[state="open"] | | ports port[protocol="tcp"][portid="443"] state[state="open"] | diff --git a/gauntlt/os_detection.attack b/gauntlt/os_detection.attack deleted file mode 100644 index c47d084..0000000 --- a/gauntlt/os_detection.attack +++ /dev/null @@ -1,18 +0,0 @@ -Feature: OS detection - - Background: - Given "nmap" is installed - And the following profile: - | name | value | - | hostname | scanme.nmap.org | - - @slow - Scenario: Detect OS - When I launch an "nmap" attack with: - """ - nmap -sV -p80 -PN - """ - Then the output should contain: - """ - Apache - """ diff --git a/gauntlt/simple-env-var.attack b/gauntlt/simple-env-var.attack deleted file mode 100644 index 4b76788..0000000 --- a/gauntlt/simple-env-var.attack +++ /dev/null @@ -1,25 +0,0 @@ -@slow -Feature: simple nmap attack (sanity check) - - Background: - Given "nmap" is installed - - And the following environment variables: - | name | environment_variable_name | - | hostname | TEST_HOSTNAME | - - And the following profile: - | name | value | - | https_port | 443 | - | http_port | 80 | - - Scenario: Verify server is available on standard web ports - When I launch an "nmap" attack with: - """ - nmap -p , - """ - Then the output should match /80.tcp\s+open/ - And the output should not match: - """ - 443/tcp\s+open - """ diff --git a/packer/machines/web-server.json b/packer/machines/web-server.json index ffeb488..5194a59 100644 --- a/packer/machines/web-server.json +++ b/packer/machines/web-server.json @@ -24,10 +24,15 @@ { "type": "shell", "inline": [ - "sudo mkdir /app", - "sudo chown centos:centos /app" + "sudo mkdir -p /app/build", + "sudo chown -R centos:centos /app" ] }, + { + "type": "file", + "source": "/app/ansible", + "destination": "/app" + }, { "type": "file", "source": "/app/application", @@ -40,21 +45,22 @@ }, { "type": "file", - "source": "/app/ansible", + "source": "/app/gauntlt", "destination": "/app" }, { "type": "shell", "inline": [ - "sudo bash /app/bin/install-gauntlt.sh", + "bash /app/bin/install-gauntlt.sh", "bash /app/bin/install-ansible.sh", - "ansible-playbook -l localhost /app/ansible/bakery.yml", - "bash /app/bin/scan.sh" + "bash /app/bin/ansible.sh bakery.yml scan-openscap.yml scan-gauntlt.yml", + "find / -name '*.html' 2>/dev/null | grep -E 'gauntlt|scan'", + "ls -l /app /app/build" ] }, { "type": "file", - "source": "build/", + "source": "/app/build/", "direction": "download", "destination": "/app" }