mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
changed outputs to the new ones
This commit is contained in:
@@ -6,5 +6,5 @@ CHECK_ALTERNATE_check101="check11"
|
||||
check11(){
|
||||
# "Avoid the use of the root account (Scored)."
|
||||
COMMAND11=$(cat $TEMP_REPORT_FILE| grep '<root_account>' | cut -d, -f5,11,16 | sed 's/,/\ /g')
|
||||
textNotice "Root account last accessed (password key_1 key_2): $COMMAND11"
|
||||
textInfo "Root account last accessed (password key_1 key_2): $COMMAND11"
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ check110(){
|
||||
COMMAND110=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --query 'PasswordPolicy.PasswordReusePrevention' --output text 2> /dev/null)
|
||||
if [[ $COMMAND110 ]];then
|
||||
if [[ $COMMAND110 -gt "23" ]];then
|
||||
textOK "Password Policy limits reuse"
|
||||
textPass "Password Policy limits reuse"
|
||||
else
|
||||
textWarn "Password Policy has weak reuse requirement (lower than 24)"
|
||||
textFail "Password Policy has weak reuse requirement (lower than 24)"
|
||||
fi
|
||||
else
|
||||
textWarn "Password Policy missing reuse requirement"
|
||||
textFail "Password Policy missing reuse requirement"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ check111(){
|
||||
COMMAND111=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json | grep MaxPasswordAge | awk -F: '{ print $2 }'|sed 's/\ //g'|sed 's/,/ /g' 2> /dev/null)
|
||||
if [[ $COMMAND111 ]];then
|
||||
if [ "$COMMAND111" == "90" ];then
|
||||
textOK "Password Policy includes expiration"
|
||||
textPass "Password Policy includes expiration"
|
||||
fi
|
||||
else
|
||||
textWarn "Password expiration not set or set greater than 90 days "
|
||||
textFail "Password expiration not set or set greater than 90 days "
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ check112(){
|
||||
ROOTKEY1=$(cat $TEMP_REPORT_FILE |grep root_account|awk -F',' '{ print $9 }')
|
||||
ROOTKEY2=$(cat $TEMP_REPORT_FILE |grep root_account|awk -F',' '{ print $14 }')
|
||||
if [ "$ROOTKEY1" == "false" ];then
|
||||
textOK "No access key 1 found for root"
|
||||
textPass "No access key 1 found for root"
|
||||
else
|
||||
textWarn "Found access key 1 for root "
|
||||
textFail "Found access key 1 for root "
|
||||
fi
|
||||
if [ "$ROOTKEY2" == "false" ];then
|
||||
textOK "No access key 2 found for root"
|
||||
textPass "No access key 2 found for root"
|
||||
else
|
||||
textWarn "Found access key 2 for root "
|
||||
textFail "Found access key 2 for root "
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ check113(){
|
||||
# "Ensure MFA is enabled for the root account (Scored)"
|
||||
COMMAND113=$($AWSCLI iam get-account-summary $PROFILE_OPT --region $REGION --output json --query 'SummaryMap.AccountMFAEnabled')
|
||||
if [ "$COMMAND113" == "1" ]; then
|
||||
textOK "Virtual MFA is enabled for root"
|
||||
textPass "Virtual MFA is enabled for root"
|
||||
else
|
||||
textWarn "MFA is not ENABLED for root account "
|
||||
textFail "MFA is not ENABLED for root account "
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ check114(){
|
||||
if [ "$COMMAND113" == "1" ]; then
|
||||
COMMAND114=$($AWSCLI iam list-virtual-mfa-devices $PROFILE_OPT --region $REGION --output text --assignment-status Assigned --query 'VirtualMFADevices[*].[SerialNumber]' | grep '^arn:aws:iam::[0-9]\{12\}:mfa/root-account-mfa-device$')
|
||||
if [[ "$COMMAND114" ]]; then
|
||||
textWarn "Only Virtual MFA is enabled for root"
|
||||
textFail "Only Virtual MFA is enabled for root"
|
||||
else
|
||||
textOK "Hardware MFA is enabled for root "
|
||||
textPass "Hardware MFA is enabled for root "
|
||||
fi
|
||||
else
|
||||
textWarn "MFA is not ENABLED for root account "
|
||||
textFail "MFA is not ENABLED for root account "
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ CHECK_ALTERNATE_check115="check115"
|
||||
|
||||
check115(){
|
||||
# "Ensure security questions are registered in the AWS account (Not Scored)"
|
||||
textNotice "No command available for check 1.15 "
|
||||
textNotice "Login to the AWS Console as root & click on the Account "
|
||||
textNotice "Name -> My Account -> Configure Security Challenge Questions "
|
||||
textInfo "No command available for check 1.15 "
|
||||
textInfo "Login to the AWS Console as root & click on the Account "
|
||||
textInfo "Name -> My Account -> Configure Security Challenge Questions "
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ check116(){
|
||||
for user in $LIST_USERS;do
|
||||
USER_POLICY=$($AWSCLI iam list-attached-user-policies --output text $PROFILE_OPT --region $REGION --user-name $user)
|
||||
if [[ $USER_POLICY ]]; then
|
||||
textWarn "$user has policy directly attached "
|
||||
textFail "$user has policy directly attached "
|
||||
C116_NUM_USERS=$(expr $C116_NUM_USERS + 1)
|
||||
fi
|
||||
done
|
||||
if [[ $C116_NUM_USERS -eq 0 ]]; then
|
||||
textOK "No policies attached to users."
|
||||
textPass "No policies attached to users."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ CHECK_ALTERNATE_check117="check117"
|
||||
check117(){
|
||||
# "Enable detailed billing (Scored)"
|
||||
# No command available
|
||||
textNotice "No command available for check 1.17 "
|
||||
textNotice "See section 1.17 on the CIS Benchmark guide for details "
|
||||
textInfo "No command available for check 1.17 "
|
||||
textInfo "See section 1.17 on the CIS Benchmark guide for details "
|
||||
}
|
||||
|
||||
@@ -8,22 +8,22 @@ check118(){
|
||||
FINDMASTERANDMANAGER=$($AWSCLI iam list-roles $PROFILE_OPT --region $REGION --query "Roles[*].{RoleName:RoleName}" --output text | grep -E 'Master|Manager'| tr '
|
||||
' ' ')
|
||||
if [[ $FINDMASTERANDMANAGER ]];then
|
||||
textNotice "Found next roles as possible IAM Master and IAM Manager candidates: "
|
||||
textNotice "$FINDMASTERANDMANAGER "
|
||||
textNotice "run the commands below to check their policies with section 1.18 in the guide..."
|
||||
textInfo "Found next roles as possible IAM Master and IAM Manager candidates: "
|
||||
textInfo "$FINDMASTERANDMANAGER "
|
||||
textInfo "run the commands below to check their policies with section 1.18 in the guide..."
|
||||
for role in $FINDMASTERANDMANAGER;do
|
||||
# find inline policies in found roles
|
||||
INLINEPOLICIES=$($AWSCLI iam list-role-policies --role-name $role $PROFILE_OPT --region $REGION --query "PolicyNames[*]" --output text)
|
||||
for policy in $INLINEPOLICIES;do
|
||||
textNotice "INLINE: $AWSCLI iam get-role-policy --role-name $role --policy-name $policy $PROFILE_OPT --region $REGION --output json"
|
||||
textInfo "INLINE: $AWSCLI iam get-role-policy --role-name $role --policy-name $policy $PROFILE_OPT --region $REGION --output json"
|
||||
done
|
||||
# find attached policies in found roles
|
||||
ATTACHEDPOLICIES=$($AWSCLI iam list-attached-role-policies --role-name $role $PROFILE_OPT --region $REGION --query "AttachedPolicies[*]" --output text)
|
||||
for policy in $ATTACHEDPOLICIES;do
|
||||
textNotice "ATTACHED: $AWSCLI iam get-role-policy --role-name $role --policy-name $policy $PROFILE_OPT --region $REGION --output json"
|
||||
textInfo "ATTACHED: $AWSCLI iam get-role-policy --role-name $role --policy-name $policy $PROFILE_OPT --region $REGION --output json"
|
||||
done
|
||||
done
|
||||
else
|
||||
textWarn "IAM Master and IAM Manager roles not found"
|
||||
textFail "IAM Master and IAM Manager roles not found"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ CHECK_ALTERNATE_check119="check119"
|
||||
check119(){
|
||||
# "Maintain current contact details (Scored)"
|
||||
# No command available
|
||||
textNotice "No command available for check 1.19 "
|
||||
textNotice "See section 1.19 on the CIS Benchmark guide for details "
|
||||
textInfo "No command available for check 1.19 "
|
||||
textInfo "See section 1.19 on the CIS Benchmark guide for details "
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ check12(){
|
||||
done)
|
||||
if [[ $COMMAND12 ]]; then
|
||||
for u in $COMMAND12; do
|
||||
textWarn "User $u has Password enabled but MFA disabled"
|
||||
textFail "User $u has Password enabled but MFA disabled"
|
||||
done
|
||||
else
|
||||
textOK "No users found with Password enabled and MFA disabled"
|
||||
textPass "No users found with Password enabled and MFA disabled"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ CHECK_ALTERNATE_check120="check120"
|
||||
check120(){
|
||||
# "Ensure security contact information is registered (Scored)"
|
||||
# No command available
|
||||
textNotice "No command available for check 1.20 "
|
||||
textNotice "See section 1.20 on the CIS Benchmark guide for details "
|
||||
textInfo "No command available for check 1.20 "
|
||||
textInfo "See section 1.20 on the CIS Benchmark guide for details "
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@ CHECK_ALTERNATE_check121="check121"
|
||||
|
||||
check121(){
|
||||
# "Ensure IAM instance roles are used for AWS resource access from instances (Not Scored)"
|
||||
textNotice "No command available for check 1.21 "
|
||||
textNotice "See section 1.21 on the CIS Benchmark guide for details "
|
||||
textInfo "No command available for check 1.21 "
|
||||
textInfo "See section 1.21 on the CIS Benchmark guide for details "
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ check122(){
|
||||
for policyarn in $SUPPORTPOLICYARN;do
|
||||
POLICYUSERS=$($AWSCLI iam list-entities-for-policy --policy-arn $SUPPORTPOLICYARN $PROFILE_OPT --region $REGION --output json)
|
||||
if [[ $POLICYUSERS ]];then
|
||||
textOK "Support Policy attached to $policyarn"
|
||||
textPass "Support Policy attached to $policyarn"
|
||||
for user in $(echo "$POLICYUSERS" | grep UserName | cut -d'"' -f4) ; do
|
||||
textNotice "User $user has support access via $policyarn"
|
||||
textInfo "User $user has support access via $policyarn"
|
||||
done
|
||||
# textNotice "Make sure your team can create a Support case with AWS "
|
||||
# textInfo "Make sure your team can create a Support case with AWS "
|
||||
else
|
||||
textWarn "Support Policy not applied to any Group / User / Role "
|
||||
textFail "Support Policy not applied to any Group / User / Role "
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No Support Policy found"
|
||||
textFail "No Support Policy found"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -11,19 +11,19 @@ check123(){
|
||||
LIST_USERS_KEY1_ACTIVE=$(for user in $LIST_USERS_KEY1_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$9 }'|grep "true$"|awk '{ print $1 }'|sed 's/[[:blank:]]+/,/g' ; done)
|
||||
if [[ $LIST_USERS_KEY1_ACTIVE ]]; then
|
||||
for user in $LIST_USERS_KEY1_ACTIVE; do
|
||||
textNotice "$user has never used Access Key 1"
|
||||
textInfo "$user has never used Access Key 1"
|
||||
done
|
||||
else
|
||||
textOK "No users found with Access Key 1 never used"
|
||||
textPass "No users found with Access Key 1 never used"
|
||||
fi
|
||||
# List of USERS with KEY2 last_used_date as N/A
|
||||
LIST_USERS_KEY2_NA=$(for user in $LIST_USERS; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$16 }'|grep N/A |awk '{ print $1 }' ; done)
|
||||
LIST_USERS_KEY2_ACTIVE=$(for user in $LIST_USERS_KEY2_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$14 }'|grep "true$" |awk '{ print $1 }' ; done)
|
||||
if [[ $LIST_USERS_KEY2_ACTIVE ]]; then
|
||||
for user in $LIST_USERS_KEY2_ACTIVE; do
|
||||
textNotice "$user has never used Access Key 2"
|
||||
textInfo "$user has never used Access Key 2"
|
||||
done
|
||||
else
|
||||
textOK "No users found with Access Key 2 never used"
|
||||
textPass "No users found with Access Key 2 never used"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ check124(){
|
||||
# "Ensure IAM policies that allow full \"*:*\" administrative privileges are not created (Scored)"
|
||||
LIST_CUSTOM_POLICIES=$($AWSCLI iam list-policies --output text $PROFILE_OPT --region $REGION|grep 'arn:aws:iam::[0-9]\{12\}:'|awk '{ print $2 }')
|
||||
if [[ $LIST_CUSTOM_POLICIES ]]; then
|
||||
textNotice "Looking for custom policies: (skipping default policies - it may take few seconds...)"
|
||||
textInfo "Looking for custom policies: (skipping default policies - it may take few seconds...)"
|
||||
for policy in $LIST_CUSTOM_POLICIES; do
|
||||
POLICY_VERSION=$($AWSCLI iam list-policies $PROFILE_OPT --region $REGION --query 'Policies[*].[Arn,DefaultVersionId]' --output text |awk "\$1 == \"$policy\" { print \$2 }")
|
||||
POLICY_WITH_FULL=$($AWSCLI iam get-policy-version --output text --policy-arn $policy --version-id $POLICY_VERSION --query "PolicyVersion.Document.Statement[?Effect == 'Allow' && contains(Resource, '*') && contains (Action, '*')]" $PROFILE_OPT --region $REGION)
|
||||
@@ -16,14 +16,14 @@ check124(){
|
||||
fi
|
||||
done
|
||||
if [[ $POLICIES_ALLOW_LIST ]]; then
|
||||
textNotice "List of custom policies: "
|
||||
textInfo "List of custom policies: "
|
||||
for policy in $POLICIES_ALLOW_LIST; do
|
||||
textNotice "Policy $policy allows \"*:*\""
|
||||
textInfo "Policy $policy allows \"*:*\""
|
||||
done
|
||||
else
|
||||
textOK "No custom policy found that allow full \"*:*\" administrative privileges"
|
||||
textPass "No custom policy found that allow full \"*:*\" administrative privileges"
|
||||
fi
|
||||
else
|
||||
textOK "No custom policies found"
|
||||
textPass "No custom policies found"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ check13(){
|
||||
DATEUSED=$($AWSCLI iam list-users --query "Users[?UserName=='$i'].PasswordLastUsed" --output text $PROFILE_OPT --region $REGION | cut -d'T' -f1)
|
||||
HOWOLDER=$(how_older_from_today $DATEUSED)
|
||||
if [ $HOWOLDER -gt "90" ];then
|
||||
textWarn "User \"$i\" has not logged in during the last 90 days "
|
||||
textFail "User \"$i\" has not logged in during the last 90 days "
|
||||
else
|
||||
textOK "User \"$i\" found with credentials used in the last 90 days"
|
||||
textPass "User \"$i\" found with credentials used in the last 90 days"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
else
|
||||
textOK "No users found with password enabled"
|
||||
textPass "No users found with password enabled"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,39 +10,39 @@ check14(){
|
||||
C14_NUM_USERS1=0
|
||||
C14_NUM_USERS2=0
|
||||
if [[ $LIST_OF_USERS_WITH_ACCESS_KEY1 ]]; then
|
||||
# textWarn "Users with access key 1 older than 90 days:"
|
||||
# textFail "Users with access key 1 older than 90 days:"
|
||||
for user in $LIST_OF_USERS_WITH_ACCESS_KEY1; do
|
||||
# check access key 1
|
||||
DATEROTATED1=$(cat $TEMP_REPORT_FILE | grep -v user_creation_time | grep "^${user},"| awk -F, '{ print $10 }' | grep -v "N/A" | awk -F"T" '{ print $1 }')
|
||||
HOWOLDER=$(how_older_from_today $DATEROTATED1)
|
||||
|
||||
if [ $HOWOLDER -gt "90" ];then
|
||||
textWarn " $user has not rotated access key1 in over 90 days "
|
||||
textFail " $user has not rotated access key1 in over 90 days "
|
||||
C14_NUM_USERS1=$(expr $C14_NUM_USERS1 + 1)
|
||||
fi
|
||||
done
|
||||
if [[ $C14_NUM_USERS1 -eq 0 ]]; then
|
||||
textOK "No users with access key 1 older than 90 days."
|
||||
textPass "No users with access key 1 older than 90 days."
|
||||
fi
|
||||
else
|
||||
textOK "No users with access key 1."
|
||||
textPass "No users with access key 1."
|
||||
fi
|
||||
|
||||
if [[ $LIST_OF_USERS_WITH_ACCESS_KEY2 ]]; then
|
||||
# textWarn "Users with access key 2 older than 90 days:"
|
||||
# textFail "Users with access key 2 older than 90 days:"
|
||||
for user in $LIST_OF_USERS_WITH_ACCESS_KEY2; do
|
||||
# check access key 2
|
||||
DATEROTATED2=$(cat $TEMP_REPORT_FILE | grep -v user_creation_time | grep "^${user},"| awk -F, '{ print $10 }' | grep -v "N/A" | awk -F"T" '{ print $1 }')
|
||||
HOWOLDER=$(how_older_from_today $DATEROTATED2)
|
||||
if [ $HOWOLDER -gt "90" ];then
|
||||
textWarn " $user has not rotated access key2. "
|
||||
textFail " $user has not rotated access key2. "
|
||||
C14_NUM_USERS2=$(expr $C14_NUM_USERS2 + 1)
|
||||
fi
|
||||
done
|
||||
if [[ $C14_NUM_USERS2 -eq 0 ]]; then
|
||||
textOK "No users with access key 2 older than 90 days."
|
||||
textPass "No users with access key 2 older than 90 days."
|
||||
fi
|
||||
else
|
||||
textOK "No users with access key 2."
|
||||
textPass "No users with access key 2."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ check15(){
|
||||
# "Ensure IAM password policy requires at least one uppercase letter (Scored)"
|
||||
COMMAND15=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireUppercaseCharacters' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND15" == "true" ]];then
|
||||
textOK "Password Policy requires upper case"
|
||||
textPass "Password Policy requires upper case"
|
||||
else
|
||||
textWarn "Password Policy missing upper-case requirement"
|
||||
textFail "Password Policy missing upper-case requirement"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ check16(){
|
||||
# "Ensure IAM password policy require at least one lowercase letter (Scored)"
|
||||
COMMAND16=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireLowercaseCharacters' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND16" == "true" ]];then
|
||||
textOK "Password Policy requires lower case"
|
||||
textPass "Password Policy requires lower case"
|
||||
else
|
||||
textWarn "Password Policy missing lower-case requirement"
|
||||
textFail "Password Policy missing lower-case requirement"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ check17(){
|
||||
# "Ensure IAM password policy require at least one symbol (Scored)"
|
||||
COMMAND17=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireSymbols' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND17" == "true" ]];then
|
||||
textOK "Password Policy requires symbol"
|
||||
textPass "Password Policy requires symbol"
|
||||
else
|
||||
textWarn "Password Policy missing symbol requirement"
|
||||
textFail "Password Policy missing symbol requirement"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ check18(){
|
||||
# "Ensure IAM password policy require at least one number (Scored)"
|
||||
COMMAND18=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.RequireNumbers' 2> /dev/null) # must be true
|
||||
if [[ "$COMMAND18" == "true" ]];then
|
||||
textOK "Password Policy requires number"
|
||||
textPass "Password Policy requires number"
|
||||
else
|
||||
textWarn "Password Policy missing number requirement"
|
||||
textFail "Password Policy missing number requirement"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ check19(){
|
||||
# "Ensure IAM password policy requires minimum length of 14 or greater (Scored)"
|
||||
COMMAND19=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --output json --query 'PasswordPolicy.MinimumPasswordLength' 2> /dev/null)
|
||||
if [[ $COMMAND19 -gt "13" ]];then
|
||||
textOK "Password Policy requires more than 13 characters"
|
||||
textPass "Password Policy requires more than 13 characters"
|
||||
else
|
||||
textWarn "Password Policy missing or weak length requirement"
|
||||
textFail "Password Policy missing or weak length requirement"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ check21(){
|
||||
for trail in $LIST_OF_TRAILS;do
|
||||
MULTIREGION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $REGION --query 'trailList[*].IsMultiRegionTrail' --output text --trail-name-list $trail)
|
||||
if [[ "$MULTIREGION_TRAIL_STATUS" == 'False' ]];then
|
||||
textWarn "$trail trail in $REGION is not enabled in multi region mode"
|
||||
textFail "$trail trail in $REGION is not enabled in multi region mode"
|
||||
else
|
||||
textOK "$trail trail in $REGION is enabled for all regions"
|
||||
textPass "$trail trail in $REGION is enabled for all regions"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudTrail trails found!"
|
||||
textFail "No CloudTrail trails found!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ check22(){
|
||||
for trail in $LIST_OF_TRAILS;do
|
||||
LOGFILEVALIDATION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $REGION --query 'trailList[*].LogFileValidationEnabled' --output text --trail-name-list $trail)
|
||||
if [[ "$LOGFILEVALIDATION_TRAIL_STATUS" == 'False' ]];then
|
||||
textWarn "$trail trail in $REGION has not log file validation enabled"
|
||||
textFail "$trail trail in $REGION has not log file validation enabled"
|
||||
else
|
||||
textOK "$trail trail in $REGION has log file validation enabled"
|
||||
textPass "$trail trail in $REGION has log file validation enabled"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudTrail trails found!"
|
||||
textFail "No CloudTrail trails found!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ check23(){
|
||||
for bucket in $CLOUDTRAILBUCKET;do
|
||||
CLOUDTRAILBUCKET_HASALLPERMISIONS=$($AWSCLI s3api get-bucket-acl --bucket $bucket --query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers`]' $PROFILE_OPT --region $REGION --output text)
|
||||
if [[ $CLOUDTRAILBUCKET_HASALLPERMISIONS ]];then
|
||||
textWarn "check your $bucket CloudTrail bucket ACL and Policy!"
|
||||
textFail "check your $bucket CloudTrail bucket ACL and Policy!"
|
||||
else
|
||||
textOK "Bucket $bucket is set correctly"
|
||||
textPass "Bucket $bucket is set correctly"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudTrail bucket found!"
|
||||
textFail "No CloudTrail bucket found!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -12,18 +12,18 @@ check24(){
|
||||
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
|
||||
textWarn "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)"
|
||||
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
|
||||
textWarn "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)"
|
||||
textFail "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)"
|
||||
else
|
||||
textOK "$trail trail has been logging during the last 24h (it is in $TRAIL_REGION)"
|
||||
textPass "$trail trail has been logging during the last 24h (it is in $TRAIL_REGION)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudTrail trails found!"
|
||||
textFail "No CloudTrail trails found!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ check25(){
|
||||
for regx in $REGIONS; do
|
||||
CHECK_AWSCONFIG_STATUS=$($AWSCLI configservice get-status $PROFILE_OPT --region $regx --output json| grep "recorder: ON")
|
||||
if [[ $CHECK_AWSCONFIG_STATUS ]];then
|
||||
textOK "Region $regx has AWS Config recorder: ON" "$regx"
|
||||
textPass "Region $regx has AWS Config recorder: ON" "$regx"
|
||||
else
|
||||
textWarn "Region $regx has AWS Config disabled or not configured" "$regx"
|
||||
textFail "Region $regx has AWS Config disabled or not configured" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ check26(){
|
||||
for bucket in $CLOUDTRAILBUCKET;do
|
||||
CLOUDTRAILBUCKET_LOGENABLED=$($AWSCLI s3api get-bucket-logging --bucket $bucket $PROFILE_OPT --region $REGION --query 'LoggingEnabled.TargetBucket' --output text|grep -v None)
|
||||
if [[ $CLOUDTRAILBUCKET_LOGENABLED ]];then
|
||||
textOK "Bucket access logging enabled in $bucket"
|
||||
textPass "Bucket access logging enabled in $bucket"
|
||||
else
|
||||
textWarn "access logging is not enabled in $bucket CloudTrail S3 bucket!"
|
||||
textFail "access logging is not enabled in $bucket CloudTrail S3 bucket!"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "CloudTrail bucket not found!"
|
||||
textFail "CloudTrail bucket not found!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ check27(){
|
||||
for trail in $CLOUDTRAILNAME;do
|
||||
CLOUDTRAILENC_ENABLED=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $REGION --trail $trail --query 'trailList[*].KmsKeyId' --output text)
|
||||
if [[ $CLOUDTRAILENC_ENABLED ]];then
|
||||
textOK "KMS key found for $trail"
|
||||
textPass "KMS key found for $trail"
|
||||
else
|
||||
textWarn "encryption is not enabled in your CloudTrail trail $trail (KMS key not found)!"
|
||||
textFail "encryption is not enabled in your CloudTrail trail $trail (KMS key not found)!"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "CloudTrail bucket doesn't exist!"
|
||||
textFail "CloudTrail bucket doesn't exist!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -12,19 +12,19 @@ check28(){
|
||||
for key in $CHECK_KMS_KEYLIST_NO_DEFAULT; do
|
||||
CHECK_KMS_KEY_TYPE=$($AWSCLI kms describe-key --key-id $key $PROFILE_OPT --region $regx --query 'KeyMetadata.Origin' | sed 's/["]//g')
|
||||
if [[ "$CHECK_KMS_KEY_TYPE" == "EXTERNAL" ]];then
|
||||
textOK "Key $key in Region $regx Customer Uploaded Key Material." "$regx"
|
||||
textPass "Key $key in Region $regx Customer Uploaded Key Material." "$regx"
|
||||
else
|
||||
CHECK_KMS_KEY_ROTATION=$($AWSCLI kms get-key-rotation-status --key-id $key $PROFILE_OPT --region $regx --output text)
|
||||
if [[ "$CHECK_KMS_KEY_ROTATION" == "True" ]];then
|
||||
textOK "Key $key in Region $regx is set correctly"
|
||||
textPass "Key $key in Region $regx is set correctly"
|
||||
else
|
||||
textWarn "Key $key in Region $regx is not set to rotate!!!" "$regx"
|
||||
textFail "Key $key in Region $regx is not set to rotate!!!" "$regx"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
else
|
||||
textNotice "Region $regx doesn't have encryption keys" "$regx"
|
||||
textInfo "Region $regx doesn't have encryption keys" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ check31(){
|
||||
for group in $CHECK31OK; do
|
||||
metric=${group#*:}
|
||||
group=${group%:*}
|
||||
textOK "CloudWatch group $group found with metric filter $metric and alarms set for Unauthorized Operation and Access Denied"
|
||||
textPass "CloudWatch group $group found with metric filter $metric and alarms set for Unauthorized Operation and Access Denied"
|
||||
done
|
||||
fi
|
||||
if [[ $CHECK31WARN ]]; then
|
||||
@@ -40,13 +40,13 @@ check31(){
|
||||
case $group in
|
||||
*:*) metric=${group#*:}
|
||||
group=${group%:*}
|
||||
textWarn "CloudWatch group $group found with metric filter $metric but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filter $metric but no alarms associated"
|
||||
;;
|
||||
*) textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
*) textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
esac
|
||||
done
|
||||
fi
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check310(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /SecurityGroup/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for security group changes"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for security group changes"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check311(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /NetworkAcl/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for changes to NACLs"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for changes to NACLs"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check312(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /InternetGateway/ || /CustomerGateway/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for changes to network gateways"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for changes to network gateways"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check313(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /Route/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for route table changes"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for route table changes"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check314(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /VPC/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for VPC changes"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for VPC changes"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ check315(){
|
||||
TOPICS_LIST=$($AWSCLI sns list-topics $PROFILE_OPT --region $regx --output text --query 'Topics[*].TopicArn')
|
||||
ntopics=$(echo $TOPICS_LIST | wc -w )
|
||||
if [[ $TOPICS_LIST && $CAN_SNS_LIST_SUBS -eq 1 ]];then
|
||||
textNotice "Region $regx has $ntopics topics" "$regx"
|
||||
textInfo "Region $regx has $ntopics topics" "$regx"
|
||||
for topic in $TOPICS_LIST; do
|
||||
TOPIC_SHORT=$(echo $topic | awk -F: '{ print $6 }')
|
||||
CHECK_TOPIC_LIST=$($AWSCLI sns list-subscriptions-by-topic --topic-arn $topic $PROFILE_OPT --region $regx --query 'Subscriptions[*].{Endpoint:Endpoint,Protocol:Protocol}' --output text --max-items $MAXITEMS 2> /dev/null)
|
||||
@@ -18,23 +18,23 @@ check315(){
|
||||
# Permission error
|
||||
export CAN_SNS_LIST_SUBS=0
|
||||
ntopics=$(echo $TOPICS_LIST | wc -w )
|
||||
textNotice "Region $regx / $ntopics Topics / Subscriptions NO_PERMISSION" "$regx"
|
||||
textInfo "Region $regx / $ntopics Topics / Subscriptions NO_PERMISSION" "$regx"
|
||||
break;
|
||||
fi
|
||||
if [[ "Z" != "Z${CHECK_TOPIC_LIST}" ]]; then
|
||||
printf '%s
|
||||
' "$CHECK_TOPIC_LIST" | while IFS= read -r dest ; do
|
||||
textNotice "Region $regx / Topic $TOPIC_SHORT / Subscription $dest" "$regx"
|
||||
textInfo "Region $regx / Topic $TOPIC_SHORT / Subscription $dest" "$regx"
|
||||
done
|
||||
else
|
||||
textWarn "Region $regx / Topic $TOPIC_SHORT / Subscription NONE" "$regx"
|
||||
textFail "Region $regx / Topic $TOPIC_SHORT / Subscription NONE" "$regx"
|
||||
fi
|
||||
done
|
||||
elif [[ $CAN_SNS_LIST_SUBS -eq 0 ]]; then
|
||||
textNotice "Region $regx has $ntopics topics - unable to list subscribers" "$regx"
|
||||
textInfo "Region $regx has $ntopics topics - unable to list subscribers" "$regx"
|
||||
# break
|
||||
else
|
||||
textOK "Region $regx has 0 topics" "$regx"
|
||||
textPass "Region $regx has 0 topics" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check32(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /ConsoleLogin/ || /MFAUsed/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms set for sign-in Console without MFA enabled"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms set for sign-in Console without MFA enabled"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check33(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | tr '[:upper:]' '[:lower:]'| grep -Ei 'userIdentity|Root|AwsServiceEvent')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms set for usage of root account"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms set for usage of root account"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check34(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /DeletePolicy/ || /DeletePolicies/ || /Policies/ || /Policy/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for IAM policy changes"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for IAM policy changes"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check35(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /TrailChange/ || /Trails/ || /CreateTrail/ || /UpdateTrail/ || /DeleteTrail/ || /StartLogging/ || /StopLogging/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for CloudTrail configuration changes"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for CloudTrail configuration changes"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check36(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /FailedLogin/ || /ConsoleLogin/ || /Failed/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for AWS Management Console authentication failures"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for AWS Management Console authentication failures"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check37(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /DisableKey/ || /ScheduleKeyDeletion/ || /kms/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for changes of customer created CMKs"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for changes of customer created CMKs"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check38(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /S3/ || /BucketPolicy/ || /BucketPolicies/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for S3 bucket policy changes"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for S3 bucket policy changes"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ check39(){
|
||||
if [[ $METRICFILTER_SET ]];then
|
||||
HAS_ALARM_ASSOCIATED=$($AWSCLI cloudwatch describe-alarms $PROFILE_OPT --region $CLOUDWATCH_LOGGROUP_REGION --query 'MetricAlarms[].MetricName' --output text | awk 'BEGIN {IGNORECASE=1}; /config/ || /ConfigurationRecorder/ || /DeliveryChannel/;')
|
||||
if [[ $HAS_ALARM_ASSOCIATED ]];then
|
||||
textOK "CloudWatch group $group found with metric filters and alarms for AWS Config configuration changes"
|
||||
textPass "CloudWatch group $group found with metric filters and alarms for AWS Config configuration changes"
|
||||
else
|
||||
textWarn "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
textFail "CloudWatch group $group found with metric filters but no alarms associated"
|
||||
fi
|
||||
else
|
||||
textWarn "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
textFail "CloudWatch group $group found but no metric filters or alarms associated"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "No CloudWatch group found for CloudTrail events"
|
||||
textFail "No CloudWatch group found for CloudTrail events"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ check41(){
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`22` && ToPort>=`22`)) && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textWarn "Found Security Group: $SG open to 0.0.0.0/0 in Region $regx" "$regx"
|
||||
textFail "Found Security Group: $SG open to 0.0.0.0/0 in Region $regx" "$regx"
|
||||
done
|
||||
else
|
||||
textOK "No Security Groups found in $regx with port 22 TCP open to 0.0.0.0/0" "$regx"
|
||||
textPass "No Security Groups found in $regx with port 22 TCP open to 0.0.0.0/0" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ check42(){
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`3389` && ToPort>=`3389`)) && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textWarn "Found Security Group: $SG open to 0.0.0.0/0 in Region $regx" "$regx"
|
||||
textFail "Found Security Group: $SG open to 0.0.0.0/0 in Region $regx" "$regx"
|
||||
done
|
||||
else
|
||||
textOK "No Security Groups found in $regx with port 3389 TCP open to 0.0.0.0/0" "$regx"
|
||||
textPass "No Security Groups found in $regx with port 3389 TCP open to 0.0.0.0/0" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ check43(){
|
||||
CHECK_FL=$($AWSCLI ec2 describe-flow-logs $PROFILE_OPT --region $regx --query 'FlowLogs[?FlowLogStatus==`ACTIVE`].LogGroupName' --output text)
|
||||
if [[ $CHECK_FL ]];then
|
||||
for FL in $CHECK_FL;do
|
||||
textOK "VPCFlowLog is enabled for LogGroupName: $FL in Region $regx" "$regx"
|
||||
textPass "VPCFlowLog is enabled for LogGroupName: $FL in Region $regx" "$regx"
|
||||
done
|
||||
else
|
||||
textWarn "No VPCFlowLog has been found in Region $regx" "$regx"
|
||||
textFail "No VPCFlowLog has been found in Region $regx" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ check44(){
|
||||
for regx in $REGIONS; do
|
||||
CHECK_SGDEFAULT=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --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
|
||||
textWarn "Default Security Groups found that allow 0.0.0.0 IN or OUT traffic in Region $regx" "$regx"
|
||||
textFail "Default Security Groups found that allow 0.0.0.0 IN or OUT traffic in Region $regx" "$regx"
|
||||
else
|
||||
textOK "No Default Security Groups open to 0.0.0.0 found in Region $regx" "$regx"
|
||||
textPass "No Default Security Groups open to 0.0.0.0 found in Region $regx" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ CHECK_ALTERNATE_check405="check45"
|
||||
|
||||
check45(){
|
||||
# "Ensure routing tables for VPC peering are \"least access\" (Not Scored)"
|
||||
textNotice "Looking for VPC peering in all regions... "
|
||||
textInfo "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_OPT --region $regx --query 'VpcPeeringConnections[*].VpcPeeringConnectionId')
|
||||
if [[ $LIST_OF_VPCS_PEERING_CONNECTIONS ]];then
|
||||
textNotice "$regx: $LIST_OF_VPCS_PEERING_CONNECTIONS - review routing tables" "$regx"
|
||||
textInfo "$regx: $LIST_OF_VPCS_PEERING_CONNECTIONS - review routing tables" "$regx"
|
||||
#LIST_OF_VPCS=$($AWSCLI ec2 describe-vpcs $PROFILE_OPT --region $regx --query 'Vpcs[*].VpcId' --output text)
|
||||
#aws ec2 describe-route-tables --filter "Name=vpc-id,Values=vpc-0213e864" --query "RouteTables[*].{RouteTableId:RouteTableId, VpcId:VpcId, Routes:Routes, AssociatedSubnets:Associations[*].SubnetId}" $PROFILE_OPT --region $regx
|
||||
# for vpc in $LIST_OF_VPCS; do
|
||||
@@ -17,7 +17,7 @@ check45(){
|
||||
# done
|
||||
#echo $VPCS_WITH_PEERING
|
||||
else
|
||||
textOK "$regx: No VPC peering found" "$regx"
|
||||
textPass "$regx: No VPC peering found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ extra71(){
|
||||
CHECK_ADMIN_GROUP=$($AWSCLI $PROFILE_OPT iam list-attached-group-policies --group-name $grp --output json --query 'AttachedPolicies[].PolicyArn' | grep 'arn:aws:iam::aws:policy/AdministratorAccess')
|
||||
if [[ $CHECK_ADMIN_GROUP ]]; then
|
||||
ADMIN_GROUPS="$ADMIN_GROUPS $grp"
|
||||
textNotice "$grp group provides administrative access"
|
||||
textInfo "$grp group provides administrative access"
|
||||
ADMIN_USERS=$($AWSCLI $PROFILE_OPT iam get-group --group-name $grp --output json --query 'Users[].UserName' | grep '"' | cut -d'"' -f2 )
|
||||
for auser in $ADMIN_USERS; do
|
||||
# users in group are Administrators
|
||||
@@ -23,13 +23,13 @@ extra71(){
|
||||
# check for user MFA device in credential report
|
||||
USER_MFA_ENABLED=$( cat $TEMP_REPORT_FILE | grep "^$auser," | cut -d',' -f8)
|
||||
if [[ "true" == $USER_MFA_ENABLED ]]; then
|
||||
textOK "$auser / MFA Enabled / admin via group $grp"
|
||||
textPass "$auser / MFA Enabled / admin via group $grp"
|
||||
else
|
||||
textWarn "$auser / MFA DISABLED / admin via group $grp"
|
||||
textFail "$auser / MFA DISABLED / admin via group $grp"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$grp group provides non-administrative access"
|
||||
textInfo "$grp group provides non-administrative access"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -5,17 +5,17 @@ CHECK_ALTERNATE_check710="extra710"
|
||||
|
||||
extra710(){
|
||||
# "Check for internet facing EC2 Instances (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for instances in all regions... "
|
||||
textInfo "Looking for instances in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_PUBLIC_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[*].Instances[?PublicIpAddress].[InstanceId,PublicIpAddress]' --output text)
|
||||
if [[ $LIST_OF_PUBLIC_INSTANCES ]];then
|
||||
while read -r instance;do
|
||||
INSTANCE_ID=$(echo $instance | awk '{ print $1; }')
|
||||
PUBLIC_IP=$(echo $instance | awk '{ print $2; }')
|
||||
textWarn "$regx: Instance: $INSTANCE_ID at IP: $PUBLIC_IP is internet-facing!" "$regx"
|
||||
textFail "$regx: Instance: $INSTANCE_ID at IP: $PUBLIC_IP is internet-facing!" "$regx"
|
||||
done <<< "$LIST_OF_PUBLIC_INSTANCES"
|
||||
else
|
||||
textOK "$regx: no Internet Facing EC2 Instances found" "$regx"
|
||||
textPass "$regx: no Internet Facing EC2 Instances found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -5,17 +5,17 @@ CHECK_ALTERNATE_check711="extra711"
|
||||
|
||||
extra711(){
|
||||
# "Check for Publicly Accessible Redshift Clusters (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for Reshift clusters in all regions... "
|
||||
textInfo "Looking for Reshift clusters in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_PUBLIC_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[?PubliclyAccessible == `true`].[ClusterIdentifier,Endpoint.Address]' --output text)
|
||||
if [[ $LIST_OF_PUBLIC_REDSHIFT_CLUSTERS ]];then
|
||||
while read -r cluster;do
|
||||
CLUSTER_ID=$(echo $cluster | awk '{ print $1; }')
|
||||
CLUSTER_ENDPOINT=$(echo $cluster | awk '{ print $2; }')
|
||||
textWarn "$regx: Cluster: $CLUSTER_ID at Endpoint: $CLUSTER_ENDPOINT is publicly accessible!" "$regx"
|
||||
textFail "$regx: Cluster: $CLUSTER_ID at Endpoint: $CLUSTER_ENDPOINT is publicly accessible!" "$regx"
|
||||
done <<< "$LIST_OF_PUBLIC_REDSHIFT_CLUSTERS"
|
||||
else
|
||||
textOK "$regx: no Publicly Accessible Redshift Clusters found" "$regx"
|
||||
textPass "$regx: no Publicly Accessible Redshift Clusters found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ CHECK_ALTERNATE_check712="extra712"
|
||||
|
||||
extra712(){
|
||||
# "Check if Amazon Macie is enabled (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "No API commands available to check if Macie is enabled,"
|
||||
textNotice "just looking if IAM Macie related permissions exist. "
|
||||
textInfo "No API commands available to check if Macie is enabled,"
|
||||
textInfo "just looking if IAM Macie related permissions exist. "
|
||||
MACIE_IAM_ROLES_CREATED=$($AWSCLI iam list-roles $PROFILE_OPT --query 'Roles[*].Arn'|grep AWSMacieServiceCustomer|wc -l)
|
||||
if [[ $MACIE_IAM_ROLES_CREATED -eq 2 ]];then
|
||||
textOK "Macie related IAM roles exist, so it might be enabled. Check it out manually."
|
||||
textPass "Macie related IAM roles exist, so it might be enabled. Check it out manually."
|
||||
else
|
||||
textWarn "No Macie related IAM roles found. It is most likely not to be enabled"
|
||||
textFail "No Macie related IAM roles found. It is most likely not to be enabled"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ extra713(){
|
||||
while read -r detector;do
|
||||
DETECTOR_ENABLED=$($AWSCLI guardduty get-detector --detector-id $detector $PROFILE_OPT --region $regx --output text| cut -f3|grep ENABLED)
|
||||
if [[ $DETECTOR_ENABLED ]]; then
|
||||
textOK "$regx: GuardDuty detector $detector enabled" "$regx"
|
||||
textPass "$regx: GuardDuty detector $detector enabled" "$regx"
|
||||
else
|
||||
textWarn "$regx: GuardDuty detector $detector configured but suspended" "$regx"
|
||||
textFail "$regx: GuardDuty detector $detector configured but suspended" "$regx"
|
||||
fi
|
||||
done <<< "$LIST_OF_GUARDDUTY_DETECTORS"
|
||||
else
|
||||
textWarn "$regx: GuardDuty detector not configured!" "$regx"
|
||||
textFail "$regx: GuardDuty detector not configured!" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ extra714(){
|
||||
for cdn in $LIST_OF_DISTRIBUTIONS;do
|
||||
CDN_LOG_ENABLED=$($AWSCLI cloudfront get-distribution $PROFILE_OPT --region $regx --id "$cdn" --query 'Distribution.DistributionConfig.Logging.Enabled' | grep true)
|
||||
if [[ $CDN_LOG_ENABLED ]];then
|
||||
textOK "$regx: CDN $cdn logging enabled" "$regx"
|
||||
textPass "$regx: CDN $cdn logging enabled" "$regx"
|
||||
else
|
||||
textWarn "$regx: CDN $cdn logging disabled!" "$regx"
|
||||
textFail "$regx: CDN $cdn logging disabled!" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No CDN configured" "$regx"
|
||||
textInfo "$regx: No CDN configured" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ extra715(){
|
||||
for domain in $LIST_OF_DOMAINS;do
|
||||
SEARCH_SLOWLOG_ENABLED=$($AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.LogPublishingOptions.Options.SEARCH_SLOW_LOGS.Enabled --output text |grep -v ^None|grep -v ^False)
|
||||
if [[ $SEARCH_SLOWLOG_ENABLED ]];then
|
||||
textOK "$regx: ElasticSearch Service domain $domain SEARCH_SLOW_LOGS enabled" "$regx"
|
||||
textPass "$regx: ElasticSearch Service domain $domain SEARCH_SLOW_LOGS enabled" "$regx"
|
||||
else
|
||||
textWarn "$regx: ElasticSearch Service domain $domain SEARCH_SLOW_LOGS disabled!" "$regx"
|
||||
textFail "$regx: ElasticSearch Service domain $domain SEARCH_SLOW_LOGS disabled!" "$regx"
|
||||
fi
|
||||
INDEX_SLOWLOG_ENABLED=$($AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.LogPublishingOptions.Options.INDEX_SLOW_LOGS.Enabled --output text |grep -v ^None|grep -v ^False)
|
||||
if [[ $INDEX_SLOWLOG_ENABLED ]];then
|
||||
textOK "$regx: ElasticSearch Service domain $domain INDEX_SLOW_LOGS enabled" "$regx"
|
||||
textPass "$regx: ElasticSearch Service domain $domain INDEX_SLOW_LOGS enabled" "$regx"
|
||||
else
|
||||
textWarn "$regx: ElasticSearch Service domain $domain INDEX_SLOW_LOGS disabled!" "$regx"
|
||||
textFail "$regx: ElasticSearch Service domain $domain INDEX_SLOW_LOGS disabled!" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No Elasticsearch Service domain found" "$regx"
|
||||
textInfo "$regx: No Elasticsearch Service domain found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -16,16 +16,16 @@ extra716(){
|
||||
# check if the policy has Principal as *
|
||||
CHECK_ES_DOMAIN_ALLUSERS_POLICY=$(cat $TEMP_POLICY_FILE | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | awk '/Principal/ && !skip { print } { skip = /Deny/} '|grep \"Principal|grep \*)
|
||||
if [[ $CHECK_ES_DOMAIN_ALLUSERS_POLICY ]];then
|
||||
textWarn "$regx: $domain policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
|
||||
textFail "$regx: $domain policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
|
||||
else
|
||||
textOK "$regx: $domain is not open" "$regx"
|
||||
textPass "$regx: $domain is not open" "$regx"
|
||||
fi
|
||||
else
|
||||
textOK "$regx: $domain is in a VPC" "$regx"
|
||||
textPass "$regx: $domain is in a VPC" "$regx"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
textNotice "$regx: No Elasticsearch Service domain found" "$regx"
|
||||
textInfo "$regx: No Elasticsearch Service domain found" "$regx"
|
||||
rm -fr $TEMP_POLICY_FILE
|
||||
done
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ extra717(){
|
||||
for elb in $LIST_OF_ELBS; do
|
||||
CHECK_ELBS_LOG_ENABLED=$($AWSCLI elb describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-name $elb --query 'LoadBalancerAttributes.AccessLog.Enabled'|grep "^true")
|
||||
if [[ $CHECK_ELBS_LOG_ENABLED ]]; then
|
||||
textOK "$regx: $elb has access logs to S3 configured" "$regx"
|
||||
textPass "$regx: $elb has access logs to S3 configured" "$regx"
|
||||
else
|
||||
textWarn "$regx: $elb has not configured access logs" "$regx"
|
||||
textFail "$regx: $elb has not configured access logs" "$regx"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
@@ -24,14 +24,14 @@ extra717(){
|
||||
CHECK_ELBSV2_LOG_ENABLED=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query Attributes[*] --output text|grep "^access_logs.s3.enabled"|cut -f2|grep true)
|
||||
ELBV2_NAME=$(echo $elbarn|cut -d\/ -f3)
|
||||
if [[ $CHECK_ELBSV2_LOG_ENABLED ]]; then
|
||||
textOK "$regx: $ELBV2_NAME has access logs to S3 configured" "$regx"
|
||||
textPass "$regx: $ELBV2_NAME has access logs to S3 configured" "$regx"
|
||||
else
|
||||
textWarn "$regx: $ELBV2_NAME has not configured access logs" "$regx"
|
||||
textFail "$regx: $ELBV2_NAME has not configured access logs" "$regx"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
else
|
||||
textNotice "$regx: No ELBs found" "$regx"
|
||||
textInfo "$regx: No ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ extra718(){
|
||||
for bucket in $LIST_OF_BUCKETS;do
|
||||
BUCKET_SERVER_LOG_ENABLED=$($AWSCLI s3api get-bucket-logging --bucket $bucket $PROFILE_OPT --query [LoggingEnabled] --output text|grep -v "^None$")
|
||||
if [[ $BUCKET_SERVER_LOG_ENABLED ]];then
|
||||
textOK "Bucket $bucket has server access logging enabled"
|
||||
textPass "Bucket $bucket has server access logging enabled"
|
||||
else
|
||||
textWarn "Bucket $bucket has server access logging disabled!"
|
||||
textFail "Bucket $bucket has server access logging disabled!"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "No S3 Buckets found"
|
||||
textInfo "No S3 Buckets found"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ extra719(){
|
||||
for hostedzoneid in $LIST_OF_HOSTED_ZONES;do
|
||||
HOSTED_ZONE_QUERY_LOG_ENABLED=$($AWSCLI route53 list-query-logging-configs --hosted-zone-id $hostedzoneid $PROFILE_OPT --query QueryLoggingConfigs[*].CloudWatchLogsLogGroupArn --output text|cut -d: -f7)
|
||||
if [[ $HOSTED_ZONE_QUERY_LOG_ENABLED ]];then
|
||||
textOK "Route53 hosted zone Id $hostedzoneid has query logging enabled in Log Group $HOSTED_ZONE_QUERY_LOG_ENABLED"
|
||||
textPass "Route53 hosted zone Id $hostedzoneid has query logging enabled in Log Group $HOSTED_ZONE_QUERY_LOG_ENABLED"
|
||||
else
|
||||
textWarn "Route53 hosted zone Id $hostedzoneid has query logging disabled!"
|
||||
textFail "Route53 hosted zone Id $hostedzoneid has query logging disabled!"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "No Route53 hosted zones found"
|
||||
textInfo "No Route53 hosted zones found"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -7,15 +7,15 @@ CHECK_ALTERNATE_check702="extra72"
|
||||
|
||||
extra72(){
|
||||
# "Ensure there are no EBS Snapshots set as Public (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for EBS Snapshots in all regions... "
|
||||
textInfo "Looking for EBS Snapshots in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_EBS_SNAPSHOTS=$($AWSCLI ec2 describe-snapshots $PROFILE_OPT --region $regx --owner-ids $ACCOUNT_NUM --output text --query 'Snapshots[*].{ID:SnapshotId}' --max-items $MAXITEMS | grep -v None 2> /dev/null)
|
||||
for snapshot in $LIST_OF_EBS_SNAPSHOTS; do
|
||||
SNAPSHOT_IS_PUBLIC=$($AWSCLI ec2 describe-snapshot-attribute $PROFILE_OPT --region $regx --output text --snapshot-id $snapshot --attribute createVolumePermission --query "CreateVolumePermissions[?Group=='all']")
|
||||
if [[ $SNAPSHOT_IS_PUBLIC ]];then
|
||||
textWarn "$regx: $snapshot is currently Public!" "$regx"
|
||||
textFail "$regx: $snapshot is currently Public!" "$regx"
|
||||
else
|
||||
textOK "$regx: $snapshot is not Public" "$regx"
|
||||
textPass "$regx: $snapshot is not Public" "$regx"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
@@ -14,9 +14,9 @@ extra720(){
|
||||
for trail in $LIST_OF_TRAILS; do
|
||||
FUNCTION_ENABLED_IN_TRAIL=$($AWSCLI cloudtrail get-event-selectors $PROFILE_OPT --trail-name $trail --region $regx --query "EventSelectors[*].DataResources[?Type == \`AWS::Lambda::Function\`].Values" --output text |xargs -n1| grep -E "^arn:aws:lambda.*function:$lambdafunction$")
|
||||
if [[ $FUNCTION_ENABLED_IN_TRAIL ]]; then
|
||||
textOK "$regx: Lambda function $lambdafunction enabled in trail $trail" "$regx"
|
||||
textPass "$regx: Lambda function $lambdafunction enabled in trail $trail" "$regx"
|
||||
else
|
||||
textWarn "$regx: Lambda function $lambdafunction NOT enabled in trail $trail" "$regx"
|
||||
textFail "$regx: Lambda function $lambdafunction NOT enabled in trail $trail" "$regx"
|
||||
fi
|
||||
done
|
||||
# LIST_OF_MULTIREGION_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query "trailList[?IsMultiRegionTrail == \`true\`].Name" --output text)
|
||||
@@ -25,20 +25,20 @@ extra720(){
|
||||
# REGION_OF_TRAIL=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query "trailList[?IsMultiRegionTrail == \`true\` && Name == \`$trail\` ].HomeRegion" --output text)
|
||||
# FUNCTION_ENABLED_IN_THIS_REGION=$($AWSCLI cloudtrail get-event-selectors $PROFILE_OPT --trail-name $trail --region $REGION_OF_TRAIL --query "EventSelectors[*].DataResources[?Type == \`AWS::Lambda::Function\`].Values" --output text |xargs -n1| grep -E "^arn:aws:lambda.*function:$lambdafunction$")
|
||||
# if [[ $FUNCTION_ENABLED_IN_THIS_REGION ]]; then
|
||||
# textOK "$regx: Lambda function $lambdafunction enabled in trail $trail" "$regx"
|
||||
# textPass "$regx: Lambda function $lambdafunction enabled in trail $trail" "$regx"
|
||||
# else
|
||||
# textWarn "$regx: Lambda function $lambdafunction NOT enabled in trail $trail" "$regx"
|
||||
# textFail "$regx: Lambda function $lambdafunction NOT enabled in trail $trail" "$regx"
|
||||
# fi
|
||||
# done
|
||||
# else
|
||||
# textWarn "$regx: Lambda function $lambdafunction is not being recorded!" "$regx"
|
||||
# textFail "$regx: Lambda function $lambdafunction is not being recorded!" "$regx"
|
||||
# fi
|
||||
else
|
||||
textWarn "$regx: Lambda function $lambdafunction is not being recorded no CloudTrail found!" "$regx"
|
||||
textFail "$regx: Lambda function $lambdafunction is not being recorded no CloudTrail found!" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No Lambda functions found" "$regx"
|
||||
textInfo "$regx: No Lambda functions found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ extra721(){
|
||||
REDSHIFT_LOG_ENABLED=$($AWSCLI redshift describe-logging-status $PROFILE_OPT --region $regx --cluster-identifier $redshiftcluster --query LoggingEnabled --output text | grep True)
|
||||
if [[ $REDSHIFT_LOG_ENABLED ]];then
|
||||
REDSHIFT_LOG_ENABLED_BUCKET=$($AWSCLI redshift describe-logging-status $PROFILE_OPT --region $regx --cluster-identifier $redshiftcluster --query BucketName --output text)
|
||||
textOK "$regx: Redshift cluster $redshiftcluster has audit logging enabled to bucket $REDSHIFT_LOG_ENABLED_BUCKET" "$regx"
|
||||
textPass "$regx: Redshift cluster $redshiftcluster has audit logging enabled to bucket $REDSHIFT_LOG_ENABLED_BUCKET" "$regx"
|
||||
else
|
||||
textWarn "$regx: Redshift cluster $redshiftcluster logging disabled!" "$regx"
|
||||
textFail "$regx: Redshift cluster $redshiftcluster logging disabled!" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No Redshift cluster configured" "$regx"
|
||||
textInfo "$regx: No Redshift cluster configured" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -15,17 +15,17 @@ extra722(){
|
||||
for stagname in $CHECK_STAGES_NAME;do
|
||||
CHECK_STAGE_METHOD_LOGGING=$($AWSCLI apigateway get-stages $PROFILE_OPT --region $regx --rest-api-id $apigwid --query "item[?stageName == \`$stagname\` ].methodSettings" --output text|awk '{ print $1" log level "$6}')
|
||||
if [[ $CHECK_STAGE_METHOD_LOGGING ]];then
|
||||
textOK "$regx: API Gateway $API_GW_NAME has stage logging enabled for $CHECK_STAGE_METHOD_LOGGING" "$regx"
|
||||
textPass "$regx: API Gateway $API_GW_NAME has stage logging enabled for $CHECK_STAGE_METHOD_LOGGING" "$regx"
|
||||
else
|
||||
textWarn "$regx: API Gateway $API_GW_NAME logging disabled for stage $stagname!" "$regx"
|
||||
textFail "$regx: API Gateway $API_GW_NAME logging disabled for stage $stagname!" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textWarn "$regx: No Stage name found for $API_GW_NAME" "$regx"
|
||||
textFail "$regx: No Stage name found for $API_GW_NAME" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No API Gateway found" "$regx"
|
||||
textInfo "$regx: No API Gateway found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ extra723(){
|
||||
for rdssnapshot in $LIST_OF_RDS_SNAPSHOTS;do
|
||||
SNAPSHOT_IS_PUBLIC=$($AWSCLI rds describe-db-snapshot-attributes $PROFILE_OPT --region $regx --db-snapshot-identifier $rdssnapshot --query DBSnapshotAttributesResult.DBSnapshotAttributes[*] --output text|grep ^ATTRIBUTEVALUES|cut -f2|grep all)
|
||||
if [[ $SNAPSHOT_IS_PUBLIC ]];then
|
||||
textWarn "$regx: RDS Snapshot $rdssnapshot is public!" "$regx"
|
||||
textFail "$regx: RDS Snapshot $rdssnapshot is public!" "$regx"
|
||||
else
|
||||
textOK "$regx: RDS Snapshot $rdssnapshot is not shared" "$regx"
|
||||
textPass "$regx: RDS Snapshot $rdssnapshot is not shared" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No RDS Snapshots found" "$regx"
|
||||
textInfo "$regx: No RDS Snapshots found" "$regx"
|
||||
fi
|
||||
# RDS cluster snapshots
|
||||
LIST_OF_RDS_CLUSTER_SNAPSHOTS=$($AWSCLI rds describe-db-cluster-snapshots $PROFILE_OPT --region $regx --query DBClusterSnapshots[*].DBClusterSnapshotIdentifier --output text)
|
||||
@@ -26,13 +26,13 @@ extra723(){
|
||||
for rdsclustersnapshot in $LIST_OF_RDS_CLUSTER_SNAPSHOTS;do
|
||||
CLUSTER_SNAPSHOT_IS_PUBLIC=$($AWSCLI rds describe-db-cluster-snapshot-attributes $PROFILE_OPT --region $regx --db-cluster-snapshot-identifier $rdsclustersnapshot --query DBClusterSnapshotAttributesResult.DBClusterSnapshotAttributes[*] --output text|grep ^ATTRIBUTEVALUES|cut -f2|grep all)
|
||||
if [[ $CLUSTER_SNAPSHOT_IS_PUBLIC ]];then
|
||||
textWarn "$regx: RDS Cluster Snapshot $rdsclustersnapshot is public!" "$regx"
|
||||
textFail "$regx: RDS Cluster Snapshot $rdsclustersnapshot is public!" "$regx"
|
||||
else
|
||||
textOK "$regx: RDS Cluster Snapshot $rdsclustersnapshot is not shared" "$regx"
|
||||
textPass "$regx: RDS Cluster Snapshot $rdsclustersnapshot is not shared" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No RDS Cluster Snapshots found" "$regx"
|
||||
textInfo "$regx: No RDS Cluster Snapshots found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ extra724(){
|
||||
CT_ENABLED=$($AWSCLI acm describe-certificate $PROFILE_OPT --region $regx --certificate-arn $cert_arn --query Certificate.Options.CertificateTransparencyLoggingPreference --output text)
|
||||
CERT_DOMAIN_NAME=$(aws acm describe-certificate $PROFILE_OPT --region $regx --certificate-arn $cert_arn --query Certificate.DomainName --output text)
|
||||
if [[ $CT_ENABLED == "ENABLED" ]];then
|
||||
textWarn "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging enabled!" "$regx"
|
||||
textFail "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging enabled!" "$regx"
|
||||
else
|
||||
textOK "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging disabled!" "$regx"
|
||||
textPass "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging disabled!" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textNotice "$regx: No ACM Certificates found" "$regx"
|
||||
textInfo "$regx: No ACM Certificates found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ CHECK_ALTERNATE_check73="extra73"
|
||||
CHECK_ALTERNATE_check703="extra73"
|
||||
|
||||
extra73(){
|
||||
textNotice "Looking for open S3 Buckets (ACLs and Policies) in all regions... "
|
||||
textInfo "Looking for open S3 Buckets (ACLs and Policies) in all regions... "
|
||||
ALL_BUCKETS_LIST=$($AWSCLI s3api list-buckets --query 'Buckets[*].{Name:Name}' --profile $PROFILE --region $REGION --output text)
|
||||
for bucket in $ALL_BUCKETS_LIST; do
|
||||
extra73Thread $bucket &
|
||||
@@ -35,16 +35,16 @@ extra73Thread(){
|
||||
CHECK_BUCKET_ALLUSERS_POLICY=$(cat $TEMP_POLICY_FILE | sed -e 's/[{}]/''/g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}'|awk '/Principal/ && !skip { print } { skip = /Deny/} '|grep ^\"Principal|grep \*)
|
||||
if [[ $CHECK_BUCKET_ALLUSERS_ACL || $CHECK_BUCKET_AUTHUSERS_ACL || $CHECK_BUCKET_ALLUSERS_POLICY ]];then
|
||||
if [[ $CHECK_BUCKET_ALLUSERS_ACL ]];then
|
||||
textWarn "$BUCKET_LOCATION: $bucket bucket is open to the Internet (Everyone) with permissions: $CHECK_BUCKET_ALLUSERS_ACL_SINGLE_LINE" "$regx"
|
||||
textFail "$BUCKET_LOCATION: $bucket bucket is open to the Internet (Everyone) with permissions: $CHECK_BUCKET_ALLUSERS_ACL_SINGLE_LINE" "$regx"
|
||||
fi
|
||||
if [[ $CHECK_BUCKET_AUTHUSERS_ACL ]];then
|
||||
textWarn "$BUCKET_LOCATION: $bucket bucket is open to Authenticated users (Any AWS user) with permissions: $CHECK_BUCKET_AUTHUSERS_ACL_SINGLE_LINE" "$regx"
|
||||
textFail "$BUCKET_LOCATION: $bucket bucket is open to Authenticated users (Any AWS user) with permissions: $CHECK_BUCKET_AUTHUSERS_ACL_SINGLE_LINE" "$regx"
|
||||
fi
|
||||
if [[ $CHECK_BUCKET_ALLUSERS_POLICY ]];then
|
||||
textWarn "$BUCKET_LOCATION: $bucket bucket policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
|
||||
textFail "$BUCKET_LOCATION: $bucket bucket policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
|
||||
fi
|
||||
else
|
||||
textOK "$BUCKET_LOCATION: $bucket bucket is not open" "$regx"
|
||||
textPass "$BUCKET_LOCATION: $bucket bucket is not open" "$regx"
|
||||
fi
|
||||
rm -fr $TEMP_POLICY_FILE
|
||||
}
|
||||
|
||||
@@ -7,15 +7,15 @@ CHECK_ALTERNATE_check704="extra74"
|
||||
|
||||
extra74(){
|
||||
# "Ensure there are no Security Groups without ingress filtering being used (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for Security Groups in all regions... "
|
||||
textInfo "Looking for Security Groups in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_SECURITYGROUPS=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --filters "Name=ip-permission.cidr,Values=0.0.0.0/0" --query "SecurityGroups[].[GroupId]" --output text --max-items $MAXITEMS)
|
||||
for SG_ID in $LIST_OF_SECURITYGROUPS; do
|
||||
SG_NO_INGRESS_FILTER=$($AWSCLI ec2 describe-network-interfaces $PROFILE_OPT --region $regx --filters "Name=group-id,Values=$SG_ID" --query "length(NetworkInterfaces)" --output text)
|
||||
if [[ $SG_NO_INGRESS_FILTER -ne 0 ]];then
|
||||
textWarn "$regx: $SG_ID has not ingress filtering and it is being used!" "$regx"
|
||||
textFail "$regx: $SG_ID has not ingress filtering and it is being used!" "$regx"
|
||||
else
|
||||
textNotice "$regx: $SG_ID has not ingress filtering but it is no being used" "$regx"
|
||||
textInfo "$regx: $SG_ID has not ingress filtering but it is no being used" "$regx"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
@@ -7,15 +7,15 @@ CHECK_ALTERNATE_check705="extra75"
|
||||
|
||||
extra75(){
|
||||
# "Ensure there are no Security Groups not being used (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for Security Groups in all regions... "
|
||||
textInfo "Looking for Security Groups in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_SECURITYGROUPS=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --query "SecurityGroups[].[GroupId]" --output text --max-items $MAXITEMS)
|
||||
for SG_ID in $LIST_OF_SECURITYGROUPS; do
|
||||
SG_NOT_USED=$($AWSCLI ec2 describe-network-interfaces $PROFILE_OPT --region $regx --filters "Name=group-id,Values=$SG_ID" --query "length(NetworkInterfaces)" --output text)
|
||||
if [[ $SG_NOT_USED -eq 0 ]];then
|
||||
textWarn "$regx: $SG_ID is not being used!" "$regx"
|
||||
textFail "$regx: $SG_ID is not being used!" "$regx"
|
||||
else
|
||||
textOK "$regx: $SG_ID is being used" "$regx"
|
||||
textPass "$regx: $SG_ID is being used" "$regx"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
@@ -7,15 +7,15 @@ CHECK_ALTERNATE_check706="extra76"
|
||||
|
||||
extra76(){
|
||||
# "Ensure there are no EC2 AMIs set as Public (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for AMIs in all regions... "
|
||||
textInfo "Looking for AMIs in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_PUBLIC_AMIS=$($AWSCLI ec2 describe-images --owners self $PROFILE_OPT --region $regx --filters "Name=is-public,Values=true" --query 'Images[*].{ID:ImageId}' --output text)
|
||||
if [[ $LIST_OF_PUBLIC_AMIS ]];then
|
||||
for ami in $LIST_OF_PUBLIC_AMIS; do
|
||||
textWarn "$regx: $ami is currently Public!" "$regx"
|
||||
textFail "$regx: $ami is currently Public!" "$regx"
|
||||
done
|
||||
else
|
||||
textOK "$regx: No Public AMIs found" "$regx"
|
||||
textPass "$regx: No Public AMIs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ CHECK_ALTERNATE_check707="extra77"
|
||||
|
||||
extra77(){
|
||||
# "Ensure there are no ECR repositories set as Public (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for ECR repos in all regions... "
|
||||
textInfo "Looking for ECR repos in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ECR_REPOS=$($AWSCLI ecr describe-repositories $PROFILE_OPT --region $regx --query 'repositories[*].{Name:repositoryName}' --output text)
|
||||
for ecr_repo in $LIST_OF_ECR_REPOS; do
|
||||
@@ -16,9 +16,9 @@ extra77(){
|
||||
# check if the policy has Principal as *
|
||||
CHECK_ECR_REPO_ALLUSERS_POLICY=$(cat $TEMP_POLICY_FILE | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | awk '/Principal/ && !skip { print } { skip = /Deny/} '|grep \"Principal|grep \*)
|
||||
if [[ $CHECK_ECR_REPO_ALLUSERS_POLICY ]];then
|
||||
textWarn "$regx: $ecr_repo policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
|
||||
textFail "$regx: $ecr_repo policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
|
||||
else
|
||||
textOK "$regx: $ecr_repo is not open" "$regx"
|
||||
textPass "$regx: $ecr_repo is not open" "$regx"
|
||||
fi
|
||||
done
|
||||
rm -fr $TEMP_POLICY_FILE
|
||||
|
||||
@@ -7,17 +7,17 @@ CHECK_ALTERNATE_check708="extra78"
|
||||
|
||||
extra78(){
|
||||
# "Ensure there are no Public Accessible RDS instances (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for RDS instances in all regions... "
|
||||
textInfo "Looking for RDS instances in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_RDS_PUBLIC_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[?PubliclyAccessible==`true`].[DBInstanceIdentifier,Endpoint.Address]' --output text)
|
||||
if [[ $LIST_OF_RDS_PUBLIC_INSTANCES ]];then
|
||||
while read -r rds_instance;do
|
||||
RDS_NAME=$(echo $rds_instance | awk '{ print $1; }')
|
||||
RDS_DNSNAME=$(echo $rds_instance | awk '{ print $2; }')
|
||||
textWarn "$regx: RDS instance: $RDS_NAME at $RDS_DNSNAME is set as Publicly Accessible!" "$regx"
|
||||
textFail "$regx: RDS instance: $RDS_NAME at $RDS_DNSNAME is set as Publicly Accessible!" "$regx"
|
||||
done <<< "$LIST_OF_RDS_PUBLIC_INSTANCES"
|
||||
else
|
||||
textOK "$regx: no Publicly Accessible RDS instances found" "$regx"
|
||||
textPass "$regx: no Publicly Accessible RDS instances found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ CHECK_ALTERNATE_check709="extra79"
|
||||
|
||||
extra79(){
|
||||
# "Check for internet facing Elastic Load Balancers (Not Scored) (Not part of CIS benchmark)"
|
||||
textNotice "Looking for Elastic Load Balancers in all regions... "
|
||||
textInfo "Looking for Elastic Load Balancers in all regions... "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_PUBLIC_ELBS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[?Scheme == `internet-facing`].[LoadBalancerName,DNSName]' --output text)
|
||||
LIST_OF_PUBLIC_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Scheme == `internet-facing`].[LoadBalancerName,DNSName]' --output text)
|
||||
@@ -17,10 +17,10 @@ extra79(){
|
||||
while read -r elb;do
|
||||
ELB_NAME=$(echo $elb | awk '{ print $1; }')
|
||||
ELB_DNSNAME=$(echo $elb | awk '{ print $2; }')
|
||||
textWarn "$regx: ELB: $ELB_NAME at DNS: $ELB_DNSNAME is internet-facing!" "$regx"
|
||||
textFail "$regx: ELB: $ELB_NAME at DNS: $ELB_DNSNAME is internet-facing!" "$regx"
|
||||
done <<< "$LIST_OF_ALL_ELBS_PER_LINE"
|
||||
else
|
||||
textOK "$regx: no Internet Facing ELBs found" "$regx"
|
||||
textPass "$regx: no Internet Facing ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
#
|
||||
# extraN(){
|
||||
# # "Description (Not Scored) (Not part of CIS benchmark)"
|
||||
# textNotice "Looking for instances in all regions... "
|
||||
# textInfo "Looking for instances in all regions... "
|
||||
# for regx in $REGIONS; do
|
||||
# LIST_OF_PUBLIC_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[*].Instances[?PublicIpAddress].[InstanceId,PublicIpAddress]' --output text)
|
||||
# if [[ $LIST_OF_PUBLIC_INSTANCES ]];then
|
||||
# while read -r instance;do
|
||||
# INSTANCE_ID=$(echo $instance | awk '{ print $1; }')
|
||||
# PUBLIC_IP=$(echo $instance | awk '{ print $2; }')
|
||||
# textWarn "$regx: Instance: $INSTANCE_ID at IP: $PUBLIC_IP is internet-facing!" "$regx"
|
||||
# textFail "$regx: Instance: $INSTANCE_ID at IP: $PUBLIC_IP is internet-facing!" "$regx"
|
||||
# done <<< "$LIST_OF_PUBLIC_INSTANCES"
|
||||
# else
|
||||
# textOK "$regx: no Internet Facing EC2 Instances found" "$regx"
|
||||
# textPass "$regx: no Internet Facing EC2 Instances found" "$regx"
|
||||
# fi
|
||||
# done
|
||||
# }
|
||||
|
||||
@@ -11,7 +11,7 @@ saveReport(){
|
||||
$AWSCLI iam get-credential-report --query 'Content' --output text $PROFILE_OPT --region $REGION | decode_report > $TEMP_REPORT_FILE
|
||||
if [[ $KEEPCREDREPORT -eq 1 ]]; then
|
||||
textTitle "0.2" "Saving IAM Credential Report ..." "NOT_SCORED" "SUPPORT"
|
||||
textNotice "IAM Credential Report saved in $TEMP_REPORT_FILE"
|
||||
textInfo "IAM Credential Report saved in $TEMP_REPORT_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Output formatting functions
|
||||
textOK(){
|
||||
textPass(){
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
@@ -12,7 +12,7 @@ textOK(){
|
||||
fi
|
||||
}
|
||||
|
||||
textNotice(){
|
||||
textInfo(){
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
@@ -25,7 +25,7 @@ textNotice(){
|
||||
fi
|
||||
}
|
||||
|
||||
textWarn(){
|
||||
textFail(){
|
||||
EXITCODE=3
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
|
||||
@@ -13,7 +13,7 @@ getWhoami(){
|
||||
CALLER_ARN=$(echo $CALLER_ARN_RAW | tr -d '"')
|
||||
printCsvHeader
|
||||
textTitle "0.0" "Show report generation info" "NOT_SCORED" "SUPPORT"
|
||||
textNotice "ARN: $CALLER_ARN TIMESTAMP: $SCRIPT_START_TIME"
|
||||
textInfo "ARN: $CALLER_ARN TIMESTAMP: $SCRIPT_START_TIME"
|
||||
else
|
||||
echo ""
|
||||
echo -e " This report is being generated using credentials below:\n"
|
||||
|
||||
Reference in New Issue
Block a user