diff --git a/README.md b/README.md index 3f4acbb0..9ee849d6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ - [Screenshots](#screenshots) - [Advanced Usage](#advanced-usage) - [Security Hub integration](#security-hub-integration) -- [Fix](#fix) +- [CodeBuild deployment](#codebuild-deployment) +- [Whitelist/allowlist or remove FAIL from resources](whitelist-allowlist-or-remove-fail-from-resources) +- [Fix](#how-to-fix-every-fail) - [Troubleshooting](#troubleshooting) - [Extras](#extras) - [Forensics Ready Checks](#forensics-ready-checks) @@ -381,7 +383,11 @@ To use Prowler and Security Hub integration in China regions there is an additio ./prowler -r cn-north-1 -f cn-north-1 -q -S -M csv,json-asff ``` -## Whitelist or remove FAIL from resources +## CodeBuild deployment + +CodeBuild can help you running Prowler and there is a Cloud Formation template that helps you doing that [here](https://github.com/toniblyx/prowler/blob/master/util/codebuild/codebuild-auditor-account-cfn.yaml). + +## Whitelist or allowlist or remove a fail from resources Sometimes you may find resources that are intentionally configured in a certain way that may be a bad practice but it is all right with it, for example an S3 bucket open to the internet hosting a web site, or a security group with an open port needed in your use case. Now you can use `-w whitelist_sample.txt` and add your resources as `checkID:resourcename` as in this command: diff --git a/checks/check_extra7115 b/checks/check_extra7115 new file mode 100644 index 00000000..da606669 --- /dev/null +++ b/checks/check_extra7115 @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +CHECK_ID_extra7115="7.115" +CHECK_TITLE_extra7115="[extra7115] Check if Glue database connection has SSL connection enabled." +CHECK_SCORED_extra7115="NOT_SCORED" +CHECK_TYPE_extra7115="EXTRA" +CHECK_SEVERITY_extra7115="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7115="AwsGlue" +CHECK_ALTERNATE_check7115="extra7115" + +extra7115(){ + for regx in $REGIONS; do + CONNECTION_LIST=$($AWSCLI glue get-connections $PROFILE_OPT --region $regx --output json --query 'ConnectionList[*].{Name:Name,SSL:ConnectionProperties.JDBC_ENFORCE_SSL}') + if [[ $CONNECTION_LIST != '[]' ]]; then + for connection in $(echo "${CONNECTION_LIST}" | jq -r '.[] | @base64'); do + CONNECTION_NAME=$(echo $connection | base64 --decode | jq -r '.Name' ) + CONNECTION_SSL_STATE=$(echo $connection | base64 --decode | jq -r '.SSL') + if [[ "$CONNECTION_SSL_STATE" == "false" ]]; then + textFail "$regx: Glue connection $CONNECTION_NAME has SSL connection disabled" "$regx" + else + textPass "$regx: Glue connection $CONNECTION_NAME has SSL connection enabled" "$regx" + fi + done + else + textInfo "$regx: There are no Glue connections" "$regx" + fi + done +} diff --git a/checks/check_extra7116 b/checks/check_extra7116 new file mode 100644 index 00000000..2165b91a --- /dev/null +++ b/checks/check_extra7116 @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +CHECK_ID_extra7116="7.116" +CHECK_TITLE_extra7116="[extra7116] Check if Glue data-catalog settings have metadata encryption enabled." +CHECK_SCORED_extra7116="NOT_SCORED" +CHECK_TYPE_extra7116="EXTRA" +CHECK_SEVERITY_extra7116="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7116="AwsGlue" +CHECK_ALTERNATE_check7116="extra7116" + +extra7116(){ + for regx in $REGIONS; do + METADATA_ENCRYPTED=$($AWSCLI glue get-data-catalog-encryption-settings $PROFILE_OPT --region $regx --output text --query "DataCatalogEncryptionSettings.EncryptionAtRest.CatalogEncryptionMode") + if [[ "$METADATA_ENCRYPTED" == "DISABLED" ]]; then + textFail "$regx: Glue data catalog settings have metadata encryption disabled" "$regx" + else + textPass "$regx: Glue data catalog settings have metadata encryption enabled" "$regx" + fi + done +} diff --git a/checks/check_extra7117 b/checks/check_extra7117 new file mode 100644 index 00000000..7c11c76d --- /dev/null +++ b/checks/check_extra7117 @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +CHECK_ID_extra7117="7.117" +CHECK_TITLE_extra7117="[extra7117] Check if Glue data catalog settings have encrypt connection password enabled." +CHECK_SCORED_extra7117="NOT_SCORED" +CHECK_TYPE_extra7117="EXTRA" +CHECK_SEVERITY_extra7117="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7117="AwsGlue" +CHECK_ALTERNATE_check7117="extra7117" + +extra7117(){ + for regx in $REGIONS; do + METADATA_ENCRYPTED=$($AWSCLI glue get-data-catalog-encryption-settings $PROFILE_OPT --region $regx --output text --query "DataCatalogEncryptionSettings.ConnectionPasswordEncryption.ReturnConnectionPasswordEncrypted") + if [[ "$METADATA_ENCRYPTED" == "False" ]]; then + textFail "$regx: Glue data catalog connection password is not encrypted" "$regx" + else + textPass "$regx: Glue data catalog connection password is encrypted" "$regx" + fi + done +} diff --git a/checks/check_extra7118 b/checks/check_extra7118 new file mode 100644 index 00000000..aa39907f --- /dev/null +++ b/checks/check_extra7118 @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +CHECK_ID_extra7118="7.118" +CHECK_TITLE_extra7118="[extra7118] Check if Glue ETL Jobs have S3 encryption enabled." +CHECK_SCORED_extra7118="NOT_SCORED" +CHECK_TYPE_extra7118="EXTRA" +CHECK_SEVERITY_extra7118="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7118="AwsGlue" +CHECK_ALTERNATE_check7118="extra7118" + +extra7118(){ + for regx in $REGIONS; do + JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration,JobEncryption:DefaultArguments."--encryption-type"}') + if [[ $JOB_LIST != '[]' ]]; then + for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do + JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name') + SECURITY_CONFIGURATION=$(echo $job | base64 --decode | jq -r '.SecurityConfiguration // empty') + JOB_ENCRYPTION=$(echo $job | base64 --decode | jq -r '.JobEncryption // empty') + if [[ ! -z "$SECURITY_CONFIGURATION" ]]; then + S3_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${SECURITY_CONFIGURATION}" $PROFILE_OPT --region $regx --output text --query 'SecurityConfiguration.EncryptionConfiguration.S3Encryption[0].S3EncryptionMode') + if [[ "$S3_ENCRYPTION" == "DISABLED" ]]; then + if [[ ! -z "$JOB_ENCRYPTION" ]]; then + textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" + else + textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" + fi + else + textPass "$regx: Glue job $JOB_NAME does have $S3_ENCRYPTION for S3 encryption enabled" "$regx" + fi + elif [[ ! -z "$JOB_ENCRYPTION" ]]; then + textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" + else + textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" + fi + done + else + textInfo "$regx: There are no Glue jobs" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra7120 b/checks/check_extra7120 new file mode 100644 index 00000000..69695b7f --- /dev/null +++ b/checks/check_extra7120 @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +CHECK_ID_extra7120="7.120" +CHECK_TITLE_extra7120="[extra7120] Check if Glue ETL Jobs have CloudWatch Logs encryption enabled." +CHECK_SCORED_extra7120="NOT_SCORED" +CHECK_TYPE_extra7120="EXTRA" +CHECK_SEVERITY_extra7120="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7120="AwsGlue" +CHECK_ALTERNATE_check7120="extra7120" + +extra7120(){ + for regx in $REGIONS; do + JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}') + if [[ $JOB_LIST != '[]' ]]; then + for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do + JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name') + SECURITY_CONFIGURATION=$(echo $job | base64 --decode | jq -r '.SecurityConfiguration // empty') + if [[ ! -z "$SECURITY_CONFIGURATION" ]]; then + CLOUDWATCH_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${SECURITY_CONFIGURATION}" $PROFILE_OPT --region $regx --output text --query 'SecurityConfiguration.EncryptionConfiguration.CloudWatchEncryption.CloudWatchEncryptionMode') + if [[ "$CLOUDWATCH_ENCRYPTION" == "DISABLED" ]]; then + textFail "$regx: Glue job $JOB_NAME does not have CloudWatch Logs encryption enabled" "$regx" + else + textPass "$regx: Glue job $JOB_NAME does have $CLOUDWATCH_ENCRYPTION CloudWatch Logs encryption enabled" "$regx" + fi + else + textFail "$regx: Glue job $JOB_NAME does not have CloudWatch Logs encryption enabled" "$regx" + fi + done + else + textInfo "$regx: There are no Glue jobs" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra7122 b/checks/check_extra7122 new file mode 100644 index 00000000..618181c4 --- /dev/null +++ b/checks/check_extra7122 @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +CHECK_ID_extra7122="7.122" +CHECK_TITLE_extra7122="[extra7122] Check if Glue ETL Jobs have Job bookmark encryption enabled." +CHECK_SCORED_extra7122="NOT_SCORED" +CHECK_TYPE_extra7122="EXTRA" +CHECK_SEVERITY_extra7122="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7122="AwsGlue" +CHECK_ALTERNATE_check7122="extra7122" + +extra7122(){ + for regx in $REGIONS; do + JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}') + if [[ $JOB_LIST != '[]' ]]; then + for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do + JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name') + SECURITY_CONFIGURATION=$(echo $job | base64 --decode | jq -r '.SecurityConfiguration // empty') + if [[ ! -z "$SECURITY_CONFIGURATION" ]]; then + JOB_BOOKMARK_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${SECURITY_CONFIGURATION}" $PROFILE_OPT --region $regx --output text --query 'SecurityConfiguration.EncryptionConfiguration.JobBookmarksEncryption.JobBookmarksEncryptionMode') + if [[ "$JOB_BOOKMARK_ENCRYPTION" == "DISABLED" ]]; then + textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" + else + textPass "$regx: Glue job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION for Job bookmark encryption enabled" "$regx" + fi + else + textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" + fi + done + else + textInfo "$regx: There are no Glue jobs" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra764 b/checks/check_extra764 index 435cf474..d04768d4 100644 --- a/checks/check_extra764 +++ b/checks/check_extra764 @@ -47,7 +47,8 @@ extra764(){ # checking if $TEMP_STP_POLICY_FILE is a valid json before converting it to json with jq policy_str=$(cat "$TEMP_STP_POLICY_FILE") if jq -e . >/dev/null 2>&1 <<< "$policy_str"; then - CHECK_BUCKET_STP_POLICY_PRESENT=$(cat $TEMP_STP_POLICY_FILE | jq --arg arn "arn:${AWS_PARTITION}: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")') + CHECK_BUCKET_STP_POLICY_PRESENT=$(cat $TEMP_STP_POLICY_FILE | jq --arg arn "arn:${AWS_PARTITION}:s3:::${bucket}" \ + '.Statement[]|select((((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and .Effect=="Deny" and (.Action=="s3:*" or .Action=="*") 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 diff --git a/checks/check_extra78 b/checks/check_extra78 index 3c960994..b1d9c2ea 100644 --- a/checks/check_extra78 +++ b/checks/check_extra78 @@ -24,7 +24,7 @@ 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` && DBInstanceStatus=="available"].[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) if [[ $LIST_OF_RDS_PUBLIC_INSTANCES ]];then while read -r rds_instance;do RDS_NAME=$(echo $rds_instance | awk '{ print $1; }') diff --git a/groups/group24_glue b/groups/group24_glue index 3722b2cb..a9b8c313 100644 --- a/groups/group24_glue +++ b/groups/group24_glue @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Prowler - the handy cloud security tool (copyright 2222) by Toni de la Fuente +# Prowler - the handy cloud security tool (copyright 2020) by Toni de la Fuente # # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy @@ -15,5 +15,4 @@ GROUP_ID[24]='glue' GROUP_NUMBER[24]='24.0' GROUP_TITLE[24]='Amazon Glue related security checks - [glue] ******************' GROUP_RUN_BY_DEFAULT[24]='N' # run it when execute_all is called -GROUP_CHECKS[24]='extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122' - +GROUP_CHECKS[24]='extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122' \ No newline at end of file diff --git a/include/html_report b/include/html_report index ee606eff..b38a2eca 100644 --- a/include/html_report +++ b/include/html_report @@ -58,7 +58,7 @@ addHtmlHeader() {