Merge pull request #12 from pemontto/travis-docker-latest
This commit is contained in:
30
.travis.yml
30
.travis.yml
@ -5,11 +5,20 @@ python:
|
|||||||
- 2.7
|
- 2.7
|
||||||
env:
|
env:
|
||||||
- TEST_PATH=tests/data
|
- TEST_PATH=tests/data
|
||||||
|
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
# - 3.6
|
# - 3.6
|
||||||
#matrix:
|
#matrix:
|
||||||
# allow_failures:
|
# allow_failures:
|
||||||
# - python: 3.6 - Commenting out testing for Python 3.6 until ready
|
# - python: 3.6 - Commenting out testing for Python 3.6 until ready
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- mkdir -p ./data/esdata1
|
||||||
|
- mkdir -p ./data/es_snapshots
|
||||||
|
- sudo chown -R 1000:1000 ./data/es*
|
||||||
|
- docker build -t vulnwhisperer-local .
|
||||||
|
- docker-compose -f docker-compose-test.yml up -d
|
||||||
install:
|
install:
|
||||||
- pip install -r requirements.txt
|
- pip install -r requirements.txt
|
||||||
- pip install flake8 # pytest # add another testing frameworks later
|
- pip install flake8 # pytest # add another testing frameworks later
|
||||||
@ -20,25 +29,8 @@ before_script:
|
|||||||
- flake8 . --count --exit-zero --exclude=deps/qualysapi --max-complexity=10 --max-line-length=127 --statistics
|
- flake8 . --count --exit-zero --exclude=deps/qualysapi --max-complexity=10 --max-line-length=127 --statistics
|
||||||
script:
|
script:
|
||||||
- python setup.py install
|
- python setup.py install
|
||||||
# Test successful scan download and parsing
|
- bash tests/test-vuln_whisperer.sh
|
||||||
- rm -rf /tmp/VulnWhisperer
|
- bash tests/test-docker.sh
|
||||||
- vuln_whisperer -c configs/test.ini --mock --mock_dir ${TEST_PATH}
|
|
||||||
# Run a second time with no scans to import
|
|
||||||
- vuln_whisperer -c configs/test.ini --mock --mock_dir ${TEST_PATH}
|
|
||||||
# Test one failed scan
|
|
||||||
- rm -rf /tmp/VulnWhisperer
|
|
||||||
- rm -f ${TEST_PATH}/nessus/GET_scans_exports_164_download
|
|
||||||
- vuln_whisperer -c configs/test.ini --mock --mock_dir ${TEST_PATH}; [[ $? -eq 1 ]]
|
|
||||||
# Test two failed scans
|
|
||||||
- rm -rf /tmp/VulnWhisperer
|
|
||||||
- rm -f ${TEST_PATH}/qualys_vuln/scan_1553941061.87241
|
|
||||||
- vuln_whisperer -c configs/test.ini --mock --mock_dir ${TEST_PATH}; [[ $? -eq 2 ]]
|
|
||||||
# Test only nessus
|
|
||||||
- rm -rf /tmp/VulnWhisperer
|
|
||||||
- vuln_whisperer -c configs/test.ini -s nessus --mock --mock_dir ${TEST_PATH}; [[ $? -eq 1 ]]
|
|
||||||
# Test only qualy_vuln
|
|
||||||
- rm -rf /tmp/VulnWhisperer
|
|
||||||
- vuln_whisperer -c configs/test.ini -s qualys_vuln --mock --mock_dir ${TEST_PATH}; [[ $? -eq 1 ]]
|
|
||||||
notifications:
|
notifications:
|
||||||
on_success: change
|
on_success: change
|
||||||
on_failure: change # `always` will be the setting once code changes slow down
|
on_failure: change # `always` will be the setting once code changes slow down
|
||||||
|
@ -20,8 +20,7 @@ RUN python setup.py clean --all && \
|
|||||||
|
|
||||||
|
|
||||||
WORKDIR /opt/VulnWhisperer
|
WORKDIR /opt/VulnWhisperer
|
||||||
RUN python setup.py install && \
|
RUN python setup.py install
|
||||||
ln -s /opt/VulnWhisperer /tmp/VulnWhisperer
|
|
||||||
|
|
||||||
|
|
||||||
CMD vuln_whisperer -c /opt/VulnWhisperer/frameworks_example.ini
|
CMD vuln_whisperer -c /opt/VulnWhisperer/frameworks_example.ini
|
||||||
|
@ -4,8 +4,8 @@ hostname=nessus
|
|||||||
port=443
|
port=443
|
||||||
username=nessus_username
|
username=nessus_username
|
||||||
password=nessus_password
|
password=nessus_password
|
||||||
write_path=/tmp/VulnWhisperer/data/nessus/
|
write_path=/opt/VulnWhisperer/data/nessus/
|
||||||
db_path=/tmp/VulnWhisperer/data/database
|
db_path=/opt/VulnWhisperer/data/database
|
||||||
trash=false
|
trash=false
|
||||||
verbose=true
|
verbose=true
|
||||||
|
|
||||||
@ -15,8 +15,8 @@ hostname=tenable
|
|||||||
port=443
|
port=443
|
||||||
username=tenable.io_username
|
username=tenable.io_username
|
||||||
password=tenable.io_password
|
password=tenable.io_password
|
||||||
write_path=/tmp/VulnWhisperer/data/tenable/
|
write_path=/opt/VulnWhisperer/data/tenable/
|
||||||
db_path=/tmp/VulnWhisperer/data/database
|
db_path=/opt/VulnWhisperer/data/database
|
||||||
trash=false
|
trash=false
|
||||||
verbose=true
|
verbose=true
|
||||||
|
|
||||||
@ -26,8 +26,8 @@ enabled = false
|
|||||||
hostname = qualys_web
|
hostname = qualys_web
|
||||||
username = exampleuser
|
username = exampleuser
|
||||||
password = examplepass
|
password = examplepass
|
||||||
write_path=/tmp/VulnWhisperer/data/qualys_web/
|
write_path=/opt/VulnWhisperer/data/qualys_web/
|
||||||
db_path=/tmp/VulnWhisperer/data/database
|
db_path=/opt/VulnWhisperer/data/database
|
||||||
verbose=true
|
verbose=true
|
||||||
|
|
||||||
# Set the maximum number of retries each connection should attempt.
|
# Set the maximum number of retries each connection should attempt.
|
||||||
@ -42,8 +42,8 @@ enabled = true
|
|||||||
hostname = qualys_vuln
|
hostname = qualys_vuln
|
||||||
username = exampleuser
|
username = exampleuser
|
||||||
password = examplepass
|
password = examplepass
|
||||||
write_path=/tmp/VulnWhisperer/data/qualys_vuln/
|
write_path=/opt/VulnWhisperer/data/qualys_vuln/
|
||||||
db_path=/tmp/VulnWhisperer/data/database
|
db_path=/opt/VulnWhisperer/data/database
|
||||||
verbose=true
|
verbose=true
|
||||||
|
|
||||||
[detectify]
|
[detectify]
|
||||||
@ -54,8 +54,8 @@ hostname = detectify
|
|||||||
username = exampleuser
|
username = exampleuser
|
||||||
#password variable used as secretKey
|
#password variable used as secretKey
|
||||||
password = examplepass
|
password = examplepass
|
||||||
write_path =/tmp/VulnWhisperer/data/detectify/
|
write_path =/opt/VulnWhisperer/data/detectify/
|
||||||
db_path = /tmp/VulnWhisperer/data/database
|
db_path = /opt/VulnWhisperer/data/database
|
||||||
verbose = true
|
verbose = true
|
||||||
|
|
||||||
[openvas]
|
[openvas]
|
||||||
@ -64,8 +64,8 @@ hostname = openvas
|
|||||||
port = 4000
|
port = 4000
|
||||||
username = exampleuser
|
username = exampleuser
|
||||||
password = examplepass
|
password = examplepass
|
||||||
write_path=/tmp/VulnWhisperer/data/openvas/
|
write_path=/opt/VulnWhisperer/data/openvas/
|
||||||
db_path=/tmp/VulnWhisperer/data/database
|
db_path=/opt/VulnWhisperer/data/database
|
||||||
verbose=true
|
verbose=true
|
||||||
|
|
||||||
[jira]
|
[jira]
|
||||||
@ -73,8 +73,8 @@ enabled = false
|
|||||||
hostname = jira-host
|
hostname = jira-host
|
||||||
username = username
|
username = username
|
||||||
password = password
|
password = password
|
||||||
write_path = /tmp/VulnWhisperer/data/jira/
|
write_path = /opt/VulnWhisperer/data/jira/
|
||||||
db_path = /tmp/VulnWhisperer/data/database
|
db_path = /opt/VulnWhisperer/data/database
|
||||||
verbose = true
|
verbose = true
|
||||||
dns_resolv = False
|
dns_resolv = False
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ services:
|
|||||||
- xpack.monitoring.enabled=false
|
- xpack.monitoring.enabled=false
|
||||||
depends_on:
|
depends_on:
|
||||||
- elasticsearch
|
- elasticsearch
|
||||||
|
ports:
|
||||||
|
- 9600:9600
|
||||||
networks:
|
networks:
|
||||||
esnet:
|
esnet:
|
||||||
aliases:
|
aliases:
|
||||||
|
@ -12,7 +12,7 @@ saved_objects_file="kibana_APIonly.json"
|
|||||||
|
|
||||||
until curl -s "$elasticsearch_url/_cluster/health?pretty" | grep '"status"' | grep -qE "green|yellow"; do
|
until curl -s "$elasticsearch_url/_cluster/health?pretty" | grep '"status"' | grep -qE "green|yellow"; do
|
||||||
curl -s "$elasticsearch_url/_cluster/health?pretty"
|
curl -s "$elasticsearch_url/_cluster/health?pretty"
|
||||||
echo "Waiting for Elasticsearch"
|
echo "Waiting for Elasticsearch..."
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -30,8 +30,8 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
until [ "`curl -s -I "$kibana_url"/status | head -n1 |cut -d$' ' -f2`" == "200" ]; do
|
until [ "`curl -s -I "$kibana_url"/status | head -n1 |cut -d$' ' -f2`" == "200" ]; do
|
||||||
curl -I "$kibana_url"/status
|
curl -s -I "$kibana_url"/status
|
||||||
echo "Waiting for Kibana"
|
echo "Waiting for Kibana..."
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
|
|
||||||
|
109
tests/test-docker.sh
Executable file
109
tests/test-docker.sh
Executable file
@ -0,0 +1,109 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
NORMAL=$(tput sgr0)
|
||||||
|
GREEN=$(tput setaf 2)
|
||||||
|
YELLOW=$(tput setaf 3)
|
||||||
|
RED=$(tput setaf 1)
|
||||||
|
|
||||||
|
function red() {
|
||||||
|
echo -e "$RED$*$NORMAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
function green() {
|
||||||
|
echo -e "$GREEN$*$NORMAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
function yellow() {
|
||||||
|
echo -e "$YELLOW$*$NORMAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
return_code=0
|
||||||
|
|
||||||
|
elasticsearch_url="localhost:9200"
|
||||||
|
logstash_url="localhost:9600"
|
||||||
|
|
||||||
|
until curl -s "$elasticsearch_url/_cluster/health?pretty" | grep '"status"' | grep -qE "green|yellow"; do
|
||||||
|
yellow "Waiting for Elasticsearch..."
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
green "✅ Elasticsearch status is green..."
|
||||||
|
|
||||||
|
count=0
|
||||||
|
until [[ $(curl -s "$logstash_url/_node/stats" | jq '.events.out') -ge 1236 ]]; do
|
||||||
|
yellow "Waiting for Logstash load to finish... $(curl -s "$logstash_url/_node/stats" | jq '.events.out') of 1236 (attempt $count of 60)"
|
||||||
|
((count++)) && ((count==60)) && break
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ count -le 60 && $(curl -s "$logstash_url/_node/stats" | jq '.events.out') -ge 1236 ]]; then
|
||||||
|
green "✅ Logstash load finished..."
|
||||||
|
else
|
||||||
|
red "❌ Logstash load didn't complete... $(curl -s "$logstash_url/_node/stats" | jq '.events.out')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
count=0
|
||||||
|
until [[ $(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_count" | jq '.count') -ge 1232 ]] ; do
|
||||||
|
yellow "Waiting for Elasticsearch index to sync... $(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_count" | jq '.count') of 1232 logs loaded (attempt $count of 150)"
|
||||||
|
((count++)) && ((count==150)) && break
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
if [[ count -le 50 && $(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_count" | jq '.count') -ge 1232 ]]; then
|
||||||
|
green "✅ logstash-vulnwhisperer-2019.03 document count >= 1232"
|
||||||
|
else
|
||||||
|
red "❌ TIMED OUT waiting for logstash-vulnwhisperer-2019.03 document count: $(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_count" | jq) != 1232"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if [[ $(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_count" | jq '.count') == 1232 ]]; then
|
||||||
|
# green "✅ Passed: logstash-vulnwhisperer-2019.03 document count == 1232"
|
||||||
|
# else
|
||||||
|
# red "❌ Failed: logstash-vulnwhisperer-2019.03 document count == 1232 was: $(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_count") instead"
|
||||||
|
# ((return_code = return_code + 1))
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# Test Nessus plugin_name:Backported Security Patch Detection (FTP)
|
||||||
|
nessus_doc=$(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_search?q=plugin_name:%22Backported%20Security%20Patch%20Detection%20(FTP)%22%20AND%20asset:176.28.50.164%20AND%20tags:nessus" | jq '.hits.hits[]._source')
|
||||||
|
if echo $nessus_doc | jq '.risk' | grep -q "None"; then
|
||||||
|
green "✅ Passed: Nessus risk == None"
|
||||||
|
else
|
||||||
|
red "❌ Failed: Nessus risk == None was: $(echo $nessus_doc | jq '.risk') instead"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test Tenable plugin_name:Backported Security Patch Detection (FTP)
|
||||||
|
tenable_doc=$(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_search?q=plugin_name:%22Backported%20Security%20Patch%20Detection%20(FTP)%22%20AND%20asset:176.28.50.164%20AND%20tags:tenable" | jq '.hits.hits[]._source')
|
||||||
|
# Test asset
|
||||||
|
if echo $tenable_doc | jq .asset | grep -q '176.28.50.164'; then
|
||||||
|
green "✅ Passed: Tenable asset == 176.28.50.164"
|
||||||
|
else
|
||||||
|
red "❌ Failed: Tenable asset == 176.28.50.164 was: $(echo $tenable_doc | jq .asset) instead"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test @timestamp
|
||||||
|
if echo $tenable_doc | jq '.["@timestamp"]' | grep -q '2019-03-30T15:45:44.000Z'; then
|
||||||
|
green "✅ Passed: Tenable @timestamp == 2019-03-30T15:45:44.000Z"
|
||||||
|
else
|
||||||
|
red "❌ Failed: Tenable @timestamp == 2019-03-30T15:45:44.000Z was: $(echo $tenable_doc | jq '.["@timestamp"]') instead"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test Qualys plugin_name:OpenSSL Multiple Remote Security Vulnerabilities
|
||||||
|
qualys_vuln_doc=$(curl -s "$elasticsearch_url/logstash-vulnwhisperer-2019.03/_search?q=tags:qualys_vuln%20AND%20ip:%22176.28.50.164%22%20AND%20plugin_name:%22OpenSSL%20Multiple%20Remote%20Security%20Vulnerabilities%22%20AND%20port:465" | jq '.hits.hits[]._source')
|
||||||
|
# Test @timestamp
|
||||||
|
if echo $qualys_vuln_doc | jq '.["@timestamp"]' | grep -q '2019-03-30T10:17:41.000Z'; then
|
||||||
|
green "✅ Passed: Qualys VM @timestamp == 2019-03-30T10:17:41.000Z"
|
||||||
|
else
|
||||||
|
red "❌ Failed: Qualys VM @timestamp == 2019-03-30T10:17:41.000Z was: $(echo $qualys_vuln_doc | jq '.["@timestamp"]') instead"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test @XXXX
|
||||||
|
if echo $qualys_vuln_doc | jq '.cvss' | grep -q '6.8'; then
|
||||||
|
green "✅ Passed: Qualys VM cvss == 6.8"
|
||||||
|
else
|
||||||
|
red "❌ Failed: Qualys VM cvss == 6.8 was: $(echo $qualys_vuln_doc | jq '.cvss') instead"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $return_code
|
97
tests/test-vuln_whisperer.sh
Executable file
97
tests/test-vuln_whisperer.sh
Executable file
@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
NORMAL=$(tput sgr0)
|
||||||
|
GREEN=$(tput setaf 2)
|
||||||
|
YELLOW=$(tput setaf 3)
|
||||||
|
RED=$(tput setaf 1)
|
||||||
|
|
||||||
|
function red() {
|
||||||
|
echo -e "$RED$*$NORMAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
function green() {
|
||||||
|
echo -e "$GREEN$*$NORMAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
function yellow() {
|
||||||
|
echo -e "$YELLOW$*$NORMAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
return_code=0
|
||||||
|
|
||||||
|
TEST_PATH=${TEST_PATH:-"tests/data"}
|
||||||
|
|
||||||
|
yellow "\n*********************************************"
|
||||||
|
yellow "* Test successful scan download and parsing *"
|
||||||
|
yellow "*********************************************"
|
||||||
|
rm -rf /opt/VulnWhisperer/*
|
||||||
|
if vuln_whisperer -F -c configs/test.ini --mock --mock_dir "${TEST_PATH}"; then
|
||||||
|
green "\n✅ Passed: Test successful scan download and parsing"
|
||||||
|
else
|
||||||
|
red "\n❌ Failed: Test successful scan download and parsing"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
yellow "\n*********************************************"
|
||||||
|
yellow "* Test run with no scans to import *"
|
||||||
|
yellow "*********************************************"
|
||||||
|
if vuln_whisperer -F -c configs/test.ini --mock --mock_dir "${TEST_PATH}"; then
|
||||||
|
green "\n✅ Passed: Test run with no scans to import"
|
||||||
|
else
|
||||||
|
red "\n❌ Failed: Test run with no scans to import"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
yellow "\n*********************************************"
|
||||||
|
yellow "* Test one failed scan *"
|
||||||
|
yellow "*********************************************"
|
||||||
|
rm -rf /opt/VulnWhisperer/*
|
||||||
|
yellow "Removing ${TEST_PATH}/nessus/GET_scans_exports_164_download"
|
||||||
|
mv "${TEST_PATH}/nessus/GET_scans_exports_164_download"{,.bak}
|
||||||
|
if vuln_whisperer -F -c configs/test.ini --mock --mock_dir "${TEST_PATH}"; [[ $? -eq 1 ]]; then
|
||||||
|
green "\n✅ Passed: Test one failed scan"
|
||||||
|
else
|
||||||
|
red "\n❌ Failed: Test one failed scan"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
yellow "\n*********************************************"
|
||||||
|
yellow "* Test two failed scans *"
|
||||||
|
yellow "*********************************************"
|
||||||
|
rm -rf /opt/VulnWhisperer/*
|
||||||
|
yellow "Removing ${TEST_PATH}/qualys_vuln/scan_1553941061.87241"
|
||||||
|
mv "${TEST_PATH}/qualys_vuln/scan_1553941061.87241"{,.bak}
|
||||||
|
if vuln_whisperer -F -c configs/test.ini --mock --mock_dir "${TEST_PATH}"; [[ $? -eq 2 ]]; then
|
||||||
|
green "\n✅ Passed: Test two failed scans"
|
||||||
|
else
|
||||||
|
red "\n❌ Failed: Test two failed scans"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
yellow "\n*********************************************"
|
||||||
|
yellow "* Test only nessus with one failed scan *"
|
||||||
|
yellow "*********************************************"
|
||||||
|
rm -rf /opt/VulnWhisperer/*
|
||||||
|
if vuln_whisperer -F -c configs/test.ini -s nessus --mock --mock_dir "${TEST_PATH}"; [[ $? -eq 1 ]]; then
|
||||||
|
green "\n✅ Passed: Test only nessus with one failed scan"
|
||||||
|
else
|
||||||
|
red "\n❌ Failed: Test only nessus with one failed scan"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
yellow "*********************************************"
|
||||||
|
yellow "* Test only Qualys VM with one failed scan *"
|
||||||
|
yellow "*********************************************"
|
||||||
|
rm -rf /opt/VulnWhisperer/*
|
||||||
|
if vuln_whisperer -F -c configs/test.ini -s qualys_vuln --mock --mock_dir "${TEST_PATH}"; [[ $? -eq 1 ]]; then
|
||||||
|
green "\n✅ Passed: Test only Qualys VM with one failed scan"
|
||||||
|
else
|
||||||
|
red "\n❌ Failed: Test only Qualys VM with one failed scan"
|
||||||
|
((return_code = return_code + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restore the removed files
|
||||||
|
mv "${TEST_PATH}/qualys_vuln/scan_1553941061.87241.bak" "${TEST_PATH}/qualys_vuln/scan_1553941061.87241"
|
||||||
|
mv "${TEST_PATH}/nessus/GET_scans_exports_164_download.bak" "${TEST_PATH}/nessus/GET_scans_exports_164_download"
|
||||||
|
|
||||||
|
exit $return_code
|
Reference in New Issue
Block a user