From 5252518d97b081259279092fd010756f4174f2ff Mon Sep 17 00:00:00 2001 From: gabrielsoltz Date: Wed, 23 Oct 2019 13:38:36 +0200 Subject: [PATCH] extra73 --- checks/check_extra73 | 80 ++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/checks/check_extra73 b/checks/check_extra73 index 7ca96c7f..5612f04b 100644 --- a/checks/check_extra73 +++ b/checks/check_extra73 @@ -45,7 +45,15 @@ CHECK_ALTERNATE_check703="extra73" extra73(){ textInfo "Looking for open S3 Buckets (ACLs and Policies) in all regions... " ALL_BUCKETS_LIST=$($AWSCLI s3api list-buckets --query 'Buckets[*].{Name:Name}' $PROFILE_OPT --output text) + for bucket in $ALL_BUCKETS_LIST; do + + # 3 DIFFERENT POSSIBLE, Let's show only 1 finding all together + S3_FINDING_ALLUSERS_ACL="Ok" + S3_FINDING_AUTHUSERS_ACL="Ok" + S3_FINDING_POLICY="Ok" + + # LOCATION BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location --bucket $bucket $PROFILE_OPT --output text) if [[ "None" == $BUCKET_LOCATION ]]; then BUCKET_LOCATION="us-east-1" @@ -53,36 +61,58 @@ extra73(){ if [[ "EU" == $BUCKET_LOCATION ]]; then BUCKET_LOCATION="eu-west-1" fi - # Check Explicit Deny and Avoid Error + + # EXPLICIT DENY CHEK_FOR_EXPLICIT_DENY=$($AWSCLI s3api get-bucket-acl $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --output text 2>&1) if [[ $(echo "$CHEK_FOR_EXPLICIT_DENY" | grep AccessDenied) ]] ; then - textPass "$BUCKET_LOCATION: bucket have an explicit Deny. Not possible to get ACL." "$BUCKET_LOCATION" + textInfo "$BUCKET_LOCATION: $bucket have an explicit Deny. Not possible to get ACL." "$bucket" "$BUCKET_LOCATION" else - # check if AllUsers is in the ACL as Grantee - CHECK_BUCKET_ALLUSERS_ACL=$($AWSCLI s3api get-bucket-acl $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query "Grants[?Grantee.URI == 'http://acs.amazonaws.com/groups/global/AllUsers']" --output text |grep -v GRANTEE) - CHECK_BUCKET_ALLUSERS_ACL_SINGLE_LINE=$(echo -ne $CHECK_BUCKET_ALLUSERS_ACL) - # check if AuthenticatedUsers is in the ACL as Grantee, they will have access with sigened URL only - CHECK_BUCKET_AUTHUSERS_ACL=$($AWSCLI s3api get-bucket-acl $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query "Grants[?Grantee.URI == 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers']" --output text |grep -v GRANTEE) - CHECK_BUCKET_AUTHUSERS_ACL_SINGLE_LINE=$(echo -ne $CHECK_BUCKET_AUTHUSERS_ACL) - # to prevent error NoSuchBucketPolicy first clean the output controlling stderr - TEMP_POLICY_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-${bucket}.policy.XXXXXXXXXX) - $AWSCLI s3api get-bucket-policy $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --output text --query Policy > $TEMP_POLICY_FILE 2> /dev/null - # check if the S3 policy has Principal as * - 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 - textFail "$BUCKET_LOCATION: $bucket bucket is open to the Internet (Everyone) with permissions: $CHECK_BUCKET_ALLUSERS_ACL_SINGLE_LINE" "$BUCKET_LOCATION" - fi - if [[ $CHECK_BUCKET_AUTHUSERS_ACL ]];then - textFail "$BUCKET_LOCATION: $bucket bucket is open to Authenticated users (Any AWS user) with permissions: $CHECK_BUCKET_AUTHUSERS_ACL_SINGLE_LINE" "$BUCKET_LOCATION" - fi - if [[ $CHECK_BUCKET_ALLUSERS_POLICY ]];then - textFail "$BUCKET_LOCATION: $bucket bucket policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$BUCKET_LOCATION" - fi + # PUBLIC BLOCK + # https://docs.aws.amazon.com/cli/latest/reference/s3api/get-public-access-block.html + BUCKET_PUBLIC_BLOCK_IGNOREPUBLICACL=$($AWSCLI s3api get-public-access-block --bucket $bucket $PROFILE_OPT --region $BUCKET_LOCATION --output text --query PublicAccessBlockConfiguration.IgnorePublicAcls 2>/dev/null) + BUCKET_PUBLIC_BLOCK_BLOCKPUBLICPOLICY=$($AWSCLI s3api get-public-access-block --bucket $bucket $PROFILE_OPT --region $BUCKET_LOCATION --output text --query PublicAccessBlockConfiguration.BlockPublicPolicy 2>/dev/null) + BUCKET_PUBLIC_BLOCK_BLOCKPUBLICACLS=$($AWSCLI s3api get-public-access-block --bucket $bucket $PROFILE_OPT --region $BUCKET_LOCATION --output text --query PublicAccessBlockConfiguration.BlockPublicAcls 2>/dev/null) + BUCKET_PUBLIC_BLOCK_RESTRICPUBLICBUCKET=$($AWSCLI s3api get-public-access-block --bucket $bucket $PROFILE_OPT --region $BUCKET_LOCATION --output text --query PublicAccessBlockConfiguration.RestrictPublicBuckets 2>/dev/null) + if [[ $BUCKET_PUBLIC_BLOCK_IGNOREPUBLICACL == "True" ]] && [[ $BUCKET_PUBLIC_BLOCK_BLOCKPUBLICPOLICY == "True" ]] && [[ $BUCKET_PUBLIC_BLOCK_BLOCKPUBLICACLS == "True" ]] && [[ $BUCKET_PUBLIC_BLOCK_RESTRICPUBLICBUCKET == "True" ]]; then + textPass "$BUCKET_LOCATION: $bucket is public blocked (public-access-block)" "$BUCKET_LOCATION" else - textPass "$BUCKET_LOCATION: $bucket bucket is not open" "$BUCKET_LOCATION" + ## ACL + # check if AllUsers is in the ACL as Grantee + CHECK_BUCKET_ALLUSERS_ACL=$($AWSCLI s3api get-bucket-acl $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query "Grants[?Grantee.URI == 'http://acs.amazonaws.com/groups/global/AllUsers']" --output text |grep -v GRANTEE) + CHECK_BUCKET_ALLUSERS_ACL_SINGLE_LINE=$(echo -ne $CHECK_BUCKET_ALLUSERS_ACL) + # check if AuthenticatedUsers is in the ACL as Grantee, they will have access with sigened URL only + CHECK_BUCKET_AUTHUSERS_ACL=$($AWSCLI s3api get-bucket-acl $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query "Grants[?Grantee.URI == 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers']" --output text |grep -v GRANTEE) + CHECK_BUCKET_AUTHUSERS_ACL_SINGLE_LINE=$(echo -ne $CHECK_BUCKET_AUTHUSERS_ACL) + ## POLICY + BUCKET_POLICY_STATUS=$($AWSCLI s3api get-bucket-policy-status $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query PolicyStatus.IsPublic --output text 2>/dev/null) + if [[ $CHECK_BUCKET_ALLUSERS_ACL || $CHECK_BUCKET_AUTHUSERS_ACL || $CHECK_BUCKET_ALLUSERS_POLICY == "True" ]]; then + if [[ $CHECK_BUCKET_ALLUSERS_ACL || $CHECK_BUCKET_AUTHUSERS_ACL ]] && [[ $BUCKET_PUBLIC_BLOCK_IGNOREPUBLICACL != "True" ]];then + if [[ $CHECK_BUCKET_ALLUSERS_ACL ]];then + S3_FINDING_ALLUSERS_ACL="$bucket bucket ACL is open to the Internet (Everyone) with permissions: $CHECK_BUCKET_ALLUSERS_ACL_SINGLE_LINE" + fi + if [[ $CHECK_BUCKET_AUTHUSERS_ACL ]];then + S3_FINDING_AUTHUSERS_ACL="$bucket bucket ACL is open to Authenticated users (Any AWS user) with permissions: $CHECK_BUCKET_AUTHUSERS_ACL_SINGLE_LINE" + fi + fi + if [[ $BUCKET_PUBLIC_BLOCK_RESTRICPUBLICBUCKET != "True" ]] && [[ $BUCKET_POLICY_STATUS == "True" ]]; then + # Look Statement Allow, Principal * and No Condition + BUCKET_POLICY_ALLOW_ALL_WITHOUT_CONDITION=$($AWSCLI s3api get-bucket-policy $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket \ + | jq '.Policy | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*") | select(has("Condition") | not)') + if [[ $BUCKET_POLICY_ALLOW_ALL_WITHOUT_CONDITION ]]; then + BUCKET_POLICY_ALLOW_ALL_WITHOUT_CONDITION_DETAILS=$($AWSCLI s3api get-bucket-policy $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket \ + | jq '.Policy | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*") | select(has("Condition") | not)' | jq '"[Principal: " + (.Principal|tostring) + " Action: " + .Action + "]"' ) + S3_FINDING_POLICY="$bucket bucket policy allow perform actions: $BUCKET_POLICY_ALLOW_ALL_WITHOUT_CONDITION_DETAILS" + else + textPass "$BUCKET_LOCATION: $bucket bucket policy with conditions: $CHECK_BUCKET_ALLUSERS_POLICY_CONDITIONS" "$BUCKET_LOCATION" + fi + fi + else + textPass "$BUCKET_LOCATION: $bucket bucket is not open" "$bucket" "$BUCKET_LOCATION" + fi fi - rm -fr $TEMP_POLICY_FILE + fi + if [[ $S3_FINDING_ALLUSERS_ACL != "Ok" ]] || [[ $S3_FINDING_AUTHUSERS_ACL != "Ok" ]] || [[ $S3_FINDING_POLICY != "Ok" ]] ; then + textFail "$BUCKET_LOCATION: ALLUSERS_ACL: $S3_FINDING_ALLUSERS_ACL | AUTHUSERS_ACL: $S3_FINDING_AUTHUSERS_ACL | BUCKET_POLICY: $S3_FINDING_POLICY" "$BUCKET_LOCATION" fi done }