diff --git a/include/colors b/include/colors index 2383df54..2b7175ce 100644 --- a/include/colors +++ b/include/colors @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -if [[ $MODE != "mono" && $MODE != "text" && $MODE != "csv" ]]; then +if [[ $MODE != "mono" && $MODE != "text" && $MODE != "csv" && $MODE != "json" ]]; then echo "" echo "$OPTRED ERROR!$OPTNORMAL Invalid output mode. Choose text, mono, or csv." usage @@ -19,7 +19,7 @@ if [[ $MODE != "mono" && $MODE != "text" && $MODE != "csv" ]]; then exit $EXITCODE fi -if [[ "$MODE" == "mono" || "$MODE" == "csv" ]]; then +if [[ "$MODE" == "mono" || "$MODE" == "csv" || "$MODE" == "json" ]]; then MONOCHROME=1 fi diff --git a/include/jq_detector b/include/jq_detector new file mode 100644 index 00000000..544ebbef --- /dev/null +++ b/include/jq_detector @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +# AWS-CLI detector variable +JQ=$(which jq) +if [ -z "${JQ}" ]; then + echo -e "\n$RED ERROR!$NORMAL jq not found. Make sure it is installed correctly and in your \$PATH\n" + EXITCODE=1 + exit $EXITCODE +fi diff --git a/include/outputs b/include/outputs index ac70ce07..14656f59 100644 --- a/include/outputs +++ b/include/outputs @@ -20,6 +20,34 @@ textPass(){ REPREGION=$REGION fi 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 + if [[ $2 ]]; then + REPREGION=$2 + else + REPREGION=$REGION + fi + jq -c \ + --arg PROFILE "$PROFILE" \ + --arg ACCOUNT_NUM "$ACCOUNT_NUM" \ + --arg TITLE_TEXT "$TITLE_TEXT" \ + --arg MESSAGE "$(echo -e "${1}" | sed -e 's/^[[:space:]]*//')" \ + --arg SCORED "$ITEM_SCORED" \ + --arg ITEM_LEVEL "$ITEM_LEVEL" \ + --arg TITLE_ID "$TITLE_ID" \ + --arg REPREGION "$REPREGION" \ + --arg TIMESTAMP $(date -u +"%Y-%m-%dT%H:%M:%SZ") \ + -n '{ + "Profile": $PROFILE, + "Account Number": $ACCOUNT_NUM, + "Control": $TITLE_TEXT, + "Message": $MESSAGE, + "Status": "Pass", + "Scored": $SCORED, + "Level": $ITEM_LEVEL, + "Control ID": $TITLE_ID, + "Region": $REPREGION, + "Timestamp": $TIMESTAMP, + }' else echo " $OK PASS!$NORMAL $1" fi @@ -33,6 +61,34 @@ textInfo(){ REPREGION=$REGION fi 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 + if [[ $2 ]]; then + REPREGION=$2 + else + REPREGION=$REGION + fi + jq -c \ + --arg PROFILE "$PROFILE" \ + --arg ACCOUNT_NUM "$ACCOUNT_NUM" \ + --arg TITLE_TEXT "$TITLE_TEXT" \ + --arg MESSAGE "$(echo -e "${1}" | sed -e 's/^[[:space:]]*//')" \ + --arg SCORED "$ITEM_SCORED" \ + --arg ITEM_LEVEL "$ITEM_LEVEL" \ + --arg TITLE_ID "$TITLE_ID" \ + --arg REPREGION "$REPREGION" \ + --arg TIMESTAMP $(date -u +"%Y-%m-%dT%H:%M:%SZ") \ + -n '{ + "Profile": $PROFILE, + "Account Number": $ACCOUNT_NUM, + "Control": $TITLE_TEXT, + "Message": $MESSAGE, + "Status": "Info", + "Scored": $SCORED, + "Level": $ITEM_LEVEL, + "Control ID": $TITLE_ID, + "Region": $REPREGION, + "Timestamp": $TIMESTAMP, + }' else echo " $NOTICE INFO! $1 $NORMAL" fi @@ -47,6 +103,34 @@ textFail(){ REPREGION=$REGION fi 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 + if [[ $2 ]]; then + REPREGION=$2 + else + REPREGION=$REGION + fi + jq -c \ + --arg PROFILE "$PROFILE" \ + --arg ACCOUNT_NUM "$ACCOUNT_NUM" \ + --arg TITLE_TEXT "$TITLE_TEXT" \ + --arg MESSAGE "$(echo -e "${1}" | sed -e 's/^[[:space:]]*//')" \ + --arg SCORED "$ITEM_SCORED" \ + --arg ITEM_LEVEL "$ITEM_LEVEL" \ + --arg TITLE_ID "$TITLE_ID" \ + --arg REPREGION "$REPREGION" \ + --arg TIMESTAMP $(date -u +"%Y-%m-%dT%H:%M:%SZ") \ + -n '{ + "Profile": $PROFILE, + "Account Number": $ACCOUNT_NUM, + "Control": $TITLE_TEXT, + "Message": $MESSAGE, + "Status": "Fail", + "Scored": $SCORED, + "Level": $ITEM_LEVEL, + "Control ID": $TITLE_ID, + "Region": $REPREGION, + "Timestamp": $TIMESTAMP, + }' else echo " $BAD FAIL! $1 $NORMAL" fi @@ -84,6 +168,8 @@ textTitle(){ if [[ "$MODE" == "csv" ]]; then >&2 echo "$TITLE_ID $TITLE_TEXT" + elif [[ "$MODE" == "json" ]]; then + : else if [[ "$ITEM_SCORED" == "Scored" ]]; then echo -e "\n$BLUE $TITLE_ID $NORMAL $TITLE_TEXT" diff --git a/include/whoami b/include/whoami index eaf98c44..0fa8479a 100644 --- a/include/whoami +++ b/include/whoami @@ -28,6 +28,8 @@ getWhoami(){ printCsvHeader textTitle "0.0" "Show report generation info" "NOT_SCORED" "SUPPORT" textInfo "ARN: $CALLER_ARN TIMESTAMP: $SCRIPT_START_TIME" + elif [[ "$MODE" == "json" ]]; then + : else echo "" echo -e " This report is being generated using credentials below:\n" diff --git a/prowler b/prowler index 6434016a..ed65cdd6 100755 --- a/prowler +++ b/prowler @@ -260,6 +260,11 @@ if [[ $MODE != "csv" ]]; then prowlerBanner fi +# Check that jq is installed for JSON output +if [[ $MODE == "json" ]]; then + . $PROWLER_DIR/include/jq_detector +fi + # Gather account data / test aws cli connectivity getWhoami