Allow multiple report types at once #345

This commit is contained in:
Toni de la Fuente
2020-04-14 22:28:58 +02:00
parent e6fe5addbc
commit 4ea1864365
4 changed files with 73 additions and 48 deletions

View File

@@ -159,7 +159,25 @@ 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
1. If you want to save your report for later analysis:
### Save your reports
1. If you want to save your report for later analysis thare are different ways, natively (supported text, mono, csv, json and json-asff see note below for more info):
```sh
./prowler -M csv
```
or with multiple formats at the same time:
```sh
./prowler -M csv,json,json-asff
```
or just a group of checks in multiple formats:
```sh
./prowler -g gdpr -M csv,json,json-asff
```
Now `-M` creates a file inside the prowler root directory named `prowler-output-YYYYMMDDHHMMSS.format`. You don't have to specify anything else, no pipes, no redirects.
or just saving the output to a file like below:
```sh
./prowler -M mono > prowler-report.txt
@@ -172,18 +190,9 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
./prowler | ansi2html -la > report.html
```
or if you want a pipe-delimited report file, do:
>Note about output formats to use with `-M`: "text" is the default one with colors, "mono" is like default one but monochrome, "csv" is comma separated values, "json" plain basic json (without comma between lines) and "json-asff" is also json with Amazon Security Finding Format that you can ship to Security Hub using `-S`.
```sh
./prowler -M csv > output.psv
```
or json formatted output using jq, do:
```sh
./prowler -M json > prowler-output.json
```
or save your report in a S3 bucket:
or save your report in a S3 bucket (this only works for text or mono, for csv, json or json-asff it has to be copied afterwards):
```sh
./prowler -M mono | aws s3 cp - s3://bucket-name/prowler-report.txt
@@ -221,7 +230,8 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
-f <filterregion> specify an AWS region to run checks against
(i.e.: us-west-1)
-m <maxitems> specify the maximum number of items to return for long-running requests (default: 100)
-M <mode> output mode: text (default), mono, json, csv (separator is ,; data is on stdout; progress on stderr)
-M <mode> output mode: text (default), mono, json, json-asff, csv. They can be used combined comma separated.
(separator is ","; data is on stdout; progress on stderr).
-k keep the credential report
-n show check numbers to sort easier
(i.e.: 1.01 instead of 1.1)
@@ -280,7 +290,7 @@ In order to remove noise and get only FAIL findings there is a `-q` flag that ma
Since version v2.3, Prowler supports natively sending findings to [AWS Security Hub](https://aws.amazon.com/security-hub). This integration allows Prowler to import its findings to AWS Security Hub. With Security Hub, you now have a single place that aggregates, organizes, and prioritizes your security alerts, or findings, from multiple AWS services, such as Amazon GuardDuty, Amazon Inspector, Amazon Macie, AWS Identity and Access Management (IAM) Access Analyzer, and AWS Firewall Manager, as well as from AWS Partner solutions and now from Prowler. It is as simple as running the commanbd below:
```sh
```
./prowler -M json-asff -S
```
There are two requirements:

View File

@@ -11,13 +11,15 @@
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
IFS=',' read -ra MODES <<< "${MODE}"
for MODE in "${MODES[@]}"; do
if [[ "$MODE" != "mono" && "$MODE" != "text" && "$MODE" != "csv" && "$MODE" != "json" && "$MODE" != "json-asff" ]]; then
echo ""
echo "$OPTRED ERROR!$OPTNORMAL Invalid output mode. Choose text, mono, csv, json or json-asff."
usage
echo -e "${OPTRED}ERROR!$OPTNORMAL Invalid output mode. Choose text, mono, csv, json or json-asff. ./prowler -h for help"
EXITCODE=1
exit $EXITCODE
fi
done
if [[ "$MODE" == "mono" || "$MODE" == "csv" || "$MODE" == "json" || "$MODE" == "json-asff" ]]; then
MONOCHROME=1

View File

@@ -12,25 +12,36 @@
# specific language governing permissions and limitations under the License.
# Output formatting functions
EXTENSION_CSV="csv"
EXTENSION_JSON="json"
EXTENSION_ASFF="asff-json"
EXTENSION_HTML="html" # not implemented yet, use ansi2html as in documentation
OUTPUT_DATE=$(date -u +"%Y%m%d%H%M%S")
OUTPUT_FILE_NAME=prowler-output-$OUTPUT_DATE
textPass(){
if [[ "$QUIET" == 1 ]]; then
return
fi
PASS_COUNTER=$((PASS_COUNTER+1))
if [[ "$MODE" == "csv" || "$MODE" == "json" || "$MODE" == "json-asff" ]]; then
if [[ "${MODES[@]}" =~ "csv" || "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then
if [[ $2 ]]; then
REPREGION=$2
else
REPREGION=$REGION
fi
if [[ "$MODE" == "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}PASS${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
elif [[ "$MODE" == "json" ]]; then
generateJsonOutput "$1" "Pass"
elif [[ "$MODE" == "json-asff" ]]; then
if [[ "${MODES[@]}" =~ "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}PASS${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV
fi
if [[ "${MODES[@]}" =~ "json" ]]; then
generateJsonOutput "$1" "Pass" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_JSON
fi
if [[ "${MODES[@]}" =~ "json-asff" ]]; then
JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "PASSED" "INFORMATIONAL")
echo "${JSON_ASFF_OUTPUT}"
echo "${JSON_ASFF_OUTPUT}" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_ASFF
if [[ "${SEND_TO_SECURITY_HUB}" -eq 1 ]]; then
sendToSecurityHub "${JSON_ASFF_OUTPUT}"
fi
@@ -45,16 +56,17 @@ textInfo(){
return
fi
if [[ "$MODE" == "csv" || "$MODE" == "json" || "$MODE" == "json-asff" ]]; then
if [[ "${MODES[@]}" =~ "csv" || "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then
if [[ $2 ]]; then
REPREGION=$2
else
REPREGION=$REGION
fi
if [[ "$MODE" == "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}INFO${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
elif [[ "$MODE" == "json" ]]; then
generateJsonOutput "$1" "Info"
if [[ "${MODES[@]}" =~ "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}INFO${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV
fi
if [[ "${MODES[@]}" =~ "json" ]]; then
generateJsonOutput "$1" "Info" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_JSON
fi
else
echo " $NOTICE INFO! $1 $NORMAL"
@@ -64,19 +76,21 @@ textInfo(){
textFail(){
FAIL_COUNTER=$((FAIL_COUNTER+1))
EXITCODE=3
if [[ "$MODE" == "csv" || "$MODE" == "json" || "$MODE" == "json-asff" ]]; then
if [[ "${MODES[@]}" =~ "csv" || "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then
if [[ $2 ]]; then
REPREGION=$2
else
REPREGION=$REGION
fi
if [[ "$MODE" == "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}FAIL${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
elif [[ "$MODE" == "json" ]]; then
generateJsonOutput "$1" "Fail"
elif [[ "$MODE" == "json-asff" ]]; then
if [[ "${MODES[@]}" =~ "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}FAIL${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV
fi
if [[ "${MODES[@]}" =~ "json" ]]; then
generateJsonOutput "$1" "Fail" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_JSON
fi
if [[ "${MODES[@]}" =~ "json-asff" ]]; then
JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "FAILED" "HIGH")
echo "${JSON_ASFF_OUTPUT}"
echo "${JSON_ASFF_OUTPUT}" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_ASFF
if [[ "${SEND_TO_SECURITY_HUB}" -eq 1 ]]; then
sendToSecurityHub "${JSON_ASFF_OUTPUT}"
fi
@@ -117,9 +131,9 @@ textTitle(){
*) ITEM_LEVEL="Unspecified or Invalid";;
esac
if [[ "$MODE" == "csv" ]]; then
>&2 echo "$TITLE_ID $TITLE_TEXT"
elif [[ "$MODE" == "json" || "$MODE" == "json-asff" ]]; then
if [[ "${MODES[@]}" =~ "csv" ]]; then
>&2 echo "$TITLE_ID $TITLE_TEXT" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV
elif [[ "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then
:
else
if [[ "$ITEM_SCORED" == "Scored" ]]; then

View File

@@ -65,7 +65,8 @@ USAGE:
-f <filterregion> specify an AWS region to run checks against
(i.e.: us-west-1)
-m <maxitems> specify the maximum number of items to return for long-running requests (default: 100)
-M <mode> output mode: text (default), mono, json, json-asff, csv (separator is ","; data is on stdout; progress on stderr)
-M <mode> output mode: text (default), mono, json, json-asff, csv. They can be used combined comma separated.
(separator is ","; data is on stdout; progress on stderr).
-k keep the credential report
-n show check numbers to sort easier
(i.e.: 1.01 instead of 1.1)
@@ -393,7 +394,7 @@ get_all_checks_without_exclusion() {
}
### All functions defined above ... run the workflow
if [[ $MODE != "csv" ]]; then
if [[ ${MODES[@]} =~ "mono" || ${MODES[@]} =~ "text" ]]; then
prowlerBanner
fi
@@ -424,9 +425,7 @@ getWhoami
# Execute group of checks if called with -g
if [[ $GROUP_ID_READ ]];then
if [[ " ${GROUP_ID[@]} " =~ " ${GROUP_ID_READ} " ]]; then
if [[ $MODE == "csv" ]]; then
BANNER=0
fi
execute_group_by_id ${GROUP_ID_READ} ${EXCLUDE_CHECK_ID}
cleanTemp
scoring