From daa26ed14c8235792f3d4447e2498bf6b7021e78 Mon Sep 17 00:00:00 2001 From: Nimrod Kor Date: Tue, 18 Feb 2020 10:20:13 +0200 Subject: [PATCH 1/7] extra764 should also check for principal being AWS = "*" --- checks/check_extra764 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra764 b/checks/check_extra764 index 6fd2c51381..8b849208a7 100644 --- a/checks/check_extra764 +++ b/checks/check_extra764 @@ -36,7 +36,7 @@ extra764(){ fi # https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/ - CHECK_BUCKET_STP_POLICY_PRESENT=$(cat $TEMP_STP_POLICY_FILE | jq --arg arn "arn:aws:s3:::${bucket}" '.Statement[]|select(((.Principal|type == "string") and .Principal == "*") and .Action=="s3:*" and (.Resource|type == "array") and (.Resource|map({(.):0})[]|has($arn)) and (.Resource|map({(.):0})[]|has($arn+"/*")) and .Condition.Bool."aws:SecureTransport" == "false")') + CHECK_BUCKET_STP_POLICY_PRESENT=$(cat $TEMP_STP_POLICY_FILE | jq --arg arn "arn:aws:s3:::${bucket}" '.Statement[]|select((((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and .Action=="s3:*" and (.Resource|type == "array") and (.Resource|map({(.):0})[]|has($arn)) and (.Resource|map({(.):0})[]|has($arn+"/*")) and .Condition.Bool."aws:SecureTransport" == "false")') if [[ $CHECK_BUCKET_STP_POLICY_PRESENT ]]; then textPass "Bucket $bucket has S3 bucket policy to deny requests over insecure transport" else From 28a8ae757275a73f404ee49cd77e19192a035a4e Mon Sep 17 00:00:00 2001 From: Nimrod Kor Date: Tue, 18 Feb 2020 10:26:44 +0200 Subject: [PATCH 2/7] Check extra748 should fail in case of all ports (0-65535) open --- checks/check_extra748 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra748 b/checks/check_extra748 index dff4bf9fcb..50056980b5 100644 --- a/checks/check_extra748 +++ b/checks/check_extra748 @@ -18,7 +18,7 @@ CHECK_ALTERNATE_check748="extra748" extra748(){ for regx in $REGIONS; do - SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==null && ToPort==null)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text) + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`0` && ToPort==`65535`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text) if [[ $SG_LIST ]];then for SG in $SG_LIST;do textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" From 5f3293af1e41363118034de801eed3c5ab1db88c Mon Sep 17 00:00:00 2001 From: Nimrod Kor Date: Tue, 18 Feb 2020 10:01:23 +0200 Subject: [PATCH 3/7] Add conditions check for extra771 (cherry picked from commit 805b276578d5afda60b38cffa28fe09b16380799) --- checks/check_extra771 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra771 b/checks/check_extra771 index 943bbffe61..ecd240c30b 100644 --- a/checks/check_extra771 +++ b/checks/check_extra771 @@ -24,7 +24,7 @@ extra771(){ if [[ $BUCKET_POLICY_STATEMENTS == *GetBucketPolicy* ]]; then textInfo "Bucket policy does not exist for bucket $bucket" else - BUCKET_POLICY_BAD_STATEMENTS=$(echo $BUCKET_POLICY_STATEMENTS | jq --arg arn "arn:aws:s3:::$bucket" 'fromjson | .Statement[]|select(.Effect=="Allow" and (((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and (.Action|startswith("s3:Put") or startswith("s3:*")))') + BUCKET_POLICY_BAD_STATEMENTS=$(echo $BUCKET_POLICY_STATEMENTS | jq --arg arn "arn:aws:s3:::$bucket" 'fromjson | .Statement[]|select(.Effect=="Allow" and (((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and (.Action|startswith("s3:Put") or startswith("s3:*")) and .Condition == null)') if [[ $BUCKET_POLICY_BAD_STATEMENTS != "" ]]; then textFail "Bucket $bucket allows public write: $BUCKET_POLICY_BAD_STATEMENTS" else From 178a34e40d67c96743f6e31d2d7db909b9488307 Mon Sep 17 00:00:00 2001 From: Nimrod Kor Date: Tue, 18 Feb 2020 09:57:20 +0200 Subject: [PATCH 4/7] Add conditions check for extra716 (cherry picked from commit 2ec6696897a272c7d765cc31e37703a453f57289) --- checks/check_extra716 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra716 b/checks/check_extra716 index 404462b1b2..549791ce69 100644 --- a/checks/check_extra716 +++ b/checks/check_extra716 @@ -27,7 +27,7 @@ extra716(){ TEMP_POLICY_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-es-domain.policy.XXXXXXXXXX) $AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.AccessPolicies.Options --output text > $TEMP_POLICY_FILE 2> /dev/null # 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 \*) + CHECK_ES_DOMAIN_ALLUSERS_POLICY=$(cat $TEMP_POLICY_FILE | jq -r '. | .Statement[] | select(.Effect == "Allow" and (((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and .Condition == null)') if [[ $CHECK_ES_DOMAIN_ALLUSERS_POLICY ]];then textFail "$regx: $domain policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx" else From 4fe575030ba5f2448cbd3b4d0ff788df6cb37a51 Mon Sep 17 00:00:00 2001 From: Nimrod Kor Date: Tue, 18 Feb 2020 10:07:39 +0200 Subject: [PATCH 5/7] Filter for only available rds instances (cherry picked from commit 5a7356be3cd137e08161b3dc0d7b8f1b2267c304) --- checks/check_extra78 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/checks/check_extra78 b/checks/check_extra78 index 681b4d0b0e..4c0d6115e7 100644 --- a/checks/check_extra78 +++ b/checks/check_extra78 @@ -22,7 +22,8 @@ extra78(){ # "Ensure there are no Public Accessible RDS instances (Not Scored) (Not part of CIS benchmark)" 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) + LIST_OF_RDS_PUBLIC_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[?PubliclyAccessible==`true` && DBInstanceStatus=="available"].[DBInstanceIdentifier,Endpoint.Address]' --output text) + echo $LIST_OF_RDS_PUBLIC_INSTANCES if [[ $LIST_OF_RDS_PUBLIC_INSTANCES ]];then while read -r rds_instance;do RDS_NAME=$(echo $rds_instance | awk '{ print $1; }') From a6516e4af8e805b32bdbe454e313956f963aaca0 Mon Sep 17 00:00:00 2001 From: Nimrod Kor Date: Tue, 18 Feb 2020 11:36:20 +0200 Subject: [PATCH 6/7] Check 1.1 - check password access and access key usage (cherry picked from commit f62cde1bf1a32138419cc1488392b93816958595) --- checks/check11 | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/checks/check11 b/checks/check11 index 924a14eb91..f34ebed5f8 100644 --- a/checks/check11 +++ b/checks/check11 @@ -17,19 +17,21 @@ CHECK_ALTERNATE_check101="check11" check11(){ # "Avoid the use of the root account (Scored)." MAX_DAYS=-1 - last_login_date=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$5 }' |grep '' | awk '{ print $2 }') - arn=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$2 }' |grep '' | awk '{ print $2 }') + last_login_dates=$(cat $TEMP_REPORT_FILE | awk -F, '{ print $1,$5,$11,$16 }' | grep '' | cut -d' ' -f2,3,4) - #check if last_login_date date is a valid date, if not, its a pass. - if [[ ${last_login_date%T*} =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]];then - days_not_in_use=$(how_many_days_from_today ${last_login_date%T*}) - if [ "$days_not_in_use" -gt "$MAX_DAYS" ];then - textFail "Root Account $arn last accessed was less then ${MAX_DAYS#-} day ago" - else - textPass "Root Account $arn last accessed was more then ${MAX_DAYS#-} day ago" + failures=0 + for date in $last_login_dates; do + if [[ ${date%T*} =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]];then + days_not_in_use=$(how_many_days_from_today ${date%T*}) + if [ "$days_not_in_use" -gt "$MAX_DAYS" ];then + failures=1 + textFail "Root user in the account was last accessed ${MAX_DAYS#-} day ago" + break + fi fi - else - textPass "Root Account $arn last accessed was more then ${MAX_DAYS#-} day ago" - fi + done + if [[ $failures == 0 ]]; then + textPass "Root user in the account wasn't accessed in the last ${MAX_DAYS#-} days" + fi } From e41e77ed78b29afe72502d1cdbc8952663629e68 Mon Sep 17 00:00:00 2001 From: Nimrod Kor Date: Tue, 18 Feb 2020 11:57:52 +0200 Subject: [PATCH 7/7] Remove unnecessary print (cherry picked from commit 72bb29f13cabf5bd85af3c5539a46eacd34538ae) --- checks/check_extra78 | 1 - 1 file changed, 1 deletion(-) diff --git a/checks/check_extra78 b/checks/check_extra78 index 4c0d6115e7..9bea1a3db9 100644 --- a/checks/check_extra78 +++ b/checks/check_extra78 @@ -23,7 +23,6 @@ extra78(){ 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` && DBInstanceStatus=="available"].[DBInstanceIdentifier,Endpoint.Address]' --output text) - echo $LIST_OF_RDS_PUBLIC_INSTANCES if [[ $LIST_OF_RDS_PUBLIC_INSTANCES ]];then while read -r rds_instance;do RDS_NAME=$(echo $rds_instance | awk '{ print $1; }')