From a2809eb29c3936832cdc220691730b544cda8bf4 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 13 Sep 2016 15:59:53 -0400 Subject: [PATCH] added single check support --- README.md | 22 +- prowler.sh | 1017 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 613 insertions(+), 426 deletions(-) diff --git a/README.md b/README.md index 8c60ad4e..babe043c 100644 --- a/README.md +++ b/README.md @@ -28,11 +28,17 @@ git clone https://github.com/Alfresco/aws-cis-security-benchmark cd aws-cis-security-benchmark ``` -- Make sure you have properly configure your AWS-CLI with a valid Access Key and Region. +- Make sure you have properly configure your AWS-CLI with a valid Access Key and Region: ``` aws configure ``` +- Make sure your Secret and Access Keys are associated to a user with proper permissions to do all checks. To make sure add SecurityAuditor default policy to your user. Policy ARN is + +``` +arn:aws:iam::aws:policy/SecurityAudit +``` + ## How to create a report 1 - Run the prowler.sh command without options: @@ -47,7 +53,18 @@ aws configure ./prowler.sh -p custom-profile -r us-east-1 ``` -3 - For help use: +3 - For a single check use option -c: + +``` +./prowler.sh -c check310 +``` +or for custom profile and region +``` +./prowler.sh -p custom-profile -r us-east-1 -c check11 +``` +Valid check numbers are like in the AWS CIS Benchmark guide, while 1.1 is check11 or 3.10 is check310 + +4 - For help use: ``` ./prowler.sh -h @@ -57,6 +74,7 @@ USAGE: Options: -p specify your AWS profile to use (i.e.: default) -r specify a desired AWS region to use (i.e.: us-east-1) + -c specify a check number from the AWS CIS benchmark (i.e.: check11 for check 1.1) -h this help ``` diff --git a/prowler.sh b/prowler.sh index 9d75a427..5002a5a3 100755 --- a/prowler.sh +++ b/prowler.sh @@ -53,16 +53,17 @@ DEFAULT_AWS_REGION="us-east-1" # Command usage menu usage(){ echo -e "\nUSAGE: - `basename $0` -p -r [ -v ] [ -h ] + `basename $0` -p -r [ -h ] Options: -p specify your AWS profile to use (i.e.: default) -r specify a desired AWS region to use (i.e.: us-east-1) + -c specify a check number from the AWS CIS benchmark (i.e.: check11 for check 1.1) -h this help " exit } -while getopts "hp:r:" OPTION; do +while getopts "hp:r:c:" OPTION; do case $OPTION in h ) usage @@ -74,6 +75,9 @@ while getopts "hp:r:" OPTION; do r ) REGION=$OPTARG ;; + c ) + CHECKNUMBER=$OPTARG + ;; : ) echo -e "\n$RED ERROR!$NORMAL -$OPTARG requires an argument\n" exit 1 @@ -143,11 +147,11 @@ elif [[ "$OSTYPE" == "cygwin" ]]; then echo $OUTPUT_DATE } else - echo "Unknown Operating System" - exit + echo "Unknown Operating System" + exit fi -if (($# == 0)); then +if [[ "$#" -le 2 ]]; then PROFILE=$DEFULT_AWS_PROFILE REGION=$DEFAULT_AWS_REGION fi @@ -164,16 +168,6 @@ if [ -z "${AWSCLI}" ]; then exit fi -# if [ -z "${PROFILE}" ] || [ -z "${REGION}" ]; then -# PROFILE=$($AWSCLI configure list | grep "profile" | awk '{ print $2 }') -# REGION=$($AWSCLI configure list | grep "region" | awk '{ print $2 }') -# if [ -z "${PROFILE}" ] || [ -z "${REGION}" ]; then -# echo -e "\n $RED ERROR!$NORMAL No profile or region found, configure it using 'aws configure'\n" -# echo -e " or specify options -p -r \n" -# exit -# fi -# fi - # if this script runs in an AWS instance # INSTANCE_PROFILE=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/) # AWS_ACCESS_KEY_ID=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/${INSTANCE_PROFILE} | grep AccessKeyId | cut -d':' -f2 | sed 's/[^0-9A-Z]*//g') @@ -181,8 +175,6 @@ fi # AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} # AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY_ID} -#cat ~/.aws/credentials - prowlerBanner() { echo -e "$CYAN _" echo -e " _ __ _ __ _____ _| | ___ _ __" @@ -199,28 +191,28 @@ getWhoami() { $AWSCLI sts get-caller-identity --output table --profile $PROFILE --region $REGION } -prowlerBanner -echo -e "\nDate: $NOTICE$(date)$NORMAL" -getWhoami +printCurrentDate(){ + echo -e "\nDate: $NOTICE$(date)$NORMAL" +} -echo -e "\nColors Code for results: $NOTICE INFORMATIVE$NORMAL,$OK OK (RECOMMENDED VALUE)$NORMAL, $BAD CRITICAL (FIX REQUIRED)$NORMAL \n" +printColorsCode(){ + echo -e "\nColors Code for results: $NOTICE INFORMATIVE$NORMAL,$OK OK (RECOMMENDED VALUE)$NORMAL, $BAD CRITICAL (FIX REQUIRED)$NORMAL \n" +} # Generate Credential Report genCredReport() { - echo -en '\nGenerating Credential Report...' - while STATE=$($AWSCLI iam generate-credential-report --output text --query 'State' --profile $PROFILE --region $REGION) - test "$STATE" = "STARTED" - do + echo -en '\nGenerating AWS IAM Credential Report...' + until $AWSCLI iam generate-credential-report --output text --query 'State' --profile $PROFILE --region $REGION |grep -m 1 "COMPLETE"; do sleep 1 - echo -n '.' + echo -n "." done - echo -en " COMPLETE!" } -genCredReport -# Save report to a file, deletion at finish. ACB stands for AWS CIS Benchmark -TEMP_REPORT_FILE=/tmp/.acb -$AWSCLI iam get-credential-report --query 'Content' --output text --profile $PROFILE --region $REGION | base64 -D > $TEMP_REPORT_FILE +# Save report to a file, deletion at finish, acb stands for AWS CIS Benchmark +saveReport(){ + TEMP_REPORT_FILE=/tmp/.acb + $AWSCLI iam get-credential-report --query 'Content' --output text --profile $PROFILE --region $REGION | base64 -D > $TEMP_REPORT_FILE +} # Get a list of all available AWS Regions REGIONS=$($AWSCLI ec2 describe-regions --query 'Regions[].RegionName' \ @@ -228,33 +220,40 @@ REGIONS=$($AWSCLI ec2 describe-regions --query 'Regions[].RegionName' \ --profile $PROFILE \ --region $REGION) -TITLE1="$BLUE 1 Identity and Access Management *********************************$NORMAL" -echo -e "\n\n$TITLE1 " +prowlerBanner +printCurrentDate +getWhoami +printColorsCode +genCredReport +saveReport -# 1.1 -TITLE11="$BLUE 1.1$NORMAL Avoid the use of the root account (Scored). Last time root account was used +check11(){ + TITLE11="$BLUE 1.1$NORMAL Avoid the use of the root account (Scored). Last time root account was used (password last used, access_key_1_last_used, access_key_2_last_used): " - COMMAND11=$(cat $TEMP_REPORT_FILE| grep '' | cut -d, -f5,11,16) - echo -e "\n$TITLE11 $NOTICE $COMMAND11 $NORMAL" + COMMAND11=$(cat $TEMP_REPORT_FILE| grep '' | cut -d, -f5,11,16 | sed 's/,/,\ /g') + echo -e "\n$TITLE11" + echo -e " $NOTICE $COMMAND11 $NORMAL" +} -# 1.2 -TITLE12="$BLUE 1.2$NORMAL Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)" +check12(){ + TITLE12="$BLUE 1.2$NORMAL Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)" # List users with password enabled COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$4 }' |grep true | awk '{ print $1 }') COMMAND12=$( for i in $COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED; do cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$8 }' |grep $i| grep false | awk '{ print $1 }'|tr '\n' ' '; done) - echo -e "\n$TITLE12" if [[ $COMMAND12 ]]; then - echo " List of users with Password enabled but MFA disabled: $RED $COMMAND12 $NORMAL" + echo -e " List of users with Password enabled but MFA disabled:" + echo -e " $RED $COMMAND12 $NORMAL" else - echo " $OK CORRECT! No users found with Password enabled and MFA disabled $NORMAL" + echo -e " $OK CORRECT! No users found with Password enabled and MFA disabled $NORMAL" fi +} -# 1.3 -TITLE13="$BLUE 1.3$NORMAL Ensure credentials unused for 90 days or greater are disabled (Scored)" +check13(){ + TITLE13="$BLUE 1.3$NORMAL Ensure credentials unused for 90 days or greater are disabled (Scored)" COMMAND13=$( for i in $COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED; do cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$5 }' |grep $i| grep false | awk '{ print $1 }'|tr '\n' ' '; @@ -274,11 +273,12 @@ TITLE13="$BLUE 1.3$NORMAL Ensure credentials unused for 90 days or greater are d echo " $OK OK $NORMAL" fi done +} -# 1.4 -TITLE14="$BLUE 1.4$NORMAL Ensure access keys are rotated every 90 days or less (Scored)" # also checked by Security Monkey -LIST_OF_USERS_WITH_ACCESS_KEY1=$(cat $TEMP_REPORT_FILE| awk -F, '{ print $1, $9 }' |grep "\ true" | awk '{ print $1 }') -LIST_OF_USERS_WITH_ACCESS_KEY2=$(cat $TEMP_REPORT_FILE| awk -F, '{ print $1, $14 }' |grep "\ true" | awk '{ print $1 }') +check14(){ + TITLE14="$BLUE 1.4$NORMAL Ensure access keys are rotated every 90 days or less (Scored)" # also checked by Security Monkey + LIST_OF_USERS_WITH_ACCESS_KEY1=$(cat $TEMP_REPORT_FILE| awk -F, '{ print $1, $9 }' |grep "\ true" | awk '{ print $1 }') + LIST_OF_USERS_WITH_ACCESS_KEY2=$(cat $TEMP_REPORT_FILE| awk -F, '{ print $1, $14 }' |grep "\ true" | awk '{ print $1 }') echo -e "\n$TITLE14 " echo -e " Users with access key 1 older than 90 days: " for user in $LIST_OF_USERS_WITH_ACCESS_KEY1; do @@ -290,7 +290,6 @@ LIST_OF_USERS_WITH_ACCESS_KEY2=$(cat $TEMP_REPORT_FILE| awk -F, '{ print $1, $14 echo -e " $RED $user $NORMAL" fi done - echo -e " Users with access key 2 older than 90 days: " for user in $LIST_OF_USERS_WITH_ACCESS_KEY2; do # check access key 2 @@ -300,60 +299,66 @@ LIST_OF_USERS_WITH_ACCESS_KEY2=$(cat $TEMP_REPORT_FILE| awk -F, '{ print $1, $14 echo -e " $RED $user $NORMAL" fi done +} -# 1.5 -TITLE15="$BLUE 1.5$NORMAL Ensure IAM password policy requires at least one uppercase letter (Scored)" -COMMAND15=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireUppercaseCharacters') # must be true +check15(){ + TITLE15="$BLUE 1.5$NORMAL Ensure IAM password policy requires at least one uppercase letter (Scored)" + COMMAND15=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireUppercaseCharacters') # must be true echo -e "\n$TITLE15 " if [ $COMMAND15 == "True" ];then echo -e " $OK OK $NORMAL" else echo -e " $RED FALSE $NORMAL" fi +} -# 1.6 -TITLE16="$BLUE 1.6$NORMAL Ensure IAM password policy require at least one lowercase letter (Scored)" -COMMAND16=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireLowercaseCharacters') # must be true +check16(){ + TITLE16="$BLUE 1.6$NORMAL Ensure IAM password policy require at least one lowercase letter (Scored)" + COMMAND16=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireLowercaseCharacters') # must be true echo -e "\n$TITLE16 " if [ $COMMAND16 == "True" ];then echo -e " $OK OK $NORMAL" else echo -e " $RED FALSE $NORMAL" fi +} -# 1.7 -TITLE17="$BLUE 1.7$NORMAL Ensure IAM password policy require at least one symbol (Scored)" -COMMAND17=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireSymbols') # must be true +check17(){ + TITLE17="$BLUE 1.7$NORMAL Ensure IAM password policy require at least one symbol (Scored)" + COMMAND17=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireSymbols') # must be true echo -e "\n$TITLE17 " if [ $COMMAND17 == "True" ];then echo -e " $OK OK $NORMAL" else echo -e " $RED FALSE $NORMAL" fi +} -# 1.8 -TITLE18="$BLUE 1.8$NORMAL Ensure IAM password policy require at least one number (Scored)" -COMMAND18=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireNumbers') # must be true +check18(){ + TITLE18="$BLUE 1.8$NORMAL Ensure IAM password policy require at least one number (Scored)" + COMMAND18=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.RequireNumbers') # must be true echo -e "\n$TITLE18 " if [ $COMMAND18 == "True" ];then echo -e " $OK OK $NORMAL" else echo -e " $RED FALSE $NORMAL" fi +} -# 1.9 -TITLE19="$BLUE 1.9$NORMAL Ensure IAM password policy requires minimum length of 14 or greater (Scored)" -COMMAND19=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.MinimumPasswordLength') +check19(){ + TITLE19="$BLUE 1.9$NORMAL Ensure IAM password policy requires minimum length of 14 or greater (Scored)" + COMMAND19=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.MinimumPasswordLength') echo -e "\n$TITLE19 " if [ $COMMAND19 -gt "13" ];then echo -e " $OK OK $NORMAL" else echo -e " $RED FALSE $NORMAL" fi +} -# 1.10 -TITLE110="$BLUE 1.10$NORMAL Ensure IAM password policy prevents password reuse (Scored)" -COMMAND110=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.PasswordReusePrevention' | grep PasswordReusePrevention | awk -F: '{ print $2 }'|sed 's/\ //g'|sed 's/,/ /g') +check110(){ + TITLE110="$BLUE 1.10$NORMAL Ensure IAM password policy prevents password reuse (Scored)" + COMMAND110=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.PasswordReusePrevention' | grep PasswordReusePrevention | awk -F: '{ print $2 }'|sed 's/\ //g'|sed 's/,/ /g') echo -e "\n$TITLE110 " if [[ $COMMAND110 ]];then if [[ $COMMAND110 -gt "23" ]];then @@ -362,10 +367,11 @@ COMMAND110=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region else echo -e " $RED FALSE $NORMAL" fi +} -# 1.11 -TITLE111="$BLUE 1.11$NORMAL Ensure IAM password policy expires passwords within 90 days or less (Scored)" -COMMAND111=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION | grep MaxPasswordAge | awk -F: '{ print $2 }'|sed 's/\ //g'|sed 's/,/ /g') +check111(){ + TITLE111="$BLUE 1.11$NORMAL Ensure IAM password policy expires passwords within 90 days or less (Scored)" + COMMAND111=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION | grep MaxPasswordAge | awk -F: '{ print $2 }'|sed 's/\ //g'|sed 's/,/ /g') echo -e "\n$TITLE111 " if [[ $COMMAND111 ]];then if [ $COMMAND111 == "90" ];then @@ -374,60 +380,63 @@ COMMAND111=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region else echo -e " $RED FALSE $NORMAL" fi +} -# 1.12 -TITLE112="$BLUE 1.12$NORMAL Ensure no root account access key exists (Scored)" -# ensure the access_key_1_active and access_key_2_active fields are set to FALSE. -ROOTKEY1=$(cat $TEMP_REPORT_FILE |grep root_account|awk -F, '{ print $9 }') -ROOTKEY2=$(cat $TEMP_REPORT_FILE |grep root_account|awk -F, '{ print $14 }') +check112(){ + TITLE112="$BLUE 1.12$NORMAL Ensure no root account access key exists (Scored)" + # ensure the access_key_1_active and access_key_2_active fields are set to FALSE. + ROOTKEY1=$(cat $TEMP_REPORT_FILE |grep root_account|awk -F, '{ print $9 }') + ROOTKEY2=$(cat $TEMP_REPORT_FILE |grep root_account|awk -F, '{ print $14 }') echo -e "\n$TITLE112 " - if [ $ROOTKEY1 == false ];then + if [ $ROOTKEY1 == "false" ];then echo -e " $OK OK $NORMAL No access key 1 found " else echo -e " $RED Found access key 1 $NORMAL" fi - if [ $ROOTKEY2 == false ];then + if [ $ROOTKEY2 == "false" ];then echo -e " $OK OK $NORMAL No access key 2 found " else echo -e " $RED Found access key 2 $NORMAL" fi +} -# 1.13 -TITLE113="$BLUE 1.13$NORMAL Ensure hardware MFA is enabled for the root account (Scored)" -COMMAND113=$($AWSCLI iam list-virtual-mfa-devices --profile $PROFILE --region $REGION --query 'VirtualMFADevices[*].User.Arn' --output text | awk -F":" '{ print $6 }'|tr '\n' ' ') -echo -e "\n$TITLE113" +check113(){ + TITLE113="$BLUE 1.13$NORMAL Ensure hardware MFA is enabled for the root account (Scored)" + COMMAND113=$($AWSCLI iam list-virtual-mfa-devices --profile $PROFILE --region $REGION --query 'VirtualMFADevices[*].User.Arn' --output text | awk -F":" '{ print $6 }'|tr '\n' ' ') + echo -e "\n$TITLE113" if [ $COMMAND113 ]; then echo " $OK OK $NORMAL" else - echo " $RED WARNING, MFA is not ENABLED for root account $NORMAL" + echo " $RED WARNING! MFA is not ENABLED for root account $NORMAL" fi +} -# 1.14 -TITLE114="$BLUE 1.14$NORMAL Ensure security questions are registered in the AWS account (Not Scored)" -# No command available -echo -e "\n$TITLE114" -echo -e " $NOTICE No command available for check 1.14" -echo -e " Login to the AWS Console as root, click on the Account " -echo -e " Name -> My Account -> Configure Security Challenge Questions $NORMAL" +check114(){ + TITLE114="$BLUE 1.14$NORMAL Ensure security questions are registered in the AWS account (Not Scored)" + # No command available + echo -e "\n$TITLE114" + echo -e " $NOTICE No command available for check 1.14" + echo -e " Login to the AWS Console as root, click on the Account " + echo -e " Name -> My Account -> Configure Security Challenge Questions $NORMAL" +} -# 1.15 -TITLE115="$BLUE 1.15$NORMAL Ensure IAM policies are attached only to groups or roles (Scored)" -echo -e "\n$TITLE115" -LIST_USERS=$($AWSCLI iam list-users --query 'Users[*].UserName' --output text --profile $PROFILE --region $REGION) -echo -e " Users with policy attached to them instead to groups: (it may take few seconds...) " +check115(){ + TITLE115="$BLUE 1.15$NORMAL Ensure IAM policies are attached only to groups or roles (Scored)" + echo -e "\n$TITLE115" + LIST_USERS=$($AWSCLI iam list-users --query 'Users[*].UserName' --output text --profile $PROFILE --region $REGION) + echo -e " Users with policy attached to them instead to groups: (it may take few seconds...) " for user in $LIST_USERS;do USER_POLICY=$($AWSCLI iam list-attached-user-policies --output text --profile $PROFILE --region $REGION --user-name $user) if [[ $USER_POLICY ]]; then echo -e " $RED $user $NORMAL" fi done +} -TITLE2="$BLUE 2 Logging ********************************************************$NORMAL" -echo -e "\n\n$TITLE2 " - -TITLE21="$BLUE 2.1$NORMAL Ensure CloudTrail is enabled in all regions (Scored)" -echo -e "\n$TITLE21" -COMMAND21=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].IsMultiRegionTrail' --output text) +check21(){ + TITLE21="$BLUE 2.1$NORMAL Ensure CloudTrail is enabled in all regions (Scored)" + echo -e "\n$TITLE21" + COMMAND21=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].IsMultiRegionTrail' --output text) if [[ $COMMAND21 ]];then if [ $COMMAND21 == "True" ];then echo -e " $OK OK $NORMAL" @@ -435,11 +444,12 @@ COMMAND21=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGI else echo -e " $RED FALSE $NORMAL" fi +} -TITLE22="$BLUE 2.2$NORMAL Ensure CloudTrail log file validation is enabled (Scored)" -echo -e "\n$TITLE22" -COMMAND22=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].LogFileValidationEnabled' --output text -) +check22(){ + TITLE22="$BLUE 2.2$NORMAL Ensure CloudTrail log file validation is enabled (Scored)" + echo -e "\n$TITLE22" + COMMAND22=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].LogFileValidationEnabled' --output text) if [[ $COMMAND22 ]];then if [ $COMMAND22 == "True" ];then echo -e " $OK OK $NORMAL" @@ -447,362 +457,521 @@ COMMAND22=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGI else echo -e " $RED FALSE $NORMAL" fi +} -TITLE23="$BLUE 2.3$NORMAL Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)" -echo -e "\n$TITLE23" - -CLOUDTRAILBUCKET=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].S3BucketName' --output text --profile $PROFILE --region $REGION) +check23(){ + TITLE23="$BLUE 2.3$NORMAL Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)" + echo -e "\n$TITLE23" + CLOUDTRAILBUCKET=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].S3BucketName' --output text --profile $PROFILE --region $REGION) if [[ $CLOUDTRAILBUCKET ]];then CLOUDTRAILBUCKET_HASALLPERMISIONS=$($AWSCLI s3api get-bucket-acl --bucket $CLOUDTRAILBUCKET --query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers`]' --profile $PROFILE --region $REGION --output text) # aws s3api get-bucket-policy --bucket $CLOUDTRAILBUCKET --profile $PROFILE --region $REGION --output text if [[ $CLOUDTRAILBUCKET_HASALLPERMISIONS ]];then - echo -e " $RED WARNING, check your CloudTrail bucket ACL and Policy!$NORMAL" + echo -e " $RED WARNING! check your CloudTrail bucket ACL and Policy!$NORMAL" else echo -e " $OK OK $NORMAL" fi else - echo -e " $RED WARNING, CloudTrail bucket doesn't exist!$NORMAL" + echo -e " $RED WARNING! CloudTrail bucket doesn't exist!$NORMAL" fi +} -TITLE24="$BLUE 2.4$NORMAL Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)" -echo -e "\n$TITLE24" +check24(){ + TITLE24="$BLUE 2.4$NORMAL Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)" + echo -e "\n$TITLE24" + LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].Name' --output text) + if [[ $LIST_OF_TRAILS ]];then + for trail in $LIST_OF_TRAILS;do + LATESTDELIVERY_TIMESTAMP=$($AWSCLI cloudtrail get-trail-status --name $trail --profile $PROFILE --region $REGION --query 'LatestCloudWatchLogsDeliveryTime') + LATESTDELIVERY_DATE=$(timestamp_to_date $LATESTDELIVERY_TIMESTAMP) + HOWOLDER=$(how_older_from_today $LATESTDELIVERY_DATE) + if [ $HOWOLDER -gt "1" ];then + echo -e " $RED $trail is not logging in the last 24h $NORMAL" + else + echo -e " $OK $trail has been logging during the last 24h $NORMAL" + fi + done + else + echo -e " $RED WARNING! No CloudTrail trails found!$NORMAL" + fi +} -LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].Name' --output text) -if [[ $LIST_OF_TRAILS ]];then - for trail in $LIST_OF_TRAILS;do - LATESTDELIVERY_TIMESTAMP=$($AWSCLI cloudtrail get-trail-status --name $trail --profile $PROFILE --region $REGION --query 'LatestCloudWatchLogsDeliveryTime') - LATESTDELIVERY_DATE=$(timestamp_to_date $LATESTDELIVERY_TIMESTAMP) - HOWOLDER=$(how_older_from_today $LATESTDELIVERY_DATE) - if [ $HOWOLDER -gt "1" ];then - echo -e " $RED $trail is not logging in the last 24h $NORMAL" +check25(){ + TITLE25="$BLUE 2.5$NORMAL Ensure AWS Config is enabled in all regions (Scored)" + echo -e "\n$TITLE25" + for regx in $REGIONS; do + CHECK_AWSCONFIG_STATUS=$($AWSCLI configservice get-status --profile $PROFILE --region $regx | grep recorder) + if [[ $CHECK_AWSCONFIG_STATUS ]];then + echo -e " $OK Region $regx has AWS Config $CHECK_AWSCONFIG_STATUS $NORMAL" else - echo -e " $OK $trail has been logging during the last 24h $NORMAL" + echo -e " $RED WARNING! Region $regx has AWS Config disabled or not configured$NORMAL" fi done -else - echo -e " $RED WARNING, No CloudTrail trails found!$NORMAL" -fi +} -TITLE25="$BLUE 2.5$NORMAL Ensure AWS Config is enabled in all regions (Scored)" -echo -e "\n$TITLE25" -for regx in $REGIONS; do - CHECK_AWSCONFIG_STATUS=$($AWSCLI configservice get-status --profile $PROFILE --region $regx | grep recorder) - if [[ $CHECK_AWSCONFIG_STATUS ]];then - echo -e " $OK Region $regx has AWS Config $CHECK_AWSCONFIG_STATUS $NORMAL" - else - echo -e " $RED WARNING, Region $regx has AWS Config disabled or not configured$NORMAL" - fi -done - -TITLE26="$BLUE 2.6$NORMAL Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Scored)" -echo -e "\n$TITLE26" -CLOUDTRAILBUCKET=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].S3BucketName' --output text --profile $PROFILE --region $REGION) - if [[ $CLOUDTRAILBUCKET ]];then - CLOUDTRAILBUCKET_LOGENABLED=$($AWSCLI s3api get-bucket-logging --bucket $CLOUDTRAILBUCKET --profile $PROFILE --region $REGION --query 'LoggingEnabled.TargetBucket' --output text|grep -v None) - if [[ $CLOUDTRAILBUCKET_LOGENABLED ]];then - echo -e " $OK OK $NORMAL" +check26(){ + TITLE26="$BLUE 2.6$NORMAL Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Scored)" + echo -e "\n$TITLE26" + CLOUDTRAILBUCKET=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].S3BucketName' --output text --profile $PROFILE --region $REGION) + if [[ $CLOUDTRAILBUCKET ]];then + CLOUDTRAILBUCKET_LOGENABLED=$($AWSCLI s3api get-bucket-logging --bucket $CLOUDTRAILBUCKET --profile $PROFILE --region $REGION --query 'LoggingEnabled.TargetBucket' --output text|grep -v None) + if [[ $CLOUDTRAILBUCKET_LOGENABLED ]];then + echo -e " $OK OK $NORMAL" + else + echo -e " $RED WARNING! access logging is not enabled in your CloudTrail S3 bucket!$NORMAL" + fi else - echo -e " $RED WARNING, access logging is not enabled in your CloudTrail S3 bucket!$NORMAL" + echo -e " $RED WARNING! CloudTrail bucket doesn't exist!$NORMAL" + fi +} + +check27(){ + TITLE27="$BLUE 2.7$NORMAL Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)" + echo -e "\n$TITLE27" + CLOUDTRAILNAME=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].Name' --output text --profile $PROFILE --region $REGION) + if [[ $CLOUDTRAILNAME ]];then + CLOUDTRAILENC_ENABLED=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --trail $CLOUDTRAILNAME --query 'trailList[*].KmsKeyId' --output text) + if [[ $CLOUDTRAILENC_ENABLED ]];then + echo -e " $OK OK $NORMAL" + else + echo -e " $RED WARNING! encryption is not enabled in your CloudTrail trail, KMS key not found!$NORMAL" + fi + else + echo -e " $RED WARNING! CloudTrail bucket doesn't exist!$NORMAL" + fi +} + +check28(){ + TITLE28="$BLUE 2.8$NORMAL Ensure rotation for customer created CMKs is enabled (Scored)" + echo -e "\n$TITLE28" + for regx in $REGIONS; do + CHECK_KMS_KEYLIST=$($AWSCLI kms list-keys --profile $PROFILE --region $regx --output text --query 'Keys[*].KeyId') + if [[ $CHECK_KMS_KEYLIST ]];then + for key in $CHECK_KMS_KEYLIST; do + CHECK_KMS_KEY_ROTATION=$($AWSCLI kms get-key-rotation-status --key-id $key --profile $PROFILE --region $regx --output text) + if [ $CHECK_KMS_KEY_ROTATION == "True" ];then + echo -e " $OK OK $NORMAL, Key $key in Region $regx is set correctly" + else + echo -e " $RED WARNING! Key $key in Region $regx is not set to rotate!$NORMAL" + fi + done + else + echo -e " $NOTICE Region $regx doesn't have encryption keys $NORMAL" + fi + done +} + +check31(){ + TITLE31="$BLUE 3.1$NORMAL Ensure a log metric filter and alarm exist for unauthorized API calls (Scored)" + echo -e "\n$TITLE31 " + CLOUDWATCH_GROUP=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].CloudWatchLogsLogGroupArn' --output text | awk -F: '{ print $7 }') + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep AccessDenied) + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters for Access Denied enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" fi else - echo -e " $RED WARNING, CloudTrail bucket doesn't exist!$NORMAL" + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" fi +} -TITLE27="$BLUE 2.7$NORMAL Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)" -echo -e "\n$TITLE27" -CLOUDTRAILNAME=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].Name' --output text --profile $PROFILE --region $REGION) - if [[ $CLOUDTRAILNAME ]];then - CLOUDTRAILENC_ENABLED=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --trail $CLOUDTRAILNAME --query 'trailList[*].KmsKeyId' --output text) - if [[ $CLOUDTRAILENC_ENABLED ]];then - echo -e " $OK OK $NORMAL" +check32(){ + TITLE32="$BLUE 3.2$NORMAL Ensure a log metric filter and alarm exist for Management Console sign-in without MFA (Scored)" + echo -e "\n$TITLE32 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'userIdentity.sessionContext.attributes.mfaAuthenticated.*true') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters for sign-in Console without MFA enabled$NORMAL" else - echo -e " $RED WARNING, encryption is not enabled in your CloudTrail trail, KMS key not found!$NORMAL" + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" fi else - echo -e " $RED WARNING, CloudTrail bucket doesn't exist!$NORMAL" + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" fi +} -TITLE28="$BLUE 2.8$NORMAL Ensure rotation for customer created CMKs is enabled (Scored)" -echo -e "\n$TITLE28" -for regx in $REGIONS; do - CHECK_KMS_KEYLIST=$($AWSCLI kms list-keys --profile $PROFILE --region $regx --output text --query 'Keys[*].KeyId') - if [[ $CHECK_KMS_KEYLIST ]];then - for key in $CHECK_KMS_KEYLIST; do - CHECK_KMS_KEY_ROTATION=$($AWSCLI kms get-key-rotation-status --key-id $key --profile $PROFILE --region $regx --output text) - if [ $CHECK_KMS_KEY_ROTATION == "True" ];then - echo -e " $OK OK $NORMAL, Key $key in Region $regx is set correctly" - else - echo -e " $RED WARNING, Key $key in Region $regx is not set to rotate!$NORMAL" - fi +check33(){ + TITLE33="$BLUE 3.3$NORMAL Ensure a log metric filter and alarm exist for usage of root account (Scored)" + echo -e "\n$TITLE33 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'Root.*AwsServiceEvent') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters for usage of root account enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check34(){ + TITLE34="$BLUE 3.4$NORMAL Ensure a log metric filter and alarm exist for IAM policy changes (Scored)" + echo -e "\n$TITLE34 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'DeleteGroupPolicy.*DeleteRolePolicy.*DeleteUserPolicy.*PutGroupPolicy.*PutRolePolicy.*PutUserPolicy.*CreatePolicy.*DeletePolicy.*CreatePolicyVersion.*DeletePolicyVersion.*AttachRolePolicy.*DetachRolePolicy.*AttachUserPolicy.*DetachUserPolicy.*AttachGroupPolicy.*DetachGroupPolicy') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters for IAM policy changes enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check35(){ + TITLE35="$BLUE 3.5$NORMAL Ensure a log metric filter and alarm exist for CloudTrail configuration changes (Scored)" + echo -e "\n$TITLE35 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateTrail.*UpdateTrail.*DeleteTrail.*StartLogging.*StopLogging') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters for CloudTrail configuration changes enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check36(){ + TITLE36="$BLUE 3.6$NORMAL Ensure a log metric filter and alarm exist for AWS Management Console authentication failures (Scored)" + echo -e "\n$TITLE36 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'ConsoleLogin.*Failed') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters for usage of root account enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check37(){ + TITLE37="$BLUE 3.7$NORMAL Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs (Scored)" + echo -e "\n$TITLE37 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'kms.amazonaws.com.*DisableKey.*ScheduleKeyDeletion') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check38(){ + TITLE38="$BLUE 3.8$NORMAL Ensure a log metric filter and alarm exist for S3 bucket policy changes (Scored)" + echo -e "\n$TITLE38 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 's3.amazonaws.com.*PutBucketAcl.*PutBucketPolicy.*PutBucketCors.*PutBucketLifecycle.*PutBucketReplication.*DeleteBucketPolicy.*DeleteBucketCors.*DeleteBucketLifecycle.*DeleteBucketReplication') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check39(){ + TITLE39="$BLUE 3.9$NORMAL Ensure a log metric filter and alarm exist for AWS Config configuration changes (Scored)" + echo -e "\n$TITLE39 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'config.amazonaws.com.*StopConfigurationRecorder.*DeleteDeliveryChannel.*PutDeliveryChannel.*PutConfigurationRecorder') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check310(){ + TITLE310="$BLUE 3.10$NORMAL Ensure a log metric filter and alarm exist for security group changes (Scored)" + echo -e "\n$TITLE310 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'AuthorizeSecurityGroupIngress.*AuthorizeSecurityGroupEgress.*RevokeSecurityGroupIngress.*RevokeSecurityGroupEgress.*CreateSecurityGroup.*DeleteSecurityGroup') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check311(){ + TITLE311="$BLUE 3.11$NORMAL Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) (Scored)" + echo -e "\n$TITLE311 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateNetworkAcl.*CreateNetworkAclEntry.*DeleteNetworkAcl.*DeleteNetworkAclEntry.*ReplaceNetworkAclEntry.*ReplaceNetworkAclAssociation') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check312(){ + TITLE312="$BLUE 3.12$NORMAL Ensure a log metric filter and alarm exist for changes to network gateways (Scored)" + echo -e "\n$TITLE312 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateCustomerGateway.*DeleteCustomerGateway.*AttachInternetGateway.*CreateInternetGateway.*DeleteInternetGateway.*DetachInternetGateway') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check313(){ + TITLE313="$BLUE 3.13$NORMAL Ensure a log metric filter and alarm exist for route table changes (Scored)" + echo -e "\n$TITLE313 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateRoute.*CreateRouteTable.*ReplaceRoute.*ReplaceRouteTableAssociation.*DeleteRouteTable.*DeleteRoute.*DisassociateRouteTable') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check314(){ + TITLE314="$BLUE 3.14$NORMAL Ensure a log metric filter and alarm exist for VPC changes (Scored)" + echo -e "\n$TITLE314 " + if [[ $CLOUDWATCH_GROUP ]];then + METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateVpc.*DeleteVpc.*ModifyVpcAttribute.*AcceptVpcPeeringConnection.*CreateVpcPeeringConnection.*DeleteVpcPeeringConnection.*RejectVpcPeeringConnection.*AttachClassicLinkVpc.*DetachClassicLinkVpc.*DisableVpcClassicLink.*EnableVpcClassicLink') + if [[ $METRICFILTER_SET ]];then + echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" + else + echo -e " $RED WARNING! CloudWatch group found, but no metric filters or alarms associated$NORMAL" + fi + else + echo -e " $RED WARNING! No CloudWatch group found, no metric filters or alarms associated$NORMAL" + fi +} + +check315(){ + TITLE315="$BLUE 3.15$NORMAL Ensure security contact information is registered (Scored)" + # No command available + echo -e "\n$TITLE315 " + echo -e " $NOTICE No command available for check 3.15" + echo -e " Login to the AWS Console, click on My Account " + echo -e " Go to Alternate Contacts -> make sure Security section is filled $NORMAL" +} + +check316(){ + TITLE316="$BLUE 3.16$NORMAL Ensure appropriate subscribers to each SNS topic (Not Scored)" + echo -e "\n$TITLE316 " + for regx in $REGIONS; do + TOPICS_LIST=$($AWSCLI sns list-topics --profile $PROFILE --region $regx --output text --query 'Topics[*].TopicArn') + if [[ $TOPICS_LIST ]];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,Protocol:Protocol}' --output text) + if [[ $CHECK_TOPIC_LIST ]]; then + TOPIC_SHORT=$(echo $topic | awk -F: '{ print $7 }') + echo -e " $NOTICE Region $regx with Topic $TOPIC_SHORT: $NORMAL " + echo -e " $NOTICE - Suscription: $CHECK_TOPIC_LIST $NORMAL" + else + echo -e " $RED WARNING! No suscription found in: Region $regx and Topic $topic $NORMAL" + echo -e " $RED - Region $regx and Topic $topic $NORMAL" + fi + done + else + echo -e " $NOTICE Region $regx doesn't have topics $NORMAL" + fi + done +} + +check41(){ + TITLE41="$BLUE 4.1$NORMAL Ensure no security groups allow ingress from 0.0.0.0/0 to port 22 (Scored)" + echo -e "\n$TITLE41 " + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --filters "Name=ip-permission.to-port,Values=22" --query 'SecurityGroups[?length(IpPermissions[?ToPort==`22` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupName: GroupName}' --profile $PROFILE --region $regx --output text) + if [[ $SG_LIST ]];then + for SG in $SG_LIST;do + echo -e " $RED Found Security Group: $SG open to 0.0.0.0/0 in Region $regx $NORMAL " done - else - echo -e " $NOTICE Region $regx doesn't have encryption keys $NORMAL" + else + echo -e " $OK OK, No Security Groups found in $regx with port 22 TCP open to 0.0.0.0/0 $NORMAL " + fi + done +} + +check42(){ + TITLE42="$BLUE 4.2$NORMAL Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389 (Scored)" + echo -e "\n$TITLE42 " + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --filters "Name=ip-permission.to-port,Values=3389" --query 'SecurityGroups[?length(IpPermissions[?ToPort==`3389` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupName: GroupName}' --profile $PROFILE --region $regx --output text) + if [[ $SG_LIST ]];then + for SG in $SG_LIST;do + echo -e " $RED Found Security Group: $SG open to 0.0.0.0/0 in Region $regx $NORMAL " + done + else + echo -e " $OK OK, No Security Groups found in $regx with port 3389 TCP open to 0.0.0.0/0 $NORMAL " + fi + done +} + +check43(){ + TITLE43="$BLUE 4.3$NORMAL Ensure VPC Flow Logging is Enabled in all Applicable Regions (Scored)" + echo -e "\n$TITLE43 " + for regx in $REGIONS; do + CHECK_FL=$($AWSCLI ec2 describe-flow-logs --profile $PROFILE --region $regx --query 'FlowLogs[?FlowLogStatus==`ACTIVE`].LogGroupName' --output text) + if [[ $CHECK_FL ]];then + for FL in $CHECK_FL;do + echo -e " $OK OK, VPCFlowLog is enabled for LogGroupName: $FL in Region $regx $NORMAL " + done + else + echo -e " $RED WARNING! no VPCFlowLog has been found in Region $regx $NORMAL " + fi + done +} + +check44(){ + TITLE44="$BLUE 4.4$NORMAL Ensure the default security group restricts all traffic (Scored)" + echo -e "\n$TITLE44 " + for regx in $REGIONS; do + CHECK_SGDEFAULT=$($AWSCLI ec2 describe-security-groups --profile $PROFILE --region $regx --filters Name=group-name,Values='default' --query 'SecurityGroups[*].{IpPermissions:IpPermissions,IpPermissionsEgress:IpPermissionsEgress,GroupId:GroupId}' --output text |grep 0.0.0.0) + if [[ $CHECK_SGDEFAULT ]];then + echo -e " $RED WARNING! Default Security Groups found that allow 0.0.0.0 IN or OUT traffic in Region $regx $NORMAL " + else + echo -e " $RED OK, no Default Security Groups open to 0.0.0.0 found in Region $regx $NORMAL " + fi + done +} + +singleCheck(){ + if [[ $CHECKNUMBER ]];then + case "$CHECKNUMBER" in + check11) check11;exit;; + check12) check12;exit;; + check13) check13;exit;; + check14) check14;exit;; + check15) check15;exit;; + check16) check16;exit;; + check17) check17;exit;; + check18) check18;exit;; + check19) check19;exit;; + check110) check110;exit;; + check111) check111;exit;; + check112) check112;exit;; + check113) check113;exit;; + check114) check114;exit;; + check115) check115;exit;; + check21) check21;exit;; + check22) check22;exit;; + check23) check23;exit;; + check24) check24;exit;; + check25) check25;exit;; + check26) check26;exit;; + check27) check27;exit;; + check28) check28;exit;; + check31) check31;exit;; + check32) check32;exit;; + check33) check33;exit;; + check34) check34;exit;; + check35) check35;exit;; + check36) check36;exit;; + check37) check37;exit;; + check38) check38;exit;; + check39) check39;exit;; + check310) check310;exit;; + check311) check311;exit;; + check312) check312;exit;; + check313) check313;exit;; + check314) check314;exit;; + check315) check315;exit;; + check316) check316;exit;; + check41) check41;exit;; + check42) check42;exit;; + check43) check43;exit;; + check44) check44;exit;; + * ) echo -e "\n$RED ERROR! Use a valid check name (i.e. check41) $NORMAL\n";exit;; + esac fi -done +} + +singleCheck + +TITLE1="$BLUE 1 Identity and Access Management *********************************$NORMAL" +echo -e "\n\n$TITLE1 " +check11 +check12 +check13 +check14 +check15 +check16 +check17 +check18 +check19 +check110 +check111 +check112 +check113 +check114 +check115 + +TITLE2="$BLUE 2 Logging ********************************************************$NORMAL" +echo -e "\n\n$TITLE2 " +check21 +check22 +check23 +check24 +check25 +check26 +check27 +check28 TITLE3="$BLUE 3 Monitoring *****************************************************" echo -e "\n\n$TITLE3 " # 3 Monitoring check commands / Mostly covered by SecurityMonkey - -TITLE31="$BLUE 3.1$NORMAL Ensure a log metric filter and alarm exist for unauthorized API calls (Scored)" -echo -e "\n$TITLE31 " -CLOUDWATCH_GROUP=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].CloudWatchLogsLogGroupArn' --output text | awk -F: '{ print $7 }') -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep AccessDenied) - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters for Access Denied enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE32="$BLUE 3.2$NORMAL Ensure a log metric filter and alarm exist for Management Console sign-in without MFA (Scored)" -echo -e "\n$TITLE32 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'userIdentity.sessionContext.attributes.mfaAuthenticated.*true') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters for sign-in Console without MFA enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE33="$BLUE 3.3$NORMAL Ensure a log metric filter and alarm exist for usage of root account (Scored)" -echo -e "\n$TITLE33 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'Root.*AwsServiceEvent') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters for usage of root account enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE34="$BLUE 3.4$NORMAL Ensure a log metric filter and alarm exist for IAM policy changes (Scored)" -echo -e "\n$TITLE34 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'DeleteGroupPolicy.*DeleteRolePolicy.*DeleteUserPolicy.*PutGroupPolicy.*PutRolePolicy.*PutUserPolicy.*CreatePolicy.*DeletePolicy.*CreatePolicyVersion.*DeletePolicyVersion.*AttachRolePolicy.*DetachRolePolicy.*AttachUserPolicy.*DetachUserPolicy.*AttachGroupPolicy.*DetachGroupPolicy') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters for IAM policy changes enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE35="$BLUE 3.5$NORMAL Ensure a log metric filter and alarm exist for CloudTrail configuration changes (Scored)" -echo -e "\n$TITLE35 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateTrail.*UpdateTrail.*DeleteTrail.*StartLogging.*StopLogging') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters for CloudTrail configuration changes enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE36="$BLUE 3.6$NORMAL Ensure a log metric filter and alarm exist for AWS Management Console authentication failures (Scored)" -echo -e "\n$TITLE36 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'ConsoleLogin.*Failed') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters for usage of root account enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE37="$BLUE 3.7$NORMAL Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs (Scored)" -echo -e "\n$TITLE37 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'kms.amazonaws.com.*DisableKey.*ScheduleKeyDeletion') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE38="$BLUE 3.8$NORMAL Ensure a log metric filter and alarm exist for S3 bucket policy changes (Scored)" -echo -e "\n$TITLE38 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 's3.amazonaws.com.*PutBucketAcl.*PutBucketPolicy.*PutBucketCors.*PutBucketLifecycle.*PutBucketReplication.*DeleteBucketPolicy.*DeleteBucketCors.*DeleteBucketLifecycle.*DeleteBucketReplication') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE39="$BLUE 3.9$NORMAL Ensure a log metric filter and alarm exist for AWS Config configuration changes (Scored)" -echo -e "\n$TITLE39 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'config.amazonaws.com.*StopConfigurationRecorder.*DeleteDeliveryChannel.*PutDeliveryChannel.*PutConfigurationRecorder') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE310="$BLUE 3.10$NORMAL Ensure a log metric filter and alarm exist for security group changes (Scored)" -echo -e "\n$TITLE310 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'AuthorizeSecurityGroupIngress.*AuthorizeSecurityGroupEgress.*RevokeSecurityGroupIngress.*RevokeSecurityGroupEgress.*CreateSecurityGroup.*DeleteSecurityGroup') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE311="$BLUE 3.11$NORMAL Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) (Scored)" -echo -e "\n$TITLE311 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateNetworkAcl.*CreateNetworkAclEntry.*DeleteNetworkAcl.*DeleteNetworkAclEntry.*ReplaceNetworkAclEntry.*ReplaceNetworkAclAssociation') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE312="$BLUE 3.12$NORMAL Ensure a log metric filter and alarm exist for changes to network gateways (Scored)" -echo -e "\n$TITLE312 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateCustomerGateway.*DeleteCustomerGateway.*AttachInternetGateway.*CreateInternetGateway.*DeleteInternetGateway.*DetachInternetGateway') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE313="$BLUE 3.13$NORMAL Ensure a log metric filter and alarm exist for route table changes (Scored)" -echo -e "\n$TITLE313 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateRoute.*CreateRouteTable.*ReplaceRoute.*ReplaceRouteTableAssociation.*DeleteRouteTable.*DeleteRoute.*DisassociateRouteTable') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE314="$BLUE 3.14$NORMAL Ensure a log metric filter and alarm exist for VPC changes (Scored)" -echo -e "\n$TITLE314 " -if [[ $CLOUDWATCH_GROUP ]];then - METRICFILTER_SET=$($AWSCLI logs describe-metric-filters --log-group-name CloudTrail/CloudWatchGroup --profile $PROFILE --region $REGION --query 'trailList' | grep -E 'CreateVpc.*DeleteVpc.*ModifyVpcAttribute.*AcceptVpcPeeringConnection.*CreateVpcPeeringConnection.*DeleteVpcPeeringConnection.*RejectVpcPeeringConnection.*AttachClassicLinkVpc.*DetachClassicLinkVpc.*DisableVpcClassicLink.*EnableVpcClassicLink') - if [[ $METRICFILTER_SET ]];then - echo -e " $OK OK, CloudWatch group found, and metric filters enabled$NORMAL" - else - echo -e " $RED WARNING, CloudWatch group found, but no metric filters or alarms associated$NORMAL" - fi -else - echo -e " $RED WARNING, No CloudWatch group found, no metric filters or alarms associated$NORMAL" -fi - -TITLE315="$BLUE 3.15$NORMAL Ensure security contact information is registered (Scored)" -# No command available -echo -e "\n$TITLE315 " -echo -e " $NOTICE No command available for check 3.15" -echo -e " Login to the AWS Console, click on My Account " -echo -e " Go to Alternate Contacts -> make sure Security section is filled $NORMAL" - -TITLE316="$BLUE 3.16$NORMAL Ensure appropriate subscribers to each SNS topic (Not Scored)" -echo -e "\n$TITLE316 " -for regx in $REGIONS; do - TOPICS_LIST=$($AWSCLI sns list-topics --profile $PROFILE --region $regx --output text --query 'Topics[*].TopicArn') - if [[ $TOPICS_LIST ]];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,Protocol:Protocol}' --output text) - if [[ $CHECK_TOPIC_LIST ]]; then - TOPIC_SHORT=$(echo $topic | awk -F: '{ print $7 }') - echo -e " $NOTICE Region $regx with Topic $TOPIC_SHORT: $NORMAL " - echo -e " $NOTICE - Suscription: $CHECK_TOPIC_LIST $NORMAL" - else - echo -e " $RED WARNING, No suscription found in Region $regx and Topic $topic $NORMAL" - fi - done - else - echo -e " $NOTICE Region $regx doesn't have topics $NORMAL" - fi -done +check31 +check32 +check33 +check34 +check35 +check36 +check37 +check38 +check39 +check310 +check311 +check312 +check313 +check314 +check315 +check316 TITLE4="$BLUE 4 Networking **************************************************$NORMAL" echo -e "\n\n$TITLE4 " +check41 +check42 +check43 +check44 -TITLE41="$BLUE 4.1$NORMAL Ensure no security groups allow ingress from 0.0.0.0/0 to port 22 (Scored)" -echo -e "\n$TITLE41 " -for regx in $REGIONS; do - SG_LIST=$($AWSCLI ec2 describe-security-groups --filters "Name=ip-permission.to-port,Values=22" --query 'SecurityGroups[?length(IpPermissions[?ToPort==`22` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupName: GroupName}' --profile $PROFILE --region $regx --output text) - if [[ $SG_LIST ]];then - for SG in $SG_LIST;do - echo -e " $RED Found Security Group: $SG open to 0.0.0.0/0 in Region $regx $NORMAL " - done - else - echo -e " $OK OK, No Security Groups found in $regx with port 22 TCP open to 0.0.0.0/0 $NORMAL " - fi -done - -TITLE42="$BLUE 4.2$NORMAL Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389 (Scored)" -echo -e "\n$TITLE42 " -for regx in $REGIONS; do - SG_LIST=$($AWSCLI ec2 describe-security-groups --filters "Name=ip-permission.to-port,Values=3389" --query 'SecurityGroups[?length(IpPermissions[?ToPort==`3389` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupName: GroupName}' --profile $PROFILE --region $regx --output text) - if [[ $SG_LIST ]];then - for SG in $SG_LIST;do - echo -e " $RED Found Security Group: $SG open to 0.0.0.0/0 in Region $regx $NORMAL " - done - else - echo -e " $OK OK, No Security Groups found in $regx with port 3389 TCP open to 0.0.0.0/0 $NORMAL " - fi -done - -TITLE43="$BLUE 4.3$NORMAL Ensure VPC Flow Logging is Enabled in all Applicable Regions (Scored)" -echo -e "\n$TITLE43 " -for regx in $REGIONS; do - CHECK_FL=$($AWSCLI ec2 describe-flow-logs --profile $PROFILE --region $regx --query 'FlowLogs[?FlowLogStatus==`ACTIVE`].LogGroupName' --output text) - if [[ $CHECK_FL ]];then - for FL in $CHECK_FL;do - echo -e " $OK OK, VPCFlowLog is enabled for LogGroupName: $FL in Region $regx $NORMAL " - done - else - echo -e " $RED WARNING, no VPCFlowLog has been found in Region $regx $NORMAL " - fi -done - -TITLE44="$BLUE 4.4$NORMAL Ensure the default security group restricts all traffic (Scored)" -echo -e "\n$TITLE44 " -#COMMAND44= Ensure the default security group restricts all traffic -#aws ec2 describe-security-groups --filters Name=group-name,Values='default' --profile internalmg --region us-east-1 - - -# Final +# Report review note: echo -e "\n$BLUE - For more information and reference:$NORMAL" echo -e " $NOTICE https://d0.awsstatic.com/whitepapers/compliance/AWS_CIS_Foundations_Benchmark.pdf$NORMAL"