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) - [Features](#features)
- [Requirements and Installation](#requirements-and-installation) - [Requirements and Installation](#requirements-and-installation)
- [Usage](#usage) - [Usage](#usage)
- [Screenshots](#screenshots)
- [Advanced Usage](#advanced-usage) - [Advanced Usage](#advanced-usage)
- [Security Hub integration](#security-hub-integration) - [Security Hub integration](#security-hub-integration)
- [Fix](#fix) - [Fix](#fix)
- [Screenshots](#screenshots)
- [Troubleshooting](#troubleshooting) - [Troubleshooting](#troubleshooting)
- [Extras](#extras) - [Extras](#extras)
- [Forensics Ready Checks](#forensics-ready-checks) - [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 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 ### 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 ```sh
./prowler -M csv ./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: or with multiple formats at the same time:
```sh ```sh
./prowler -M csv,json,json-asff ./prowler -M csv,json,json-asff,html
``` ```
or just a group of checks in multiple formats: 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 ./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. 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: 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 ./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`: 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 ```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> 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 ## Troubleshooting
### STS expired token ### STS expired token

View File

@@ -14,8 +14,8 @@
IFS=',' read -ra MODES <<< "${MODE}" IFS=',' read -ra MODES <<< "${MODE}"
for MODE in "${MODES[@]}"; do for MODE in "${MODES[@]}"; do
if [[ "$MODE" != "mono" && "$MODE" != "text" && "$MODE" != "csv" && "$MODE" != "json" && "$MODE" != "json-asff" && "$MODE" != "junit-xml" ]]; then 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 or junit-xml. ./prowler -h for help" 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 EXITCODE=1
exit $EXITCODE exit $EXITCODE
fi fi

View File

@@ -17,13 +17,23 @@ EXTENSION_CSV="csv"
EXTENSION_JSON="json" EXTENSION_JSON="json"
EXTENSION_ASFF="asff-json" EXTENSION_ASFF="asff-json"
EXTENSION_TEXT="txt" 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_DATE=$(date -u +"%Y%m%d%H%M%S")
OUTPUT_DIR="${PROWLER_DIR}/output" OUTPUT_DIR="${PROWLER_DIR}/output"
OUTPUT_FILE_NAME="${OUTPUT_DIR}/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}" 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 # Ensure that output directory always exists when -M is used
mkdir -p "${OUTPUT_DIR}" 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 if [[ $PROFILE == "" ]];then
PROFILE="ENV" PROFILE="ENV"
@@ -62,6 +72,9 @@ textPass(){
if [[ "${MODES[@]}" =~ "text" || "${MODES[@]}" =~ "mono" ]]; then if [[ "${MODES[@]}" =~ "text" || "${MODES[@]}" =~ "mono" ]]; then
echo " $OK PASS!$NORMAL $1" echo " $OK PASS!$NORMAL $1"
fi fi
if [[ "${MODES[@]}" =~ "html" ]]; then
generateHtmlOutput "$1" "PASS"
fi
} }
textInfo(){ textInfo(){
@@ -89,6 +102,9 @@ textInfo(){
if [[ "${MODES[@]}" =~ "text" ]]; then if [[ "${MODES[@]}" =~ "text" ]]; then
echo " $NOTICE INFO! $1 $NORMAL" echo " $NOTICE INFO! $1 $NORMAL"
fi fi
if [[ "${MODES[@]}" =~ "html" ]]; then
generateHtmlOutput "$1" "INFO"
fi
} }
textFail(){ textFail(){
@@ -147,6 +163,9 @@ textFail(){
if [[ "${MODES[@]}" =~ "text" ]]; then if [[ "${MODES[@]}" =~ "text" ]]; then
echo " $colorcode ${level}! $1 $NORMAL" echo " $colorcode ${level}! $1 $NORMAL"
fi fi
if [[ "${MODES[@]}" =~ "html" ]]; then
generateHtmlOutput "$1" "${level}"
fi
} }
textTitle(){ 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="" OPTNORMAL=""
# Set the defaults variables # Set the defaults variables
PROWLER_VERSION=2.3.0RC PROWLER_VERSION=2.3.0RC2
PROWLER_DIR=$(dirname "$0") PROWLER_DIR=$(dirname "$0")
REGION="" REGION=""
@@ -196,6 +196,10 @@ done
clean_up() { clean_up() {
rm -f /tmp/prowler*.policy.* 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() { handle_ctrl_c() {
@@ -213,16 +217,17 @@ trap handle_ctrl_c INT
. $PROWLER_DIR/include/aws_profile_loader . $PROWLER_DIR/include/aws_profile_loader
. $PROWLER_DIR/include/awscli_detector . $PROWLER_DIR/include/awscli_detector
. $PROWLER_DIR/include/whoami . $PROWLER_DIR/include/whoami
. $PROWLER_DIR/include/outputs . $PROWLER_DIR/include/assume_role
. $PROWLER_DIR/include/csv_header . $PROWLER_DIR/include/csv_header
. $PROWLER_DIR/include/banner . $PROWLER_DIR/include/banner
. $PROWLER_DIR/include/html_report
. $PROWLER_DIR/include/outputs
. $PROWLER_DIR/include/credentials_report . $PROWLER_DIR/include/credentials_report
. $PROWLER_DIR/include/scoring . $PROWLER_DIR/include/scoring
. $PROWLER_DIR/include/python_detector . $PROWLER_DIR/include/python_detector
. $PROWLER_DIR/include/secrets_detector . $PROWLER_DIR/include/secrets_detector
. $PROWLER_DIR/include/check_creds_last_used . $PROWLER_DIR/include/check_creds_last_used
. $PROWLER_DIR/include/check3x . $PROWLER_DIR/include/check3x
. $PROWLER_DIR/include/assume_role
. $PROWLER_DIR/include/connection_tests . $PROWLER_DIR/include/connection_tests
. $PROWLER_DIR/include/securityhub_integration . $PROWLER_DIR/include/securityhub_integration
. $PROWLER_DIR/include/junit_integration . $PROWLER_DIR/include/junit_integration
@@ -509,6 +514,9 @@ if [[ $GROUP_ID_READ ]];then
if [[ " ${GROUP_ID[@]} " =~ " ${GROUP_ID_READ} " ]]; then if [[ " ${GROUP_ID[@]} " =~ " ${GROUP_ID_READ} " ]]; then
execute_group_by_id ${GROUP_ID_READ} ${EXCLUDE_CHECK_ID} execute_group_by_id ${GROUP_ID_READ} ${EXCLUDE_CHECK_ID}
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
cleanTemp cleanTemp
scoring scoring
exit $EXITCODE exit $EXITCODE
@@ -535,11 +543,17 @@ if [[ $CHECK_ID ]];then
for CHECK in "${CHECKS[@]}"; do for CHECK in "${CHECKS[@]}"; do
execute_check $CHECK execute_check $CHECK
done done
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
cleanTemp cleanTemp
exit $EXITCODE exit $EXITCODE
fi fi
execute_all execute_all
if [[ "${MODES[@]}" =~ "html" ]]; then
addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
fi
scoring scoring
cleanTemp cleanTemp
@@ -550,5 +564,4 @@ if [[ $ACCOUNT_TO_ASSUME ]]; then
unset AWS_SESSION_TOKEN unset AWS_SESSION_TOKEN
fi fi
exit $EXITCODE
exit $EXITCODE