Added native html report - upgrade to 21st century ;)

This commit is contained in:
Toni de la Fuente
2020-05-25 21:24:33 +02:00
parent 3e6f29c3fd
commit 78b26a022a
4 changed files with 117 additions and 30 deletions

View File

@@ -6,10 +6,10 @@
- [Features](#features)
- [Requirements and Installation](#requirements-and-installation)
- [Usage](#usage)
- [Screenshots](#screenshots)
- [Advanced Usage](#advanced-usage)
- [Security Hub integration](#security-hub-integration)
- [Fix](#fix)
- [Screenshots](#screenshots)
- [Troubleshooting](#troubleshooting)
- [Extras](#extras)
- [Forensics Ready Checks](#forensics-ready-checks)
@@ -168,9 +168,22 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
Valid check numbers are based on the AWS CIS Benchmark guide, so 1.1 is check11 and 3.10 is check310
## Screenshots
- Sample screenshot of report first lines:
<img width="1125" alt="screenshot 2016-09-13 16 05 42" src="https://cloud.githubusercontent.com/assets/3985464/18489640/50fe6824-79cc-11e6-8a9c-e788b88a8a6b.png">
- Sample screenshot of single check for check 3.3:
<img width="1006" alt="screenshot 2016-09-14 13 20 46" src="https://cloud.githubusercontent.com/assets/3985464/18522590/a04ca9a6-7a7e-11e6-8730-b545c9204990.png">
- Sample screenshot of the html output `-M html`:
<img width="1006" alt="Prowler html" src="https://user-images.githubusercontent.com/3985464/82838608-0229ce80-9ecd-11ea-860c-468f66aa2790.png">
### Save your reports
1. If you want to save your report for later analysis thare are different ways, natively (supported text, mono, csv, json, json-asff and junit-xml see note below for more info):
1. If you want to save your report for later analysis thare are different ways, natively (supported text, mono, csv, json, json-asff, junit-xml and html, see note below for more info):
```sh
./prowler -M csv
@@ -179,7 +192,7 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
or with multiple formats at the same time:
```sh
./prowler -M csv,json,json-asff
./prowler -M csv,json,json-asff,html
```
or just a group of checks in multiple formats:
@@ -188,6 +201,12 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
./prowler -g gdpr -M csv,json,json-asff
```
or if you want a sorted and dynamic HTML report do:
```sh
./prowler -M html
```
Now `-M` creates a file inside the prowler `output` directory named `prowler-output-AWSACCOUNTID-YYYYMMDDHHMMSS.format`. You don't have to specify anything else, no pipes, no redirects.
or just saving the output to a file like below:
@@ -196,13 +215,6 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
./prowler -M mono > prowler-report.txt
```
or if you want a coloured HTML report do:
```sh
pip install ansi2html
./prowler | ansi2html -la > report.html
```
To generate JUnit report files, include the junit-xml format. This can be combined with any other format. Files are written inside a prowler root directory named `junit-reports`:
```sh
@@ -374,16 +386,6 @@ Whitelist option works along with other options and adds a `WARNING` instead of
Check your report and fix the issues following all specific guidelines per check in <https://d0.awsstatic.com/whitepapers/compliance/AWS_CIS_Foundations_Benchmark.pdf>
## Screenshots
- Sample screenshot of report first lines:
<img width="1125" alt="screenshot 2016-09-13 16 05 42" src="https://cloud.githubusercontent.com/assets/3985464/18489640/50fe6824-79cc-11e6-8a9c-e788b88a8a6b.png">
- Sample screenshot of single check for check 3.3:
<img width="1006" alt="screenshot 2016-09-14 13 20 46" src="https://cloud.githubusercontent.com/assets/3985464/18522590/a04ca9a6-7a7e-11e6-8730-b545c9204990.png">
## Troubleshooting
### STS expired token

View File

@@ -14,8 +14,8 @@
IFS=',' read -ra MODES <<< "${MODE}"
for MODE in "${MODES[@]}"; do
if [[ "$MODE" != "mono" && "$MODE" != "text" && "$MODE" != "csv" && "$MODE" != "json" && "$MODE" != "json-asff" && "$MODE" != "junit-xml" ]]; then
echo -e "${OPTRED}ERROR!$OPTNORMAL Invalid output mode. Choose text, mono, csv, json, json-asff or junit-xml. ./prowler -h for help"
if [[ "$MODE" != "mono" && "$MODE" != "text" && "$MODE" != "csv" && "$MODE" != "json" && "$MODE" != "json-asff" && "$MODE" != "junit-xml" && "$MODE" != "html" ]]; then
echo -e "${OPTRED}ERROR!$OPTNORMAL Invalid output mode. Choose text, mono, csv, json, json-asff, junit-xml or html. ./prowler -h for help"
EXITCODE=1
exit $EXITCODE
fi

View File

@@ -17,13 +17,23 @@ EXTENSION_CSV="csv"
EXTENSION_JSON="json"
EXTENSION_ASFF="asff-json"
EXTENSION_TEXT="txt"
EXTENSION_HTML="html" # not implemented yet, use ansi2html as in documentation
EXTENSION_HTML="html"
OUTPUT_DATE=$(date -u +"%Y%m%d%H%M%S")
OUTPUT_DIR="${PROWLER_DIR}/output"
OUTPUT_FILE_NAME="${OUTPUT_DIR}/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}"
HTML_LOGO_URL="https://github.com/toniblyx/prowler/"
HTML_LOGO_IMG="https://raw.githubusercontent.com/toniblyx/prowler/master/util/html/prowler-logo.png"
TIMESTAMP=$(get_iso8601_timestamp)
PROWLER_PARAMETERS=$@
# Ensure that output directory always exists
mkdir -p "${OUTPUT_DIR}"
# Ensure that output directory always exists when -M is used
if [[ $MODE ]];then
mkdir -p "${OUTPUT_DIR}"
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlHeader > ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
HTML_REPORT_INIT="1"
fi
fi
if [[ $PROFILE == "" ]];then
PROFILE="ENV"
@@ -62,6 +72,9 @@ textPass(){
if [[ "${MODES[@]}" =~ "text" || "${MODES[@]}" =~ "mono" ]]; then
echo " $OK PASS!$NORMAL $1"
fi
if [[ "${MODES[@]}" =~ "html" ]]; then
generateHtmlOutput "$1" "PASS"
fi
}
textInfo(){
@@ -89,6 +102,9 @@ textInfo(){
if [[ "${MODES[@]}" =~ "text" ]]; then
echo " $NOTICE INFO! $1 $NORMAL"
fi
if [[ "${MODES[@]}" =~ "html" ]]; then
generateHtmlOutput "$1" "INFO"
fi
}
textFail(){
@@ -147,6 +163,9 @@ textFail(){
if [[ "${MODES[@]}" =~ "text" ]]; then
echo " $colorcode ${level}! $1 $NORMAL"
fi
if [[ "${MODES[@]}" =~ "html" ]]; then
generateHtmlOutput "$1" "${level}"
fi
}
textTitle(){
@@ -284,3 +303,56 @@ generateJsonAsffOutput(){
}
}'
}
generateHtmlOutput(){
local message=$1
local status=$2
if [[ $status == "INFO" ]];then
echo '<tr class="table-info">' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td><i class="fas fa-info-circle"></i></td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>INFO</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$message'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '</tr>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
if [[ $status == "PASS" ]];then
echo '<tr class="p-3 mb-2 bg-success">' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td><i class="fas fa-thumbs-up"></i></td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>PASS</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$message'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '</tr>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
if [[ $status == "FAIL" ]];then
echo '<tr class="table-danger" >' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td> <i class="fas fa-thumbs-down"></i></td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>FAIL</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$message'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '</tr>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
if [[ $status == "WARNING" ]];then
echo '<tr class="table-warning">' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td><i class="fas fa-exclamation-triangle"></i></td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>WARN</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$message'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '</tr>'>> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
}

23
prowler
View File

@@ -32,7 +32,7 @@ OPTRED=""
OPTNORMAL=""
# Set the defaults variables
PROWLER_VERSION=2.3.0RC
PROWLER_VERSION=2.3.0RC2
PROWLER_DIR=$(dirname "$0")
REGION=""
@@ -196,6 +196,10 @@ done
clean_up() {
rm -f /tmp/prowler*.policy.*
# in case html output is used, make sure it closes html file properly
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
}
handle_ctrl_c() {
@@ -213,16 +217,17 @@ trap handle_ctrl_c INT
. $PROWLER_DIR/include/aws_profile_loader
. $PROWLER_DIR/include/awscli_detector
. $PROWLER_DIR/include/whoami
. $PROWLER_DIR/include/outputs
. $PROWLER_DIR/include/assume_role
. $PROWLER_DIR/include/csv_header
. $PROWLER_DIR/include/banner
. $PROWLER_DIR/include/html_report
. $PROWLER_DIR/include/outputs
. $PROWLER_DIR/include/credentials_report
. $PROWLER_DIR/include/scoring
. $PROWLER_DIR/include/python_detector
. $PROWLER_DIR/include/secrets_detector
. $PROWLER_DIR/include/check_creds_last_used
. $PROWLER_DIR/include/check3x
. $PROWLER_DIR/include/assume_role
. $PROWLER_DIR/include/connection_tests
. $PROWLER_DIR/include/securityhub_integration
. $PROWLER_DIR/include/junit_integration
@@ -509,6 +514,9 @@ if [[ $GROUP_ID_READ ]];then
if [[ " ${GROUP_ID[@]} " =~ " ${GROUP_ID_READ} " ]]; then
execute_group_by_id ${GROUP_ID_READ} ${EXCLUDE_CHECK_ID}
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
cleanTemp
scoring
exit $EXITCODE
@@ -535,11 +543,17 @@ if [[ $CHECK_ID ]];then
for CHECK in "${CHECKS[@]}"; do
execute_check $CHECK
done
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
cleanTemp
exit $EXITCODE
fi
execute_all
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
scoring
cleanTemp
@@ -550,5 +564,4 @@ if [[ $ACCOUNT_TO_ASSUME ]]; then
unset AWS_SESSION_TOKEN
fi
exit $EXITCODE
exit $EXITCODE