From ecc08722e1d12b88b4ee53ebf938c1a1d353de50 Mon Sep 17 00:00:00 2001 From: "C.J" <31103058+zfLQ2qx2@users.noreply.github.com> Date: Tue, 12 Jan 2021 13:37:30 -0500 Subject: [PATCH] Handle shadow cloudtrails more gracefully --- checks/check21 | 43 ++++++++++++++++++++++--------------------- checks/check22 | 37 ++++++++++++++++++++++++------------- checks/check24 | 44 +++++++++++++++++++++++++++----------------- checks/check27 | 30 ++++++++++++++++++++++-------- 4 files changed, 95 insertions(+), 59 deletions(-) diff --git a/checks/check21 b/checks/check21 index eed98f61..d89c14cb 100644 --- a/checks/check21 +++ b/checks/check21 @@ -21,27 +21,28 @@ CHECK_ASFF_COMPLIANCE_TYPE_check21="ens-op.acc.7.aws.iam.1,ens-op.mon.1.aws.trai check21(){ trail_count=0 # "Ensure CloudTrail is enabled in all regions (Scored)" - for regx in $REGIONS; do - LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].Name' --output text --no-include-shadow-trails) - if [[ $LIST_OF_TRAILS ]];then - for trail in $LIST_OF_TRAILS;do - trail_count=$((trail_count + 1)) - MULTIREGION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].IsMultiRegionTrail' --output text --trail-name-list $trail) - if [[ "$MULTIREGION_TRAIL_STATUS" == 'False' ]];then - textFail "$trail trail in $regx is not enabled in multi region mode" - else - textPass "$trail trail in $regx is enabled for all regions" - fi - done - fi - done + for regx in $REGIONS; do + TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text | tr " " ',') + if [[ $TRAILS_AND_REGIONS ]]; then + for reg_trail in $TRAILS_AND_REGIONS; do + TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1) + if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region + continue + fi + trail=$(echo $reg_trail | cut -d',' -f2) + trail_count=$((trail_count + 1)) - if [[ $trail_count == 0 ]]; then - ORG_TRAIL=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region us-east-1 | jq '.trailList[] | select(.IsMultiRegionTrail and .IsOrganizationTrail) | .Name' | sed 's/"//g') - if [[ $ORG_TRAIL != "" ]]; then - textPass "$ORG_TRAIL trail in $regx is enabled for all regions" - else - textFail "No CloudTrail trails were found in the account" + MULTIREGION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].IsMultiRegionTrail' --output text --trail-name-list $trail) + if [[ "$MULTIREGION_TRAIL_STATUS" == 'False' ]];then + textFail "Trail $trail in $regx is not enabled for all regions" + else + textPass "Trail $trail in $regx is enabled for all regions" + fi + + done fi + done + if [[ $trail_count == 0 ]]; then + textFail "No CloudTrail trails were found in the account" fi -} \ No newline at end of file +} diff --git a/checks/check22 b/checks/check22 index 9deeb4c9..3acc072c 100644 --- a/checks/check22 +++ b/checks/check22 @@ -19,19 +19,30 @@ CHECK_ALTERNATE_check202="check22" CHECK_ASFF_COMPLIANCE_TYPE_check22="ens-op.exp.10.aws.trail.1" check22(){ + trail_count=0 # "Ensure CloudTrail log file validation is enabled (Scored)" + for regx in $REGIONS; do + TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text | tr " " ',') + if [[ $TRAILS_AND_REGIONS ]]; then + for reg_trail in $TRAILS_AND_REGIONS; do + TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1) + if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region + continue + fi + trail=$(echo $reg_trail | cut -d',' -f2) + trail_count=$((trail_count + 1)) - for regx in $REGIONS; do - LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].Name' --output text --no-include-shadow-trails) - if [[ $LIST_OF_TRAILS ]];then - for trail in $LIST_OF_TRAILS;do - LOGFILEVALIDATION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].LogFileValidationEnabled' --output text --trail-name-list $trail) - if [[ "$LOGFILEVALIDATION_TRAIL_STATUS" == 'False' ]];then - textFail "$trail trail in $regx has not log file validation enabled" - else - textPass "$trail trail in $regx has log file validation enabled" - fi - done - fi - done + LOGFILEVALIDATION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].LogFileValidationEnabled' --output text --trail-name-list $trail) + if [[ "$LOGFILEVALIDATION_TRAIL_STATUS" == 'False' ]];then + textFail "Trail $trail in $regx has not log file validation enabled" + else + textPass "Trail $trail in $regx has log file validation enabled" + fi + + done + fi + done + if [[ $trail_count == 0 ]]; then + textFail "No CloudTrail trails were found in the account" + fi } diff --git a/checks/check24 b/checks/check24 index 16f7cf7f..8ce255d3 100644 --- a/checks/check24 +++ b/checks/check24 @@ -19,26 +19,36 @@ CHECK_ALTERNATE_check204="check24" CHECK_ASFF_COMPLIANCE_TYPE_check24="ens-op.exp.8.aws.cw.1" check24(){ + trail_count=0 # "Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)" - TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $REGION --query 'trailList[*].{Name:Name, HomeRegion:HomeRegion}' --output text | tr " " ',') - if [[ $TRAILS_AND_REGIONS ]];then - for reg_trail in $TRAILS_AND_REGIONS;do - trail=$(echo $reg_trail | cut -d',' -f2) - TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1) - LATESTDELIVERY_TIMESTAMP=$($AWSCLI cloudtrail get-trail-status --name $trail $PROFILE_OPT --region $TRAIL_REGION --query 'LatestCloudWatchLogsDeliveryTime' --output text|grep -v None) - if [[ ! $LATESTDELIVERY_TIMESTAMP ]];then - textFail "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)" - else - LATESTDELIVERY_DATE=$(timestamp_to_date $LATESTDELIVERY_TIMESTAMP) - HOWOLDER=$(how_older_from_today $LATESTDELIVERY_DATE) - if [ $HOWOLDER -gt "1" ];then + for regx in $REGIONS; do + TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text | tr " " ',') + if [[ $TRAILS_AND_REGIONS ]]; then + for reg_trail in $TRAILS_AND_REGIONS; do + TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1) + if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region + continue + fi + trail=$(echo $reg_trail | cut -d',' -f2) + trail_count=$((trail_count + 1)) + + LATESTDELIVERY_TIMESTAMP=$($AWSCLI cloudtrail get-trail-status --name $trail $PROFILE_OPT --region $TRAIL_REGION --query 'LatestCloudWatchLogsDeliveryTime' --output text|grep -v None) + if [[ ! $LATESTDELIVERY_TIMESTAMP ]];then textFail "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)" else - textPass "$trail trail has been logging during the last 24h (it is in $TRAIL_REGION)" + LATESTDELIVERY_DATE=$(timestamp_to_date $LATESTDELIVERY_TIMESTAMP) + HOWOLDER=$(how_older_from_today $LATESTDELIVERY_DATE) + if [ $HOWOLDER -gt "1" ];then + textFail "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)" + else + textPass "$trail trail has been logging during the last 24h (it is in $TRAIL_REGION)" + fi fi - fi - done - else - textFail "No CloudTrail trails found!" + + done + fi + done + if [[ $trail_count == 0 ]]; then + textFail "No CloudTrail trails were found in the account" fi } diff --git a/checks/check27 b/checks/check27 index ba9caa83..b17b7838 100644 --- a/checks/check27 +++ b/checks/check27 @@ -19,16 +19,30 @@ CHECK_ALTERNATE_check207="check27" CHECK_ASFF_COMPLIANCE_TYPE_check27="ens-op.exp.10.aws.trail.5" check27(){ + trail_count=0 # "Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)" - $AWSCLI cloudtrail describe-trails --query 'trailList[].[Name,KmsKeyId]' --output text $PROFILE_OPT --region $REGION | while read trail key; do - if [[ "$trail" ]] ; then - if [[ "$key" != "None" ]] ; then - textPass "KMS key found for $trail" - else - textFail "Encryption is not enabled in your CloudTrail trail $trail (KMS key not found)!" + for regx in $REGIONS; do + TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text | tr " " ',') + if [[ $TRAILS_AND_REGIONS ]]; then + for reg_trail in $TRAILS_AND_REGIONS; do + TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1) + if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region + continue fi - else - textFail "CloudTrail bucket doesn't exist!" + trail=$(echo $reg_trail | cut -d',' -f2) + trail_count=$((trail_count + 1)) + + KMSKEYID=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].KmsKeyId' --output text --trail-name-list $trail) + if [[ "$KMSKEYID" == 'None' ]];then + textFail "Trail $trail in $regx has encryption disabled" + else + textPass "Trail $trail in $regx has encryption enabled" + fi + + done fi done + if [[ $trail_count == 0 ]]; then + textFail "No CloudTrail trails were found in the account" + fi }