From 6334e197305b069c02a6e4b63b61ecd62cd2698c Mon Sep 17 00:00:00 2001 From: Ben Allen Date: Mon, 26 Jun 2017 14:53:45 -0500 Subject: [PATCH] pull ID out of title, and pass it to text_title --- prowler | 270 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 162 insertions(+), 108 deletions(-) diff --git a/prowler b/prowler index 72555387..616c7ac1 100755 --- a/prowler +++ b/prowler @@ -240,21 +240,23 @@ fi # AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} # AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY_ID} +TITLE_ID="" ## Output formatting functions text_ok(){ - echo " $OK OK! $NORMAL $@" + echo " $TITLE_ID $OK OK! $NORMAL $@" } text_notice(){ - echo " $NOTICE NOTICE! $@ $NORMAL" + echo " $TITLE_ID $NOTICE INFO! $@ $NORMAL" } text_warn(){ - echo " $BAD WARNING! $@ $NORMAL" + echo " $TITLE_ID $BAD WARNING! $@ $NORMAL" } text_title(){ - echo -e "\n$@" + TITLE_ID=$1 + echo -e "\n$BLUE $TITLE_ID $NORMAL ${@:2}" } prowlerBanner() { @@ -333,21 +335,23 @@ infoReferenceShort(){ } check11(){ - TITLE11="$BLUE 1.1$NORMAL Avoid the use of the root account (Scored)." + ID11="1.1" + TITLE11="Avoid the use of the root account (Scored)." COMMAND11=$(cat $TEMP_REPORT_FILE| grep '' | cut -d, -f5,11,16 | sed 's/,/,\ /g') - text_title "$TITLE11" + text_title "$ID11" "$TITLE11" text_notice "Root account last accessed (password, key_1, key_2): $COMMAND11" } check12(){ - TITLE12="$BLUE 1.2$NORMAL Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)" + ID12="1.2" + TITLE12="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 -w $i| grep false | awk '{ print $1 }' done) - text_title "$TITLE12" + text_title "$ID12" "$TITLE12" if [[ $COMMAND12 ]]; then for u in $COMMAND12; do text_warn "User $u has Password enabled but MFA disabled" @@ -358,8 +362,9 @@ check12(){ } check13(){ - TITLE13="$BLUE 1.3$NORMAL Ensure credentials unused for 90 days or greater are disabled (Scored)" - text_title "$TITLE13" + ID13="1.3" + TITLE13="Ensure credentials unused for 90 days or greater are disabled (Scored)" + text_title "$ID13" "$TITLE13" COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$4 }' |grep true | awk '{ print $1 }') if [[ $COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED ]]; then COMMAND13=$( @@ -387,10 +392,11 @@ check13(){ } check14(){ - TITLE14="$BLUE 1.4$NORMAL Ensure access keys are rotated every 90 days or less (Scored)" # also checked by Security Monkey + ID14="1.4" + TITLE14="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 }') - text_title "$TITLE14" + text_title "$ID14" "$TITLE14" C14_NUM_USERS1=0 C14_NUM_USERS2=0 # $(expr $C116_NUM_USERS + 1) @@ -433,9 +439,10 @@ check14(){ } check15(){ - TITLE15="$BLUE 1.5$NORMAL Ensure IAM password policy requires at least one uppercase letter (Scored)" + ID15="1.5" + TITLE15="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 - text_title "$TITLE15" + text_title "$ID15" "$TITLE15" if [[ $COMMAND15 == "true" ]];then text_ok "Password Policy requires upper case" else @@ -444,9 +451,10 @@ check15(){ } check16(){ - TITLE16="$BLUE 1.6$NORMAL Ensure IAM password policy require at least one lowercase letter (Scored)" + ID16="1.6" + TITLE16="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 - text_title "$TITLE16" + text_title "$ID16" "$TITLE16" if [[ $COMMAND16 == "true" ]];then text_ok "Password Policy requires lower case" else @@ -455,9 +463,10 @@ check16(){ } check17(){ - TITLE17="$BLUE 1.7$NORMAL Ensure IAM password policy require at least one symbol (Scored)" + ID17="1.7" + TITLE17="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 - text_title "$TITLE17" + text_title "$ID17" "$TITLE17" if [[ $COMMAND17 == "true" ]];then text_ok "Password Policy requires symbol" else @@ -466,9 +475,10 @@ check17(){ } check18(){ - TITLE18="$BLUE 1.8$NORMAL Ensure IAM password policy require at least one number (Scored)" + ID18="1.8" + TITLE18="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 - text_title "$TITLE18" + text_title "$ID18" "$TITLE18" if [[ $COMMAND18 == "true" ]];then text_ok "Password Policy requires number" else @@ -477,9 +487,10 @@ check18(){ } check19(){ - TITLE19="$BLUE 1.9$NORMAL Ensure IAM password policy requires minimum length of 14 or greater (Scored)" + ID19="1.9" + TITLE19="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') - text_title "$TITLE19" + text_title "$ID19" "$TITLE19" if [[ $COMMAND19 -gt "13" ]];then text_ok "Password Policy requires more than 13 characters" else @@ -488,9 +499,10 @@ check19(){ } check110(){ - TITLE110="$BLUE 1.10$NORMAL Ensure IAM password policy prevents password reuse (Scored)" + ID110="1.10" + TITLE110="Ensure IAM password policy prevents password reuse (Scored)" COMMAND110=$($AWSCLI iam get-account-password-policy --profile $PROFILE --region $REGION --query 'PasswordPolicy.PasswordReusePrevention' --output text) - text_title "$TITLE110" + text_title "$ID110" "$TITLE110" if [[ $COMMAND110 ]];then if [[ $COMMAND110 -gt "23" ]];then text_ok "Password Policy limits reuse" @@ -503,9 +515,10 @@ check110(){ } check111(){ - TITLE111="$BLUE 1.11$NORMAL Ensure IAM password policy expires passwords within 90 days or less (Scored)" + ID111="1.11" + TITLE111="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') - text_title "$TITLE111" + text_title "$ID111" "$TITLE111" if [[ $COMMAND111 ]];then if [ $COMMAND111 == "90" ];then text_ok "Password Policy includes expiration" @@ -516,11 +529,12 @@ check111(){ } check112(){ - TITLE112="$BLUE 1.12$NORMAL Ensure no root account access key exists (Scored)" + ID112="1.12" + TITLE112="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 }') - text_title "$TITLE112" + text_title "$ID112" "$TITLE112" if [ $ROOTKEY1 == "false" ];then text_ok "No access key 1 found for root" else @@ -534,9 +548,10 @@ check112(){ } check113(){ - TITLE113="$BLUE 1.13$NORMAL Ensure MFA is enabled for the root account (Scored)" + ID113="1.13" + TITLE113="Ensure MFA is enabled for the root account (Scored)" COMMAND113=$($AWSCLI iam get-account-summary --profile $PROFILE --region $REGION |grep AccountMFAEnabled | awk -F': ' '{ print $2 }'|sed 's/,//') - text_title "$TITLE113" + text_title "$ID113" "$TITLE113" if [ $COMMAND113 == "1" ]; then text_ok "Virtual MFA is enabled for root" else @@ -545,9 +560,10 @@ check113(){ } check114(){ - TITLE114="$BLUE 1.14$NORMAL Ensure hardware MFA is enabled for the root account (Scored)" + ID114="1.14" + TITLE114="Ensure hardware MFA is enabled for the root account (Scored)" COMMAND113=$($AWSCLI iam get-account-summary --profile $PROFILE --region $REGION |grep AccountMFAEnabled | awk -F': ' '{ print $2 }'|sed 's/,//') - text_title "$TITLE114" + text_title "$ID114" "$TITLE114" if [ $COMMAND113 == "1" ]; then COMMAND114=$($AWSCLI iam list-virtual-mfa-devices --profile $PROFILE --region $REGION --query 'VirtualMFADevices' --output text|grep :root |wc -l) if [ $COMMAND114 == "1" ]; then @@ -561,17 +577,19 @@ check114(){ } check115(){ - TITLE115="$BLUE 1.15$NORMAL Ensure security questions are registered in the AWS account (Not Scored)" + ID115="1.15" + TITLE115="Ensure security questions are registered in the AWS account (Not Scored)" # No command available - text_title "$TITLE115" + text_title "$ID115" "$TITLE115" text_notice "No command available for check 1.15 " text_notice "Login to the AWS Console as root, click on the Account " text_notice "Name -> My Account -> Configure Security Challenge Questions " } check116(){ - TITLE116="$BLUE 1.16$NORMAL Ensure IAM policies are attached only to groups or roles (Scored)" - text_title "$TITLE116" + ID116="1.16" + TITLE116="Ensure IAM policies are attached only to groups or roles (Scored)" + text_title "$ID116" "$TITLE116" LIST_USERS=$($AWSCLI iam list-users --query 'Users[*].UserName' --output text --profile $PROFILE --region $REGION) C116_NUM_USERS=0 for user in $LIST_USERS;do @@ -587,17 +605,19 @@ check116(){ } check117(){ - TITLE117="$BLUE 1.17$NORMAL Enable detailed billing (Scored)" + ID117="1.17" + TITLE117="Enable detailed billing (Scored)" # No command available - text_title "$TITLE117" + text_title "$ID117" "$TITLE117" text_notice "No command available for check 1.17 " text_notice "See section 1.17 on the CIS Benchmark guide for details " infoReferenceShort } check118(){ - TITLE118="$BLUE 1.18$NORMAL Ensure IAM Master and IAM Manager roles are active (Scored)" - text_title "$TITLE118" + ID118="1.18" + TITLE118="Ensure IAM Master and IAM Manager roles are active (Scored)" + text_title "$ID118" "$TITLE118" FINDMASTERANDMANAGER=$($AWSCLI iam list-roles --profile $PROFILE --region $REGION --query "Roles[*].{RoleName:RoleName}" --output text | grep -E 'Master|Manager'| tr '\n' ' ') if [[ $FINDMASTERANDMANAGER ]];then text_notice "Found next roles as possible IAM Master and IAM Manager candidates: " @@ -621,34 +641,38 @@ check118(){ } check119(){ - TITLE119="$BLUE 1.19$NORMAL Maintain current contact details (Scored)" + ID119="1.19" + TITLE119="Maintain current contact details (Scored)" # No command available - text_title "$TITLE119" + text_title "$ID119" "$TITLE119" text_notice "No command available for check 1.19 " text_notice "See section 1.19 on the CIS Benchmark guide for details " infoReferenceShort } check120(){ - TITLE120="$BLUE 1.20$NORMAL Ensure security contact information is registered (Scored)" + ID120="1.20" + TITLE120="Ensure security contact information is registered (Scored)" # No command available - text_title "$TITLE120" + text_title "$ID120" "$TITLE120" text_notice "No command available for check 1.20 " text_notice "See section 1.20 on the CIS Benchmark guide for details " infoReferenceShort } check121(){ - TITLE121="$BLUE 1.21$NORMAL Ensure IAM instance roles are used for AWS resource access from instances (Not Scored)" - text_title "$TITLE121" + ID121="1.21" + TITLE121="Ensure IAM instance roles are used for AWS resource access from instances (Not Scored)" + text_title "$ID121" "$TITLE121" text_notice "No command available for check 1.21 " text_notice "See section 1.21 on the CIS Benchmark guide for details " infoReferenceShort } check122(){ - TITLE122="$BLUE 1.22$NORMAL Ensure a support role has been created to manage incidents with AWS Support (Scored)" - text_title "$TITLE122" + ID122="1.22" + TITLE122="Ensure a support role has been created to manage incidents with AWS Support (Scored)" + text_title "$ID122" "$TITLE122" SUPPORTPOLICYARN=$($AWSCLI iam list-policies --query "Policies[?PolicyName == 'AWSSupportAccess'].Arn" --profile $PROFILE --region $REGION --output text) if [[ $SUPPORTPOLICYARN ]];then for policyarn in $SUPPORTPOLICYARN;do @@ -666,8 +690,9 @@ check122(){ } check123(){ - TITLE123="$BLUE 1.23$NORMAL Do not setup access keys during initial user setup for all IAM users that have a console password (Not Scored)" - text_title "$TITLE123" + ID123="1.23" + TITLE123="Do not setup access keys during initial user setup for all IAM users that have a console password (Not Scored)" + text_title "$ID123" "$TITLE123" LIST_USERS=$($AWSCLI iam list-users --query 'Users[*].UserName' --output text --profile $PROFILE --region $REGION) # List of USERS with KEY1 last_used_date as N/A LIST_USERS_KEY1_NA=$(for user in $LIST_USERS; do grep $user $TEMP_REPORT_FILE|awk -F, '{ print $1,$11 }'|grep N/A |awk '{ print $1 }'; done) @@ -690,8 +715,9 @@ check123(){ } check124(){ - TITLE124="$BLUE 1.24$NORMAL Ensure IAM policies that allow full \"*:*\" administrative privileges are not created (Scored)" - text_title "$TITLE124" + ID124="1.24" + TITLE124="Ensure IAM policies that allow full \"*:*\" administrative privileges are not created (Scored)" + text_title "$ID124" "$TITLE124" LIST_CUSTOM_POLICIES=$($AWSCLI iam list-policies --output text --profile $PROFILE --region $REGION|grep 'arn:aws:iam::[0-9]\{12\}:'|awk '{ print $2 }') if [[ $LIST_CUSTOM_POLICIES ]]; then text_notice "Looking for custom policies: (skipping default policies, it may take few seconds...)" @@ -716,8 +742,9 @@ check124(){ } check21(){ - TITLE21="$BLUE 2.1$NORMAL Ensure CloudTrail is enabled in all regions (Scored)" - text_title "$TITLE21" + ID21="2.1" + TITLE21="Ensure CloudTrail is enabled in all regions (Scored)" + text_title "$ID21" "$TITLE21" 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 @@ -734,8 +761,9 @@ check21(){ } check22(){ - TITLE22="$BLUE 2.2$NORMAL Ensure CloudTrail log file validation is enabled (Scored)" - text_title "$TITLE22" + ID22="2.2" + TITLE22="Ensure CloudTrail log file validation is enabled (Scored)" + text_title "$ID22" "$TITLE22" 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 @@ -752,8 +780,9 @@ check22(){ } check23(){ - TITLE23="$BLUE 2.3$NORMAL Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)" - text_title "$TITLE23" + ID23="2.3" + TITLE23="Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)" + text_title "$ID23" "$TITLE23" CLOUDTRAILBUCKET=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].S3BucketName' --output text --profile $PROFILE --region $REGION) if [[ $CLOUDTRAILBUCKET ]];then for bucket in $CLOUDTRAILBUCKET;do @@ -770,8 +799,9 @@ check23(){ } check24(){ - TITLE24="$BLUE 2.4$NORMAL Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)" - text_title "$TITLE24" + ID24="2.4" + TITLE24="Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)" + text_title "$ID24" "$TITLE24" TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails --profile $PROFILE --region $REGION --query 'trailList[*].{Name:Name, HomeRegion:HomeRegion}' --output text | tr "\t" ',') if [[ $TRAILS_AND_REGIONS ]];then for reg_trail in $TRAILS_AND_REGIONS;do @@ -796,8 +826,9 @@ check24(){ } check25(){ - TITLE25="$BLUE 2.5$NORMAL Ensure AWS Config is enabled in all regions (Scored)" - text_title "$TITLE25" + ID25="2.5" + TITLE25="Ensure AWS Config is enabled in all regions (Scored)" + text_title "$ID25" "$TITLE25" for regx in $REGIONS; do CHECK_AWSCONFIG_STATUS=$($AWSCLI configservice get-status --profile $PROFILE --region $regx | grep "recorder: ON") if [[ $CHECK_AWSCONFIG_STATUS ]];then @@ -809,8 +840,9 @@ check25(){ } check26(){ - TITLE26="$BLUE 2.6$NORMAL Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Scored)" - text_title "$TITLE26" + ID26="2.6" + TITLE26="Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Scored)" + text_title "$ID26" "$TITLE26" CLOUDTRAILBUCKET=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].S3BucketName' --output text --profile $PROFILE --region $REGION) if [[ $CLOUDTRAILBUCKET ]];then for bucket in $CLOUDTRAILBUCKET;do @@ -827,8 +859,9 @@ check26(){ } check27(){ - TITLE27="$BLUE 2.7$NORMAL Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)" - text_title "$TITLE27" + ID27="2.7" + TITLE27="Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)" + text_title "$ID27" "$TITLE27" CLOUDTRAILNAME=$($AWSCLI cloudtrail describe-trails --query 'trailList[*].Name' --output text --profile $PROFILE --region $REGION) if [[ $CLOUDTRAILNAME ]];then for trail in $CLOUDTRAILNAME;do @@ -845,8 +878,9 @@ check27(){ } check28(){ - TITLE28="$BLUE 2.8$NORMAL Ensure rotation for customer created CMKs is enabled (Scored)" - text_title "$TITLE28" + ID28="2.8" + TITLE28="Ensure rotation for customer created CMKs is enabled (Scored)" + text_title "$ID28" "$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 @@ -875,8 +909,9 @@ check28(){ } check31(){ - TITLE31="$BLUE 3.1$NORMAL Ensure a log metric filter and alarm exist for unauthorized API calls (Scored)" - text_title "$TITLE31" + ID31="3.1" + TITLE31="Ensure a log metric filter and alarm exist for unauthorized API calls (Scored)" + text_title "$ID31" "$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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep AccessDenied) @@ -891,8 +926,9 @@ check31(){ } check32(){ - TITLE32="$BLUE 3.2$NORMAL Ensure a log metric filter and alarm exist for Management Console sign-in without MFA (Scored)" - text_title "$TITLE32" + ID32="3.2" + TITLE32="Ensure a log metric filter and alarm exist for Management Console sign-in without MFA (Scored)" + text_title "$ID32" "$TITLE32" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'userIdentity.sessionContext.attributes.mfaAuthenticated.*true') @@ -907,8 +943,9 @@ check32(){ } check33(){ - TITLE33="$BLUE 3.3$NORMAL Ensure a log metric filter and alarm exist for usage of root account (Scored)" - text_title "$TITLE33" + ID33="3.3" + TITLE33="Ensure a log metric filter and alarm exist for usage of root account (Scored)" + text_title "$ID33" "$TITLE33" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION |grep -E 'userIdentity.*Root.*AwsServiceEvent') @@ -923,8 +960,9 @@ check33(){ } check34(){ - TITLE34="$BLUE 3.4$NORMAL Ensure a log metric filter and alarm exist for IAM policy changes (Scored)" - text_title "$TITLE34" + ID34="3.4" + TITLE34="Ensure a log metric filter and alarm exist for IAM policy changes (Scored)" + text_title "$ID34" "$TITLE34" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'DeleteGroupPolicy.*DeleteRolePolicy.*DeleteUserPolicy.*PutGroupPolicy.*PutRolePolicy.*PutUserPolicy.*CreatePolicy.*DeletePolicy.*CreatePolicyVersion.*DeletePolicyVersion.*AttachRolePolicy.*DetachRolePolicy.*AttachUserPolicy.*DetachUserPolicy.*AttachGroupPolicy.*DetachGroupPolicy') @@ -939,8 +977,9 @@ check34(){ } check35(){ - TITLE35="$BLUE 3.5$NORMAL Ensure a log metric filter and alarm exist for CloudTrail configuration changes (Scored)" - text_title "$TITLE35" + ID35="3.5" + TITLE35="Ensure a log metric filter and alarm exist for CloudTrail configuration changes (Scored)" + text_title "$ID35" "$TITLE35" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'CreateTrail.*UpdateTrail.*DeleteTrail.*StartLogging.*StopLogging') @@ -955,8 +994,9 @@ check35(){ } check36(){ - TITLE36="$BLUE 3.6$NORMAL Ensure a log metric filter and alarm exist for AWS Management Console authentication failures (Scored)" - text_title "$TITLE36" + ID36="3.6" + TITLE36="Ensure a log metric filter and alarm exist for AWS Management Console authentication failures (Scored)" + text_title "$ID36" "$TITLE36" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'ConsoleLogin.*Failed') @@ -971,8 +1011,9 @@ check36(){ } check37(){ - TITLE37="$BLUE 3.7$NORMAL Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs (Scored)" - text_title "$TITLE37" + ID37="3.7" + TITLE37="Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs (Scored)" + text_title "$ID37" "$TITLE37" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'kms.amazonaws.com.*DisableKey.*ScheduleKeyDeletion') @@ -987,8 +1028,9 @@ check37(){ } check38(){ - TITLE38="$BLUE 3.8$NORMAL Ensure a log metric filter and alarm exist for S3 bucket policy changes (Scored)" - text_title "$TITLE38" + ID38="3.8" + TITLE38="Ensure a log metric filter and alarm exist for S3 bucket policy changes (Scored)" + text_title "$ID38" "$TITLE38" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 's3.amazonaws.com.*PutBucketAcl.*PutBucketPolicy.*PutBucketCors.*PutBucketLifecycle.*PutBucketReplication.*DeleteBucketPolicy.*DeleteBucketCors.*DeleteBucketLifecycle.*DeleteBucketReplication') @@ -1003,8 +1045,9 @@ check38(){ } check39(){ - TITLE39="$BLUE 3.9$NORMAL Ensure a log metric filter and alarm exist for AWS Config configuration changes (Scored)" - text_title "$TITLE39" + ID39="3.9" + TITLE39="Ensure a log metric filter and alarm exist for AWS Config configuration changes (Scored)" + text_title "$ID39" "$TITLE39" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'config.amazonaws.com.*StopConfigurationRecorder.*DeleteDeliveryChannel.*PutDeliveryChannel.*PutConfigurationRecorder') @@ -1019,8 +1062,9 @@ check39(){ } check310(){ - TITLE310="$BLUE 3.10$NORMAL Ensure a log metric filter and alarm exist for security group changes (Scored)" - text_title "$TITLE310" + ID310="3.10" + TITLE310="Ensure a log metric filter and alarm exist for security group changes (Scored)" + text_title "$ID310" "$TITLE310" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'AuthorizeSecurityGroupIngress.*AuthorizeSecurityGroupEgress.*RevokeSecurityGroupIngress.*RevokeSecurityGroupEgress.*CreateSecurityGroup.*DeleteSecurityGroup') @@ -1035,8 +1079,9 @@ check310(){ } check311(){ - TITLE311="$BLUE 3.11$NORMAL Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) (Scored)" - text_title "$TITLE311" + ID311="3.11" + TITLE311="Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) (Scored)" + text_title "$ID311" "$TITLE311" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'CreateNetworkAcl.*CreateNetworkAclEntry.*DeleteNetworkAcl.*DeleteNetworkAclEntry.*ReplaceNetworkAclEntry.*ReplaceNetworkAclAssociation') @@ -1051,8 +1096,9 @@ check311(){ } check312(){ - TITLE312="$BLUE 3.12$NORMAL Ensure a log metric filter and alarm exist for changes to network gateways (Scored)" - text_title "$TITLE312" + ID312="3.12" + TITLE312="Ensure a log metric filter and alarm exist for changes to network gateways (Scored)" + text_title "$ID312" "$TITLE312" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'CreateCustomerGateway.*DeleteCustomerGateway.*AttachInternetGateway.*CreateInternetGateway.*DeleteInternetGateway.*DetachInternetGateway') @@ -1067,8 +1113,9 @@ check312(){ } check313(){ - TITLE313="$BLUE 3.13$NORMAL Ensure a log metric filter and alarm exist for route table changes (Scored)" - text_title "$TITLE313" + ID313="3.13" + TITLE313="Ensure a log metric filter and alarm exist for route table changes (Scored)" + text_title "$ID313" "$TITLE313" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'CreateRoute.*CreateRouteTable.*ReplaceRoute.*ReplaceRouteTableAssociation.*DeleteRouteTable.*DeleteRoute.*DisassociateRouteTable') @@ -1083,8 +1130,9 @@ check313(){ } check314(){ - TITLE314="$BLUE 3.14$NORMAL Ensure a log metric filter and alarm exist for VPC changes (Scored)" - text_title "$TITLE314" + ID314="3.14" + TITLE314="Ensure a log metric filter and alarm exist for VPC changes (Scored)" + text_title "$ID314" "$TITLE314" 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 $CLOUDWATCH_GROUP --profile $PROFILE --region $REGION --query 'metricFilters' | grep -E 'CreateVpc.*DeleteVpc.*ModifyVpcAttribute.*AcceptVpcPeeringConnection.*CreateVpcPeeringConnection.*DeleteVpcPeeringConnection.*RejectVpcPeeringConnection.*AttachClassicLinkVpc.*DetachClassicLinkVpc.*DisableVpcClassicLink.*EnableVpcClassicLink') @@ -1099,8 +1147,9 @@ check314(){ } check315(){ - TITLE315="$BLUE 3.15$NORMAL Ensure appropriate subscribers to each SNS topic (Not Scored)" - text_title "$TITLE315" + ID315="3.15" + TITLE315="Ensure appropriate subscribers to each SNS topic (Not Scored)" + text_title "$ID315" "$TITLE315" for regx in $REGIONS; do TOPICS_LIST=$($AWSCLI sns list-topics --profile $PROFILE --region $regx --output text --query 'Topics[*].TopicArn') if [[ $TOPICS_LIST ]];then @@ -1122,8 +1171,9 @@ check315(){ } check41(){ - TITLE41="$BLUE 4.1$NORMAL Ensure no security groups allow ingress from 0.0.0.0/0 to port 22 (Scored)" - text_title "$TITLE41" + ID41="4.1" + TITLE41="Ensure no security groups allow ingress from 0.0.0.0/0 to port 22 (Scored)" + text_title "$ID41" "$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 @@ -1137,8 +1187,9 @@ check41(){ } check42(){ - TITLE42="$BLUE 4.2$NORMAL Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389 (Scored)" - text_title "$TITLE42" + ID42="4.2" + TITLE42="Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389 (Scored)" + text_title "$ID42" "$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 @@ -1152,8 +1203,9 @@ check42(){ } check43(){ - TITLE43="$BLUE 4.3$NORMAL Ensure VPC Flow Logging is Enabled in all VPCs (Scored)" - text_title "$TITLE43" + ID43="4.3" + TITLE43="Ensure VPC Flow Logging is Enabled in all VPCs (Scored)" + text_title "$ID43" "$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 @@ -1167,8 +1219,9 @@ check43(){ } check44(){ - TITLE44="$BLUE 4.4$NORMAL Ensure the default security group of every VPC restricts all traffic (Scored)" - text_title "$TITLE44" + ID44="4.4" + TITLE44="Ensure the default security group of every VPC restricts all traffic (Scored)" + text_title "$ID44" "$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 @@ -1181,8 +1234,9 @@ check44(){ check45(){ #set -xe - TITLE45="$BLUE 4.5$NORMAL Ensure routing tables for VPC peering are \"least access\" (Not Scored)" - text_title "$TITLE45" + ID45="4.5" + TITLE45="Ensure routing tables for VPC peering are \"least access\" (Not Scored)" + text_title "$ID45" "$TITLE45" text_notice "Looking for VPC peering in all regions... " for regx in $REGIONS; do LIST_OF_VPCS_PEERING_CONNECTIONS=$($AWSCLI ec2 describe-vpc-peering-connections --output text --profile $PROFILE --region $regx --query 'VpcPeeringConnections[*].VpcPeeringConnectionId')