diff --git a/prowler b/prowler index f0695418..21fb74e9 100755 --- a/prowler +++ b/prowler @@ -25,8 +25,6 @@ # set -vx # Exits if any error is found # set -e -# Enable set -x to see commands and debug -# set -x OPTRED="" OPTNORMAL="" @@ -312,10 +310,7 @@ textTitle(){ printCsvHeader() { >&2 echo "" - >&2 echo "" - >&2 echo "Generating \"${SEP}\" delimited report on stdout; Diagnostics on stderr." - >&2 echo " Using Profile $PROFILE, Account $ACCOUNT_NUM" - >&2 echo "" + >&2 echo "Generating \"${SEP}\" delimited report on stdout for profile $PROFILE, account $ACCOUNT_NUM" echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}RESULT${SEP}SCORED${SEP}TITLE_TEXT${SEP}NOTES" } @@ -1253,31 +1248,32 @@ check315(){ CAN_SNS_LIST_SUBS=1 for regx in $REGIONS; do TOPICS_LIST=$($AWSCLI sns list-topics --profile $PROFILE --region $regx --output text --query 'Topics[*].TopicArn') + ntopics=$(echo $TOPICS_LIST | wc -w ) if [[ $TOPICS_LIST && $CAN_SNS_LIST_SUBS -eq 1 ]];then - for topic in $TOPICS_LIST; do - CHECK_TOPIC_LIST=$($AWSCLI sns list-subscriptions-by-topic --topic-arn $topic --profile $PROFILE --region $regx --query 'Subscriptions[*].{Endpoint:Endpoint,SubscriptionArn:SubscriptionArn}' --output text --max-items $MAXITEMS 2> /dev/null) - TOPIC_SHORT=$(echo $topic | awk -F: '{ print $6 }') - if [[ $? -eq 255 ]]; then - # Permission error - export CAN_SNS_LIST_SUBS=0 - textNotice "No permission to list subscribers in topics" - ntopics=$(echo $TOPICS_LIST | wc -w ) - textNotice "Region $regx has $ntopics topics" "$regx" - break; - fi - if [[ $(echo $CHECK_TOPIC_LIST| grep -v 'PendingConfirmation') ]]; then - CHECK_TOPIC_LIST_SHORT=$(echo $CHECK_TOPIC_LIST| awk '{ print $1 }') - textOK "Region $regx with Topic $TOPIC_SHORT has a Suscription to $CHECK_TOPIC_LIST_SHORT" "$regx" - else - textWarn "No suscription found in: Region $regx and Topic $TOPIC_SHORT" "$regx" - fi - done - elif [[ $CAN_SNS_LIST_SUBS -eq 0 ]]; then - ntopics=$(echo $TOPICS_LIST | wc -w ) textNotice "Region $regx has $ntopics topics" "$regx" + for topic in $TOPICS_LIST; do + TOPIC_SHORT=$(echo $topic | awk -F: '{ print $6 }') + CHECK_TOPIC_LIST=$($AWSCLI sns list-subscriptions-by-topic --topic-arn $topic --profile $PROFILE --region $regx --query 'Subscriptions[*].{Endpoint:Endpoint,Protocol:Protocol}' --output text --max-items $MAXITEMS 2> /dev/null) + if [[ $? -eq 255 ]]; then + # Permission error + export CAN_SNS_LIST_SUBS=0 + ntopics=$(echo $TOPICS_LIST | wc -w ) + textNotice "Region $regx / $ntopics Topics / Subscriptions NO_PERMISSION" "$regx" + break; + fi + if [[ "Z" != "Z${CHECK_TOPIC_LIST}" ]]; then + printf '%s\n' "$CHECK_TOPIC_LIST" | while IFS= read -r dest ; do + textNotice "Region $regx / Topic $TOPIC_SHORT / Suscription $dest" "$regx" + done + else + textWarn "Region $regx / Topic $TOPIC_SHORT / Suscription NONE NONE" "$regx" + fi + done + elif [[ $CAN_SNS_LIST_SUBS -eq 0 ]]; then + textNotice "Region $regx has $ntopics topics - unable to list subscribers" "$regx" # break else - textNotice "Region $regx doesn't have topics" "$regx" + textOK "Region $regx has 0 topics" "$regx" fi done } @@ -1366,6 +1362,41 @@ check45(){ done } +extra71(){ + # set -x + ID71="7.1" + TITLE71="Ensure users with AdministratorAccess policy have MFA tokens enabled (Not Scored) (Not part of CIS benchmark)" + textTitle "$ID71" "$TITLE71" "0" + + ADMIN_GROUPS='' + AWS_GROUPS=$($AWSCLI --profile $PROFILE iam list-groups --output text --query 'Groups[].GroupName') + for grp in $AWS_GROUPS; do + # aws --profile onlinetraining iam list-attached-group-policies --group-name Administrators --query 'AttachedPolicies[].PolicyArn' | grep 'arn:aws:iam::aws:policy/AdministratorAccess' + # list-attached-group-policies + CHECK_ADMIN_GROUP=$($AWSCLI --profile $PROFILE iam list-attached-group-policies --group-name $grp --output json --query 'AttachedPolicies[].PolicyArn' | grep 'arn:aws:iam::aws:policy/AdministratorAccess') + if [[ $CHECK_ADMIN_GROUP ]]; then + ADMIN_GROUPS="$ADMIN_GROUPS $grp" + textNotice "$grp group provides administrative access" + ADMIN_USERS=$($AWSCLI --profile $PROFILE iam get-group --group-name $grp --output json --query 'Users[].UserName' | grep '"' | cut -d'"' -f2 ) + for auser in $ADMIN_USERS; do + # users in group are Administrators + # users + # check for user MFA device in credential report + USER_MFA_ENABLED=$( cat $TEMP_REPORT_FILE | grep "^$auser," | cut -d',' -f8) + if [[ "true" == $USER_MFA_ENABLED ]]; then + textOK "$auser / MFA Enabled / admin via group $grp" + else + textWarn "$auser / MFA DISABLED / admin via group $grp" + fi + done + else + textNotice "$grp group provides non-administrative access" + fi + done + # set +x +} + + callCheck(){ if [[ $CHECKNUMBER ]];then case "$CHECKNUMBER" in @@ -1421,6 +1452,8 @@ callCheck(){ check43 ) check43;; check44 ) check44;; check45 ) check45;; + extra71 ) extra71;; + ## Groups of Checks check1 ) check11;check12;check13;check14;check15;check16;check17;check18; check19;check110;check111;check112;check113;check114;check115; @@ -1453,6 +1486,9 @@ callCheck(){ check310;check311;check312;check313;check314;check315;check41;check42; check43;check44;check45 ;; + extras ) + extra71; + ;; * ) textWarn "ERROR! Use a valid check name (i.e. check41)\n"; esac @@ -1468,10 +1504,11 @@ if [[ $MODE != "csv" ]]; then prowlerBanner printCurrentDate printColorsCode + getWhoami else + getWhoami printCsvHeader fi -getWhoami genCredReport saveReport