mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
Added native html report - upgrade to 21st century ;)
This commit is contained in:
42
README.md
42
README.md
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
23
prowler
@@ -32,7 +32,7 @@ OPTRED="[1;31m"
|
||||
OPTNORMAL="[0;39m"
|
||||
|
||||
# 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
|
||||
Reference in New Issue
Block a user