From 49533de21ba8dbd1f194a8d9a7d842e03107bcb9 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 15 Apr 2021 23:51:21 +0200 Subject: [PATCH 01/82] Added support for custom output folder and S3 bucket --- include/outputs | 14 +++++++++++ include/outputs_bucket | 53 ++++++++++++++++++++++++++++++++++++++++++ prowler | 19 +++++++++++++-- 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 include/outputs_bucket diff --git a/include/outputs b/include/outputs index d9d4fb1c..b16bc6bd 100644 --- a/include/outputs +++ b/include/outputs @@ -20,6 +20,20 @@ EXTENSION_TEXT="txt" EXTENSION_HTML="html" OUTPUT_DATE=$(date -u +"%Y%m%d%H%M%S") OUTPUT_DIR="${PROWLER_DIR}/output" # default output if none +if [[ $OUTPUT_DIR_CUSTOM ]]; then + # output mode has to be set to other than text + if [[ ! " ${MODES[@]} " =~ " text " || ${check_id} == 7.1 || ${check_id} == 7.74 ]]; then + if [[ ! -d $OUTPUT_DIR_CUSTOM ]]; then + echo "$OPTRED ERROR!$OPTNORMAL directory \"$OUTPUT_DIR_CUSTOM\" does not exist." + exit 1 + else + OUTPUT_DIR=$OUTPUT_DIR_CUSTOM + fi + else + echo "$OPTRED ERROR!$OPTNORMAL - Mode (-M) has to be set as well. Use -h for help." + exit 1 + fi +fi OUTPUT_FILE_NAME="${OUTPUT_DIR}/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}" HTML_LOGO_URL="https://github.com/toniblyx/prowler/" #HTML_LOGO_IMG="https://raw.githubusercontent.com/toniblyx/prowler/master/util/html/prowler-logo.png" diff --git a/include/outputs_bucket b/include/outputs_bucket new file mode 100644 index 00000000..41cbefe1 --- /dev/null +++ b/include/outputs_bucket @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2021) 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. + +if [[ $OUTPUT_BUCKET ]]; then + # output mode has to be set to other than text + if [[ "${MODES[@]}" =~ "html" ]] || [[ "${MODES[@]}" =~ "csv" ]] || [[ "${MODES[@]}" =~ "json" ]] || [[ "${MODES[@]}" =~ "json-asff" ]]; then + OUTPUT_BUCKET_WITHOUT_FOLDERS=$(echo $OUTPUT_BUCKET | awk -F'/' '{ print $1 }') + OUTPUT_BUCKET_STATUS=$($AWSCLI s3api head-bucket --bucket "$OUTPUT_BUCKET" 2>&1 || true) + if [[ ! -z $OUTPUT_BUCKET_STATUS ]]; then + echo "$OPTRED ERROR!$OPTNORMAL wrong bucket name or not right permissions." + exit 1 + else + # need to make sure last / is not set to avoid // in S3 + if [[ $OUTPUT_BUCKET != *"/" ]]; then + OUTPUT_BUCKET="$OUTPUT_BUCKET" + else + OUTPUT_BUCKET=${OUTPUT_BUCKET::-1} + fi + fi + else + echo "$OPTRED ERROR!$OPTNORMAL - Mode (-M) has to be set as well. Use -h for help." + exit 1 + fi +fi + +copyToS3(){ + # Prowler will copy each format to its own folder in S3, that is for better handling + # and processing by Quicksight or others. + if [[ $OUTPUT_BUCKET ]]; then + if [[ "${MODES[@]}" =~ "csv" ]]; then + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_CSV s3://$OUTPUT_BUCKET/csv/ + fi + if [[ "${MODES[@]}" =~ "html" ]]; then + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_HTML s3://$OUTPUT_BUCKET/html/ + fi + if [[ "${MODES[@]}" =~ "json" ]]; then + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_JSON s3://$OUTPUT_BUCKET/json/ + fi + if [[ "${MODES[@]}" =~ "json-asff" ]]; then + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_ASFF s3://$OUTPUT_BUCKET/json-asff/ + fi + fi +} \ No newline at end of file diff --git a/prowler b/prowler index 8d129916..9987a504 100755 --- a/prowler +++ b/prowler @@ -32,7 +32,7 @@ OPTRED="" OPTNORMAL="" # Set the defaults variables -PROWLER_VERSION=2.4.0-07042021 +PROWLER_VERSION=2.5.0-15042021 PROWLER_DIR=$(dirname "$0") REGION="" @@ -100,13 +100,17 @@ USAGE: -w whitelist file. See whitelist_sample.txt for reference and format (i.e.: whitelist_sample.txt) -N Shoadan API key used by check extra7102. + -o Custom output directory, if not specified will use default prowler/output, requires -M + (i.e.: -M csv -o /tmp/reports/) + -B Custom output bucket, requires -M and it can work also with -o flag. + (i.e.: -M csv -B my-bucket or -M csv -B my-bucket/folder/) -V show version number & exit -h this help " exit } -while getopts ":hlLkqp:r:c:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:" OPTION; do +while getopts ":hlLkqp:r:c:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:" OPTION; do case $OPTION in h ) usage @@ -190,6 +194,12 @@ while getopts ":hlLkqp:r:c:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:" OPTION; do N ) SHODAN_API_KEY=$OPTARG ;; + o ) + OUTPUT_DIR_CUSTOM=$OPTARG + ;; + B ) + OUTPUT_BUCKET=$OPTARG + ;; : ) echo "" echo "$OPTRED ERROR!$OPTNORMAL -$OPTARG requires an argument" @@ -243,6 +253,7 @@ unset AWS_DEFAULT_OUTPUT . $PROWLER_DIR/include/csv_header . $PROWLER_DIR/include/banner . $PROWLER_DIR/include/html_report +. $PROWLER_DIR/include/outputs_bucket . $PROWLER_DIR/include/outputs . $PROWLER_DIR/include/credentials_report . $PROWLER_DIR/include/scoring @@ -607,6 +618,7 @@ if [[ $GROUP_ID_READ ]];then fi cleanTemp scoring + copyToS3 exit $EXITCODE else textFail "Use a valid check group ID i.e.: group1, extras, forensics-ready, etc." @@ -634,6 +646,7 @@ if [[ $CHECK_ID ]];then if [[ "${MODES[@]}" =~ "html" ]]; then addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi + copyToS3 cleanTemp exit $EXITCODE fi @@ -643,8 +656,10 @@ execute_all if [[ "${MODES[@]}" =~ "html" ]]; then addHtmlFooter >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi + scoring cleanTemp +copyToS3 if [[ $ACCOUNT_TO_ASSUME ]]; then # unset env variables with assumed role credentials From 2ac96cf29a52b796cbae7e7bf0909c1b96fbea62 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Mon, 19 Apr 2021 19:18:23 +0200 Subject: [PATCH 02/82] feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to FTP ports 20 or 21 --- checks/check_extra7134 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 checks/check_extra7134 diff --git a/checks/check_extra7134 b/checks/check_extra7134 new file mode 100644 index 00000000..bb577b28 --- /dev/null +++ b/checks/check_extra7134 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7134="7.134" +CHECK_TITLE_extra7134="[extra7134] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to FTP ports 20 or 21 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7134="NOT_SCORED" +CHECK_TYPE_extra7134="EXTRA" +CHECK_SEVERITY_extra7134="High" +CHECK_ASFF_RESOURCE_TYPE_extra7134="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7134="extra7134" +CHECK_SERVICENAME_extra7134="ec2" +CHECK_RISK_extra7134='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7134='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7134='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7134='Infrastructure Security' + +extra7134(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`20` && ToPort==`21`)) && (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 for FTP ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for FTP ports" "$regx" + fi + done +} \ No newline at end of file From 68b3e1fa06253d3240206eff3bf12d87d7b4428c Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Mon, 19 Apr 2021 19:19:24 +0200 Subject: [PATCH 03/82] feat(aws-securitygroups): include extra control 7134 in extra group --- groups/group7_extras | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/group7_extras b/groups/group7_extras index e7333d62..d7539f16 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 595bcba1d98c536714371a38432746e4525a0131 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Mon, 19 Apr 2021 19:24:31 +0200 Subject: [PATCH 04/82] feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to Kafka port 9092 --- checks/check_extra7135 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 checks/check_extra7135 diff --git a/checks/check_extra7135 b/checks/check_extra7135 new file mode 100644 index 00000000..3150a2d1 --- /dev/null +++ b/checks/check_extra7135 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7135="7.135" +CHECK_TITLE_extra7135="[extra7135] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Kafka port 9092 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7135="NOT_SCORED" +CHECK_TYPE_extra7135="EXTRA" +CHECK_SEVERITY_extra7135="High" +CHECK_ASFF_RESOURCE_TYPE_extra7135="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7135="extra7135" +CHECK_SERVICENAME_extra7135="ec2" +CHECK_RISK_extra7135='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7135='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7135='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7135='Infrastructure Security' + +extra7135(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`9092` && ToPort==`9092`)) && (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 for Kafka ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Kafka ports" "$regx" + fi + done +} \ No newline at end of file From ab43a8b71767a4b7e64264a4f58c01e2b406e5ae Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Mon, 19 Apr 2021 19:26:10 +0200 Subject: [PATCH 05/82] feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to Telnet port 23 --- checks/check_extra7136 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 checks/check_extra7136 diff --git a/checks/check_extra7136 b/checks/check_extra7136 new file mode 100644 index 00000000..6117d61e --- /dev/null +++ b/checks/check_extra7136 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7136="7.136" +CHECK_TITLE_extra7136="[extra7136] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Telnet port 23 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7136="NOT_SCORED" +CHECK_TYPE_extra7136="EXTRA" +CHECK_SEVERITY_extra7136="High" +CHECK_ASFF_RESOURCE_TYPE_extra7136="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7136="extra7136" +CHECK_SERVICENAME_extra7136="ec2" +CHECK_RISK_extra7136='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7136='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7136='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7136='Infrastructure Security' + +extra7136(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`23` && ToPort==`23`)) && (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 for Telnet ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Telnet ports" "$regx" + fi + done +} \ No newline at end of file From 4327333d008cc0f4825c8d94f76453c180ee3fb3 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Mon, 19 Apr 2021 19:28:10 +0200 Subject: [PATCH 06/82] feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to Microsoft SQL Server ports 1433 or 1434 --- checks/check_extra7137 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 checks/check_extra7137 diff --git a/checks/check_extra7137 b/checks/check_extra7137 new file mode 100644 index 00000000..81d45c98 --- /dev/null +++ b/checks/check_extra7137 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7137="7.137" +CHECK_TITLE_extra7137="[extra7137] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Windows SQL Server ports 1433 or 1434 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7137="NOT_SCORED" +CHECK_TYPE_extra7137="EXTRA" +CHECK_SEVERITY_extra7137="High" +CHECK_ASFF_RESOURCE_TYPE_extra7137="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7137="extra7137" +CHECK_SERVICENAME_extra7137="ec2" +CHECK_RISK_extra7137='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7137='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7137='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7137='Infrastructure Security' + +extra7137(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`1433` && ToPort==`1434`)) && (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 for Microsoft SQL Server ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Microsoft SQL Server ports" "$regx" + fi + done +} \ No newline at end of file From 672f3833fc3e7936379864ba8d76c31c521f6a54 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Mon, 19 Apr 2021 19:31:06 +0200 Subject: [PATCH 07/82] feat(aws-securitygroups): include extra controls 7135, 7136 and 7137 in extra and internet-exposed groups --- groups/group17_internetexposed | 2 +- groups/group7_extras | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/groups/group17_internetexposed b/groups/group17_internetexposed index 9cf2563c..8df4a499 100644 --- a/groups/group17_internetexposed +++ b/groups/group17_internetexposed @@ -15,7 +15,7 @@ GROUP_ID[17]='internet-exposed' GROUP_NUMBER[17]='17.0' GROUP_TITLE[17]='Find resources exposed to the internet - [internet-exposed] ***' GROUP_RUN_BY_DEFAULT[17]='N' # run it when execute_all is called -GROUP_CHECKS[17]='check41,check42,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102' +GROUP_CHECKS[17]='check41,check42,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102,extra7134,extra7135,extra7136,extra7137' # 4.1 [check41] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored) [group4, cislevel1, cislevel2] # 4.2 [check42] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored) [group4, cislevel1, cislevel2] diff --git a/groups/group7_extras b/groups/group7_extras index d7539f16..ea9ce095 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From cb60085779f739e973db034abc319e3167467c17 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Thu, 22 Apr 2021 18:29:12 +0200 Subject: [PATCH 08/82] New Networking checks for FTP, Telnet, SQL Server and Kafka (#2) * feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to FTP ports 20 or 21 * feat(aws-securitygroups): include extra control 7134 in extra group * feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to Kafka port 9092 * feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to Telnet port 23 * feat(aws-securitygroups): include new control to test ingress from 0.0.0.0/0 or ::/0 to Microsoft SQL Server ports 1433 or 1434 * feat(aws-securitygroups): include extra controls 7135, 7136 and 7137 in extra and internet-exposed groups --- checks/check_extra7134 | 37 ++++++++++++++++++++++++++++++++++ checks/check_extra7135 | 37 ++++++++++++++++++++++++++++++++++ checks/check_extra7136 | 37 ++++++++++++++++++++++++++++++++++ checks/check_extra7137 | 37 ++++++++++++++++++++++++++++++++++ groups/group17_internetexposed | 2 +- groups/group7_extras | 2 +- 6 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 checks/check_extra7134 create mode 100644 checks/check_extra7135 create mode 100644 checks/check_extra7136 create mode 100644 checks/check_extra7137 diff --git a/checks/check_extra7134 b/checks/check_extra7134 new file mode 100644 index 00000000..bb577b28 --- /dev/null +++ b/checks/check_extra7134 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7134="7.134" +CHECK_TITLE_extra7134="[extra7134] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to FTP ports 20 or 21 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7134="NOT_SCORED" +CHECK_TYPE_extra7134="EXTRA" +CHECK_SEVERITY_extra7134="High" +CHECK_ASFF_RESOURCE_TYPE_extra7134="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7134="extra7134" +CHECK_SERVICENAME_extra7134="ec2" +CHECK_RISK_extra7134='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7134='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7134='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7134='Infrastructure Security' + +extra7134(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`20` && ToPort==`21`)) && (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 for FTP ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for FTP ports" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra7135 b/checks/check_extra7135 new file mode 100644 index 00000000..3150a2d1 --- /dev/null +++ b/checks/check_extra7135 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7135="7.135" +CHECK_TITLE_extra7135="[extra7135] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Kafka port 9092 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7135="NOT_SCORED" +CHECK_TYPE_extra7135="EXTRA" +CHECK_SEVERITY_extra7135="High" +CHECK_ASFF_RESOURCE_TYPE_extra7135="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7135="extra7135" +CHECK_SERVICENAME_extra7135="ec2" +CHECK_RISK_extra7135='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7135='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7135='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7135='Infrastructure Security' + +extra7135(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`9092` && ToPort==`9092`)) && (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 for Kafka ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Kafka ports" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra7136 b/checks/check_extra7136 new file mode 100644 index 00000000..6117d61e --- /dev/null +++ b/checks/check_extra7136 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7136="7.136" +CHECK_TITLE_extra7136="[extra7136] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Telnet port 23 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7136="NOT_SCORED" +CHECK_TYPE_extra7136="EXTRA" +CHECK_SEVERITY_extra7136="High" +CHECK_ASFF_RESOURCE_TYPE_extra7136="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7136="extra7136" +CHECK_SERVICENAME_extra7136="ec2" +CHECK_RISK_extra7136='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7136='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7136='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7136='Infrastructure Security' + +extra7136(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`23` && ToPort==`23`)) && (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 for Telnet ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Telnet ports" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra7137 b/checks/check_extra7137 new file mode 100644 index 00000000..81d45c98 --- /dev/null +++ b/checks/check_extra7137 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7137="7.137" +CHECK_TITLE_extra7137="[extra7137] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Windows SQL Server ports 1433 or 1434 (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7137="NOT_SCORED" +CHECK_TYPE_extra7137="EXTRA" +CHECK_SEVERITY_extra7137="High" +CHECK_ASFF_RESOURCE_TYPE_extra7137="AwsEc2SecurityGroup" +CHECK_ALTERNATE_check7137="extra7137" +CHECK_SERVICENAME_extra7137="ec2" +CHECK_RISK_extra7137='If Security groups are not properly configured the attack surface is increased. ' +CHECK_REMEDIATION_extra7137='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.' +CHECK_DOC_extra7137='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html' +CHECK_CAF_EPIC_extra7137='Infrastructure Security' + +extra7137(){ + for regx in $REGIONS; do + SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`1433` && ToPort==`1434`)) && (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 for Microsoft SQL Server ports" "$regx" + done + else + textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Microsoft SQL Server ports" "$regx" + fi + done +} \ No newline at end of file diff --git a/groups/group17_internetexposed b/groups/group17_internetexposed index 9cf2563c..8df4a499 100644 --- a/groups/group17_internetexposed +++ b/groups/group17_internetexposed @@ -15,7 +15,7 @@ GROUP_ID[17]='internet-exposed' GROUP_NUMBER[17]='17.0' GROUP_TITLE[17]='Find resources exposed to the internet - [internet-exposed] ***' GROUP_RUN_BY_DEFAULT[17]='N' # run it when execute_all is called -GROUP_CHECKS[17]='check41,check42,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102' +GROUP_CHECKS[17]='check41,check42,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102,extra7134,extra7135,extra7136,extra7137' # 4.1 [check41] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored) [group4, cislevel1, cislevel2] # 4.2 [check42] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored) [group4, cislevel1, cislevel2] diff --git a/groups/group7_extras b/groups/group7_extras index e7333d62..ea9ce095 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 8f784a45486f51ff411a1d2a9361a4d707c90247 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Sat, 24 Apr 2021 13:13:41 +0200 Subject: [PATCH 09/82] feat(network-acls): include checks to test NetworkACLs open to 22, 3389 and any port --- checks/check45 | 38 ++++++++++++++++++++++++++++++++++++++ checks/check46 | 38 ++++++++++++++++++++++++++++++++++++++ checks/check_extra7138 | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 checks/check45 create mode 100644 checks/check46 create mode 100644 checks/check_extra7138 diff --git a/checks/check45 b/checks/check45 new file mode 100644 index 00000000..7471e1ae --- /dev/null +++ b/checks/check45 @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_check45="4.5" +CHECK_TITLE_check45="[check45] Ensure no Network ACLs allow ingress from 0.0.0.0/0 to SSH port 22" +CHECK_SCORED_check45="SCORED" +CHECK_TYPE_check45="LEVEL2" +CHECK_SEVERITY_check45="High" +CHECK_ASFF_TYPE_check45="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" +CHECK_ASFF_RESOURCE_TYPE_check45="AwsEc2NetworkACLs" +CHECK_ALTERNATE_check401="check45" +CHECK_SERVICENAME_check45="ec2" +CHECK_RISK_check45='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' +CHECK_REMEDIATION_check45='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.' +CHECK_DOC_check45='' +CHECK_CAF_EPIC_check45='Infrastructure Security' + +check45(){ + for regx in $REGIONS; do + NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`22` && PortRange.To>=`22`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) + if [[ $NACL_LIST ]];then + for NACL in $NACL_LIST;do + textFail "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for SSH port 22" "$regx" + done + else + textPass "$regx: No Network ACL found with SSH port 22 open to 0.0.0.0/0" "$regx" + fi + done +} diff --git a/checks/check46 b/checks/check46 new file mode 100644 index 00000000..81225920 --- /dev/null +++ b/checks/check46 @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_check46="4.6" +CHECK_TITLE_check46="[check46] Ensure no Network ACLs allow ingress from 0.0.0.0/0 to Microsoft RDP port 3389" +CHECK_SCORED_check46="SCORED" +CHECK_TYPE_check46="LEVEL2" +CHECK_SEVERITY_check46="High" +CHECK_ASFF_TYPE_check46="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" +CHECK_ASFF_RESOURCE_TYPE_check46="AwsEc2NetworkACLs" +CHECK_ALTERNATE_check401="check46" +CHECK_SERVICENAME_check46="ec2" +CHECK_RISK_check46='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' +CHECK_REMEDIATION_check46='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.' +CHECK_DOC_check46='' +CHECK_CAF_EPIC_check46='Infrastructure Security' + +check46(){ + for regx in $REGIONS; do + NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`3389` && PortRange.To>=`3389`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) + if [[ $NACL_LIST ]];then + for NACL in $NACL_LIST;do + textFail "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for Microsoft RDP port 3389" "$regx" + done + else + textPass "$regx: No Network ACL found with Microsoft RDP port 3389 open to 0.0.0.0/0" "$regx" + fi + done +} diff --git a/checks/check_extra7138 b/checks/check_extra7138 new file mode 100644 index 00000000..21ec01f8 --- /dev/null +++ b/checks/check_extra7138 @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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. +Ensure no security groups +CHECK_ID_extra7138="7.138" +CHECK_TITLE_extra7138="[extra7138] Ensure no Network ACLs allow ingress from 0.0.0.0/0 to any port" +CHECK_SCORED_extra7138="NOT SCORED" +CHECK_TYPE_extra7138="LEVEL2" +CHECK_SEVERITY_extra7138="High" +CHECK_ASFF_TYPE_extra7138="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" +CHECK_ASFF_RESOURCE_TYPE_extra7138="AwsEc2NetworkACLs" +CHECK_ALTERNATE_check7138="extra7138" +CHECK_SERVICENAME_extra7138="ec2" +CHECK_RISK_extra7138='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' +CHECK_REMEDIATION_extra7138='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.' +CHECK_DOC_extra7138='' +CHECK_CAF_EPIC_extra7138='Infrastructure Security' + +extra7138(){ + for regx in $REGIONS; do + NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?((!PortRange) && (CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) + if [[ $NACL_LIST ]];then + for NACL in $NACL_LIST;do + textFail "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for any port" "$regx" + done + else + textPass "$regx: No Network ACL found with any port open to 0.0.0.0/0" "$regx" + fi + done +} \ No newline at end of file From 056190cfc92354cc82945111713936e8fbf7e8cd Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Sat, 24 Apr 2021 13:23:14 +0200 Subject: [PATCH 10/82] feat(network-acls): change textFail to textInfo because NACLs are stateless --- checks/check45 | 2 +- checks/check46 | 2 +- checks/check_extra7138 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/checks/check45 b/checks/check45 index 7471e1ae..f0e1d898 100644 --- a/checks/check45 +++ b/checks/check45 @@ -29,7 +29,7 @@ check45(){ NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`22` && PortRange.To>=`22`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) if [[ $NACL_LIST ]];then for NACL in $NACL_LIST;do - textFail "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for SSH port 22" "$regx" + textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for SSH port 22" "$regx" done else textPass "$regx: No Network ACL found with SSH port 22 open to 0.0.0.0/0" "$regx" diff --git a/checks/check46 b/checks/check46 index 81225920..97252df1 100644 --- a/checks/check46 +++ b/checks/check46 @@ -29,7 +29,7 @@ check46(){ NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`3389` && PortRange.To>=`3389`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) if [[ $NACL_LIST ]];then for NACL in $NACL_LIST;do - textFail "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for Microsoft RDP port 3389" "$regx" + textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for Microsoft RDP port 3389" "$regx" done else textPass "$regx: No Network ACL found with Microsoft RDP port 3389 open to 0.0.0.0/0" "$regx" diff --git a/checks/check_extra7138 b/checks/check_extra7138 index 21ec01f8..90c57f13 100644 --- a/checks/check_extra7138 +++ b/checks/check_extra7138 @@ -30,7 +30,7 @@ extra7138(){ NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?((!PortRange) && (CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) if [[ $NACL_LIST ]];then for NACL in $NACL_LIST;do - textFail "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for any port" "$regx" + textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for any port" "$regx" done else textPass "$regx: No Network ACL found with any port open to 0.0.0.0/0" "$regx" From 625384ad6d9c7419fd2406ff84f6bae3cc9df416 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Sat, 24 Apr 2021 13:38:36 +0200 Subject: [PATCH 11/82] feat(network-acls): include checks in networking and internetexposed checks --- groups/group17_internetexposed | 2 +- groups/group4_networking | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/groups/group17_internetexposed b/groups/group17_internetexposed index 8df4a499..33e30e18 100644 --- a/groups/group17_internetexposed +++ b/groups/group17_internetexposed @@ -15,7 +15,7 @@ GROUP_ID[17]='internet-exposed' GROUP_NUMBER[17]='17.0' GROUP_TITLE[17]='Find resources exposed to the internet - [internet-exposed] ***' GROUP_RUN_BY_DEFAULT[17]='N' # run it when execute_all is called -GROUP_CHECKS[17]='check41,check42,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102,extra7134,extra7135,extra7136,extra7137' +GROUP_CHECKS[17]='check41,check42,check45,check46,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102,extra7134,extra7135,extra7136,extra7137,extra7138' # 4.1 [check41] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored) [group4, cislevel1, cislevel2] # 4.2 [check42] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored) [group4, cislevel1, cislevel2] diff --git a/groups/group4_networking b/groups/group4_networking index 05b307b4..ca124465 100644 --- a/groups/group4_networking +++ b/groups/group4_networking @@ -12,4 +12,4 @@ GROUP_ID[4]='group4' GROUP_NUMBER[4]='4.0' GROUP_TITLE[4]='Networking - CIS only - [group4] *******************************' GROUP_RUN_BY_DEFAULT[4]='Y' # run it when execute_all is called -GROUP_CHECKS[4]='check41,check42,check43,check44' +GROUP_CHECKS[4]='check41,check42,check43,check44,check45,check46' From 2dc1ce61ec1375f036218fdcfc87491213385ec1 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Mon, 26 Apr 2021 12:30:44 +0200 Subject: [PATCH 12/82] fix(network-acls): fix line typo --- checks/check_extra7138 | 1 - 1 file changed, 1 deletion(-) diff --git a/checks/check_extra7138 b/checks/check_extra7138 index 90c57f13..a7b47806 100644 --- a/checks/check_extra7138 +++ b/checks/check_extra7138 @@ -10,7 +10,6 @@ # 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. -Ensure no security groups CHECK_ID_extra7138="7.138" CHECK_TITLE_extra7138="[extra7138] Ensure no Network ACLs allow ingress from 0.0.0.0/0 to any port" CHECK_SCORED_extra7138="NOT SCORED" From 2727b7e8e2391b7f2f577a02c6d95ab741246467 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Wed, 28 Apr 2021 18:50:20 +0200 Subject: [PATCH 13/82] fix(network-acls): update resource type to match AWS documentation --- checks/check45 | 2 +- checks/check46 | 2 +- checks/check_extra7138 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/checks/check45 b/checks/check45 index f0e1d898..299adbc1 100644 --- a/checks/check45 +++ b/checks/check45 @@ -16,7 +16,7 @@ CHECK_SCORED_check45="SCORED" CHECK_TYPE_check45="LEVEL2" CHECK_SEVERITY_check45="High" CHECK_ASFF_TYPE_check45="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" -CHECK_ASFF_RESOURCE_TYPE_check45="AwsEc2NetworkACLs" +CHECK_ASFF_RESOURCE_TYPE_check45="AwsEc2NetworkAcl" CHECK_ALTERNATE_check401="check45" CHECK_SERVICENAME_check45="ec2" CHECK_RISK_check45='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' diff --git a/checks/check46 b/checks/check46 index 97252df1..5f69998d 100644 --- a/checks/check46 +++ b/checks/check46 @@ -16,7 +16,7 @@ CHECK_SCORED_check46="SCORED" CHECK_TYPE_check46="LEVEL2" CHECK_SEVERITY_check46="High" CHECK_ASFF_TYPE_check46="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" -CHECK_ASFF_RESOURCE_TYPE_check46="AwsEc2NetworkACLs" +CHECK_ASFF_RESOURCE_TYPE_check46="AwsEc2NetworkAcl" CHECK_ALTERNATE_check401="check46" CHECK_SERVICENAME_check46="ec2" CHECK_RISK_check46='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' diff --git a/checks/check_extra7138 b/checks/check_extra7138 index a7b47806..e23f0a81 100644 --- a/checks/check_extra7138 +++ b/checks/check_extra7138 @@ -16,7 +16,7 @@ CHECK_SCORED_extra7138="NOT SCORED" CHECK_TYPE_extra7138="LEVEL2" CHECK_SEVERITY_extra7138="High" CHECK_ASFF_TYPE_extra7138="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" -CHECK_ASFF_RESOURCE_TYPE_extra7138="AwsEc2NetworkACLs" +CHECK_ASFF_RESOURCE_TYPE_extra7138="AwsEc2NetworkAcl" CHECK_ALTERNATE_check7138="extra7138" CHECK_SERVICENAME_extra7138="ec2" CHECK_RISK_extra7138='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' From ce00f3a019765f8ad448f5b5d0cdc2cba1b8f6a2 Mon Sep 17 00:00:00 2001 From: Pablo Pagani Date: Sat, 1 May 2021 17:33:54 -0300 Subject: [PATCH 14/82] improved error handling. Added check 7139 . --- checks/check_extra7139 | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 checks/check_extra7139 diff --git a/checks/check_extra7139 b/checks/check_extra7139 new file mode 100644 index 00000000..ad24f11b --- /dev/null +++ b/checks/check_extra7139 @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7139="7.139" +CHECK_TITLE_extra7139="[extra7139] There are High severity GuardDuty findings (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7139="NOT_SCORED" +CHECK_TYPE_extra7139="EXTRA" +CHECK_SEVERITY_extra7139="High" +CHECK_ASFF_RESOURCE_TYPE_extra7139="AwsGuardDutyDetector" +CHECK_ALTERNATE_check7138="extra7139" +CHECK_SERVICENAME_extra7139="guardduty" +CHECK_RISK_extra7139='If critical findings are not addressed threats can spread in the environment.' +CHECK_REMEDIATION_extra7139='Review and remediate critical GuardDuty findings as quickly as possible.' +CHECK_DOC_extra7139='https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_findings.html' +CHECK_CAF_EPIC_extra7139='Incident Response' +extra7139(){ + + for regx in $REGIONS; do + DETECTORS_LIST="" + DETECTORS_LIST=$($AWSCLI guardduty list-detectors --query DetectorIds $PROFILE_OPT --region $regx --output text) + if [[ $DETECTORS_LIST ]];then + for DETECTOR in $DETECTORS_LIST;do + FINDINGS_COUNT="" + FINDINGS_COUNT=$($AWSCLI $PROFILE_OPT --region $regx --output text guardduty list-findings --detector-id $DETECTOR --finding-criteria '{"Criterion":{"severity": {"Eq":["8"]}}}' 2> /dev/null | wc -l | xargs) # Severity LOW=2, MED=4, HIGH=8 + if [[ $FINDINGS_COUNT -gt 0 ]];then + textFail "$regx: GuardDuty has $FINDINGS_COUNT high severity findings." "$regx" + else + textPass "$regx: GuardDuty has no high severity findings." "$regx" + fi + done + else + textInfo "$regx: No GuardDuty detectors found." "$regx" + fi + done +} \ No newline at end of file From 9ac8c78fdb98810c0796b2ae05a480ee62f5563f Mon Sep 17 00:00:00 2001 From: Pablo Pagani <79593935+pablopagani@users.noreply.github.com> Date: Sat, 1 May 2021 17:47:08 -0300 Subject: [PATCH 15/82] improved error handling when listing regions --- prowler | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prowler b/prowler index 8d129916..21639796 100755 --- a/prowler +++ b/prowler @@ -295,7 +295,8 @@ TOTAL_CHECKS=($(echo "${TOTAL_CHECKS[*]}" | tr ' ' '\n' | awk '!seen[$0]++' | so get_regions() { # Get list of regions based on include/whoami REGIONS=$($AWSCLI ec2 describe-regions --query 'Regions[].RegionName' --output text $PROFILE_OPT --region $REGION_FOR_STS --region-names $FILTERREGION 2>&1) - if [[ $(echo "$REGIONS" | grep 'AccessDenied\|UnauthorizedOperation') ]]; then + ret=$? + if [[ $ret -ne 0 ]]; then echo "$OPTRED Access Denied trying to describe regions! Review permissions as described here: https://github.com/toniblyx/prowler/#requirements-and-installation $OPTNORMAL" EXITCODE=1 exit $EXITCODE From 5385c4e5467340965472e9ef766397ba4a33c7ea Mon Sep 17 00:00:00 2001 From: Pablo Pagani <79593935+pablopagani@users.noreply.github.com> Date: Sat, 1 May 2021 17:54:11 -0300 Subject: [PATCH 16/82] Improved error handling sts get-caller-identity Instead of looking for a fixed error string, it uses error codes from aws cli Previos condition was not catching this error message: An error occurred (ExpiredToken) when calling the GetCallerIdentity operation: The security token included in the request is expired Also forced the output of the command to json. In some tests I was doing was failing becuase it was sending output as text --- include/whoami | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/whoami b/include/whoami index a2fa3ce2..a7c6256e 100644 --- a/include/whoami +++ b/include/whoami @@ -29,8 +29,9 @@ case "$REGION" in ;; esac -GETCALLER=$($AWSCLI sts get-caller-identity $PROFILE_OPT --region $REGION_FOR_STS 2>&1) -if [[ $(echo "$GETCALLER" | grep 'Unable') ]]; then +GETCALLER=$($AWSCLI sts get-caller-identity $PROFILE_OPT --output json --region $REGION_FOR_STS 2>&1) +ret=$? +if [[ $ret -ne 0 ]]; then if [[ $PRINTCHECKSONLY || $PRINTGROUPSONLY ]]; then echo Listing... else From b72f66469e6fc0b3b7d308e080660b6c1195fae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Lipt=C3=A1k?= Date: Mon, 17 May 2021 11:23:51 -0400 Subject: [PATCH 17/82] Bump Alpine to 3.13 in Dockerfile --- util/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/Dockerfile b/util/Dockerfile index f7a5ee67..87911e46 100644 --- a/util/Dockerfile +++ b/util/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.9 +FROM alpine:3.13 ARG USERNAME=prowler ARG USERID=34000 From 8d9ca987b55a2ac5171281592ecc5a028c412a47 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 18 May 2021 15:41:45 +0200 Subject: [PATCH 18/82] Added link to doc for check45 check46 extra7138 and extras --- checks/check45 | 2 +- checks/check46 | 2 +- checks/check_extra7138 | 2 +- groups/group7_extras | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/checks/check45 b/checks/check45 index 299adbc1..fd847076 100644 --- a/checks/check45 +++ b/checks/check45 @@ -21,7 +21,7 @@ CHECK_ALTERNATE_check401="check45" CHECK_SERVICENAME_check45="ec2" CHECK_RISK_check45='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' CHECK_REMEDIATION_check45='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.' -CHECK_DOC_check45='' +CHECK_DOC_check45='https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html' CHECK_CAF_EPIC_check45='Infrastructure Security' check45(){ diff --git a/checks/check46 b/checks/check46 index 5f69998d..b98eb2f0 100644 --- a/checks/check46 +++ b/checks/check46 @@ -21,7 +21,7 @@ CHECK_ALTERNATE_check401="check46" CHECK_SERVICENAME_check46="ec2" CHECK_RISK_check46='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' CHECK_REMEDIATION_check46='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.' -CHECK_DOC_check46='' +CHECK_DOC_check46='https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html' CHECK_CAF_EPIC_check46='Infrastructure Security' check46(){ diff --git a/checks/check_extra7138 b/checks/check_extra7138 index e23f0a81..5af3d0ba 100644 --- a/checks/check_extra7138 +++ b/checks/check_extra7138 @@ -21,7 +21,7 @@ CHECK_ALTERNATE_check7138="extra7138" CHECK_SERVICENAME_extra7138="ec2" CHECK_RISK_extra7138='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.' CHECK_REMEDIATION_extra7138='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.' -CHECK_DOC_extra7138='' +CHECK_DOC_extra7138='https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html' CHECK_CAF_EPIC_extra7138='Infrastructure Security' extra7138(){ diff --git a/groups/group7_extras b/groups/group7_extras index ea9ce095..7fa96aaa 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 501082876cce6800105f109c7e6516568bbabc85 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 18 May 2021 16:08:10 +0200 Subject: [PATCH 19/82] Fixed alias of extra7139 --- checks/check_extra7139 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra7139 b/checks/check_extra7139 index ad24f11b..bfb10568 100644 --- a/checks/check_extra7139 +++ b/checks/check_extra7139 @@ -15,7 +15,7 @@ CHECK_SCORED_extra7139="NOT_SCORED" CHECK_TYPE_extra7139="EXTRA" CHECK_SEVERITY_extra7139="High" CHECK_ASFF_RESOURCE_TYPE_extra7139="AwsGuardDutyDetector" -CHECK_ALTERNATE_check7138="extra7139" +CHECK_ALTERNATE_check7139="extra7139" CHECK_SERVICENAME_extra7139="guardduty" CHECK_RISK_extra7139='If critical findings are not addressed threats can spread in the environment.' CHECK_REMEDIATION_extra7139='Review and remediate critical GuardDuty findings as quickly as possible.' From 30442b2da76ff4784bf3597c3896047878b935cf Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 18 May 2021 16:10:55 +0200 Subject: [PATCH 20/82] Added new check extra7140 for public SSM Documents --- checks/check_extra7140 | 41 +++++++++++++++++++++++++++++++++++++++++ groups/group7_extras | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 checks/check_extra7140 diff --git a/checks/check_extra7140 b/checks/check_extra7140 new file mode 100644 index 00000000..1c605cdb --- /dev/null +++ b/checks/check_extra7140 @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7140="7.140" +CHECK_TITLE_extra7140="[extra7140] Check if there are SSM Documents set as public" +CHECK_SCORED_extra7140="NOT_SCORED" +CHECK_TYPE_extra7140="EXTRA" +CHECK_SEVERITY_extra7140="High" +CHECK_ASFF_RESOURCE_TYPE_extra7140="AwsSsmDocument" +CHECK_ALTERNATE_check7140="extra7140" +CHECK_SERVICENAME_extra7140="ssm" +CHECK_RISK_extra7140='SSM Documents may contain private information or even secrets and tokens.' +CHECK_REMEDIATION_extra7140='Carefully review the contents of the document before is shared. Enable SSM Block public sharing for documents.' +CHECK_DOC_extra7140='https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-before-you-share.html' +CHECK_CAF_EPIC_extra7140='Data Protection' +extra7140(){ + + for regx in $REGIONS; do + SSM_DOCS=$($AWSCLI $PROFILE_OPT --region $regx ssm list-documents --filters Key=Owner,Values=Self --query DocumentIdentifiers[].Name --output text) + if [[ $SSM_DOCS ]];then + for ssmdoc in $SSM_DOCS; do + SSM_DOC_SHARED_ALL=$($AWSCLI $PROFILE_OPT --region $regx ssm describe-document-permission --name "$ssmdoc" --permission-type "Share" --query AccountIds[] --output text | grep all) + if [[ $SSM_DOC_SHARED_ALL ]];then + textFail "$regx: SSM Document $ssmdoc is public." "$regx" + else + textPass "$regx: SSM Document $ssmdoc is not public." "$regx" + fi + done + else + textInfo "$regx: No SSM Document found." "$regx" + fi + done +} \ No newline at end of file diff --git a/groups/group7_extras b/groups/group7_extras index 7fa96aaa..7dd686bb 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 1655bdb9025238694c1024993d18a2dc39c6bcdd Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 18 May 2021 16:57:37 +0200 Subject: [PATCH 21/82] Added resource id to RDS checks and in json,csv,html outputs --- checks/check_extra7113 | 7 +++---- checks/check_extra7131 | 6 +++--- checks/check_extra7132 | 6 +++--- checks/check_extra7133 | 6 +++--- checks/check_extra723 | 12 ++++++------ checks/check_extra735 | 7 +++---- checks/check_extra739 | 6 +++--- checks/check_extra747 | 6 +++--- checks/check_extra78 | 5 ++--- include/csv_header | 2 +- include/html_report | 1 + include/outputs | 40 +++++++++++++++++++++++++++++----------- 12 files changed, 60 insertions(+), 44 deletions(-) diff --git a/checks/check_extra7113 b/checks/check_extra7113 index a9dcbcce..aba1629e 100644 --- a/checks/check_extra7113 +++ b/checks/check_extra7113 @@ -36,20 +36,19 @@ CHECK_DOC_extra7113='https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER CHECK_CAF_EPIC_extra7113='Data Protection' extra7113(){ - textInfo "Looking for RDS Volumes in all regions... " for regx in $REGIONS; do LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].DBInstanceIdentifier' --output text) if [[ $LIST_OF_RDS_INSTANCES ]];then for rdsinstance in $LIST_OF_RDS_INSTANCES; do IS_DELETIONPROTECTION=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].DeletionProtection' --output text) if [[ $IS_DELETIONPROTECTION == "False" ]]; then - textFail "$regx: RDS instance $rdsinstance deletion protection is not enabled!" "$regx" + textFail "$regx: RDS instance $rdsinstance deletion protection is not enabled!" "$regx" "$rdsinstance" else - textPass "$regx: RDS instance $rdsinstance deletion protection is enabled" "$regx" + textPass "$regx: RDS instance $rdsinstance deletion protection is enabled" "$regx" "$rdsinstance" fi done else - textInfo "$regx: No RDS instances found" "$regx" + textInfo "$regx: No RDS instances found" "$regx" "$rdsinstance" fi done } diff --git a/checks/check_extra7131 b/checks/check_extra7131 index fc8266a1..946f1682 100644 --- a/checks/check_extra7131 +++ b/checks/check_extra7131 @@ -32,13 +32,13 @@ extra7131(){ RDS_NAME=$(echo $rds_instance | awk '{ print $1; }') RDS_AUTOMINORUPGRADE_FLAG=$(echo $rds_instance | awk '{ print $2; }') if [[ $RDS_AUTOMINORUPGRADE_FLAG == "True" ]];then - textPass "$regx: RDS instance: $RDS_NAME is has minor version upgrade enabled" "$regx" + textPass "$regx: RDS instance: $RDS_NAME is has minor version upgrade enabled" "$regx" "$RDS_NAME" else - textFail "$regx: RDS instance: $RDS_NAME does not have minor version upgrade enabled" "$regx" + textFail "$regx: RDS instance: $RDS_NAME does not have minor version upgrade enabled" "$regx" "$RDS_NAME" fi done <<< "$LIST_OF_RDS_INSTANCES" else - textInfo "$regx: no RDS instances found" "$regx" + textInfo "$regx: no RDS instances found" "$regx" "$RDS_NAME" fi done } diff --git a/checks/check_extra7132 b/checks/check_extra7132 index eb64827d..97e72ad0 100644 --- a/checks/check_extra7132 +++ b/checks/check_extra7132 @@ -31,13 +31,13 @@ extra7132(){ RDS_NAME="$rdsinstance" MONITORING_FLAG=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].[EnhancedMonitoringResourceArn]' --output text) if [[ $MONITORING_FLAG == "None" ]];then - textFail "$regx: RDS instance: $RDS_NAME has enhanced monitoring disabled!" "$rex" + textFail "$regx: RDS instance: $RDS_NAME has enhanced monitoring disabled!" "$rex" "$RDS_NAME" else - textPass "$regx: RDS instance: $RDS_NAME has enhanced monitoring enabled." "$regx" + textPass "$regx: RDS instance: $RDS_NAME has enhanced monitoring enabled." "$regx" "$RDS_NAME" fi done else - textInfo "$regx: no RDS instances found" "$regx" + textInfo "$regx: no RDS instances found" "$regx" "$RDS_NAME" fi done } diff --git a/checks/check_extra7133 b/checks/check_extra7133 index 2be3d662..62e8847d 100644 --- a/checks/check_extra7133 +++ b/checks/check_extra7133 @@ -31,13 +31,13 @@ extra7133(){ RDS_NAME="$rdsinstance" MULTIAZ_FLAG=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].MultiAZ' --output text) if [[ $MULTIAZ_FLAG == "True" ]];then - textPass "$regx: RDS instance: $RDS_NAME has multi-AZ enabled" "$rex" + textPass "$regx: RDS instance: $RDS_NAME has multi-AZ enabled" "$regx" "$RDS_NAME" else - textFail "$regx: RDS instance: $RDS_NAME has multi-AZ disabled!" "$regx" + textFail "$regx: RDS instance: $RDS_NAME has multi-AZ disabled!" "$regx" "$RDS_NAME" fi done else - textInfo "$regx: no RDS instances found" "$regx" + textInfo "$regx: no RDS instances found" "$regx" "$RDS_NAME" fi done } diff --git a/checks/check_extra723 b/checks/check_extra723 index 187f50ce..3e0cbd04 100644 --- a/checks/check_extra723 +++ b/checks/check_extra723 @@ -32,13 +32,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 - textFail "$regx: RDS Snapshot $rdssnapshot is public!" "$regx" + textFail "$regx: RDS Snapshot $rdssnapshot is public!" "$regx" "$rdssnapshot" else - textPass "$regx: RDS Snapshot $rdssnapshot is not shared" "$regx" + textPass "$regx: RDS Snapshot $rdssnapshot is not shared" "$regx" "$rdssnapshot" fi done else - textInfo "$regx: No RDS Snapshots found" "$regx" + textInfo "$regx: No RDS Snapshots found" "$regx" "$rdssnapshot" fi # RDS cluster snapshots LIST_OF_RDS_CLUSTER_SNAPSHOTS=$($AWSCLI rds describe-db-cluster-snapshots $PROFILE_OPT --region $regx --query DBClusterSnapshots[*].DBClusterSnapshotIdentifier --output text) @@ -46,13 +46,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 - textFail "$regx: RDS Cluster Snapshot $rdsclustersnapshot is public!" "$regx" + textFail "$regx: RDS Cluster Snapshot $rdsclustersnapshot is public!" "$regx" "$rdsclustersnapshot" else - textPass "$regx: RDS Cluster Snapshot $rdsclustersnapshot is not shared" "$regx" + textPass "$regx: RDS Cluster Snapshot $rdsclustersnapshot is not shared" "$regx" "$rdsclustersnapshot" fi done else - textInfo "$regx: No RDS Cluster Snapshots found" "$regx" + textInfo "$regx: No RDS Cluster Snapshots found" "$regx" "$rdsclustersnapshot" fi done } diff --git a/checks/check_extra735 b/checks/check_extra735 index 0b789f5e..f1d07aba 100644 --- a/checks/check_extra735 +++ b/checks/check_extra735 @@ -25,20 +25,19 @@ CHECK_DOC_extra735='https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overv CHECK_CAF_EPIC_extra735='Data Protection' extra735(){ - textInfo "Looking for RDS Volumes in all regions... " for regx in $REGIONS; do LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].DBInstanceIdentifier' --output text) if [[ $LIST_OF_RDS_INSTANCES ]];then for rdsinstance in $LIST_OF_RDS_INSTANCES; do IS_ENCRYPTED=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].StorageEncrypted' --output text) if [[ $IS_ENCRYPTED == "False" ]]; then - textFail "$regx: RDS instance $rdsinstance is not encrypted!" "$regx" + textFail "$regx: RDS instance $rdsinstance is not encrypted!" "$regx" "$rdsinstance" else - textPass "$regx: RDS instance $rdsinstance is encrypted" "$regx" + textPass "$regx: RDS instance $rdsinstance is encrypted" "$regx" "$rdsinstance" fi done else - textInfo "$regx: No RDS instances found" "$regx" + textInfo "$regx: No RDS instances found" "$regx" "$rdsinstance" fi done } diff --git a/checks/check_extra739 b/checks/check_extra739 index e36f4ab1..0cf5eb98 100644 --- a/checks/check_extra739 +++ b/checks/check_extra739 @@ -31,13 +31,13 @@ extra739(){ # if retention is 0 then is disabled BACKUP_RETENTION=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].BackupRetentionPeriod' --output text) if [[ $BACKUP_RETENTION == "0" ]]; then - textFail "$regx: RDS instance $rdsinstance has not backup enabled!" "$regx" + textFail "$regx: RDS instance $rdsinstance has not backup enabled!" "$regx" "$rdsinstance" else - textPass "$regx: RDS instance $rdsinstance has backup enabled with retention period $BACKUP_RETENTION days" "$regx" + textPass "$regx: RDS instance $rdsinstance has backup enabled with retention period $BACKUP_RETENTION days" "$regx" "$rdsinstance" fi done else - textInfo "$regx: No RDS instances found" "$regx" + textInfo "$regx: No RDS instances found" "$regx" "$rdsinstance" fi done } diff --git a/checks/check_extra747 b/checks/check_extra747 index f2473563..ec6a86d8 100644 --- a/checks/check_extra747 +++ b/checks/check_extra747 @@ -31,13 +31,13 @@ extra747(){ # if retention is 0 then is disabled ENABLED_CLOUDWATCHLOGS_EXPORTS=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].EnabledCloudwatchLogsExports' --output text) if [[ $ENABLED_CLOUDWATCHLOGS_EXPORTS ]]; then - textPass "$regx: RDS instance $rdsinstance is shipping $ENABLED_CLOUDWATCHLOGS_EXPORTS to CloudWatch Logs" "$regx" + textPass "$regx: RDS instance $rdsinstance is shipping $ENABLED_CLOUDWATCHLOGS_EXPORTS to CloudWatch Logs" "$regx" "$rdsinstance" else - textFail "$regx: RDS instance $rdsinstance has no CloudWatch Logs enabled!" "$regx" + textFail "$regx: RDS instance $rdsinstance has no CloudWatch Logs enabled!" "$regx" "$rdsinstance" fi done else - textInfo "$regx: No RDS instances found" "$regx" + textInfo "$regx: No RDS instances found" "$regx" "$rdsinstance" fi done } diff --git a/checks/check_extra78 b/checks/check_extra78 index 16d91ba2..a164eddb 100644 --- a/checks/check_extra78 +++ b/checks/check_extra78 @@ -27,17 +27,16 @@ CHECK_CAF_EPIC_extra78='Data Protection' 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) 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; }') - textFail "$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" "$RDS_NAME" done <<< "$LIST_OF_RDS_PUBLIC_INSTANCES" else - textPass "$regx: no Publicly Accessible RDS instances found" "$regx" + textPass "$regx: no Publicly Accessible RDS instances found" "$regx" "$RDS_NAME" fi done } diff --git a/include/csv_header b/include/csv_header index 7a867815..3ab095c3 100644 --- a/include/csv_header +++ b/include/csv_header @@ -15,6 +15,6 @@ printCsvHeader() { # >&2 echo "" # >&2 echo "Generating \"${SEP}\" delimited report on stdout for profile $PROFILE, account $ACCOUNT_NUM" - echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}CHECK_RESULT${SEP}ITEM_SCORED${SEP}ITEM_LEVEL${SEP}TITLE_TEXT${SEP}CHECK_RESULT_EXTENDED${SEP}CHECK_ASFF_COMPLIANCE_TYPE${SEP}CHECK_SEVERITY${SEP}CHECK_SERVICENAME${SEP}CHECK_ASFF_RESOURCE_TYPE${SEP}CHECK_ASFF_TYPE${SEP}CHECK_RISK${SEP}CHECK_REMEDIATION${SEP}CHECK_DOC${SEP}CHECK_CAF_EPIC" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}CHECK_RESULT${SEP}ITEM_SCORED${SEP}ITEM_LEVEL${SEP}TITLE_TEXT${SEP}CHECK_RESULT_EXTENDED${SEP}CHECK_ASFF_COMPLIANCE_TYPE${SEP}CHECK_SEVERITY${SEP}CHECK_SERVICENAME${SEP}CHECK_ASFF_RESOURCE_TYPE${SEP}CHECK_ASFF_TYPE${SEP}CHECK_RISK${SEP}CHECK_REMEDIATION${SEP}CHECK_DOC${SEP}CHECK_CAF_EPIC${SEP}CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV # echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}RESULT${SEP}SCORED${SEP}LEVEL${SEP}TITLE_TEXT${SEP}NOTES${SEP}COMPLIANCE${SEP}SEVERITY${SEP}SERVICENAME" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV } diff --git a/include/html_report b/include/html_report index 42db8626..5db51f08 100644 --- a/include/html_report +++ b/include/html_report @@ -158,6 +158,7 @@ addHtmlHeader() { Risk Remediation Link to doc + Resource ID diff --git a/include/outputs b/include/outputs index 5cfa4fe9..bd22569e 100644 --- a/include/outputs +++ b/include/outputs @@ -77,6 +77,7 @@ fi textPass(){ CHECK_RESULT="PASS" CHECK_RESULT_EXTENDED="$1" + CHECK_RESOURCE_ID="$3" if [[ "$QUIET" == 1 ]]; then return @@ -89,13 +90,13 @@ textPass(){ REPREGION=$REGION fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then - generateJsonOutput "$1" "Pass" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_JSON + generateJsonOutput "$1" "Pass" "$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_JSON fi if [[ "${MODES[@]}" =~ "json-asff" ]]; then - JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "PASSED") + JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "PASSED" "$CHECK_RESOURCE_ID") echo "${JSON_ASFF_OUTPUT}" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_ASFF if [[ "${SEND_TO_SECURITY_HUB}" -eq 1 ]]; then sendToSecurityHub "${JSON_ASFF_OUTPUT}" "${REPREGION}" @@ -118,6 +119,7 @@ textPass(){ textInfo(){ CHECK_RESULT="INFO" CHECK_RESULT_EXTENDED="$1" + CHECK_RESOURCE_ID="$3" if [[ "$QUIET" == 1 ]]; then return @@ -129,10 +131,10 @@ textInfo(){ REPREGION=$REGION fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then - generateJsonOutput "$1" "Info" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} + generateJsonOutput "$1" "Info" "$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} fi if is_junit_output_enabled; then output_junit_info "$1" @@ -144,7 +146,7 @@ textInfo(){ echo " $NOTICE INFO! $1 $NORMAL" fi if [[ "${MODES[@]}" =~ "html" ]]; then - generateHtmlOutput "$1" "INFO" + generateHtmlOutput "$1" "INFO" "$CHECK_RESOURCE_ID" fi } @@ -176,6 +178,7 @@ textFail(){ CHECK_RESULT=$level CHECK_RESULT_EXTENDED="$1" + CHECK_RESOURCE_ID="$3" if [[ $2 ]]; then REPREGION=$2 @@ -184,13 +187,13 @@ textFail(){ fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then - generateJsonOutput "$1" "${level}" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} + generateJsonOutput "$1" "${level}" "$CHECK_RESOURCE_ID"| tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} fi if [[ "${MODES[@]}" =~ "json-asff" ]]; then - JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "${level}") + JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "${level}" "$CHECK_RESOURCE_ID") echo "${JSON_ASFF_OUTPUT}" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_ASFF} if [[ "${SEND_TO_SECURITY_HUB}" -eq 1 ]]; then sendToSecurityHub "${JSON_ASFF_OUTPUT}" "${REPREGION}" @@ -210,7 +213,7 @@ textFail(){ echo " $colorcode ${level}! $1 $NORMAL" fi if [[ "${MODES[@]}" =~ "html" ]]; then - generateHtmlOutput "$1" "${level}" + generateHtmlOutput "$1" "${level}" "$CHECK_RESOURCE_ID" fi } @@ -265,6 +268,7 @@ textTitle(){ generateJsonOutput(){ local message=$1 local status=$2 + local resource_id=$3 jq -M -c \ --arg PROFILE "$PROFILE" \ --arg ACCOUNT_NUM "$ACCOUNT_NUM" \ @@ -279,6 +283,11 @@ generateJsonOutput(){ --arg TYPE "$CHECK_ASFF_COMPLIANCE_TYPE" \ --arg TIMESTAMP "$(get_iso8601_timestamp)" \ --arg SERVICENAME "$CHECK_SERVICENAME" \ + --arg CHECK_CAF_EPIC "$CHECK_CAF_EPIC" \ + --arg CHECK_RISK "$CHECK_RISK" \ + --arg CHECK_REMEDIATION "$CHECK_REMEDIATION" \ + --arg CHECK_DOC "$CHECK_DOC" \ + --arg CHECK_RESOURCE_ID "$resource_id" \ -n '{ "Profile": $PROFILE, "Account Number": $ACCOUNT_NUM, @@ -292,7 +301,12 @@ generateJsonOutput(){ "Region": $REPREGION, "Timestamp": $TIMESTAMP, "Compliance": $TYPE, - "Service": $SERVICENAME + "Service": $SERVICENAME, + "CAF Epic": $CHECK_CAF_EPIC, + "Risk": $CHECK_RISK, + "Remediation": $CHECK_REMEDIATION, + "Doc link": $CHECK_DOC, + "Resource ID": $CHECK_RESOURCE_ID }' } @@ -377,6 +391,7 @@ generateHtmlOutput(){ echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_RESOURCE_ID'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi if [[ $status == "PASS" ]];then @@ -395,6 +410,7 @@ generateHtmlOutput(){ echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_RESOURCE_ID'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi if [[ $status == "FAIL" ]];then @@ -413,6 +429,7 @@ generateHtmlOutput(){ echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_RESOURCE_ID'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi if [[ $status == "WARNING" ]];then @@ -431,6 +448,7 @@ generateHtmlOutput(){ echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_RESOURCE_ID'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''>> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi } \ No newline at end of file From 78e5dc5dba71d23ac6d9cfbda93952d60a17255c Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 18 May 2021 18:28:15 +0200 Subject: [PATCH 22/82] Added new check extra7141 to detect secrets in SSM Documents --- checks/check_extra7141 | 55 ++++++++++++++++++++++++++++++++++++++++++ groups/group11_secrets | 7 +----- groups/group7_extras | 2 +- 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 checks/check_extra7141 diff --git a/checks/check_extra7141 b/checks/check_extra7141 new file mode 100644 index 00000000..3bb32926 --- /dev/null +++ b/checks/check_extra7141 @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2019) 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_extra7141="7.7141" +CHECK_TITLE_extra7141="[extra7141] Find secrets in SSM Documents" +CHECK_SCORED_extra7141="NOT_SCORED" +CHECK_TYPE_extra7141="EXTRA" +CHECK_SEVERITY_extra7141="Critical" +CHECK_ASFF_RESOURCE_TYPE_extra7141="AwsSsmDocument" +CHECK_ALTERNATE_check7141="extra7141" +CHECK_SERVICENAME_extra7141="ssm" +CHECK_RISK_extra7141='Secrets hardcoded into SSM Documents by malware and bad actors to gain lateral access to other services.' +CHECK_REMEDIATION_extra7141='Implement automated detective control (e.g. using tools like Prowler) to scan accounts for passwords and secrets. Use Secrets Manager service to store and retrieve passwords and secrets.' +CHECK_DOC_extra7141='https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-secretsmanager-secret-generatesecretstring.html' +CHECK_CAF_EPIC_extra7141='IAM' + +extra7141(){ + SECRETS_TEMP_FOLDER="$PROWLER_DIR/secrets-$ACCOUNT_NUM" + if [[ ! -d $SECRETS_TEMP_FOLDER ]]; then + # this folder is deleted once this check is finished + mkdir $SECRETS_TEMP_FOLDER + fi + + for regx in $REGIONS; do + SSM_DOCS=$($AWSCLI $PROFILE_OPT --region $regx ssm list-documents --filters Key=Owner,Values=Self --query DocumentIdentifiers[].Name --output text) + if [[ $SSM_DOCS ]];then + for ssmdoc in $SSM_DOCS; do + SSM_DOC_FILE="$SECRETS_TEMP_FOLDER/extra7141-$ssmdoc-$regx-content.txt" + $AWSCLI $PROFILE_OPT --region $regx ssm get-document --name $ssmdoc --output text --document-format JSON > $SSM_DOC_FILE + FINDINGS=$(secretsDetector file $SSM_DOC_FILE) + if [[ $FINDINGS -eq 0 ]]; then + textPass "$regx: No secrets found in SSM Document $ssmdoc" "$regx" "$ssmdoc" + # delete file if nothing interesting is there + rm -f $SSM_DOC_FILE + else + textFail "$regx: Potential secret found SSM Document $ssmdoc" "$regx" "$ssmdoc" + # delete file to not leave trace, user must look at the CFN Stack + rm -f $SSM_DOC_FILE + fi + done + else + textInfo "$regx: No SSM Document found." "$regx" + fi + done + rm -rf $SECRETS_TEMP_FOLDER +} diff --git a/groups/group11_secrets b/groups/group11_secrets index 52a2df02..76d46056 100644 --- a/groups/group11_secrets +++ b/groups/group11_secrets @@ -15,13 +15,8 @@ GROUP_ID[11]='secrets' GROUP_NUMBER[11]='11.0' GROUP_TITLE[11]='Look for keys secrets or passwords around resources - [secrets]' GROUP_RUN_BY_DEFAULT[11]='N' # but it runs when execute_all is called (default) -GROUP_CHECKS[11]='extra741,extra742,extra759,extra760,extra768,extra775' +GROUP_CHECKS[11]='extra741,extra742,extra759,extra760,extra768,extra775,extra7141' # requires https://github.com/Yelp/detect-secrets # `pip install detect-secrets` -# Initially: -# - EC2 UserData -# - CloudFormation Outputs -# - Lambda variables -# - Lambda code diff --git a/groups/group7_extras b/groups/group7_extras index 7dd686bb..fa5e60a1 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 229d9ba00c779940f8955b49612984932d732a18 Mon Sep 17 00:00:00 2001 From: Josh Moss <45637452+Outrun207@users.noreply.github.com> Date: Thu, 20 May 2021 12:36:30 -0400 Subject: [PATCH 23/82] ALB Header Check --- checks/check_extra7142 | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 checks/check_extra7142 diff --git a/checks/check_extra7142 b/checks/check_extra7142 new file mode 100644 index 00000000..4e42eb26 --- /dev/null +++ b/checks/check_extra7142 @@ -0,0 +1,39 @@ +#!/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_extra7142="7.142" +CHECK_TITLE_extra7142="[extra7142] Check if Application Load Balancer is dropping invalid packets to prevent header based http request smuggling" +CHECK_SCORED_extra7142="NOT_SCORED" +CHECK_TYPE_extra7142="EXTRA" +CHECK_SEVERITY_extra7142="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7142="AwsElasticLoadBalancingV2LoadBalancer" +CHECK_ALTERNATE_check7142="extra7142" +CHECK_ASFF_COMPLIANCE_TYPE_extra7142="" +CHECK_SERVICENAME_extra7142="elb" + +extra7142(){ + for regx in $REGIONS; do + LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application`].[LoadBalancerArn]' --output text) + if [[ $LIST_OF_ELBSV2 ]];then + for alb in $LIST_OF_ELBSV2;do + CHECK_IF_DROP_INVALID_HEADER_FIELDS=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $alb --query 'Attributes[6]' --output text|grep -i true) + if [[ $CHECK_IF_DROP_INVALID_HEADER_FIELDS ]];then + textPass "Application Load Balancer $alb is dropping invalid header fields" + else + textFail "Application Load Balancer $alb is not dropping invalid header fields" + fi + done + else + textInfo "no ALBs found" + fi + done +} \ No newline at end of file From a711b482dff11f76d647690d89a38829faf7b550 Mon Sep 17 00:00:00 2001 From: "Sam (Yang) Li" Date: Thu, 20 May 2021 14:49:53 -0400 Subject: [PATCH 24/82] Fix #795 custom file option --- include/outputs | 22 ++++++++++++---------- prowler | 12 ++++++++---- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/outputs b/include/outputs index 5cfa4fe9..ce6d6dfa 100644 --- a/include/outputs +++ b/include/outputs @@ -19,7 +19,7 @@ EXTENSION_ASFF="asff-json" EXTENSION_TEXT="txt" EXTENSION_HTML="html" OUTPUT_DATE=$(date -u +"%Y%m%d%H%M%S") -OUTPUT_DIR="${PROWLER_DIR}/output" # default output if none +OUTPUT_DIR="${PROWLER_DIR}/output" # default output if none if [[ $OUTPUT_DIR_CUSTOM ]]; then # output mode has to be set to other than text if [[ ! " ${MODES[@]} " =~ " text " || ${check_id} == 7.1 || ${check_id} == 7.74 ]]; then @@ -32,9 +32,11 @@ if [[ $OUTPUT_DIR_CUSTOM ]]; then else echo "$OPTRED ERROR!$OPTNORMAL - Mode (-M) has to be set as well. Use -h for help." exit 1 - fi + fi +fi +if [ -z ${OUTPUT_FILE_NAME+x} ]; then + OUTPUT_FILE_NAME="${OUTPUT_DIR}/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}" fi -OUTPUT_FILE_NAME="${OUTPUT_DIR}/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}" HTML_LOGO_URL="https://github.com/toniblyx/prowler/" HTML_LOGO_IMG="https://github.com/toniblyx/prowler/raw/2.4/util/html/prowler-logo-new.png" TIMESTAMP=$(get_iso8601_timestamp) @@ -46,19 +48,19 @@ PROWLER_PARAMETERS=$@ # $ACCOUNT_NUM AWS Account ID # $REPREGION AWS region scanned # $TITLE_ID Numeric identifier of each check (1.2, 2.3, etc), originally based on CIS checks. -# $CHECK_RESULT values can be PASS, FAIL, INFO or WARNING if whitelisted +# $CHECK_RESULT values can be PASS, FAIL, INFO or WARNING if whitelisted # $ITEM_SCORED corresponds to CHECK_SCORED, values can be Scored/Not Scored. This is CIS only, will be deprecated in Prowler. # $ITEM_LEVEL corresponds to CHECK_TYPE_ currently only for CIS Level 1, CIS Level 2 and Extras (all checks not part of CIS) -# $TITLE_TEXT corresponds to CHECK_TITLE_ shows title of each check +# $TITLE_TEXT corresponds to CHECK_TITLE_ shows title of each check # $CHECK_RESULT_EXTENDED shows response of each check per resource like sg-123438 is open! -# $CHECK_ASFF_COMPLIANCE_TYPE specify type from taxonomy https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format-type-taxonomy.html +# $CHECK_ASFF_COMPLIANCE_TYPE specify type from taxonomy https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format-type-taxonomy.html # $CHECK_SEVERITY severity Low, Medium, High, Critical # $CHECK_SERVICENAME AWS service name short name # $CHECK_ASFF_RESOURCE_TYPE values from https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format.html#asff-resources # $CHECK_ASFF_TYPE generic type from taxonomy here https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format-type-taxonomy.html -# $CHECK_RISK text about risk -# $CHECK_REMEDIATION text about remediation -# $CHECK_DOC link to related documentation +# $CHECK_RISK text about risk +# $CHECK_REMEDIATION text about remediation +# $CHECK_DOC link to related documentation # $CHECK_CAF_EPIC it can be Logging and Monitoring, IAM, Data Protection, Infrastructure Security. Incident Response is not included since CAF has not specific checks on it logs enablement are part of Logging and Monitoring. # Ensure that output directory always exists when -M is used @@ -433,4 +435,4 @@ generateHtmlOutput(){ echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''>> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi -} \ No newline at end of file +} diff --git a/prowler b/prowler index 528aec4a..f62b16e9 100755 --- a/prowler +++ b/prowler @@ -104,13 +104,14 @@ USAGE: (i.e.: -M csv -o /tmp/reports/) -B Custom output bucket, requires -M and it can work also with -o flag. (i.e.: -M csv -B my-bucket or -M csv -B my-bucket/folder/) + -F Custom output report name, if not specified will use default output/prowler-output-ACCOUNT_NUM-OUTPUT_DATE -V show version number & exit -h this help " exit } -while getopts ":hlLkqp:r:c:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:" OPTION; do +while getopts ":hlLkqp:r:c:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:F:" OPTION; do case $OPTION in h ) usage @@ -200,6 +201,9 @@ while getopts ":hlLkqp:r:c:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:" OPTION; do B ) OUTPUT_BUCKET=$OPTARG ;; + F ) + OUTPUT_FILE_NAME=$OPTARG + ;; : ) echo "" echo "$OPTRED ERROR!$OPTNORMAL -$OPTARG requires an argument" @@ -356,7 +360,7 @@ show_group_title() { execute_check() { if [[ $ACCOUNT_TO_ASSUME ]]; then - # Following logic looks for time remaining in the session and review it + # Following logic looks for time remaining in the session and review it # if it is less than 600 seconds, 10 minutes. CURRENT_TIMESTAMP=$(date -u "+%s") SESSION_TIME_REMAINING=$(expr $AWS_SESSION_EXPIRATION - $CURRENT_TIMESTAMP) @@ -369,7 +373,7 @@ execute_check() { fi fi - CHECK_ID="$1" + CHECK_ID="$1" # See if this is an alternate name for a check # for example, we might have been passed 1.01 which is another name for 1.1 @@ -382,7 +386,7 @@ execute_check() { local asff_compliance_type_var=CHECK_ASFF_COMPLIANCE_TYPE_$1 CHECK_ASFF_COMPLIANCE_TYPE="${!asff_compliance_type_var:-Software and Configuration Checks}" - + # See if this check defines an ASFF Resource Type, if so, use this, falling back to a sane default # For a list of Resource Types, see: https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format.html#asff-resources local asff_resource_type_var=CHECK_ASFF_RESOURCE_TYPE_$1 From e3893c7d5b259c85c6731adffa3d611683b79827 Mon Sep 17 00:00:00 2001 From: Josh Moss <45637452+Outrun207@users.noreply.github.com> Date: Tue, 25 May 2021 13:49:27 -0400 Subject: [PATCH 25/82] Update check_extra7142 --- checks/check_extra7142 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/checks/check_extra7142 b/checks/check_extra7142 index 4e42eb26..9822fce2 100644 --- a/checks/check_extra7142 +++ b/checks/check_extra7142 @@ -27,13 +27,13 @@ extra7142(){ for alb in $LIST_OF_ELBSV2;do CHECK_IF_DROP_INVALID_HEADER_FIELDS=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $alb --query 'Attributes[6]' --output text|grep -i true) if [[ $CHECK_IF_DROP_INVALID_HEADER_FIELDS ]];then - textPass "Application Load Balancer $alb is dropping invalid header fields" + textPass "$regx: Application Load Balancer $alb is dropping invalid header fields." "$regx" "$alb" else - textFail "Application Load Balancer $alb is not dropping invalid header fields" + textFail "$regx: Application Load Balancer $alb is not dropping invalid header fields" "$regx" "$alb" fi done else - textInfo "no ALBs found" + textInfo "$regx: no ALBs found" fi done -} \ No newline at end of file +} From baf5232cbc11ebbacc5a1d3ce0dbd565d341ca63 Mon Sep 17 00:00:00 2001 From: Dom Bellizzi Date: Sat, 29 May 2021 22:26:15 +0000 Subject: [PATCH 26/82] Fix finding customer kms keys in cli v2 for checks extra737 extra736 Key id is in position 6 in aws cli version 2.2.5, but in position 4 in aws cli 1.x Use --query to select only the data necessary and output in a consistent format --- checks/check_extra736 | 2 +- checks/check_extra737 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checks/check_extra736 b/checks/check_extra736 index 0b5993a7..660f34be 100644 --- a/checks/check_extra736 +++ b/checks/check_extra736 @@ -19,7 +19,7 @@ CHECK_ALTERNATE_check736="extra736" extra736(){ textInfo "Looking for KMS keys in all regions... " for regx in $REGIONS; do - LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --output text |grep -v :alias/aws/ |awk '{ print $4 }') + LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --query "Aliases[].[AliasName,TargetKeyId]" --output text |grep -v ^alias/aws/ |awk '{ print $2 }') if [[ $LIST_OF_CUSTOMER_KMS_KEYS ]];then for key in $LIST_OF_CUSTOMER_KMS_KEYS; do CHECK_POLICY=$($AWSCLI kms get-key-policy --key-id $key --policy-name default $PROFILE_OPT --region $regx --output text|awk '/Principal/{n=NR+1} n>=NR' |grep AWS\"\ :\ \"\\*\"$) diff --git a/checks/check_extra737 b/checks/check_extra737 index d10a301f..5fda36c5 100644 --- a/checks/check_extra737 +++ b/checks/check_extra737 @@ -19,7 +19,7 @@ CHECK_ALTERNATE_check737="extra737" extra737(){ textInfo "Looking for KMS keys in all regions... " for regx in $REGIONS; do - LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --output text |grep -v :alias/aws/ |awk '{ print $4 }') + LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --query "Aliases[].[AliasName,TargetKeyId]" --output text |grep -v ^alias/aws/ |awk '{ print $2 }') if [[ $LIST_OF_CUSTOMER_KMS_KEYS ]];then for key in $LIST_OF_CUSTOMER_KMS_KEYS; do CHECK_ROTATION=$($AWSCLI kms get-key-rotation-status --key-id $key $PROFILE_OPT --region $regx --output text) From 55e703540ef4bd23043c026814deb770a919fafa Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Mon, 31 May 2021 18:47:56 +0200 Subject: [PATCH 27/82] Fixed typo in check extra7141 ID --- checks/check_extra7141 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra7141 b/checks/check_extra7141 index 3bb32926..ff4ce69c 100644 --- a/checks/check_extra7141 +++ b/checks/check_extra7141 @@ -10,7 +10,7 @@ # 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_extra7141="7.7141" +CHECK_ID_extra7141="7.141" CHECK_TITLE_extra7141="[extra7141] Find secrets in SSM Documents" CHECK_SCORED_extra7141="NOT_SCORED" CHECK_TYPE_extra7141="EXTRA" From 5f1fa558c95cd6c04997ee31a278909d2e1e7bad Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 1 Jun 2021 09:09:25 +0200 Subject: [PATCH 28/82] Changes in text output with severity and service name --- include/outputs | 56 +++++++++++++++++++++++++------------------------ prowler | 4 +++- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/include/outputs b/include/outputs index bd22569e..f707bfa6 100644 --- a/include/outputs +++ b/include/outputs @@ -219,49 +219,51 @@ textFail(){ textTitle(){ CHECKS_COUNTER=$((CHECKS_COUNTER+1)) - TITLE_ID=$1 + TITLE_ID="$BLUE$1$NORMAL" if [[ $NUMERAL ]]; then # Left-pad the check ID with zeros to simplify sorting, e.g. 1.1 -> 1.01 TITLE_ID=$(awk -F'.' '{ printf "%d.%02d", $1, $2 }' <<< "$TITLE_ID") fi TITLE_TEXT=$2 + CHECK_SERVICENAME="$MAGENTA$3$NORMAL" + CHECK_SEVERITY="$BROWN[$4]$NORMAL" - case "$3" in - 0|No|NOT_SCORED) - ITEM_SCORED="Not Scored" - ;; - 1|Yes|SCORED) - ITEM_SCORED="Scored" - ;; - *) - ITEM_SCORED="Unspecified" - ;; - esac + # case "$3" in + # 0|No|NOT_SCORED) + # ITEM_SCORED="Not Scored" + # ;; + # 1|Yes|SCORED) + # ITEM_SCORED="Scored" + # ;; + # *) + # ITEM_SCORED="Unspecified" + # ;; + # esac - case "$4" in - LEVEL1) ITEM_LEVEL="Level 1";; - LEVEL2) ITEM_LEVEL="Level 2";; - EXTRA) ITEM_LEVEL="Extra";; - SUPPORT) ITEM_LEVEL="Support";; - *) ITEM_LEVEL="Unspecified or Invalid";; - esac + # case "$4" in + # LEVEL1) ITEM_LEVEL="Level 1";; + # LEVEL2) ITEM_LEVEL="Level 2";; + # EXTRA) ITEM_LEVEL="Extra";; + # SUPPORT) ITEM_LEVEL="Support";; + # *) ITEM_LEVEL="Unspecified or Invalid";; + # esac local group_ids - if [[ -n "$5" ]]; then - group_ids="$CYAN [$5] $NORMAL" - fi + # if [[ -n "$4" ]]; then + group_ids="$CYAN[$5]$NORMAL" + # fi if [[ "${MODES[@]}" =~ "csv" ]]; then >&2 echo "$TITLE_ID $TITLE_TEXT" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_CSV} elif [[ "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then : else - if [[ "$ITEM_SCORED" == "Scored" ]]; then - echo -e "\n$BLUE $TITLE_ID $NORMAL $TITLE_TEXT $6 $group_ids " - else - echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $6 $NORMAL $group_ids " - fi + # if [[ "$ITEM_SCORED" == "Scored" ]]; then + echo -e "$TITLE_ID $CHECK_SERVICENAME $TITLE_TEXT $CHECK_SEVERITY $group_ids " + # else + # echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $6 $NORMAL $group_ids " + # fi fi } diff --git a/prowler b/prowler index 528aec4a..2f9da953 100755 --- a/prowler +++ b/prowler @@ -322,6 +322,8 @@ show_check_title() { local check_scored=CHECK_SCORED_$1 local check_type=CHECK_TYPE_$1 local check_asff_compliance_type=CHECK_ASFF_COMPLIANCE_TYPE_$1 + local check_severity=CHECK_SEVERITY_$1 + local check_servicename=CHECK_SERVICENAME_$1 local group_ids local group_index # If requested ($2 is any non-null value) iterate all GROUP_CHECKS and produce a comma-separated list of all @@ -340,7 +342,7 @@ show_check_title() { if [[ ${GROUP_ID_READ} == "ens" ]];then textTitle "${!check_id}" "${!check_title}" "${!check_scored}" "${!check_type}" "$group_ids" "(${!check_asff_compliance_type})" else - textTitle "${!check_id}" "${!check_title}" "${!check_scored}" "${!check_type}" "$group_ids" + textTitle "${!check_id}" "${!check_title}" "${!check_servicename}" "${!check_severity}" "$group_ids" fi } From 311d21546de80724b0cdc90bc43ca664ee19f315 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 1 Jun 2021 09:10:51 +0200 Subject: [PATCH 29/82] Enhanced -f usage info --- prowler | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prowler b/prowler index 2f9da953..0981f0c5 100755 --- a/prowler +++ b/prowler @@ -74,7 +74,7 @@ USAGE: -g specify a group of checks by id, to see all available group of checks use "-L" (i.e.: "group3" for entire section 3, "cislevel1" for CIS Level 1 Profile Definitions or "forensics-ready") -f specify an AWS region to run checks against - (i.e.: us-west-1) + (i.e.: us-west-1 or for multiple regions use single quote like 'us-west-1 us-west-2') -m specify the maximum number of items to return for long-running requests (default: 100) -M output mode: text (default), mono, html, json, json-asff, junit-xml, csv. They can be used combined comma separated. (separator is ","; data is on stdout; progress on stderr). From 4ddf0aff862fa079a6b01c5bbd80cadb3a4ac68c Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 1 Jun 2021 12:28:30 +0200 Subject: [PATCH 30/82] Added extra7142 to group extras --- groups/group7_extras | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/group7_extras b/groups/group7_extras index fa5e60a1..2ecde56a 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 124ae0fd2e46c3e37cb8228f05685831096fd5f8 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Wed, 2 Jun 2021 17:53:12 +0200 Subject: [PATCH 31/82] Fixed kms keys compatibility in cli v2 and v1 --- checks/check_extra7126 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra7126 b/checks/check_extra7126 index f1b80877..7b91e0e2 100644 --- a/checks/check_extra7126 +++ b/checks/check_extra7126 @@ -26,7 +26,7 @@ CHECK_CAF_EPIC_extra7126='Data Protection' extra7126(){ for regx in $REGIONS; do - LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --output text |grep -v :alias/aws/ |awk '{ print $4 }') + LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --query "Aliases[].[AliasName,TargetKeyId]" --output text |grep -v ^alias/aws/ |awk '{ print $2 }') if [[ $LIST_OF_CUSTOMER_KMS_KEYS ]];then for key in $LIST_OF_CUSTOMER_KMS_KEYS; do CHECK_STATUS=$($AWSCLI kms describe-key --key-id $key $PROFILE_OPT --region $regx --output json | jq -r '.KeyMetadata.KeyState') From 5aeb670a846f4c5c5cbcf8835eb9a21f2654f6c9 Mon Sep 17 00:00:00 2001 From: h1008 <9917357+h1008@users.noreply.github.com> Date: Sat, 5 Jun 2021 11:57:04 +0200 Subject: [PATCH 32/82] Fixed issue #811 --- checks/check_extra7113 | 2 +- checks/check_extra7132 | 2 +- checks/check_extra7133 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/checks/check_extra7113 b/checks/check_extra7113 index a9dcbcce..26809c67 100644 --- a/checks/check_extra7113 +++ b/checks/check_extra7113 @@ -38,7 +38,7 @@ CHECK_CAF_EPIC_extra7113='Data Protection' extra7113(){ textInfo "Looking for RDS Volumes in all regions... " for regx in $REGIONS; do - LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].DBInstanceIdentifier' --output text) + LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text) if [[ $LIST_OF_RDS_INSTANCES ]];then for rdsinstance in $LIST_OF_RDS_INSTANCES; do IS_DELETIONPROTECTION=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].DeletionProtection' --output text) diff --git a/checks/check_extra7132 b/checks/check_extra7132 index eb64827d..4fbdfbc5 100644 --- a/checks/check_extra7132 +++ b/checks/check_extra7132 @@ -25,7 +25,7 @@ CHECK_CAF_EPIC_extra7132='Logging and Monitoring' extra7132(){ for regx in $REGIONS; do - RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].DBInstanceIdentifier' --output text) + RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text) if [[ $RDS_INSTANCES ]];then for rdsinstance in ${RDS_INSTANCES}; do RDS_NAME="$rdsinstance" diff --git a/checks/check_extra7133 b/checks/check_extra7133 index 2be3d662..6daec448 100644 --- a/checks/check_extra7133 +++ b/checks/check_extra7133 @@ -25,7 +25,7 @@ CHECK_CAF_EPIC_extra7133='Data Protection' extra7133(){ for regx in $REGIONS; do - RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].DBInstanceIdentifier' --output text) + RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text) if [[ $RDS_INSTANCES ]];then for rdsinstance in ${RDS_INSTANCES}; do RDS_NAME="$rdsinstance" From c74faa6d0748dd78dd21486fa2f8c7f998d4b983 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 8 Jun 2021 14:18:46 +0200 Subject: [PATCH 33/82] add missing * to align with the rest of the titles --- groups/group21_soc2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/groups/group21_soc2 b/groups/group21_soc2 index 20e3f0d5..84f2cac3 100644 --- a/groups/group21_soc2 +++ b/groups/group21_soc2 @@ -13,11 +13,11 @@ GROUP_ID[21]='soc2' GROUP_NUMBER[21]='21.0' -GROUP_TITLE[21]='SOC2 Readiness - ONLY AS REFERENCE - [soc2] ***' +GROUP_TITLE[21]='SOC2 Readiness - ONLY AS REFERENCE - [soc2] *******************' GROUP_RUN_BY_DEFAULT[21]='N' # run it when execute_all is called GROUP_CHECKS[21]='check110,check111,check113,check12,check122,check13,check15,check16,check17,check18,check19,check21,check31,check310,check32,check33,check34,check35,check36,check37,check38,check39,check41,check42,check43,extra711,extra72,extra723,extra729,extra731,extra734,extra735,extra739,extra76,extra78,extra792' # References: # 1. https://www.aicpa.org/content/dam/aicpa/interestareas/frc/assuranceadvisoryservices/downloadabledocuments/trust-services-criteria.pdf # 2. https://www.aicpa.org/interestareas/frc/assuranceadvisoryservices/mappingsrelevanttothesocsuiteofservices.html -# 3. https://www.aicpa.org/content/dam/aicpa/interestareas/frc/assuranceadvisoryservices/downloadabledocuments/othermapping/mapping-final-2017-tsc-to-extant-2016-tspc.xlsx \ No newline at end of file +# 3. https://www.aicpa.org/content/dam/aicpa/interestareas/frc/assuranceadvisoryservices/downloadabledocuments/othermapping/mapping-final-2017-tsc-to-extant-2016-tspc.xlsx From aa3edbc63657c605fb320505713bfbf47ec79a49 Mon Sep 17 00:00:00 2001 From: Pablo Pagani <79593935+pablopagani@users.noreply.github.com> Date: Wed, 9 Jun 2021 14:01:27 -0300 Subject: [PATCH 34/82] corrected bug on groups when listing checks corrected bug on groups when listing checks (option -l) Previous regular expression will include groups when it matched half of the check_id --- prowler | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/prowler b/prowler index e6075a09..b3cc2e09 100755 --- a/prowler +++ b/prowler @@ -330,16 +330,19 @@ show_check_title() { local check_servicename=CHECK_SERVICENAME_$1 local group_ids local group_index + local check_name # If requested ($2 is any non-null value) iterate all GROUP_CHECKS and produce a comma-separated list of all # the GROUP_IDs that include this particular check if [[ -n "$2" ]]; then for group_index in "${!GROUP_ID[@]}"; do - if [[ "${GROUP_CHECKS[$group_index]}" =~ "$1" ]]; then - if [[ -n "$group_ids" ]]; then - group_ids+=", " + for check_name in $(echo "${GROUP_CHECKS[$group_index]}" | sed "s/,/ /g");do + if [[ "$check_name" == "$1" ]]; then + if [[ -n "$group_ids" ]]; then + group_ids+=", " + fi + group_ids+="${GROUP_ID[$group_index]}" fi - group_ids+="${GROUP_ID[$group_index]}" - fi + done done fi # This shows ASFF_COMPLIANCE_TYPE if group used is ens, this si used to show ENS compliance ID control, can be used for other compliance groups as well. From 79a0eb622d95876755c86f53a487701698c5889c Mon Sep 17 00:00:00 2001 From: kamiryo Date: Thu, 10 Jun 2021 23:13:17 +0900 Subject: [PATCH 35/82] Add WAF CLASSIC check for extra7129 --- checks/check_extra7129 | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/checks/check_extra7129 b/checks/check_extra7129 index 130c8074..a96ad6c2 100644 --- a/checks/check_extra7129 +++ b/checks/check_extra7129 @@ -28,30 +28,45 @@ extra7129(){ for regx in $REGIONS; do LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Scheme == `internet-facing` && Type == `application`].[LoadBalancerName]' --output text) LIST_OF_WAFV2_WEBACL_ARN=$($AWSCLI wafv2 list-web-acls $PROFILE_OPT --region=$regx --scope=REGIONAL --query WebACLs[*].ARN --output text) + LIST_OF_WAFV1_WEBACL_WEBACLID=$($AWSCLI waf-regional list-web-acls $PROFILE_OPT --region $regx --query WebACLs[*].[WebACLId] --output text) + if [[ $LIST_OF_ELBSV2 ]]; then for alb in $LIST_OF_ELBSV2; do - if [[ $LIST_OF_WAFV2_WEBACL_ARN ]]; then + if [[ ${#LIST_OF_WAFV2_WEBACL_ARN[@]} -gt 0 || ${#LIST_OF_WAFV1_WEBACL_WEBACLID[@]} -gt 0 ]]; then WAF_PROTECTED_ALBS=() for wafaclarn in $LIST_OF_WAFV2_WEBACL_ARN; do ALB_RESOURCES_IN_WEBACL=$($AWSCLI wafv2 list-resources-for-web-acl $PROFILE_OPT --web-acl-arn $wafaclarn --region=$regx --resource-type APPLICATION_LOAD_BALANCER --query ResourceArns --output text | xargs -n1 | awk -F'/' '{ print $3 }'| grep $alb) - if [[ $ALB_RESOURCES_IN_WEBACL ]]; then + if [[ $ALB_RESOURCES_IN_WEBACL ]]; then WAF_PROTECTED_ALBS+=($wafaclarn) fi done - if [[ ${#WAF_PROTECTED_ALBS[@]} -gt 0 ]]; then - for wafaclarn in "${WAF_PROTECTED_ALBS[@]}"; do - WAFV2_WEBACL_ARN_SHORT=$(echo $wafaclarn | awk -F'/' '{ print $3 }') - textPass "$regx: Application Load Balancer $alb is protected by WAFv2 ACL $WAFV2_WEBACL_ARN_SHORT" "$regx" - done + for wafv1aclid in $LIST_OF_WAFV1_WEBACL_WEBACLID; do + ALB_RESOURCES_IN_WEBACL=$($AWSCLI waf-regional list-resources-for-web-acl $PROFILE_OPT --web-acl-id $wafv1aclid --region=$regx --resource-type APPLICATION_LOAD_BALANCER --output text --query "[ResourceArns]"| grep $alb) + if [[ $ALB_RESOURCES_IN_WEBACL ]]; then + WAFv1_PROTECTED_ALBS+=($wafv1aclid) + fi + done + if [[ ${#WAF_PROTECTED_ALBS[@]} -gt 0 || ${#WAFv1_PROTECTED_ALBS[@]} -gt 0 ]]; then + if [[ ${#WAF_PROTECTED_ALBS[@]} -gt 0 ]]; then + for wafaclarn in "${WAF_PROTECTED_ALBS[@]}"; do + WAFV2_WEBACL_ARN_SHORT=$(echo $wafaclarn | awk -F'/' '{ print $3 }') + textPass "$regx: Application Load Balancer $alb is protected by WAFv2 ACL $WAFV2_WEBACL_ARN_SHORT" "$regx" + done + fi + if [[ ${#WAFv1_PROTECTED_ALBS[@]} -gt 0 ]]; then + for wafv1aclid in "${WAFv1_PROTECTED_ALBS[@]}"; do + textPass "$regx: Application Load Balancer $alb is protected by WAFv1 ACL $wafv1aclid" "$regx" + done + fi else - textFail "$regx: Application Load Balancer $alb is not protected by WAFv2 ACL" "$regx" + textFail "$regx: Application Load Balancer $alb is not protected by WAF ACL" "$regx" fi - else - textFail "$regx: Application Load Balancer $alb is not protected no WAFv2 ACL found" "$regx" + else + textFail "$regx: Application Load Balancer $alb is not protected no WAF ACL found" "$regx" fi - done + done else textInfo "$regx: No Application Load Balancers found" "$regx" - fi + fi done } \ No newline at end of file From 8e9ef841e5b990e3955f796365ea0de1a751a31c Mon Sep 17 00:00:00 2001 From: Patel Date: Mon, 14 Jun 2021 12:43:21 +0530 Subject: [PATCH 36/82] Adding custom security checks --- checks/check_extra91 | 46 ++++++++++++++++++++++++++++++++++++++++++ checks/check_extra92 | 48 ++++++++++++++++++++++++++++++++++++++++++++ checks/check_extra93 | 35 ++++++++++++++++++++++++++++++++ checks/check_extra94 | 47 +++++++++++++++++++++++++++++++++++++++++++ checks/check_extra95 | 41 +++++++++++++++++++++++++++++++++++++ 5 files changed, 217 insertions(+) create mode 100644 checks/check_extra91 create mode 100644 checks/check_extra92 create mode 100644 checks/check_extra93 create mode 100644 checks/check_extra94 create mode 100644 checks/check_extra95 diff --git a/checks/check_extra91 b/checks/check_extra91 new file mode 100644 index 00000000..70afae9a --- /dev/null +++ b/checks/check_extra91 @@ -0,0 +1,46 @@ +#!/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_extra91="9.1" +CHECK_TITLE_extra91="[extra91] Check if S3 glacier vaults have policies which allow access to everyone (Not Scored) (Not part of CIS benchmark) (Custom Check)" +CHECK_SCORED_extra91="NOT_SCORED" +CHECK_TYPE_extra91="EXTRA" +CHECK_SEVERITY_extra91="Critical" +CHECK_ASFF_RESOURCE_TYPE_extra91="AwsS3Glacier" +CHECK_ALTERNATE_check91="extra91" +CHECK_SERVICENAME_extra91="s3Glacier" + +# If an s3 glacier vault has a policy principle as *, we consider it public accessible resource. + +extra91(){ + for region in $REGIONS; do + LIST_OF_VAULTS=$($AWSCLI glacier list-vaults $PROFILE_OPT --region $region --account-id $ACCOUNT_NUM --query VaultList[*].VaultName --output text|xargs -n1) + if [[ $LIST_OF_VAULTS ]]; then + for vault in $LIST_OF_VAULTS;do + VAULT_POLICY_STATEMENTS=$($AWSCLI glacier $PROFILE_OPT get-vault-access-policy --region $region --account-id $ACCOUNT_NUM --vault-name $vault --output json --query policy.Policy 2>&1) + if [[ $VAULT_POLICY_STATEMENTS == *GetVaultAccessPolicy* ]]; then + textInfo "Vault policy does not exist for vault $vault" + else + VAULT_POLICY_BAD_STATEMENTS=$(echo $VAULT_POLICY_STATEMENTS | jq '. | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') + if [[ $VAULT_POLICY_BAD_STATEMENTS != "" ]]; then + textFail "$region : Vault $vault allows public access with policy as: $VAULT_POLICY_BAD_STATEMENTS" + else + textPass "$region :Vault $vault has vault policy which does not allow public access" + fi + fi + done + + else + textInfo "No glacier vaults found in $region region" + fi + done +} diff --git a/checks/check_extra92 b/checks/check_extra92 new file mode 100644 index 00000000..0f76bd84 --- /dev/null +++ b/checks/check_extra92 @@ -0,0 +1,48 @@ +#!/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_extra92="9.2" +CHECK_TITLE_extra92="[extra92] Check if EFS have policies which allow access to everyone (Not Scored) (Not part of CIS benchmark) (Custom Check)" +CHECK_SCORED_extra92="NOT_SCORED" +CHECK_TYPE_extra92="EXTRA" +CHECK_SEVERITY_extra92="Critical" +CHECK_ASFF_RESOURCE_TYPE_extra92="AwsEFS" +CHECK_ALTERNATE_check92="extra92" +CHECK_SERVICENAME_extra92="EFS" + +# If an EFS has a policy principle as *, we consider it as public accessible even though client connects through a vpc peering or transit gateway. Also if EFS has a default policy(no user defined +# policy), it's also a security risk, as default policy grants full access to any client that can connect to the file system using a file system mount target. + +extra92(){ + for region in $REGIONS; do + LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $region --query FileSystems[*].FileSystemId --output text|xargs -n1) + if [[ $LIST_OF_EFS_IDS ]]; then + for efsId in $LIST_OF_EFS_IDS;do + EFS_POLICY_STATEMENTS=$($AWSCLI efs $PROFILE_OPT describe-file-system-policy --region $region --file-system-id $efsId --output json --query Policy 2>&1) + if [[ $EFS_POLICY_STATEMENTS == *PolicyNotFound* ]]; then + textFail "$region : EFS $efsId doesn't have any policy which means it grants full access to any client" + # textInfo "EFS policy does not exist for efs id $efsId" + else + EFS_POLICY_BAD_STATEMENTS=$(echo $EFS_POLICY_STATEMENTS | jq '. | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') + if [[ $EFS_POLICY_BAD_STATEMENTS != "" ]]; then + textFail "$region : EFS $efsId allows public access with policy as: $EFS_POLICY_BAD_STATEMENTS" + else + textPass "$region : EFS $efsId has file system policy which does not allow public access" + fi + fi + done + + else + textInfo "No EFS found in $region region" + fi + done +} diff --git a/checks/check_extra93 b/checks/check_extra93 new file mode 100644 index 00000000..c9aed63d --- /dev/null +++ b/checks/check_extra93 @@ -0,0 +1,35 @@ +#!/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_extra93="9.3" +CHECK_TITLE_extra93="[extra93] Check if aws cloudwatch has allowed sharing with other accounts (Not Scored) (Not part of CIS benchmark) (Custom Check)" +CHECK_SCORED_extra93="NOT_SCORED" +CHECK_TYPE_extra93="EXTRA" +CHECK_SEVERITY_extra93="Critical" +CHECK_ASFF_RESOURCE_TYPE_extra93="AwsCloudWatch" +CHECK_ALTERNATE_check93="extra93" +CHECK_SERVICENAME_extra93="CloudWatch" + +# When CloudWatch allows cross account sharing, a role with name CloudWatch-CrossAccountSharingRole get's created by aws itself. So we are validating role name existance for checking the +# cloudwatch security. + +extra93(){ + + CLOUDWATCH_CROSS_ACCOUNT_ROLE=$($AWSCLI iam get-role $PROFILE_OPT --role-name=CloudWatch-CrossAccountSharingRole --output json --query Role 2>&1) + if [[ $CLOUDWATCH_CROSS_ACCOUNT_ROLE != *NoSuchEntity* ]]; then + CLOUDWATCH_POLICY_BAD_STATEMENTS=$(echo $CLOUDWATCH_CROSS_ACCOUNT_ROLE | jq '.AssumeRolePolicyDocument') + textFail "Cloudwatch has allowed cross account sharing with policy as $CLOUDWATCH_POLICY_BAD_STATEMENTS" + else + textPass "CloudWatch doesn't allows cross account sharing" + fi +} diff --git a/checks/check_extra94 b/checks/check_extra94 new file mode 100644 index 00000000..bd721d92 --- /dev/null +++ b/checks/check_extra94 @@ -0,0 +1,47 @@ +#!/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_extra94="9.4" +CHECK_TITLE_extra94="[extra94] Check if lambda functions has policies which allow access to everyone having an aws account (Not Scored) (Not part of CIS benchmark) (Custom Check)" +CHECK_SCORED_extra94="NOT_SCORED" +CHECK_TYPE_extra94="EXTRA" +CHECK_SEVERITY_extra94="Critical" +CHECK_ASFF_RESOURCE_TYPE_extra94="AwsCloudWatch" +CHECK_ALTERNATE_check94="extra94" +CHECK_SERVICENAME_extra94="CloudWatch" + +# If a lambda function has a policy principle as *, It can be accessed by any aws account. We consider such functions as publicly accessible resource. + +extra94(){ + for region in $REGIONS; do + LIST_OF_LAMBDA_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $region --query Functions[*].FunctionName --output text) + if [[ $LIST_OF_LAMBDA_FUNCTIONS ]]; then + for lambdaFunction in $LIST_OF_LAMBDA_FUNCTIONS;do + FUNCTION_POLICY_STATEMENTS=$($AWSCLI lambda $PROFILE_OPT get-policy --region $region --function-name $lambdaFunction --output json --query Policy 2>&1) + if [[ $FUNCTION_POLICY_STATEMENTS == *ResourceNotFoundException* ]]; then + textInfo "$region : Lambda function $lambdaFunction doesn't have any policy" + else + FUNCTION_POLICY_BAD_STATEMENTS=$(echo $FUNCTION_POLICY_STATEMENTS | jq '. | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') + if [[ $FUNCTION_POLICY_BAD_STATEMENTS != "" ]]; then + textFail "$region : Lambda function $lambdaFunction allows public access with policy as: $FUNCTION_POLICY_BAD_STATEMENTS" + else + textPass "$region : Lambda function $lambdaFunction has policy which doesn't allow access to everyone having an aws account" + fi + fi + done + + else + textInfo "No lambda functions found in $region region" + fi + done +} diff --git a/checks/check_extra95 b/checks/check_extra95 new file mode 100644 index 00000000..f9cee66c --- /dev/null +++ b/checks/check_extra95 @@ -0,0 +1,41 @@ +#!/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_extra95="9.5" +CHECK_TITLE_extra95="[extra95] Check if there is any unassigned elastic ip's (Not Scored) (Not part of CIS benchmark) (Custom Check)" +CHECK_SCORED_extra95="NOT_SCORED" +CHECK_TYPE_extra95="EXTRA" +CHECK_SEVERITY_extra95="Critical" +CHECK_ASFF_RESOURCE_TYPE_extra95="AwsCloudWatch" +CHECK_ALTERNATE_check95="extra95" +CHECK_SERVICENAME_extra95="CloudWatch" + +# If there is any elasting ip which is not assigned to any instance or network interface, we will list that out. + +extra95(){ + for region in $REGIONS; do + ELASTIC_IP_ADDRESSES=$($AWSCLI ec2 describe-addresses $PROFILE_OPT --region $region --query Addresses --output json) + if [[ $ELASTIC_IP_ADDRESSES != [] ]]; then + LIST_OF_ASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId!=null) | .PublicIp') + LIST_OF_UNASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId==null) | .PublicIp') + for ass_ip in $LIST_OF_ASSOCIATED_IPS; do + textPass "$region : Elastic IP $ass_ip is associated with an instance or network interface" + done + for unass_ip in $LIST_OF_UNASSOCIATED_IPS; do + textInfo "$region : Elastic IP $unass_ip is not associated with any instance or network interface, it may incurr cost" + done + else + textInfo "No elastic ip's found in region $region" + fi + done +} From f5a4e357b9de68ae03508e5da0ca364a6450a470 Mon Sep 17 00:00:00 2001 From: Nick Malcolm Date: Mon, 14 Jun 2021 20:27:16 +1200 Subject: [PATCH 37/82] Consolidate javascript at the bottom of the template. Remove duplicate bootstrap includes - you only need bundle to get Popper (see https://getbootstrap.com/docs/4.0/getting-started/contents/#js-files) and you don't need both plain bootstrap and bundled bootstrap. Remove dupe jQuery too. --- include/html_report | 60 ++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/include/html_report b/include/html_report index 42db8626..76935786 100644 --- a/include/html_report +++ b/include/html_report @@ -29,31 +29,10 @@ addHtmlHeader() { - - - - Prowler - AWS Security Assessments @@ -179,16 +158,31 @@ addHtmlFooter() { - - - - - - + + \$(document).ready(function(){ + + \$('#findingsTable').dataTable( { "lengthMenu": [ [50, 100, -1], [50, 100, "All"] ], "ordering": true } ); + + var maxLength = 30; + \$(".show-read-more").each(function(){ + var myStr = \$(this).text(); + if(\$.trim(myStr).length > maxLength){ + var newStr = myStr.substring(0, maxLength); + var removedStr = myStr.substring(maxLength, \$.trim(myStr).length); + \$(this).empty().html(newStr); + \$(this).append(' read more...'); + \$(this).append('' + removedStr + ''); + } + }); + \$(".read-more").click(function(){ + \$(this).siblings(".more-text").contents().unwrap(); + \$(this).remove(); + }); + }); + + EOF From 89af81ed22ee2bdfd60e560310a5a1acd32e3eda Mon Sep 17 00:00:00 2001 From: Nick Malcolm Date: Mon, 14 Jun 2021 20:31:34 +1200 Subject: [PATCH 38/82] Use DataTable's SearchPanes extension to allow easy filtering by result, severity, region, service, or check. --- include/html_report | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/include/html_report b/include/html_report index 76935786..8db263d5 100644 --- a/include/html_report +++ b/include/html_report @@ -27,7 +27,8 @@ addHtmlHeader() { - + + + + + +
+
+ +
+ +

Dashboard

+

This is the homepage of a simple admin interface which is part of a tutorial written on Themesberg

+
+
+
+
Customers
+
+
345k
+

Feb 1 - Apr 1, United States

+

18.2% increase since last month

+
+
+
+
+
+
Revenue
+
+
$2.4k
+

Feb 1 - Apr 1, United States

+

4.6% increase since last month

+
+
+
+
+
+
Purchases
+
+
43
+

Feb 1 - Apr 1, United States

+

2.6% decrease since last month

+
+
+
+
+
+
Traffic
+
+
64k
+

Feb 1 - Apr 1, United States

+

2.5% increase since last month

+
+
+
+
+
+
+
+
Latest transactions
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OrderProductCustomerTotalDate
17371705Volt Premium Bootstrap 5 Dashboardjohndoe@gmail.com€61.11Aug 31 2020View
17370540Pixel Pro Premium Bootstrap UI Kitjacob.monroe@company.com$153.11Aug 28 2020View
17371705Volt Premium Bootstrap 5 Dashboardjohndoe@gmail.com€61.11Aug 31 2020View
17370540Pixel Pro Premium Bootstrap UI Kitjacob.monroe@company.com$153.11Aug 28 2020View
17371705Volt Premium Bootstrap 5 Dashboardjohndoe@gmail.com€61.11Aug 31 2020View
17370540Pixel Pro Premium Bootstrap UI Kitjacob.monroe@company.com$153.11Aug 28 2020View
+
+ View all +
+
+
+
+
+
Traffic last 6 months
+
+
+
+
+
+
+ +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/util/ec2-automation/one-time-or-continuous-monitoring-template.yaml-WIP b/util/ec2-automation/one-time-or-continuous-monitoring-template.yaml-WIP new file mode 100644 index 00000000..b80526c9 --- /dev/null +++ b/util/ec2-automation/one-time-or-continuous-monitoring-template.yaml-WIP @@ -0,0 +1,369 @@ +--- +Description: Stack for AWS resources to run Prowler scan +AWSTemplateFormatVersion: "2010-09-09" + +Parameters: + ServiceName: + Description: 'Specifies the service name used within component naming' + Type: String + Default: 'prowler' + + LogsRetentionInDays: + Description: 'Specifies the number of days you want to retain CloudWatch log events in the specified log group.' + Type: Number + Default: 3 + AllowedValues: [1, 3, 5, 7, 14, 30, 60] + + ProwlerOptions: + Description: 'Options to pass to Prowler command. For all options see ./prowler -h' + Type: String + Default: '-r eu-west-1 -f eu-west-1 -M text,junit-xml,html -c check11,check12,check13,check14' + + ProwlerSchedule: + Description: The time when Prowler will run in cron format. Default is daily at 22:00h/10PM + Type: String + Default: '0 22 * * *' + + ProwlerInstanceType: + Description: Enter Instance Type + Type: String + Default: t2.micro + + Ec2ImageId: + Type: AWS::SSM::Parameter::Value + Description: Latest AMI ID for Amazon Linux 2 (via AWS Publis SSM Parameters. See https://tinyurl.com/aws-public-ssm-parameters. + Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs + + Ec2InstanceKeyName: + Description: The name of key pair + Type: AWS::EC2::KeyPair::KeyName + + SecurityGroupIds: + Description: Security group IDs + Type: CommaDelimitedList + + SubnetIds: + Description: VPC subnet IDs + Type: CommaDelimitedList + +Resources: + + ReportBucket: + Type: AWS::S3::Bucket + Properties: + BucketName: !Sub 'prowler-reports-${AWS::Region}-${AWS::AccountId}' + AccessControl: Private + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: AES256 + PublicAccessBlockConfiguration: + BlockPublicAcls: true + BlockPublicPolicy: true + IgnorePublicAcls: true + RestrictPublicBuckets: true + VersioningConfiguration: + Status: Enabled + # LoggingConfiguration: + # DestinationBucketName: !Sub "my-access-log-bucket-${AWS::Region}-${AWS::AccountId}" + # LogFilePrefix: !Sub "${ProwlerReportBucket}/" + LifecycleConfiguration: + Rules: + - Id: AutoDelete + Status: Enabled + NoncurrentVersionExpirationInDays: 30 + ExpirationInDays: 365 + Transition: + TransitionInDays: 30 + StorageClass: STANDARD_IA + + ReportBucketPolicy: + Type: "AWS::S3::BucketPolicy" + Properties: + Bucket: !Ref ReportBucket + PolicyDocument: + Statement: + - Sid: DenyDelete + Effect: Deny + Principal: "*" + Action: s3:Delete* + Resource: + - !Sub "${ReportBucket.Arn}/*" + - Sid: S3ForceSSL + Effect: Deny + Principal: '*' + Action: '*' + Resource: + - !Join ['', ['arn:aws:s3:::', !Ref 'ReportBucket', '/*']] + Condition: + Bool: + aws:SecureTransport: 'false' + - Sid: ForceUploadEcryption + Effect: Deny + Principal: '*' + Action: 's3:PutObject' + Condition: + 'Null': + s3:x-amz-server-side-encryption: 'true' + Resource: + - !Sub "${ReportBucket.Arn}" + - !Sub "${ReportBucket.Arn}/*" + + InstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + Path: "/" + Roles: + - !Ref InstanceRole + + InstanceRole: + Type: AWS::IAM::Role + Properties: + Path: "/" + RoleName: !Sub "${ServiceName}-prowler-role" + MaxSessionDuration: 10800 + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Action: + - sts:AssumeRole + ManagedPolicyArns: + - "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess" + - "arn:aws:iam::aws:policy/SecurityAudit" + - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore' + Policies: + - PolicyName: ProwlerAdditionsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowMoreReadForProwler + Action: + - "access-analyzer:List*" + - "apigateway:Get*" + - "apigatewayv2:Get*" + - "aws-marketplace:ViewSubscriptions" + - "dax:ListTables" + - "ds:ListAuthorizedApplications" + - "ds:DescribeRoles" + - "ec2:GetEbsEncryptionByDefault" + - "ecr:Describe*" + - "lambda:GetAccountSettings" + - "lambda:GetFunction" + - "lambda:GetFunctionConfiguration" + - "lambda:GetLayerVersionPolicy" + - "lambda:GetPolicy" + - "opsworks-cm:Describe*" + - "opsworks:Describe*" + - "secretsmanager:ListSecretVersionIds" + - "sns:List*" + - "sqs:ListQueueTags" + - "states:ListActivities" + - "support:Describe*" + - "tag:GetTagKeys" + Effect: "Allow" + Resource: "*" + - PolicyName: LogGroup + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogStream + - logs:CreateLogGroup + - logs:PutLogEvents + Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${ProwlerLogGroup}:*' + - PolicyName: CloudWatchMetrics + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - cloudwatch:PutMetricData + Resource: "*" + - PolicyName: ProwlerMaintenancePolicy + PolicyDocument: + Version: "2012-10-17" + Statement: + # - Sid: AllowAssumeProwlerRole + # Effect: Allow + # Action: + # - "sts:AssumeRole" + # Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/application/prod-prowler-role" + - Sid: AllowScaleDownAutoScalingGroup + Effect: Allow + Action: + - "autoscaling:DescribeAutoScalingGroups" + - "autoscaling:DescribeAutoScalingInstances" + - "autoscaling:SetDesiredCapacity" + Resource: "*" + - Sid: AllowDescribeRegions + Effect: Allow + Action: + - "ec2:DescribeRegions" + Resource: "*" + - Sid: SSMSessionManager + Effect: Allow + Action: + - ec2messages:* + - ssmmessages:* + - ssm:* + Resource: "*" + # - Sid: SlackNotification + # Effect: Allow + # Action: + # - events:PutEvents + # Resource: !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:event-bus/default" + - Sid: AllowUploadReport + Effect: Allow + Action: + - "s3:PutObject" + Resource: + - !Sub "${ReportBucket.Arn}/*" + + ProwlerLogGroup: + Type: 'AWS::Logs::LogGroup' + Properties: + LogGroupName: !Sub "${ServiceName}-${AWS::StackName}" + RetentionInDays: !Ref LogsRetentionInDays + + Ec2InstanceLaunchTemplate: + Type: AWS::EC2::LaunchTemplate + Metadata: + AWS::CloudFormation::Init: + config: + files: + /opt/prowler.sh: + content: !Sub | + #!/usr/bin/env bash + set -e + + # export AWS_DEFAULT_REGION=${AWS::Region} + # export AWS_PARTITION=aws + + # declare -A ACCOUNTS + # ACCOUNTS[ssvc]='798980982229' + # ACCOUNTS[prod]='579842252590' + # ACCOUNTS[uat]='990839841794' + + # TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 360" "http://169.254.169.254/latest/api/token") + # INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token:$TOKEN" "http://169.254.169.254/latest/meta-data/instance-id") + # ASG_NAME=$(aws autoscaling describe-auto-scaling-instances --instance-ids $INSTANCE_ID --query 'AutoScalingInstances[0].AutoScalingGroupName' --output text) + # ENVIRONMENT=$(aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ASG_NAME --query 'AutoScalingGroups[0].Tags[?Key==`ScanTarget`]|[0].Value' --output text) + + # PROWLER_REPORT="${!ENVIRONMENT}_prowler_report_$(date +%d%m%Y).csv" + # REPORT_S3_LOCATION="${ReportBucket}" + + # cd /opt/prowler + # /opt/prowler/prowler -f eu-west-1 -c check12 -M text,html,csv + # aws s3 cp --sse AES256 /opt/prowler/prowler/output/*.{html,csv} s3://$REPORT_S3_LOCATION/ + + # /opt/prowler/prowler -A "${!ACCOUNTS[$ENVIRONMENT]}" \ + # -R "application/${!ENVIRONMENT}-prowler-role" \ + # -T 10800 \ + # -m 500 \ + # -r ${AWS::Region} \ + # -E extra79,extra710,extra712,extra757,extra758,extra770,extra774 \ + # -b -q -M csv | tee -a $PROWLER_REPORT + + # Upload to S3 + # aws s3 cp $PROWLER_REPORT $REPORT_S3_LOCATION --sse + + # Send Slack notification + # message="Prowler scan for \`${!ENVIRONMENT}\` completed. Please check report from \`${!REPORT_S3_LOCATION}\`." + # aws events put-events --entries "[{\"Source\":\"myorg:slack\",\"DetailType\":\"hello\",\"Detail\":\"{\\\"username\\\":\\\"Prowler Scanner\\\",\\\"avatar\\\":\\\":aws:\\\",\\\"channel\\\":\\\"#t-fs-calabash\\\",\\\"text\\\":\\\"${!message}\\\"}\"}]" + + # Scale Down Auto Scaling Group + # aws autoscaling set-desired-capacity --auto-scaling-group-name $ASG_NAME --desired-capacity 0 + mode: '000755' + owner: root + group: root + Properties: + LaunchTemplateData: + SecurityGroupIds: !Ref SecurityGroupIds + MetadataOptions: + HttpEndpoint: enabled + HttpTokens: optional + TagSpecifications: + - ResourceType: instance + Tags: + - Key: Name + Value: !Ref 'AWS::StackName' + UserData: + Fn::Base64: !Sub | + #cloud-config + runcmd: + - while ! curl --connect-timeout 1 -s http://169.254.169.254/ > /dev/null; do echo "-- waiting for instance network to wake up ..."; done + - /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource Ec2InstanceLaunchTemplate --region ${AWS::Region} + - yum update -y + - yum install -y python3-pip git jq + - pip3 install detect-secrets + - git clone https://github.com/toniblyx/prowler.git /opt/prowler + - export AWS_DEFAULT_REGION=${AWS::Region} + - export REPORT_S3_LOCATION=${ReportBucket} + - export TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 360" "http://169.254.169.254/latest/api/token") + - export INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token:$TOKEN" "http://169.254.169.254/latest/meta-data/instance-id") + - export ASG_NAME=$(aws autoscaling describe-auto-scaling-instances --instance-ids $INSTANCE_ID --query 'AutoScalingInstances[0].AutoScalingGroupName' --output text) + - export ENVIRONMENT=$(aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ASG_NAME --query 'AutoScalingGroups[0].Tags[?Key==`ScanTarget`]|[0].Value' --output text) + - cd /opt/prowler + - /opt/prowler/prowler -f eu-west-1 -c check12 -M text,html,csv + - aws s3 cp --sse AES256 /opt/prowler/prowler/output/*.{html,csv} s3://$REPORT_S3_LOCATION/ + - aws autoscaling set-desired-capacity --auto-scaling-group-name $ASG_NAME --desired-capacity 0 + - /opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --resource ASGroup --region ${AWS::Region} + InstanceInitiatedShutdownBehavior: terminate + IamInstanceProfile: + Name: !Ref InstanceProfile + KeyName: !Ref 'Ec2InstanceKeyName' + ImageId: !Ref 'Ec2ImageId' + InstanceType: !Ref ProwlerInstanceType + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + Encrypted: true + KmsKeyId: alias/aws/ebs + VolumeType: standard + DeleteOnTermination: true + VolumeSize: 8 + InstanceMarketOptions: + MarketType: spot + SpotOptions: + SpotInstanceType: one-time + MaxPrice: 0.006 + + ProwlerAutoScalingGroup: + Type: AWS::AutoScaling::AutoScalingGroup + UpdatePolicy: + AutoScalingReplacingUpdate: + WillReplace: true + Properties: + VPCZoneIdentifier: !Ref SubnetIds + LaunchTemplate: + LaunchTemplateId: !Ref 'Ec2InstanceLaunchTemplate' + Version: !GetAtt 'Ec2InstanceLaunchTemplate.LatestVersionNumber' + MinSize: 1 + MaxSize: 1 + HealthCheckGracePeriod: 300 + HealthCheckType: EC2 + Tags: + - Key: Name + Value: !Sub "${AWS::StackName}" + PropagateAtLaunch: true + + ProwlerScheduledScaleUp: + Type: AWS::AutoScaling::ScheduledAction + Properties: + AutoScalingGroupName: !Ref ProwlerAutoScalingGroup + DesiredCapacity: 1 + MaxSize: 1 + MinSize: 0 + Recurrence: !Ref ProwlerSchedule + +Outputs: + ReportBucket: + Description: Report Bucket Name + Value: !Ref 'ReportBucket' + Export: + Name: !Sub 'prowler-reports-${AWS::Region}-${AWS::AccountId}' \ No newline at end of file diff --git a/util/quicksight/create-data-source-cli-input.json b/util/quicksight/create-data-source-cli-input.json new file mode 100644 index 00000000..a65da2b7 --- /dev/null +++ b/util/quicksight/create-data-source-cli-input.json @@ -0,0 +1,217 @@ +{ + "AwsAccountId": "", + "DataSourceId": "", + "Name": "", + "Type": "SNOWFLAKE", + "DataSourceParameters": { + "AmazonElasticsearchParameters": { + "Domain": "" + }, + "AthenaParameters": { + "WorkGroup": "" + }, + "AuroraParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "AuroraPostgreSqlParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "AwsIotAnalyticsParameters": { + "DataSetName": "" + }, + "JiraParameters": { + "SiteBaseUrl": "" + }, + "MariaDbParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "MySqlParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "OracleParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "PostgreSqlParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "PrestoParameters": { + "Host": "", + "Port": 0, + "Catalog": "" + }, + "RdsParameters": { + "InstanceId": "", + "Database": "" + }, + "RedshiftParameters": { + "Host": "", + "Port": 0, + "Database": "", + "ClusterId": "" + }, + "S3Parameters": { + "ManifestFileLocation": { + "Bucket": "", + "Key": "" + } + }, + "ServiceNowParameters": { + "SiteBaseUrl": "" + }, + "SnowflakeParameters": { + "Host": "", + "Database": "", + "Warehouse": "" + }, + "SparkParameters": { + "Host": "", + "Port": 0 + }, + "SqlServerParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "TeradataParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "TwitterParameters": { + "Query": "", + "MaxRows": 0 + } + }, + "Credentials": { + "CredentialPair": { + "Username": "", + "Password": "", + "AlternateDataSourceParameters": [ + { + "AmazonElasticsearchParameters": { + "Domain": "" + }, + "AthenaParameters": { + "WorkGroup": "" + }, + "AuroraParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "AuroraPostgreSqlParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "AwsIotAnalyticsParameters": { + "DataSetName": "" + }, + "JiraParameters": { + "SiteBaseUrl": "" + }, + "MariaDbParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "MySqlParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "OracleParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "PostgreSqlParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "PrestoParameters": { + "Host": "", + "Port": 0, + "Catalog": "" + }, + "RdsParameters": { + "InstanceId": "", + "Database": "" + }, + "RedshiftParameters": { + "Host": "", + "Port": 0, + "Database": "", + "ClusterId": "" + }, + "S3Parameters": { + "ManifestFileLocation": { + "Bucket": "", + "Key": "" + } + }, + "ServiceNowParameters": { + "SiteBaseUrl": "" + }, + "SnowflakeParameters": { + "Host": "", + "Database": "", + "Warehouse": "" + }, + "SparkParameters": { + "Host": "", + "Port": 0 + }, + "SqlServerParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "TeradataParameters": { + "Host": "", + "Port": 0, + "Database": "" + }, + "TwitterParameters": { + "Query": "", + "MaxRows": 0 + } + } + ] + }, + "CopySourceArn": "" + }, + "Permissions": [ + { + "Principal": "", + "Actions": [ + "" + ] + } + ], + "VpcConnectionProperties": { + "VpcConnectionArn": "" + }, + "SslProperties": { + "DisableSsl": true + }, + "Tags": [ + { + "Key": "", + "Value": "" + } + ] +} diff --git a/util/quicksight/create-template-cli-input.json b/util/quicksight/create-template-cli-input.json new file mode 100644 index 00000000..ee3d3567 --- /dev/null +++ b/util/quicksight/create-template-cli-input.json @@ -0,0 +1,18 @@ +{ + "AwsAccountId": "951061203682", + "TemplateId": "DemoDashboardTemplate", + "Name": "Demo Dashboard Template", + "SourceEntity": { + "SourceAnalysis": { + "Arn": "arn:aws:quicksight:eu-west-1:951061203682:analysis/ e52808ac-43df-46c2-bde6-d08393effcf", + "DataSetReferences": [ + { + "DataSetPlaceholder": "DS1", + "DataSetArn": " arn:aws:quicksight:eu-west-1:951061203682:dataset/44767579-c881-42e7-bf4c-929af56bdc69" + } + ] + } + }, + "VersionDescription": "1" +} + diff --git a/util/quicksight/prowler-quicksight-datasource-manifest.json b/util/quicksight/prowler-quicksight-datasource-manifest.json new file mode 100644 index 00000000..0bc67c2c --- /dev/null +++ b/util/quicksight/prowler-quicksight-datasource-manifest.json @@ -0,0 +1,12 @@ +{ + "fileLocations": [{ + "URIPrefixes": [ + "https://s3-eu-west-1.amazonaws.com/prowler-ens-reports-eu-west-1-prowler-951061203682/" + ] + }], + "globalUploadSettings": { + "format": "CSV", + "delimiter": ",", + "containsHeader": "true" + } +} \ No newline at end of file From 90ae53a9765550c884db36087c36ee294e9cdb84 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Mon, 5 Jul 2021 20:15:33 +0200 Subject: [PATCH 52/82] Delete util/quicksight directory --- .../create-data-source-cli-input.json | 217 ------------------ .../quicksight/create-template-cli-input.json | 18 -- ...rowler-quicksight-datasource-manifest.json | 12 - 3 files changed, 247 deletions(-) delete mode 100644 util/quicksight/create-data-source-cli-input.json delete mode 100644 util/quicksight/create-template-cli-input.json delete mode 100644 util/quicksight/prowler-quicksight-datasource-manifest.json diff --git a/util/quicksight/create-data-source-cli-input.json b/util/quicksight/create-data-source-cli-input.json deleted file mode 100644 index a65da2b7..00000000 --- a/util/quicksight/create-data-source-cli-input.json +++ /dev/null @@ -1,217 +0,0 @@ -{ - "AwsAccountId": "", - "DataSourceId": "", - "Name": "", - "Type": "SNOWFLAKE", - "DataSourceParameters": { - "AmazonElasticsearchParameters": { - "Domain": "" - }, - "AthenaParameters": { - "WorkGroup": "" - }, - "AuroraParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "AuroraPostgreSqlParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "AwsIotAnalyticsParameters": { - "DataSetName": "" - }, - "JiraParameters": { - "SiteBaseUrl": "" - }, - "MariaDbParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "MySqlParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "OracleParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "PostgreSqlParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "PrestoParameters": { - "Host": "", - "Port": 0, - "Catalog": "" - }, - "RdsParameters": { - "InstanceId": "", - "Database": "" - }, - "RedshiftParameters": { - "Host": "", - "Port": 0, - "Database": "", - "ClusterId": "" - }, - "S3Parameters": { - "ManifestFileLocation": { - "Bucket": "", - "Key": "" - } - }, - "ServiceNowParameters": { - "SiteBaseUrl": "" - }, - "SnowflakeParameters": { - "Host": "", - "Database": "", - "Warehouse": "" - }, - "SparkParameters": { - "Host": "", - "Port": 0 - }, - "SqlServerParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "TeradataParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "TwitterParameters": { - "Query": "", - "MaxRows": 0 - } - }, - "Credentials": { - "CredentialPair": { - "Username": "", - "Password": "", - "AlternateDataSourceParameters": [ - { - "AmazonElasticsearchParameters": { - "Domain": "" - }, - "AthenaParameters": { - "WorkGroup": "" - }, - "AuroraParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "AuroraPostgreSqlParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "AwsIotAnalyticsParameters": { - "DataSetName": "" - }, - "JiraParameters": { - "SiteBaseUrl": "" - }, - "MariaDbParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "MySqlParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "OracleParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "PostgreSqlParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "PrestoParameters": { - "Host": "", - "Port": 0, - "Catalog": "" - }, - "RdsParameters": { - "InstanceId": "", - "Database": "" - }, - "RedshiftParameters": { - "Host": "", - "Port": 0, - "Database": "", - "ClusterId": "" - }, - "S3Parameters": { - "ManifestFileLocation": { - "Bucket": "", - "Key": "" - } - }, - "ServiceNowParameters": { - "SiteBaseUrl": "" - }, - "SnowflakeParameters": { - "Host": "", - "Database": "", - "Warehouse": "" - }, - "SparkParameters": { - "Host": "", - "Port": 0 - }, - "SqlServerParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "TeradataParameters": { - "Host": "", - "Port": 0, - "Database": "" - }, - "TwitterParameters": { - "Query": "", - "MaxRows": 0 - } - } - ] - }, - "CopySourceArn": "" - }, - "Permissions": [ - { - "Principal": "", - "Actions": [ - "" - ] - } - ], - "VpcConnectionProperties": { - "VpcConnectionArn": "" - }, - "SslProperties": { - "DisableSsl": true - }, - "Tags": [ - { - "Key": "", - "Value": "" - } - ] -} diff --git a/util/quicksight/create-template-cli-input.json b/util/quicksight/create-template-cli-input.json deleted file mode 100644 index ee3d3567..00000000 --- a/util/quicksight/create-template-cli-input.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "AwsAccountId": "951061203682", - "TemplateId": "DemoDashboardTemplate", - "Name": "Demo Dashboard Template", - "SourceEntity": { - "SourceAnalysis": { - "Arn": "arn:aws:quicksight:eu-west-1:951061203682:analysis/ e52808ac-43df-46c2-bde6-d08393effcf", - "DataSetReferences": [ - { - "DataSetPlaceholder": "DS1", - "DataSetArn": " arn:aws:quicksight:eu-west-1:951061203682:dataset/44767579-c881-42e7-bf4c-929af56bdc69" - } - ] - } - }, - "VersionDescription": "1" -} - diff --git a/util/quicksight/prowler-quicksight-datasource-manifest.json b/util/quicksight/prowler-quicksight-datasource-manifest.json deleted file mode 100644 index 0bc67c2c..00000000 --- a/util/quicksight/prowler-quicksight-datasource-manifest.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fileLocations": [{ - "URIPrefixes": [ - "https://s3-eu-west-1.amazonaws.com/prowler-ens-reports-eu-west-1-prowler-951061203682/" - ] - }], - "globalUploadSettings": { - "format": "CSV", - "delimiter": ",", - "containsHeader": "true" - } -} \ No newline at end of file From f540758e36b6b29dce2804fd505b47988293cdfe Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Mon, 5 Jul 2021 20:15:48 +0200 Subject: [PATCH 53/82] Delete util/ec2-automation directory --- ...or-continuous-monitoring-template.yaml-WIP | 369 ------------------ 1 file changed, 369 deletions(-) delete mode 100644 util/ec2-automation/one-time-or-continuous-monitoring-template.yaml-WIP diff --git a/util/ec2-automation/one-time-or-continuous-monitoring-template.yaml-WIP b/util/ec2-automation/one-time-or-continuous-monitoring-template.yaml-WIP deleted file mode 100644 index b80526c9..00000000 --- a/util/ec2-automation/one-time-or-continuous-monitoring-template.yaml-WIP +++ /dev/null @@ -1,369 +0,0 @@ ---- -Description: Stack for AWS resources to run Prowler scan -AWSTemplateFormatVersion: "2010-09-09" - -Parameters: - ServiceName: - Description: 'Specifies the service name used within component naming' - Type: String - Default: 'prowler' - - LogsRetentionInDays: - Description: 'Specifies the number of days you want to retain CloudWatch log events in the specified log group.' - Type: Number - Default: 3 - AllowedValues: [1, 3, 5, 7, 14, 30, 60] - - ProwlerOptions: - Description: 'Options to pass to Prowler command. For all options see ./prowler -h' - Type: String - Default: '-r eu-west-1 -f eu-west-1 -M text,junit-xml,html -c check11,check12,check13,check14' - - ProwlerSchedule: - Description: The time when Prowler will run in cron format. Default is daily at 22:00h/10PM - Type: String - Default: '0 22 * * *' - - ProwlerInstanceType: - Description: Enter Instance Type - Type: String - Default: t2.micro - - Ec2ImageId: - Type: AWS::SSM::Parameter::Value - Description: Latest AMI ID for Amazon Linux 2 (via AWS Publis SSM Parameters. See https://tinyurl.com/aws-public-ssm-parameters. - Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs - - Ec2InstanceKeyName: - Description: The name of key pair - Type: AWS::EC2::KeyPair::KeyName - - SecurityGroupIds: - Description: Security group IDs - Type: CommaDelimitedList - - SubnetIds: - Description: VPC subnet IDs - Type: CommaDelimitedList - -Resources: - - ReportBucket: - Type: AWS::S3::Bucket - Properties: - BucketName: !Sub 'prowler-reports-${AWS::Region}-${AWS::AccountId}' - AccessControl: Private - BucketEncryption: - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 - PublicAccessBlockConfiguration: - BlockPublicAcls: true - BlockPublicPolicy: true - IgnorePublicAcls: true - RestrictPublicBuckets: true - VersioningConfiguration: - Status: Enabled - # LoggingConfiguration: - # DestinationBucketName: !Sub "my-access-log-bucket-${AWS::Region}-${AWS::AccountId}" - # LogFilePrefix: !Sub "${ProwlerReportBucket}/" - LifecycleConfiguration: - Rules: - - Id: AutoDelete - Status: Enabled - NoncurrentVersionExpirationInDays: 30 - ExpirationInDays: 365 - Transition: - TransitionInDays: 30 - StorageClass: STANDARD_IA - - ReportBucketPolicy: - Type: "AWS::S3::BucketPolicy" - Properties: - Bucket: !Ref ReportBucket - PolicyDocument: - Statement: - - Sid: DenyDelete - Effect: Deny - Principal: "*" - Action: s3:Delete* - Resource: - - !Sub "${ReportBucket.Arn}/*" - - Sid: S3ForceSSL - Effect: Deny - Principal: '*' - Action: '*' - Resource: - - !Join ['', ['arn:aws:s3:::', !Ref 'ReportBucket', '/*']] - Condition: - Bool: - aws:SecureTransport: 'false' - - Sid: ForceUploadEcryption - Effect: Deny - Principal: '*' - Action: 's3:PutObject' - Condition: - 'Null': - s3:x-amz-server-side-encryption: 'true' - Resource: - - !Sub "${ReportBucket.Arn}" - - !Sub "${ReportBucket.Arn}/*" - - InstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - Path: "/" - Roles: - - !Ref InstanceRole - - InstanceRole: - Type: AWS::IAM::Role - Properties: - Path: "/" - RoleName: !Sub "${ServiceName}-prowler-role" - MaxSessionDuration: 10800 - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com - Action: - - sts:AssumeRole - ManagedPolicyArns: - - "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess" - - "arn:aws:iam::aws:policy/SecurityAudit" - - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore' - Policies: - - PolicyName: ProwlerAdditionsPolicy - PolicyDocument: - Version: 2012-10-17 - Statement: - - Sid: AllowMoreReadForProwler - Action: - - "access-analyzer:List*" - - "apigateway:Get*" - - "apigatewayv2:Get*" - - "aws-marketplace:ViewSubscriptions" - - "dax:ListTables" - - "ds:ListAuthorizedApplications" - - "ds:DescribeRoles" - - "ec2:GetEbsEncryptionByDefault" - - "ecr:Describe*" - - "lambda:GetAccountSettings" - - "lambda:GetFunction" - - "lambda:GetFunctionConfiguration" - - "lambda:GetLayerVersionPolicy" - - "lambda:GetPolicy" - - "opsworks-cm:Describe*" - - "opsworks:Describe*" - - "secretsmanager:ListSecretVersionIds" - - "sns:List*" - - "sqs:ListQueueTags" - - "states:ListActivities" - - "support:Describe*" - - "tag:GetTagKeys" - Effect: "Allow" - Resource: "*" - - PolicyName: LogGroup - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - logs:CreateLogStream - - logs:CreateLogGroup - - logs:PutLogEvents - Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${ProwlerLogGroup}:*' - - PolicyName: CloudWatchMetrics - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - cloudwatch:PutMetricData - Resource: "*" - - PolicyName: ProwlerMaintenancePolicy - PolicyDocument: - Version: "2012-10-17" - Statement: - # - Sid: AllowAssumeProwlerRole - # Effect: Allow - # Action: - # - "sts:AssumeRole" - # Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/application/prod-prowler-role" - - Sid: AllowScaleDownAutoScalingGroup - Effect: Allow - Action: - - "autoscaling:DescribeAutoScalingGroups" - - "autoscaling:DescribeAutoScalingInstances" - - "autoscaling:SetDesiredCapacity" - Resource: "*" - - Sid: AllowDescribeRegions - Effect: Allow - Action: - - "ec2:DescribeRegions" - Resource: "*" - - Sid: SSMSessionManager - Effect: Allow - Action: - - ec2messages:* - - ssmmessages:* - - ssm:* - Resource: "*" - # - Sid: SlackNotification - # Effect: Allow - # Action: - # - events:PutEvents - # Resource: !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:event-bus/default" - - Sid: AllowUploadReport - Effect: Allow - Action: - - "s3:PutObject" - Resource: - - !Sub "${ReportBucket.Arn}/*" - - ProwlerLogGroup: - Type: 'AWS::Logs::LogGroup' - Properties: - LogGroupName: !Sub "${ServiceName}-${AWS::StackName}" - RetentionInDays: !Ref LogsRetentionInDays - - Ec2InstanceLaunchTemplate: - Type: AWS::EC2::LaunchTemplate - Metadata: - AWS::CloudFormation::Init: - config: - files: - /opt/prowler.sh: - content: !Sub | - #!/usr/bin/env bash - set -e - - # export AWS_DEFAULT_REGION=${AWS::Region} - # export AWS_PARTITION=aws - - # declare -A ACCOUNTS - # ACCOUNTS[ssvc]='798980982229' - # ACCOUNTS[prod]='579842252590' - # ACCOUNTS[uat]='990839841794' - - # TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 360" "http://169.254.169.254/latest/api/token") - # INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token:$TOKEN" "http://169.254.169.254/latest/meta-data/instance-id") - # ASG_NAME=$(aws autoscaling describe-auto-scaling-instances --instance-ids $INSTANCE_ID --query 'AutoScalingInstances[0].AutoScalingGroupName' --output text) - # ENVIRONMENT=$(aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ASG_NAME --query 'AutoScalingGroups[0].Tags[?Key==`ScanTarget`]|[0].Value' --output text) - - # PROWLER_REPORT="${!ENVIRONMENT}_prowler_report_$(date +%d%m%Y).csv" - # REPORT_S3_LOCATION="${ReportBucket}" - - # cd /opt/prowler - # /opt/prowler/prowler -f eu-west-1 -c check12 -M text,html,csv - # aws s3 cp --sse AES256 /opt/prowler/prowler/output/*.{html,csv} s3://$REPORT_S3_LOCATION/ - - # /opt/prowler/prowler -A "${!ACCOUNTS[$ENVIRONMENT]}" \ - # -R "application/${!ENVIRONMENT}-prowler-role" \ - # -T 10800 \ - # -m 500 \ - # -r ${AWS::Region} \ - # -E extra79,extra710,extra712,extra757,extra758,extra770,extra774 \ - # -b -q -M csv | tee -a $PROWLER_REPORT - - # Upload to S3 - # aws s3 cp $PROWLER_REPORT $REPORT_S3_LOCATION --sse - - # Send Slack notification - # message="Prowler scan for \`${!ENVIRONMENT}\` completed. Please check report from \`${!REPORT_S3_LOCATION}\`." - # aws events put-events --entries "[{\"Source\":\"myorg:slack\",\"DetailType\":\"hello\",\"Detail\":\"{\\\"username\\\":\\\"Prowler Scanner\\\",\\\"avatar\\\":\\\":aws:\\\",\\\"channel\\\":\\\"#t-fs-calabash\\\",\\\"text\\\":\\\"${!message}\\\"}\"}]" - - # Scale Down Auto Scaling Group - # aws autoscaling set-desired-capacity --auto-scaling-group-name $ASG_NAME --desired-capacity 0 - mode: '000755' - owner: root - group: root - Properties: - LaunchTemplateData: - SecurityGroupIds: !Ref SecurityGroupIds - MetadataOptions: - HttpEndpoint: enabled - HttpTokens: optional - TagSpecifications: - - ResourceType: instance - Tags: - - Key: Name - Value: !Ref 'AWS::StackName' - UserData: - Fn::Base64: !Sub | - #cloud-config - runcmd: - - while ! curl --connect-timeout 1 -s http://169.254.169.254/ > /dev/null; do echo "-- waiting for instance network to wake up ..."; done - - /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource Ec2InstanceLaunchTemplate --region ${AWS::Region} - - yum update -y - - yum install -y python3-pip git jq - - pip3 install detect-secrets - - git clone https://github.com/toniblyx/prowler.git /opt/prowler - - export AWS_DEFAULT_REGION=${AWS::Region} - - export REPORT_S3_LOCATION=${ReportBucket} - - export TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 360" "http://169.254.169.254/latest/api/token") - - export INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token:$TOKEN" "http://169.254.169.254/latest/meta-data/instance-id") - - export ASG_NAME=$(aws autoscaling describe-auto-scaling-instances --instance-ids $INSTANCE_ID --query 'AutoScalingInstances[0].AutoScalingGroupName' --output text) - - export ENVIRONMENT=$(aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ASG_NAME --query 'AutoScalingGroups[0].Tags[?Key==`ScanTarget`]|[0].Value' --output text) - - cd /opt/prowler - - /opt/prowler/prowler -f eu-west-1 -c check12 -M text,html,csv - - aws s3 cp --sse AES256 /opt/prowler/prowler/output/*.{html,csv} s3://$REPORT_S3_LOCATION/ - - aws autoscaling set-desired-capacity --auto-scaling-group-name $ASG_NAME --desired-capacity 0 - - /opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --resource ASGroup --region ${AWS::Region} - InstanceInitiatedShutdownBehavior: terminate - IamInstanceProfile: - Name: !Ref InstanceProfile - KeyName: !Ref 'Ec2InstanceKeyName' - ImageId: !Ref 'Ec2ImageId' - InstanceType: !Ref ProwlerInstanceType - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - Encrypted: true - KmsKeyId: alias/aws/ebs - VolumeType: standard - DeleteOnTermination: true - VolumeSize: 8 - InstanceMarketOptions: - MarketType: spot - SpotOptions: - SpotInstanceType: one-time - MaxPrice: 0.006 - - ProwlerAutoScalingGroup: - Type: AWS::AutoScaling::AutoScalingGroup - UpdatePolicy: - AutoScalingReplacingUpdate: - WillReplace: true - Properties: - VPCZoneIdentifier: !Ref SubnetIds - LaunchTemplate: - LaunchTemplateId: !Ref 'Ec2InstanceLaunchTemplate' - Version: !GetAtt 'Ec2InstanceLaunchTemplate.LatestVersionNumber' - MinSize: 1 - MaxSize: 1 - HealthCheckGracePeriod: 300 - HealthCheckType: EC2 - Tags: - - Key: Name - Value: !Sub "${AWS::StackName}" - PropagateAtLaunch: true - - ProwlerScheduledScaleUp: - Type: AWS::AutoScaling::ScheduledAction - Properties: - AutoScalingGroupName: !Ref ProwlerAutoScalingGroup - DesiredCapacity: 1 - MaxSize: 1 - MinSize: 0 - Recurrence: !Ref ProwlerSchedule - -Outputs: - ReportBucket: - Description: Report Bucket Name - Value: !Ref 'ReportBucket' - Export: - Name: !Sub 'prowler-reports-${AWS::Region}-${AWS::AccountId}' \ No newline at end of file From a9f277e131c97da1ea29cd92291409429aedcdeb Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Mon, 5 Jul 2021 20:16:22 +0200 Subject: [PATCH 54/82] Delete util/dashboard directory --- util/dashboard/index.html | 307 -------------------------------------- 1 file changed, 307 deletions(-) delete mode 100644 util/dashboard/index.html diff --git a/util/dashboard/index.html b/util/dashboard/index.html deleted file mode 100644 index afa55c3c..00000000 --- a/util/dashboard/index.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - - Bootstrap 5 Simple Admin Dashboard - - - - - - -
-
- -
- -

Dashboard

-

This is the homepage of a simple admin interface which is part of a tutorial written on Themesberg

-
-
-
-
Customers
-
-
345k
-

Feb 1 - Apr 1, United States

-

18.2% increase since last month

-
-
-
-
-
-
Revenue
-
-
$2.4k
-

Feb 1 - Apr 1, United States

-

4.6% increase since last month

-
-
-
-
-
-
Purchases
-
-
43
-

Feb 1 - Apr 1, United States

-

2.6% decrease since last month

-
-
-
-
-
-
Traffic
-
-
64k
-

Feb 1 - Apr 1, United States

-

2.5% increase since last month

-
-
-
-
-
-
-
-
Latest transactions
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OrderProductCustomerTotalDate
17371705Volt Premium Bootstrap 5 Dashboardjohndoe@gmail.com€61.11Aug 31 2020View
17370540Pixel Pro Premium Bootstrap UI Kitjacob.monroe@company.com$153.11Aug 28 2020View
17371705Volt Premium Bootstrap 5 Dashboardjohndoe@gmail.com€61.11Aug 31 2020View
17370540Pixel Pro Premium Bootstrap UI Kitjacob.monroe@company.com$153.11Aug 28 2020View
17371705Volt Premium Bootstrap 5 Dashboardjohndoe@gmail.com€61.11Aug 31 2020View
17370540Pixel Pro Premium Bootstrap UI Kitjacob.monroe@company.com$153.11Aug 28 2020View
-
- View all -
-
-
-
-
-
Traffic last 6 months
-
-
-
-
-
-
- -
-
-
- - - - - - - - \ No newline at end of file From c09385976a36900f02feab5b83ce20322dea2419 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Mon, 5 Jul 2021 20:17:27 +0200 Subject: [PATCH 55/82] Consolidated titles and outputs including resource ID in ASFF --- checks/check11 | 4 +-- checks/check110 | 8 +++--- checks/check111 | 8 +++--- checks/check112 | 10 +++---- checks/check113 | 6 ++-- checks/check114 | 8 +++--- checks/check115 | 6 ++-- checks/check116 | 8 +++--- checks/check117 | 5 ++-- checks/check118 | 5 ++-- checks/check119 | 6 ++-- checks/check12 | 4 +-- checks/check120 | 8 +++--- checks/check121 | 10 +++---- checks/check122 | 10 +++---- checks/check13 | 2 +- checks/check14 | 14 ++++----- checks/check15 | 6 ++-- checks/check16 | 6 ++-- checks/check17 | 6 ++-- checks/check18 | 6 ++-- checks/check19 | 4 +-- checks/check21 | 10 +++---- checks/check22 | 10 +++---- checks/check23 | 6 ++-- checks/check24 | 12 ++++---- checks/check25 | 10 +++---- checks/check26 | 18 ++++++------ checks/check27 | 10 +++---- checks/check28 | 4 +-- checks/check29 | 4 +-- checks/check31 | 2 +- checks/check310 | 2 +- checks/check311 | 2 +- checks/check312 | 2 +- checks/check313 | 2 +- checks/check314 | 2 +- checks/check32 | 2 +- checks/check33 | 2 +- checks/check34 | 2 +- checks/check35 | 2 +- checks/check36 | 2 +- checks/check37 | 2 +- checks/check38 | 2 +- checks/check39 | 2 +- checks/check41 | 6 ++-- checks/check42 | 6 ++-- checks/check43 | 6 ++-- checks/check44 | 7 ++--- checks/check45 | 4 +-- checks/check46 | 4 +-- checks/check_extra71 | 12 ++++---- checks/check_extra710 | 5 ++-- checks/check_extra7100 | 7 ++--- checks/check_extra711 | 5 ++-- checks/check_extra7113 | 2 +- checks/check_extra712 | 10 +++---- checks/check_extra713 | 4 +-- checks/check_extra7130 | 1 - checks/check_extra7134 | 2 +- checks/check_extra7135 | 2 +- checks/check_extra7136 | 2 +- checks/check_extra7137 | 2 +- checks/check_extra7139 | 2 +- checks/check_extra714 | 10 +++---- checks/check_extra716 | 6 ++-- checks/check_extra717 | 4 +-- checks/check_extra718 | 12 ++++---- checks/check_extra719 | 8 +++--- checks/check_extra72 | 5 ++-- checks/check_extra720 | 8 +++--- checks/check_extra721 | 4 +-- checks/check_extra722 | 4 +-- checks/check_extra723 | 4 +-- checks/check_extra724 | 7 ++--- checks/check_extra725 | 18 ++++++------ checks/check_extra726 | 22 +++++++------- checks/check_extra727 | 4 +-- checks/check_extra728 | 2 +- checks/check_extra729 | 5 ++-- checks/check_extra73 | 22 +++++++------- checks/check_extra730 | 2 +- checks/check_extra731 | 2 +- checks/check_extra732 | 8 +++--- checks/check_extra733 | 6 ++-- checks/check_extra734 | 18 ++++++------ checks/check_extra735 | 2 +- checks/check_extra736 | 3 +- checks/check_extra737 | 3 +- checks/check_extra738 | 10 +++---- checks/check_extra739 | 2 +- checks/check_extra74 | 7 ++--- checks/check_extra740 | 7 ++--- checks/check_extra741 | 5 ++-- checks/check_extra742 | 3 +- checks/check_extra743 | 2 +- checks/check_extra744 | 2 +- checks/check_extra745 | 2 +- checks/check_extra746 | 2 +- checks/check_extra747 | 2 +- checks/check_extra748 | 2 +- checks/check_extra749 | 2 +- checks/check_extra75 | 8 ++---- checks/check_extra750 | 2 +- checks/check_extra751 | 2 +- checks/check_extra752 | 2 +- checks/check_extra753 | 2 +- checks/check_extra754 | 2 +- checks/check_extra755 | 2 +- checks/check_extra756 | 2 +- checks/check_extra757 | 3 +- checks/check_extra758 | 3 +- checks/check_extra759 | 3 +- checks/check_extra76 | 5 ++-- checks/check_extra760 | 4 +-- checks/check_extra761 | 7 ++--- checks/check_extra762 | 2 +- checks/check_extra763 | 4 +-- checks/check_extra764 | 2 +- checks/check_extra765 | 2 +- checks/check_extra767 | 2 +- checks/check_extra768 | 5 ++-- checks/check_extra769 | 2 +- checks/check_extra77 | 24 ++++++++-------- checks/check_extra770 | 5 ++-- checks/check_extra771 | 2 +- checks/check_extra772 | 2 +- checks/check_extra773 | 4 +-- checks/check_extra775 | 3 +- checks/check_extra776 | 2 +- checks/check_extra777 | 3 +- checks/check_extra778 | 3 +- checks/check_extra78 | 4 +-- checks/check_extra786 | 2 +- checks/check_extra788 | 2 +- checks/check_extra79 | 7 ++--- checks/check_extra792 | 4 +-- checks/check_extra793 | 4 +-- checks/check_extra794 | 1 - checks/check_extra795 | 1 - checks/check_extra796 | 1 - checks/check_extra797 | 1 - checks/check_sample | 4 +-- groups/group17_internetexposed | 52 +++++++++++++++++----------------- include/check3x | 16 +++++------ include/check_creds_last_used | 20 ++++++------- include/outputs | 44 +++++++++++++++------------- prowler | 2 +- 148 files changed, 415 insertions(+), 452 deletions(-) diff --git a/checks/check11 b/checks/check11 index b77edbbe..6162db56 100644 --- a/checks/check11 +++ b/checks/check11 @@ -35,13 +35,13 @@ check11(){ 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" + textFail "$REGION: Root user in the account was last accessed ${MAX_DAYS#-} day ago" "$REGION" "root" break fi fi done if [[ $failures == 0 ]]; then - textPass "Root user in the account wasn't accessed in the last ${MAX_DAYS#-} days" + textPass "$REGION: Root user in the account wasn't accessed in the last ${MAX_DAYS#-} days" "$REGION" "root" fi } diff --git a/checks/check110 b/checks/check110 index e031bf60..2e60a65e 100644 --- a/checks/check110 +++ b/checks/check110 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check110="1.10" -CHECK_TITLE_check110="[check110] Ensure IAM password policy prevents password reuse: 24 or greater (Scored)" +CHECK_TITLE_check110="[check110] Ensure IAM password policy prevents password reuse: 24 or greater" CHECK_SCORED_check110="SCORED" CHECK_TYPE_check110="LEVEL1" CHECK_SEVERITY_check110="Medium" @@ -29,11 +29,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 - textPass "Password Policy limits reuse" + textPass "$REGION: Password Policy limits reuse" "$REGION" "password policy" else - textFail "Password Policy has weak reuse requirement (lower than 24)" + textFail "$REGION: Password Policy has weak reuse requirement (lower than 24)" "$REGION" "password policy" fi else - textFail "Password Policy missing reuse requirement" + textFail "$REGION: Password Policy missing reuse requirement" "$REGION" "password policy" fi } diff --git a/checks/check111 b/checks/check111 index 1cc174da..1a696f0b 100644 --- a/checks/check111 +++ b/checks/check111 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check111="1.11" -CHECK_TITLE_check111="[check111] Ensure IAM password policy expires passwords within 90 days or less (Scored)" +CHECK_TITLE_check111="[check111] Ensure IAM password policy expires passwords within 90 days or less" CHECK_SCORED_check111="SCORED" CHECK_TYPE_check111="LEVEL1" CHECK_SEVERITY_check111="Medium" @@ -29,11 +29,11 @@ check111(){ COMMAND111=$($AWSCLI iam get-account-password-policy $PROFILE_OPT --region $REGION --query PasswordPolicy.MaxPasswordAge --output text 2> /dev/null) if [[ $COMMAND111 == [0-9]* ]];then if [[ "$COMMAND111" -le "90" ]];then - textPass "Password Policy includes expiration (Value: $COMMAND111)" + textPass "$REGION: Password Policy includes expiration (Value: $COMMAND111)" "$REGION" "password policy" else - textFail "Password expiration is set greater than 90 days" + textFail "$REGION: Password expiration is set greater than 90 days" "$REGION" "password policy" fi else - textFail "Password expiration is not set" + textFail "$REGION: Password expiration is not set" "$REGION" "password policy" fi } diff --git a/checks/check112 b/checks/check112 index 0336877a..f2f6c422 100644 --- a/checks/check112 +++ b/checks/check112 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check112="1.12" -CHECK_TITLE_check112="[check112] Ensure no root account access key exists (Scored)" +CHECK_TITLE_check112="[check112] Ensure no root account access key exists" CHECK_SCORED_check112="SCORED" CHECK_TYPE_check112="LEVEL1" CHECK_SEVERITY_check112="Critical" @@ -30,13 +30,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 - textPass "No access key 1 found for root" + textPass "$REGION: No access key 1 found for root" "$REGION" "root access key1" else - textFail "Found access key 1 for root" + textFail "$REGION: Found access key 1 for root" "$REGION" "root access key1" fi if [ "$ROOTKEY2" == "false" ];then - textPass "No access key 2 found for root" + textPass "$REGION: No access key 2 found for root" "$REGION" "root access key2" else - textFail "Found access key 2 for root" + textFail "$REGION: Found access key 2 for root" "$REGION" "root access key2" fi } diff --git a/checks/check113 b/checks/check113 index 63717306..657c9b0a 100644 --- a/checks/check113 +++ b/checks/check113 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check113="1.13" -CHECK_TITLE_check113="[check113] Ensure MFA is enabled for the root account (Scored)" +CHECK_TITLE_check113="[check113] Ensure MFA is enabled for the root account" CHECK_SCORED_check113="SCORED" CHECK_TYPE_check113="LEVEL1" CHECK_SEVERITY_check113="Critical" @@ -28,8 +28,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 - textPass "Virtual MFA is enabled for root" + textPass "$REGION: Virtual MFA is enabled for root" "$REGION" "MFA" else - textFail "MFA is not ENABLED for root account" + textFail "$REGION: MFA is not ENABLED for root account" "$REGION" "MFA" fi } diff --git a/checks/check114 b/checks/check114 index f8a5b315..7872583f 100644 --- a/checks/check114 +++ b/checks/check114 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check114="1.14" -CHECK_TITLE_check114="[check114] Ensure hardware MFA is enabled for the root account (Scored)" +CHECK_TITLE_check114="[check114] Ensure hardware MFA is enabled for the root account" CHECK_SCORED_check114="SCORED" CHECK_TYPE_check114="LEVEL2" CHECK_SEVERITY_check114="Critical" @@ -30,11 +30,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_PARTITION}:iam::[0-9]\{12\}:mfa/root-account-mfa-device$") if [[ "$COMMAND114" ]]; then - textFail "Only Virtual MFA is enabled for root" + textFail "$REGION: Only Virtual MFA is enabled for root" "$REGION" "MFA" else - textPass "Hardware MFA is enabled for root" + textPass "$REGION: Hardware MFA is enabled for root" "$REGION" "MFA" fi else - textFail "MFA is not ENABLED for root account" + textFail "$REGION: MFA is not ENABLED for root account" "$REGION" "MFA" fi } diff --git a/checks/check115 b/checks/check115 index 54dfc0a9..356ba6d7 100644 --- a/checks/check115 +++ b/checks/check115 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check115="1.15" -CHECK_TITLE_check115="[check115] Ensure security questions are registered in the AWS account (Not Scored)" +CHECK_TITLE_check115="[check115] Ensure security questions are registered in the AWS account" CHECK_SCORED_check115="NOT_SCORED" CHECK_TYPE_check115="LEVEL1" CHECK_SEVERITY_check115="Medium" @@ -26,7 +26,5 @@ CHECK_CAF_EPIC_check115='IAM' check115(){ # "Ensure security questions are registered in the AWS account (Not Scored)" - 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 " + textInfo "No command available for check 1.15. Login to the AWS Console as root & click on the Account. Name -> My Account -> Configure Security Challenge Questions." } diff --git a/checks/check116 b/checks/check116 index 2d864117..18a0cbc3 100644 --- a/checks/check116 +++ b/checks/check116 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check116="1.16" -CHECK_TITLE_check116="[check116] Ensure IAM policies are attached only to groups or roles (Scored)" +CHECK_TITLE_check116="[check116] Ensure IAM policies are attached only to groups or roles" CHECK_SCORED_check116="SCORED" CHECK_TYPE_check116="LEVEL1" CHECK_SEVERITY_check116="Low" @@ -33,16 +33,16 @@ 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 - textFail "$user has managed policy directly attached" "us-east-1" "$user" + textFail "$REGION: $user has managed policy directly attached" "$REGION" "$user" C116_NUM_USERS=$(expr $C116_NUM_USERS + 1) fi USER_POLICY=$($AWSCLI iam list-user-policies --output text $PROFILE_OPT --region $REGION --user-name $user) if [[ $USER_POLICY ]]; then - textFail "$user has inline policy directly attached" "us-east-1" "$user" + textFail "$REGION: $user has inline policy directly attached" "$REGION" "$user" C116_NUM_USERS=$(expr $C116_NUM_USERS + 1) fi done if [[ $C116_NUM_USERS -eq 0 ]]; then - textPass "No policies attached to users" + textPass "$REGION: No policies attached to users" "$REGION" "$user" fi } diff --git a/checks/check117 b/checks/check117 index 85c5eb56..e9854cd0 100644 --- a/checks/check117 +++ b/checks/check117 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check117="1.17" -CHECK_TITLE_check117="[check117] Maintain current contact details (Not Scored)" +CHECK_TITLE_check117="[check117] Maintain current contact details" CHECK_SCORED_check117="NOT_SCORED" CHECK_TYPE_check117="LEVEL1" CHECK_SEVERITY_check117="Medium" @@ -27,6 +27,5 @@ CHECK_CAF_EPIC_check117='IAM' check117(){ # "Maintain current contact details (Scored)" # No command available - textInfo "No command available for check 1.17 " - textInfo "See section 1.17 on the CIS Benchmark guide for details " + textInfo "No command available for check 1.17. See section 1.17 on the CIS Benchmark guide for details." } diff --git a/checks/check118 b/checks/check118 index c57647d5..736bb594 100644 --- a/checks/check118 +++ b/checks/check118 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check118="1.18" -CHECK_TITLE_check118="[check118] Ensure security contact information is registered (Not Scored)" +CHECK_TITLE_check118="[check118] Ensure security contact information is registered" CHECK_SCORED_check118="NOT_SCORED" CHECK_TYPE_check118="LEVEL1" CHECK_SEVERITY_check118="Medium" @@ -27,6 +27,5 @@ CHECK_CAF_EPIC_check118='IAM' check118(){ # "Ensure security contact information is registered (Scored)" # No command available - textInfo "No command available for check 1.18 " - textInfo "See section 1.18 on the CIS Benchmark guide for details " + textInfo "No command available for check 1.18. See section 1.18 on the CIS Benchmark guide for details." } diff --git a/checks/check119 b/checks/check119 index e82f8e83..e9d148dc 100644 --- a/checks/check119 +++ b/checks/check119 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check119="1.19" -CHECK_TITLE_check119="[check119] Ensure IAM instance roles are used for AWS resource access from instances (Not Scored)" +CHECK_TITLE_check119="[check119] Ensure IAM instance roles are used for AWS resource access from instances" CHECK_SCORED_check119="NOT_SCORED" CHECK_TYPE_check119="LEVEL2" CHECK_SEVERITY_check119="Medium" @@ -38,12 +38,12 @@ check119(){ if [[ $PROFILEARN == "null" ]]; then textFail "$regx: Instance $instance not associated with an instance role" "$regx" "$instance" else - textPass "$regx: Instance $instance associated with role ${PROFILEARN##*/}" $regx + textPass "$regx: Instance $instance associated with role ${PROFILEARN##*/}" "$regx" "$instance" fi fi done else - textInfo "$regx: No EC2 instances found" $regx + textInfo "$regx: No EC2 instances found" "$regx" "$instance" fi done } diff --git a/checks/check12 b/checks/check12 index 63314bab..15ae9e4b 100644 --- a/checks/check12 +++ b/checks/check12 @@ -36,9 +36,9 @@ check12(){ done) if [[ $COMMAND12 ]]; then for u in $COMMAND12; do - textFail "User $u has Password enabled but MFA disabled" + textFail "$REGION: User $u has Password enabled but MFA disabled" "$REGION" "$u" done else - textPass "No users found with Password enabled and MFA disabled" + textPass "$REGION: No users found with Password enabled and MFA disabled" "$REGION" "$u" fi } diff --git a/checks/check120 b/checks/check120 index 6cabbad4..e2935a5b 100644 --- a/checks/check120 +++ b/checks/check120 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check120="1.20" -CHECK_TITLE_check120="[check120] Ensure a support role has been created to manage incidents with AWS Support (Scored)" +CHECK_TITLE_check120="[check120] Ensure a support role has been created to manage incidents with AWS Support" CHECK_SCORED_check120="SCORED" CHECK_TYPE_check120="LEVEL1" CHECK_SEVERITY_check120="Medium" @@ -34,16 +34,16 @@ check120(){ POLICYROLES=$($AWSCLI iam list-entities-for-policy --policy-arn $SUPPORTPOLICYARN $PROFILE_OPT --region $REGION --output text | awk -F$'\t' '{ print $3 }') if [[ $POLICYROLES ]];then for name in $POLICYROLES; do - textPass "Support Policy attached to $name" + textPass "$REGION: Support Policy attached to $name" "$REGION" "$name" done # for user in $(echo "$POLICYUSERS" | grep UserName | cut -d'"' -f4) ; do # textInfo "User $user has support access via $policyarn" # done else - textFail "Support Policy not applied to any Role" + textFail "$REGION: Support Policy not applied to any Role" "$REGION" "$name" fi done else - textFail "No Support Policy found" + textFail "$REGION: No Support Policy found" "$REGION" "$name" fi } diff --git a/checks/check121 b/checks/check121 index 26f2458e..64dd729c 100644 --- a/checks/check121 +++ b/checks/check121 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check121="1.21" -CHECK_TITLE_check121="[check121] Do not setup access keys during initial user setup for all IAM users that have a console password (Not Scored)" +CHECK_TITLE_check121="[check121] Do not setup access keys during initial user setup for all IAM users that have a console password" CHECK_SCORED_check121="NOT_SCORED" CHECK_TYPE_check121="LEVEL1" CHECK_SEVERITY_check121="Medium" @@ -35,10 +35,10 @@ check121(){ LIST_USERS_KEY1_ACTIVE=$(for user in $LIST_USERS_KEY1_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$4,$9 }'|grep "true true$"|awk '{ print $1 }'|sed 's/[[:blank:]]+/,/g' ; done) if [[ $LIST_USERS_KEY1_ACTIVE ]]; then for user in $LIST_USERS_KEY1_ACTIVE; do - textFail "User $user has never used access key 1" "us-east-1" "$user" + textFail "$REGION: User $user has never used access key 1" "$REGION" "$user" done else - textPass "No users found with access key 1 never used" + textPass "$REGION: No users found with access key 1 never used" "$REGION" "$user" 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) @@ -46,9 +46,9 @@ check121(){ LIST_USERS_KEY2_ACTIVE=$(for user in $LIST_USERS_KEY2_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$4,$14 }'|grep "true true$" |awk '{ print $1 }' ; done) if [[ $LIST_USERS_KEY2_ACTIVE ]]; then for user in $LIST_USERS_KEY2_ACTIVE; do - textFail "User $user has never used access key 2" + textFail "$REGION: User $user has never used access key 2" "$REGION" "$user" done else - textPass "No users found with access key 2 never used" + textPass "$REGION: No users found with access key 2 never used" "$REGION" "$user" fi } diff --git a/checks/check122 b/checks/check122 index 0aa01e3c..70423199 100644 --- a/checks/check122 +++ b/checks/check122 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check122="1.22" -CHECK_TITLE_check122="[check122] Ensure IAM policies that allow full \"*:*\" administrative privileges are not created (Scored)" +CHECK_TITLE_check122="[check122] Ensure IAM policies that allow full \"*:*\" administrative privileges are not created" CHECK_SCORED_check122="SCORED" CHECK_TYPE_check122="LEVEL1" CHECK_SEVERITY_check122="Medium" @@ -29,7 +29,6 @@ check122(){ # "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 --scope Local --query 'Policies[*].[Arn,DefaultVersionId]' | grep -v -e '^None$' | awk -F '\t' '{print $1","$2"\n"}') if [[ $LIST_CUSTOM_POLICIES ]]; then - textInfo "Looking for custom policies: (skipping default policies - it may take few seconds...)" for policy in $LIST_CUSTOM_POLICIES; do POLICY_ARN=$(echo $policy | awk -F ',' '{print $1}') POLICY_VERSION=$(echo $policy | awk -F ',' '{print $2}') @@ -39,14 +38,13 @@ check122(){ fi done if [[ $POLICIES_ALLOW_LIST ]]; then - textInfo "List of custom policies: " for policy in $POLICIES_ALLOW_LIST; do - textFail "Policy $policy allows \"*:*\"" "us-east-1" "$policy" + textFail "$REGION: Policy $policy allows \"*:*\"" "$REGION" "$policy" done else - textPass "No custom policy found that allow full \"*:*\" administrative privileges" + textPass "$REGION: No custom policy found that allow full \"*:*\" administrative privileges" "$REGION" "$policy" fi else - textPass "No custom policies found" + textPass "$REGION: No custom policies found" "$REGION" "$policy" fi } diff --git a/checks/check13 b/checks/check13 index 6ede4ae6..81b2c52b 100644 --- a/checks/check13 +++ b/checks/check13 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check13="1.3" -CHECK_TITLE_check13="[check13] Ensure credentials unused for 90 days or greater are disabled (Scored)" +CHECK_TITLE_check13="[check13] Ensure credentials unused for 90 days or greater are disabled" CHECK_SCORED_check13="SCORED" CHECK_TYPE_check13="LEVEL1" CHECK_SEVERITY_check13="Medium" diff --git a/checks/check14 b/checks/check14 index 594a785e..0d9d1cc7 100644 --- a/checks/check14 +++ b/checks/check14 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check14="1.4" -CHECK_TITLE_check14="[check14] Ensure access keys are rotated every 90 days or less (Scored)" +CHECK_TITLE_check14="[check14] Ensure access keys are rotated every 90 days or less" CHECK_SCORED_check14="SCORED" CHECK_TYPE_check14="LEVEL1" CHECK_SEVERITY_check14="Medium" @@ -40,15 +40,15 @@ check14(){ HOWOLDER=$(how_older_from_today $DATEROTATED1) if [ $HOWOLDER -gt "90" ];then - textFail "$user has not rotated access key 1 in over 90 days" "us-east-1" "$user" + textFail "$REGION: $user has not rotated access key 1 in over 90 days" "$REGION" "$user" C14_NUM_USERS1=$(expr $C14_NUM_USERS1 + 1) fi done if [[ $C14_NUM_USERS1 -eq 0 ]]; then - textPass "No users with access key 1 older than 90 days" + textPass "$REGION: No users with access key 1 older than 90 days" "$REGION" "$user" fi else - textPass "No users with access key 1" + textPass "$REGION: No users with access key 1" "$REGION" "$user" fi if [[ $LIST_OF_USERS_WITH_ACCESS_KEY2 ]]; then @@ -58,14 +58,14 @@ check14(){ DATEROTATED2=$(cat $TEMP_REPORT_FILE | grep -v user_creation_time | grep "^${user},"| awk -F, '{ print $15 }' | grep -v "N/A" | awk -F"T" '{ print $1 }') HOWOLDER=$(how_older_from_today $DATEROTATED2) if [ $HOWOLDER -gt "90" ];then - textFail "$user has not rotated access key 2 in over 90 days" "us-east-1" "$user" + textFail "$REGION: $user has not rotated access key 2 in over 90 days" "$REGION" "$user" C14_NUM_USERS2=$(expr $C14_NUM_USERS2 + 1) fi done if [[ $C14_NUM_USERS2 -eq 0 ]]; then - textPass "No users with access key 2 older than 90 days" + textPass "$REGION: No users with access key 2 older than 90 days" "$REGION" "$user" fi else - textPass "No users with access key 2" + textPass "$REGION: No users with access key 2" "$REGION" "$user" fi } diff --git a/checks/check15 b/checks/check15 index 902efcdf..079245d0 100644 --- a/checks/check15 +++ b/checks/check15 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check15="1.5" -CHECK_TITLE_check15="[check15] Ensure IAM password policy requires at least one uppercase letter (Scored)" +CHECK_TITLE_check15="[check15] Ensure IAM password policy requires at least one uppercase letter" CHECK_SCORED_check15="SCORED" CHECK_TYPE_check15="LEVEL1" CHECK_SEVERITY_check15="Medium" @@ -28,8 +28,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 - textPass "Password Policy requires upper case" + textPass "$REGION: Password Policy requires upper case" "$REGION" "password policy" else - textFail "Password Policy missing upper-case requirement" + textFail "$REGION: Password Policy missing upper-case requirement" "$REGION" "password policy" fi } diff --git a/checks/check16 b/checks/check16 index bb818535..719811d9 100644 --- a/checks/check16 +++ b/checks/check16 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check16="1.6" -CHECK_TITLE_check16="[check16] Ensure IAM password policy require at least one lowercase letter (Scored)" +CHECK_TITLE_check16="[check16] Ensure IAM password policy require at least one lowercase letter" CHECK_SCORED_check16="SCORED" CHECK_TYPE_check16="LEVEL1" CHECK_SEVERITY_check16="Medium" @@ -28,8 +28,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 - textPass "Password Policy requires lower case" + textPass "$REGION: Password Policy requires lower case" "$REGION" "password policy" else - textFail "Password Policy missing lower-case requirement" + textFail "$REGION: Password Policy missing lower-case requirement" "$REGION" "password policy" fi } diff --git a/checks/check17 b/checks/check17 index 8995dcc3..72fdd247 100644 --- a/checks/check17 +++ b/checks/check17 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check17="1.7" -CHECK_TITLE_check17="[check17] Ensure IAM password policy require at least one symbol (Scored)" +CHECK_TITLE_check17="[check17] Ensure IAM password policy require at least one symbol" CHECK_SCORED_check17="SCORED" CHECK_TYPE_check17="LEVEL1" CHECK_SEVERITY_check17="Medium" @@ -28,8 +28,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 - textPass "Password Policy requires symbol" + textPass "$REGION: Password Policy requires symbol" "$REGION" "password policy" else - textFail "Password Policy missing symbol requirement" + textFail "$REGION: Password Policy missing symbol requirement" "$REGION" "password policy" fi } diff --git a/checks/check18 b/checks/check18 index cb68c2e9..c13e101b 100644 --- a/checks/check18 +++ b/checks/check18 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check18="1.8" -CHECK_TITLE_check18="[check18] Ensure IAM password policy require at least one number (Scored)" +CHECK_TITLE_check18="[check18] Ensure IAM password policy require at least one number" CHECK_SCORED_check18="SCORED" CHECK_TYPE_check18="LEVEL1" CHECK_SEVERITY_check18="Medium" @@ -28,8 +28,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 - textPass "Password Policy requires number" + textPass "$REGION: Password Policy requires number" "$REGION" "password policy" else - textFail "Password Policy missing number requirement" + textFail "$REGION: Password Policy missing number requirement" "$REGION" "password policy" fi } diff --git a/checks/check19 b/checks/check19 index c28d21d8..27a61f9d 100644 --- a/checks/check19 +++ b/checks/check19 @@ -28,8 +28,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 - textPass "Password Policy requires more than 13 characters" + textPass "$REGION: Password Policy requires more than 13 characters" "$REGION" "password policy" else - textFail "Password Policy missing or weak length requirement" + textFail "$REGION: Password Policy missing or weak length requirement" "$REGION" "password policy" fi } diff --git a/checks/check21 b/checks/check21 index e88b2a71..bf7d2064 100644 --- a/checks/check21 +++ b/checks/check21 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check21="2.1" -CHECK_TITLE_check21="[check21] Ensure CloudTrail is enabled in all regions (Scored)" +CHECK_TITLE_check21="[check21] Ensure CloudTrail is enabled in all regions" CHECK_SCORED_check21="SCORED" CHECK_TYPE_check21="LEVEL1" CHECK_SEVERITY_check21="High" @@ -32,7 +32,7 @@ check21(){ for regx in $REGIONS; do TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',') if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails in $regx" + textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail" continue fi if [[ $TRAILS_AND_REGIONS ]]; then @@ -46,15 +46,15 @@ check21(){ MULTIREGION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].IsMultiRegionTrail' --output text --trail-name-list $trail) if [[ "$MULTIREGION_TRAIL_STATUS" == 'False' ]];then - textFail "Trail $trail in $regx is not enabled for all regions" "$regx" "$trail" + textFail "$regx: Trail $trail is not enabled for all regions" "$regx" "$trail" else - textPass "Trail $trail in $regx is enabled for all regions" "$regx" "$trail" + textPass "$regx: Trail $trail is enabled for all regions" "$regx" "$trail" fi done fi done if [[ $trail_count == 0 ]]; then - textFail "No CloudTrail trails were found in the account" + textFail "$regx: No CloudTrail trails were found in the account" "$regx" "$trail" fi } diff --git a/checks/check22 b/checks/check22 index 9aaba77c..3ae3e775 100644 --- a/checks/check22 +++ b/checks/check22 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check22="2.2" -CHECK_TITLE_check22="[check22] Ensure CloudTrail log file validation is enabled (Scored)" +CHECK_TITLE_check22="[check22] Ensure CloudTrail log file validation is enabled" CHECK_SCORED_check22="SCORED" CHECK_TYPE_check22="LEVEL2" CHECK_SEVERITY_check22="Medium" @@ -32,7 +32,7 @@ check22(){ for regx in $REGIONS; do TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',') if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails in $regx" + textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail" continue fi if [[ $TRAILS_AND_REGIONS ]]; then @@ -46,15 +46,15 @@ check22(){ LOGFILEVALIDATION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].LogFileValidationEnabled' --output text --trail-name-list $trail) if [[ "$LOGFILEVALIDATION_TRAIL_STATUS" == 'False' ]];then - textFail "Trail $trail in $regx log file validation disabled" "$regx" "$trail" + textFail "$regx: Trail $trail log file validation disabled" "$regx" "$trail" else - textPass "Trail $trail in $regx log file validation enabled" "$regx" "$trail" + textPass "$regx: Trail $trail log file validation enabled" "$regx" "$trail" fi done fi done if [[ $trail_count == 0 ]]; then - textFail "No CloudTrail trails were found in the account" + textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail" fi } diff --git a/checks/check23 b/checks/check23 index 719a3ac7..56984176 100644 --- a/checks/check23 +++ b/checks/check23 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check23="2.3" -CHECK_TITLE_check23="[check23] Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)" +CHECK_TITLE_check23="[check23] Ensure the S3 bucket CloudTrail logs to is not publicly accessible" CHECK_SCORED_check23="SCORED" CHECK_TYPE_check23="LEVEL1" CHECK_SEVERITY_check23="Critical" @@ -32,7 +32,7 @@ check23(){ for regx in $REGIONS; do TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',') if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails in $regx" + textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail" continue fi if [[ $TRAILS_AND_REGIONS ]]; then @@ -89,6 +89,6 @@ check23(){ fi done if [[ $trail_count == 0 ]]; then - textFail "No CloudTrail trails were found in the account" + textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail" fi } diff --git a/checks/check24 b/checks/check24 index 3146d71d..57691f3b 100644 --- a/checks/check24 +++ b/checks/check24 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check24="2.4" -CHECK_TITLE_check24="[check24] Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)" +CHECK_TITLE_check24="[check24] Ensure CloudTrail trails are integrated with CloudWatch Logs" CHECK_SCORED_check24="SCORED" CHECK_TYPE_check24="LEVEL1" CHECK_SEVERITY_check24="Low" @@ -32,7 +32,7 @@ check24(){ for regx in $REGIONS; do TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',') if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails in $regx" + textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail" continue fi if [[ $TRAILS_AND_REGIONS ]]; then @@ -46,14 +46,14 @@ check24(){ LATESTDELIVERY_TIMESTAMP=$($AWSCLI cloudtrail get-trail-status --name $trail $PROFILE_OPT --region $TRAIL_REGION --query 'LatestCloudWatchLogsDeliveryTime' --output text|grep -v None) if [[ ! $LATESTDELIVERY_TIMESTAMP ]];then - textFail "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)" + textFail "$TRAIL_REGION: $trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)" "$TRAIL_REGION" "$trail" else LATESTDELIVERY_DATE=$(timestamp_to_date $LATESTDELIVERY_TIMESTAMP) HOWOLDER=$(how_older_from_today $LATESTDELIVERY_DATE) if [ $HOWOLDER -gt "1" ];then - textFail "$trail trail is not logging in the last 24h or not configured (it is in $TRAIL_REGION)" + textFail "$TRAIL_REGION: $trail trail is not logging in the last 24h or not configured" "$TRAIL_REGION" "$trail" else - textPass "$trail trail has been logging during the last 24h (it is in $TRAIL_REGION)" + textPass "$TRAIL_REGION: $trail trail has been logging during the last 24h" "$TRAIL_REGION" "$trail" fi fi @@ -61,6 +61,6 @@ check24(){ fi done if [[ $trail_count == 0 ]]; then - textFail "No CloudTrail trails were found in the account" + textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail" fi } diff --git a/checks/check25 b/checks/check25 index 3444bbdb..c853cde5 100644 --- a/checks/check25 +++ b/checks/check25 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check25="2.5" -CHECK_TITLE_check25="[check25] Ensure AWS Config is enabled in all regions (Scored)" +CHECK_TITLE_check25="[check25] Ensure AWS Config is enabled in all regions" CHECK_SCORED_check25="SCORED" CHECK_TYPE_check25="LEVEL1" CHECK_SEVERITY_check25="Medium" @@ -31,17 +31,17 @@ check25(){ CHECK_AWSCONFIG_RECORDING=$($AWSCLI configservice describe-configuration-recorder-status $PROFILE_OPT --region $regx --query 'ConfigurationRecordersStatus[*].recording' --output text 2>&1) CHECK_AWSCONFIG_STATUS=$($AWSCLI configservice describe-configuration-recorder-status $PROFILE_OPT --region $regx --query 'ConfigurationRecordersStatus[*].lastStatus' --output text 2>&1) if [[ $(echo "$CHECK_AWSCONFIG_STATUS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe configuration recorder status in $regx" + textFail "$regx: Access Denied trying to describe configuration recorder status" "$regx" "recorder" continue fi if [[ $CHECK_AWSCONFIG_RECORDING == "True" ]]; then if [[ $CHECK_AWSCONFIG_STATUS == "SUCCESS" ]]; then - textPass "Region $regx AWS Config recorder enabled" + textPass "$regx: AWS Config recorder enabled" "$regx" "recorder" else - textFail "Region $regx AWS Config recorder in failure state" + textFail "$regx: AWS Config recorder in failure state" "$regx" "recorder" fi else - textFail "Region $regx AWS Config recorder disabled" + textFail "$regx: AWS Config recorder disabled" "$regx" "recorder" fi done } diff --git a/checks/check26 b/checks/check26 index 3b1e0947..a6663a22 100644 --- a/checks/check26 +++ b/checks/check26 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check26="2.6" -CHECK_TITLE_check26="[check26] Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Scored)" +CHECK_TITLE_check26="[check26] Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket" CHECK_SCORED_check26="SCORED" CHECK_TYPE_check26="LEVEL1" CHECK_SEVERITY_check26="Medium" @@ -31,7 +31,7 @@ check26(){ for regx in $REGIONS; do TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',') if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails in $regx" + textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail" continue fi if [[ $TRAILS_AND_REGIONS ]]; then @@ -45,13 +45,13 @@ check26(){ CLOUDTRAILBUCKET=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].[S3BucketName]' --output text --trail-name-list $trail) if [[ -z $CLOUDTRAILBUCKET ]]; then - textFail "Trail $trail in $TRAIL_REGION does not publish to S3" + textFail "$regx: Trail $trail does not publish to S3" "$TRAIL_REGION" "$trail" continue fi CLOUDTRAIL_ACCOUNT_ID=$(echo $trail | awk -F: '{ print $5 }') if [ "$CLOUDTRAIL_ACCOUNT_ID" != "$ACCOUNT_NUM" ]; then - textInfo "Trail $trail in $TRAIL_REGION S3 logging bucket $CLOUDTRAILBUCKET is not in current account" + textInfo "$regx: Trail $trail S3 logging bucket $CLOUDTRAILBUCKET is not in current account" "$TRAIL_REGION" "$trail" continue fi @@ -62,7 +62,7 @@ check26(){ # BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location $PROFILE_OPT --region $regx --bucket $CLOUDTRAILBUCKET --output text 2>&1) if [[ $(echo "$BUCKET_LOCATION" | grep AccessDenied) ]]; then - textFail "Trail $trail in $TRAIL_REGION Access Denied getting bucket location for $CLOUDTRAILBUCKET" + textFail "$regx: Trail $trail Access Denied getting bucket location for $CLOUDTRAILBUCKET" "$TRAIL_REGION" "$trail" continue fi if [[ $BUCKET_LOCATION == "None" ]]; then @@ -74,20 +74,20 @@ check26(){ CLOUDTRAILBUCKET_LOGENABLED=$($AWSCLI s3api get-bucket-logging --bucket $CLOUDTRAILBUCKET $PROFILE_OPT --region $BUCKET_LOCATION --query 'LoggingEnabled.TargetBucket' --output text 2>&1) if [[ $(echo "$CLOUDTRAILBUCKET_LOGENABLED" | grep AccessDenied) ]]; then - textInfo "Trail $trail in $TRAIL_REGION Access Denied getting bucket logging for $CLOUDTRAILBUCKET" + textInfo "$regx: Trail $trail Access Denied getting bucket logging for $CLOUDTRAILBUCKET" "$TRAIL_REGION" "$trail" continue fi if [[ $CLOUDTRAILBUCKET_LOGENABLED != "None" ]]; then - textPass "Trail $trail in $TRAIL_REGION S3 bucket access logging is enabled for $CLOUDTRAILBUCKET" + textPass "$regx: Trail $trail S3 bucket access logging is enabled for $CLOUDTRAILBUCKET" "$TRAIL_REGION" "$trail" else - textFail "Trail $trail in $TRAIL_REGION S3 bucket access logging is not enabled for $CLOUDTRAILBUCKET" + textFail "$regx: Trail $trail S3 bucket access logging is not enabled for $CLOUDTRAILBUCKET" "$TRAIL_REGION" "$trail" fi done fi done if [[ $trail_count == 0 ]]; then - textFail "No CloudTrail trails were found in the account" + textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail" fi } diff --git a/checks/check27 b/checks/check27 index 8eb61059..fa6a432d 100644 --- a/checks/check27 +++ b/checks/check27 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check27="2.7" -CHECK_TITLE_check27="[check27] Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)" +CHECK_TITLE_check27="[check27] Ensure CloudTrail logs are encrypted at rest using KMS CMKs" CHECK_SCORED_check27="SCORED" CHECK_TYPE_check27="LEVEL2" CHECK_SEVERITY_check27="Medium" @@ -32,7 +32,7 @@ check27(){ for regx in $REGIONS; do TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',') if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails in $regx" + textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail" continue fi if [[ $TRAILS_AND_REGIONS ]]; then @@ -46,14 +46,14 @@ check27(){ KMSKEYID=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].KmsKeyId' --output text --trail-name-list $trail) if [[ "$KMSKEYID" ]];then - textPass "Trail $trail in $regx has encryption enabled" + textPass "$regx: Trail $trail has encryption enabled" "$regx" "$trail" else - textFail "Trail $trail in $regx has encryption disabled" + textFail "$regx: Trail $trail has encryption disabled" "$regx" "$trail" fi done fi done if [[ $trail_count == 0 ]]; then - textFail "No CloudTrail trails were found in the account" + textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail" fi } diff --git a/checks/check28 b/checks/check28 index a1f7b547..aef746b1 100644 --- a/checks/check28 +++ b/checks/check28 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check28="2.8" -CHECK_TITLE_check28="[check28] Ensure rotation for customer created KMS CMKs is enabled (Scored)" +CHECK_TITLE_check28="[check28] Ensure rotation for customer created KMS CMKs is enabled" CHECK_SCORED_check28="SCORED" CHECK_TYPE_check28="LEVEL2" CHECK_SEVERITY_check28="Medium" @@ -30,7 +30,7 @@ check28(){ for regx in $REGIONS; do CHECK_KMS_KEYLIST=$($AWSCLI kms list-keys $PROFILE_OPT --region $regx --output text --query 'Keys[*].KeyId' --output text 2>&1) if [[ $(echo "$CHECK_KMS_KEYLIST" | grep AccessDenied) ]]; then - textFail "Access Denied trying to list keys in $regx" "$regx" "$key" + textFail "$regx: Access Denied trying to list keys" "$regx" "$key" continue fi if [[ $CHECK_KMS_KEYLIST ]]; then diff --git a/checks/check29 b/checks/check29 index 0187f628..b5023894 100644 --- a/checks/check29 +++ b/checks/check29 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check29="2.9" -CHECK_TITLE_check29="[check29] Ensure VPC Flow Logging is Enabled in all VPCs (Scored)" +CHECK_TITLE_check29="[check29] Ensure VPC Flow Logging is Enabled in all VPCs" CHECK_SCORED_check29="SCORED" CHECK_TYPE_check29="LEVEL2" CHECK_SEVERITY_check29="Medium" @@ -31,7 +31,7 @@ check29(){ for regx in $REGIONS; do AVAILABLE_VPC=$($AWSCLI ec2 describe-vpcs $PROFILE_OPT --region $regx --query 'Vpcs[?State==`available`].VpcId' --output text 2>&1) if [[ $(echo "$AVAILABLE_VPC" | grep AccessDenied) ]]; then - textFail "$regx: Access Denied trying to describe VPCs" + textFail "$regx: Access Denied trying to describe VPCs" "$regx" "$vpcx" continue fi for vpcx in $AVAILABLE_VPC; do diff --git a/checks/check31 b/checks/check31 index 938c147d..4411c6fa 100644 --- a/checks/check31 +++ b/checks/check31 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check31="3.1" -CHECK_TITLE_check31="[check31] Ensure a log metric filter and alarm exist for unauthorized API calls (Scored)" +CHECK_TITLE_check31="[check31] Ensure a log metric filter and alarm exist for unauthorized API calls" CHECK_SCORED_check31="SCORED" CHECK_TYPE_check31="LEVEL1" CHECK_SEVERITY_check31="Medium" diff --git a/checks/check310 b/checks/check310 index 4f821784..0a2d53d9 100644 --- a/checks/check310 +++ b/checks/check310 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check310="3.10" -CHECK_TITLE_check310="[check310] Ensure a log metric filter and alarm exist for security group changes (Scored)" +CHECK_TITLE_check310="[check310] Ensure a log metric filter and alarm exist for security group changes" CHECK_SCORED_check310="SCORED" CHECK_TYPE_check310="LEVEL2" CHECK_SEVERITY_check310="Medium" diff --git a/checks/check311 b/checks/check311 index 9c661251..fb66edb6 100644 --- a/checks/check311 +++ b/checks/check311 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check311="3.11" -CHECK_TITLE_check311="[check311] Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) (Scored)" +CHECK_TITLE_check311="[check311] Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL)" CHECK_SCORED_check311="SCORED" CHECK_TYPE_check311="LEVEL2" CHECK_SEVERITY_check311="Medium" diff --git a/checks/check312 b/checks/check312 index 8c44117e..1de26238 100644 --- a/checks/check312 +++ b/checks/check312 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check312="3.12" -CHECK_TITLE_check312="[check312] Ensure a log metric filter and alarm exist for changes to network gateways (Scored)" +CHECK_TITLE_check312="[check312] Ensure a log metric filter and alarm exist for changes to network gateways" CHECK_SCORED_check312="SCORED" CHECK_TYPE_check312="LEVEL1" CHECK_SEVERITY_check312="Medium" diff --git a/checks/check313 b/checks/check313 index 5852e63e..2ce23a51 100644 --- a/checks/check313 +++ b/checks/check313 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check313="3.13" -CHECK_TITLE_check313="[check313] Ensure a log metric filter and alarm exist for route table changes (Scored)" +CHECK_TITLE_check313="[check313] Ensure a log metric filter and alarm exist for route table changes" CHECK_SCORED_check313="SCORED" CHECK_TYPE_check313="LEVEL1" CHECK_SEVERITY_check313="Medium" diff --git a/checks/check314 b/checks/check314 index 820458eb..a0d728bb 100644 --- a/checks/check314 +++ b/checks/check314 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check314="3.14" -CHECK_TITLE_check314="[check314] Ensure a log metric filter and alarm exist for VPC changes (Scored)" +CHECK_TITLE_check314="[check314] Ensure a log metric filter and alarm exist for VPC changes" CHECK_SCORED_check314="SCORED" CHECK_TYPE_check314="LEVEL1" CHECK_SEVERITY_check314="Medium" diff --git a/checks/check32 b/checks/check32 index 9a28147d..b932b13a 100644 --- a/checks/check32 +++ b/checks/check32 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check32="3.2" -CHECK_TITLE_check32="[check32] Ensure a log metric filter and alarm exist for Management Console sign-in without MFA (Scored)" +CHECK_TITLE_check32="[check32] Ensure a log metric filter and alarm exist for Management Console sign-in without MFA" CHECK_SCORED_check32="SCORED" CHECK_TYPE_check32="LEVEL1" CHECK_SEVERITY_check32="Medium" diff --git a/checks/check33 b/checks/check33 index 7af68e62..1cd54328 100644 --- a/checks/check33 +++ b/checks/check33 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check33="3.3" -CHECK_TITLE_check33="[check33] Ensure a log metric filter and alarm exist for usage of root account (Scored)" +CHECK_TITLE_check33="[check33] Ensure a log metric filter and alarm exist for usage of root account" CHECK_SCORED_check33="SCORED" CHECK_TYPE_check33="LEVEL1" CHECK_SEVERITY_check33="Medium" diff --git a/checks/check34 b/checks/check34 index d32bc066..250044e0 100644 --- a/checks/check34 +++ b/checks/check34 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check34="3.4" -CHECK_TITLE_check34="[check34] Ensure a log metric filter and alarm exist for IAM policy changes (Scored)" +CHECK_TITLE_check34="[check34] Ensure a log metric filter and alarm exist for IAM policy changes" CHECK_SCORED_check34="SCORED" CHECK_TYPE_check34="LEVEL1" CHECK_SEVERITY_check34="Medium" diff --git a/checks/check35 b/checks/check35 index cdbbf038..bae1f254 100644 --- a/checks/check35 +++ b/checks/check35 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check35="3.5" -CHECK_TITLE_check35="[check35] Ensure a log metric filter and alarm exist for CloudTrail configuration changes (Scored)" +CHECK_TITLE_check35="[check35] Ensure a log metric filter and alarm exist for CloudTrail configuration changes" CHECK_SCORED_check35="SCORED" CHECK_TYPE_check35="LEVEL1" CHECK_SEVERITY_check35="Medium" diff --git a/checks/check36 b/checks/check36 index 1696912b..fc9e4c39 100644 --- a/checks/check36 +++ b/checks/check36 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check36="3.6" -CHECK_TITLE_check36="[check36] Ensure a log metric filter and alarm exist for AWS Management Console authentication failures (Scored)" +CHECK_TITLE_check36="[check36] Ensure a log metric filter and alarm exist for AWS Management Console authentication failures" CHECK_SCORED_check36="SCORED" CHECK_TYPE_check36="LEVEL2" CHECK_SEVERITY_check36="Medium" diff --git a/checks/check37 b/checks/check37 index 2d7d189b..03f593ea 100644 --- a/checks/check37 +++ b/checks/check37 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check37="3.7" -CHECK_TITLE_check37="[check37] Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created KMS CMKs (Scored)" +CHECK_TITLE_check37="[check37] Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created KMS CMKs" CHECK_SCORED_check37="SCORED" CHECK_TYPE_check37="LEVEL2" CHECK_SEVERITY_check37="Medium" diff --git a/checks/check38 b/checks/check38 index 196ced51..9d81443c 100644 --- a/checks/check38 +++ b/checks/check38 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check38="3.8" -CHECK_TITLE_check38="[check38] Ensure a log metric filter and alarm exist for S3 bucket policy changes (Scored)" +CHECK_TITLE_check38="[check38] Ensure a log metric filter and alarm exist for S3 bucket policy changes" CHECK_SCORED_check38="SCORED" CHECK_TYPE_check38="LEVEL1" CHECK_SEVERITY_check38="Medium" diff --git a/checks/check39 b/checks/check39 index 5e580499..aabbd359 100644 --- a/checks/check39 +++ b/checks/check39 @@ -37,7 +37,7 @@ # --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic CHECK_ID_check39="3.9" -CHECK_TITLE_check39="[check39] Ensure a log metric filter and alarm exist for AWS Config configuration changes (Scored)" +CHECK_TITLE_check39="[check39] Ensure a log metric filter and alarm exist for AWS Config configuration changes" CHECK_SCORED_check39="SCORED" CHECK_TYPE_check39="LEVEL2" CHECK_SEVERITY_check39="Medium" diff --git a/checks/check41 b/checks/check41 index 1ffd8961..02f0fbf5 100644 --- a/checks/check41 +++ b/checks/check41 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check41="4.1" -CHECK_TITLE_check41="[check41] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored)" +CHECK_TITLE_check41="[check41] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22" CHECK_SCORED_check41="SCORED" CHECK_TYPE_check41="LEVEL2" CHECK_SEVERITY_check41="High" @@ -32,10 +32,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`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text) if [[ $SG_LIST ]];then for SG in $SG_LIST;do - textFail "Found Security Group: $SG open to 0.0.0.0/0 in Region $regx" "$regx" "$SG" + textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" "$SG" done else - textPass "No Security Groups found in $regx with port 22 TCP open to 0.0.0.0/0" "$regx" + textPass "$regx: No Security Groups found with port 22 TCP open to 0.0.0.0/0" "$regx" "$SG" fi done } diff --git a/checks/check42 b/checks/check42 index d0e34354..a2bf70fd 100644 --- a/checks/check42 +++ b/checks/check42 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check42="4.2" -CHECK_TITLE_check42="[check42] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored)" +CHECK_TITLE_check42="[check42] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389" CHECK_SCORED_check42="SCORED" CHECK_TYPE_check42="LEVEL2" CHECK_SEVERITY_check42="High" @@ -32,10 +32,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`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text) if [[ $SG_LIST ]];then for SG in $SG_LIST;do - textFail "Found Security Group: $SG open to 0.0.0.0/0 in Region $regx" "$regx" "$SG" + textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" "$SG" done else - textPass "No Security Groups found in $regx with port 3389 TCP open to 0.0.0.0/0" "$regx" + textPass "$regx: No Security Groups found with port 3389 TCP open to 0.0.0.0/0" "$regx" "$SG" fi done } diff --git a/checks/check43 b/checks/check43 index a8da5612..205f4eb3 100644 --- a/checks/check43 +++ b/checks/check43 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check43="4.3" -CHECK_TITLE_check43="[check43] Ensure the default security group of every VPC restricts all traffic (Scored)" +CHECK_TITLE_check43="[check43] Ensure the default security group of every VPC restricts all traffic" CHECK_SCORED_check43="SCORED" CHECK_TYPE_check43="LEVEL2" CHECK_SEVERITY_check43="High" @@ -33,9 +33,9 @@ check43(){ for CHECK_SGDEFAULT_ID in $CHECK_SGDEFAULT_IDS; do CHECK_SGDEFAULT_ID_OPEN=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --group-ids $CHECK_SGDEFAULT_ID --query 'SecurityGroups[*].{IpPermissions:IpPermissions,IpPermissionsEgress:IpPermissionsEgress,GroupId:GroupId}' --output text |egrep '\s0.0.0.0|\:\:\/0') if [[ $CHECK_SGDEFAULT_ID_OPEN ]];then - textFail "Default Security Groups ($CHECK_SGDEFAULT_ID) found that allow 0.0.0.0 IN or OUT traffic in Region $regx" "$regx" "$CHECK_SGDEFAULT_ID" + textFail "$regx: Default Security Groups ($CHECK_SGDEFAULT_ID) found that allow 0.0.0.0 IN or OUT traffic" "$regx" "$CHECK_SGDEFAULT_ID" else - textPass "No Default Security Groups ($CHECK_SGDEFAULT_ID) open to 0.0.0.0 found in Region $regx" "$regx" "$CHECK_SGDEFAULT_ID" + textPass "$regx: No Default Security Groups ($CHECK_SGDEFAULT_ID) open to 0.0.0.0 found" "$regx" "$CHECK_SGDEFAULT_ID" fi done done diff --git a/checks/check44 b/checks/check44 index 62a8bf4d..e5328c29 100644 --- a/checks/check44 +++ b/checks/check44 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check44="4.4" -CHECK_TITLE_check44="[check44] Ensure routing tables for VPC peering are \"least access\" (Not Scored)" +CHECK_TITLE_check44="[check44] Ensure routing tables for VPC peering are \"least access\"" CHECK_SCORED_check44="NOT_SCORED" CHECK_TYPE_check44="LEVEL2" CHECK_SEVERITY_check44="Medium" @@ -27,11 +27,10 @@ CHECK_CAF_EPIC_check44='Infrastructure Security' check44(){ # "Ensure routing tables for VPC peering are \"least access\" (Not Scored)" - 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'| sort | paste -s -d" " -) if [[ $LIST_OF_VPCS_PEERING_CONNECTIONS ]];then - textInfo "$regx: $LIST_OF_VPCS_PEERING_CONNECTIONS - review routing tables" "$regx" + textInfo "$regx: $LIST_OF_VPCS_PEERING_CONNECTIONS - review routing tables" "$regx" "$LIST_OF_VPCS_PEERING_CONNECTIONS" #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 @@ -39,7 +38,7 @@ check44(){ # done #echo $VPCS_WITH_PEERING else - textPass "$regx: No VPC peering found" "$regx" + textPass "$regx: No VPC peering found" "$regx" "$LIST_OF_VPCS_PEERING_CONNECTIONS" fi done } diff --git a/checks/check45 b/checks/check45 index fdd5912f..d68fc140 100644 --- a/checks/check45 +++ b/checks/check45 @@ -30,10 +30,10 @@ check45(){ NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`22` && PortRange.To>=`22`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) if [[ $NACL_LIST ]];then for NACL in $NACL_LIST;do - textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for SSH port 22" "$regx" + textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for SSH port 22" "$regx" "$NACL" done else - textPass "$regx: No Network ACL found with SSH port 22 open to 0.0.0.0/0" "$regx" + textPass "$regx: No Network ACL found with SSH port 22 open to 0.0.0.0/0" "$regx" "$NACL" fi done } diff --git a/checks/check46 b/checks/check46 index fc03c121..02c2101b 100644 --- a/checks/check46 +++ b/checks/check46 @@ -30,10 +30,10 @@ check46(){ NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`3389` && PortRange.To>=`3389`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text) if [[ $NACL_LIST ]];then for NACL in $NACL_LIST;do - textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for Microsoft RDP port 3389" "$regx" + textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for Microsoft RDP port 3389" "$regx" "$NACL" done else - textPass "$regx: No Network ACL found with Microsoft RDP port 3389 open to 0.0.0.0/0" "$regx" + textPass "$regx: No Network ACL found with Microsoft RDP port 3389 open to 0.0.0.0/0" "$regx" "$NACL" fi done } diff --git a/checks/check_extra71 b/checks/check_extra71 index 23234823..4bf1706c 100644 --- a/checks/check_extra71 +++ b/checks/check_extra71 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra71="7.1" -CHECK_TITLE_extra71="[extra71] Ensure users of groups with AdministratorAccess policy have MFA tokens enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra71="[extra71] Ensure users of groups with AdministratorAccess policy have MFA tokens enabled" CHECK_SCORED_extra71="NOT_SCORED" CHECK_TYPE_extra71="EXTRA" CHECK_SEVERITY_extra71="High" @@ -27,7 +27,7 @@ CHECK_DOC_extra71='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentia CHECK_CAF_EPIC_extra71='Infrastructure Security' extra71(){ - # "Ensure users of groups with AdministratorAccess policy have MFA tokens enabled (Not Scored) (Not part of CIS benchmark)" + # "Ensure users of groups with AdministratorAccess policy have MFA tokens enabled " ADMIN_GROUPS='' AWS_GROUPS=$($AWSCLI $PROFILE_OPT iam list-groups --output text --region $REGION --query 'Groups[].GroupName') for grp in $AWS_GROUPS; do @@ -36,7 +36,7 @@ extra71(){ CHECK_ADMIN_GROUP=$($AWSCLI $PROFILE_OPT --region $REGION iam list-attached-group-policies --group-name $grp --output json --query 'AttachedPolicies[].PolicyArn' | grep "arn:${AWS_PARTITION}:iam::aws:policy/AdministratorAccess") if [[ $CHECK_ADMIN_GROUP ]]; then ADMIN_GROUPS="$ADMIN_GROUPS $grp" - textInfo "$grp group provides administrative access" + textInfo "$REGION: $grp group provides administrative access" "$REGION" "$grp" ADMIN_USERS=$($AWSCLI $PROFILE_OPT iam get-group --region $REGION --group-name $grp --output json --query 'Users[].UserName' | grep '"' | cut -d'"' -f2 ) for auser in $ADMIN_USERS; do # users in group are Administrators @@ -44,13 +44,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 - textPass "$auser / MFA Enabled / admin via group $grp" "us-east-1" "$auser" + textPass "$REGION: $auser / MFA Enabled / admin via group $grp" "$REGION" "$grp" else - textFail "$auser / MFA DISABLED / admin via group $grp" "us-east-1" "$auser" + textFail "$REGION: $auser / MFA DISABLED / admin via group $grp" "$REGION" "$grp" fi done else - textInfo "$grp group provides non-administrative access" + textInfo "$REGION: $grp group provides non-administrative access" "$REGION" "$grp" fi done } diff --git a/checks/check_extra710 b/checks/check_extra710 index 8e13384d..a1c10252 100644 --- a/checks/check_extra710 +++ b/checks/check_extra710 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra710="7.10" -CHECK_TITLE_extra710="[extra710] Check for internet facing EC2 Instances (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra710="[extra710] Check for internet facing EC2 Instances" CHECK_SCORED_extra710="NOT_SCORED" CHECK_TYPE_extra710="EXTRA" CHECK_SEVERITY_extra710="Medium" @@ -25,8 +25,7 @@ CHECK_DOC_extra710='https://aws.amazon.com/blogs/aws/aws-web-application-firewal CHECK_CAF_EPIC_extra710='Infrastructure Security' extra710(){ - # "Check for internet facing EC2 Instances (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for instances in all regions... " + # "Check for internet facing EC2 Instances " 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 diff --git a/checks/check_extra7100 b/checks/check_extra7100 index 1aa6859f..8e2a3807 100644 --- a/checks/check_extra7100 +++ b/checks/check_extra7100 @@ -37,7 +37,6 @@ extra7100(){ # Learn more: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_permissions-to-switch.html#roles-usingrole-createpolicy LIST_CUSTOM_POLICIES=$($AWSCLI iam list-policies --output text $PROFILE_OPT --region $REGION --scope Local --query 'Policies[*].[Arn,DefaultVersionId]' | grep -v -e '^None$' | awk -F '\t' '{print $1","$2"\n"}') if [[ $LIST_CUSTOM_POLICIES ]]; then - textInfo "Looking for custom policies: (skipping default policies - it may take few seconds...)" for policy in $LIST_CUSTOM_POLICIES; do POLICY_ARN=$(echo $policy | awk -F ',' '{print $1}') POLICY_VERSION=$(echo $policy | awk -F ',' '{print $2}') @@ -72,12 +71,12 @@ extra7100(){ textInfo "STS AssumeRole Policies should only include the complete ARNs for the Roles that the user needs" textInfo "Learn more: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_permissions-to-switch.html#roles-usingrole-createpolicy" for policy in $PERMISSIVE_POLICIES_LIST; do - textFail "Policy $policy allows permissive STS Role assumption" "us-east-1" "$policy" + textFail "$REGION: Policy $policy allows permissive STS Role assumption" "$REGION" "$policy" done else - textPass "No custom policies found that allow permissive STS Role assumption" + textPass "$REGION: No custom policies found that allow permissive STS Role assumption" "$REGION" fi else - textPass "No custom policies found" + textPass "$REGION: No custom policies found" "$REGION" fi } diff --git a/checks/check_extra711 b/checks/check_extra711 index 746d4a8f..4a0b5d66 100644 --- a/checks/check_extra711 +++ b/checks/check_extra711 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra711="7.11" -CHECK_TITLE_extra711="[extra711] Check for Publicly Accessible Redshift Clusters (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra711="[extra711] Check for Publicly Accessible Redshift Clusters" CHECK_SCORED_extra711="NOT_SCORED" CHECK_TYPE_extra711="EXTRA" CHECK_SEVERITY_extra711="High" @@ -24,8 +24,7 @@ CHECK_DOC_extra711='https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cl CHECK_CAF_EPIC_extra711='Data Protection' extra711(){ - # "Check for Publicly Accessible Redshift Clusters (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for Redshift clusters in all regions... " + # "Check for Publicly Accessible Redshift Clusters " 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 diff --git a/checks/check_extra7113 b/checks/check_extra7113 index 876ce7eb..3412a56b 100644 --- a/checks/check_extra7113 +++ b/checks/check_extra7113 @@ -23,7 +23,7 @@ # [--apply-immediately | --no-apply-immediately] CHECK_ID_extra7113="7.113" -CHECK_TITLE_extra7113="[extra7113] Check if RDS instances have deletion protection enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7113="[extra7113] Check if RDS instances have deletion protection enabled " CHECK_SCORED_extra7113="NOT_SCORED" CHECK_TYPE_extra7113="EXTRA" CHECK_SEVERITY_extra7113="Medium" diff --git a/checks/check_extra712 b/checks/check_extra712 index 21c9fcae..754c3559 100644 --- a/checks/check_extra712 +++ b/checks/check_extra712 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra712="7.12" -CHECK_TITLE_extra712="[extra712] Check if Amazon Macie is enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra712="[extra712] Check if Amazon Macie is enabled" CHECK_SCORED_extra712="NOT_SCORED" CHECK_TYPE_extra712="EXTRA" CHECK_SEVERITY_extra712="Low" @@ -24,12 +24,12 @@ CHECK_DOC_extra712='https://docs.aws.amazon.com/macie/latest/user/getting-starte CHECK_CAF_EPIC_extra712='Data Protection' extra712(){ -# textInfo "No API commands available to check if Macie is enabled," -# textInfo "just looking if IAM Macie related permissions exist. " +# "No API commands available to check if Macie is enabled," +# "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 - textPass "Macie related IAM roles exist so it might be enabled. Check it out manually" + textPass "$REGION: Macie related IAM roles exist so it might be enabled. Check it out manually" "$REGION" else - textFail "No Macie related IAM roles found. It is most likely not to be enabled" + textFail "$REGION: No Macie related IAM roles found. It is most likely not to be enabled" "$REGION" fi } diff --git a/checks/check_extra713 b/checks/check_extra713 index 008bf252..7a83b9bb 100644 --- a/checks/check_extra713 +++ b/checks/check_extra713 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra713="7.13" -CHECK_TITLE_extra713="[extra713] Check if GuardDuty is enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra713="[extra713] Check if GuardDuty is enabled" CHECK_SCORED_extra713="NOT_SCORED" CHECK_TYPE_extra713="EXTRA" CHECK_SEVERITY_extra713="High" @@ -25,7 +25,7 @@ CHECK_DOC_extra713='https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_se CHECK_CAF_EPIC_extra713='Data Protection' extra713(){ - # "Check if GuardDuty is enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if GuardDuty is enabled " for regx in $REGIONS; do LIST_OF_GUARDDUTY_DETECTORS=$($AWSCLI guardduty list-detectors $PROFILE_OPT --region $regx --output text --query DetectorIds[*] 2> /dev/null) RESULT=$? diff --git a/checks/check_extra7130 b/checks/check_extra7130 index 7c55d7fe..a302f0d4 100644 --- a/checks/check_extra7130 +++ b/checks/check_extra7130 @@ -25,7 +25,6 @@ CHECK_DOC_extra7130='https://docs.aws.amazon.com/sns/latest/dg/sns-server-side-e CHECK_CAF_EPIC_extra7130='Data Protection' extra7130(){ - textInfo "Looking for SNS Topics in all regions... " for regx in $REGIONS; do LIST_SNS=$($AWSCLI sns list-topics $PROFILE_OPT --region $regx --query 'Topics[*].TopicArn' --output text) if [[ $LIST_SNS ]];then diff --git a/checks/check_extra7134 b/checks/check_extra7134 index 6d38148c..4d649f83 100644 --- a/checks/check_extra7134 +++ b/checks/check_extra7134 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7134="7.134" -CHECK_TITLE_extra7134="[extra7134] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to FTP ports 20 or 21 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7134="[extra7134] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to FTP ports 20 or 21 " CHECK_SCORED_extra7134="NOT_SCORED" CHECK_TYPE_extra7134="EXTRA" CHECK_SEVERITY_extra7134="High" diff --git a/checks/check_extra7135 b/checks/check_extra7135 index c8562b52..42a27bfb 100644 --- a/checks/check_extra7135 +++ b/checks/check_extra7135 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7135="7.135" -CHECK_TITLE_extra7135="[extra7135] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Kafka port 9092 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7135="[extra7135] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Kafka port 9092 " CHECK_SCORED_extra7135="NOT_SCORED" CHECK_TYPE_extra7135="EXTRA" CHECK_SEVERITY_extra7135="High" diff --git a/checks/check_extra7136 b/checks/check_extra7136 index 3c247bcb..7b440031 100644 --- a/checks/check_extra7136 +++ b/checks/check_extra7136 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7136="7.136" -CHECK_TITLE_extra7136="[extra7136] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Telnet port 23 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7136="[extra7136] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Telnet port 23 " CHECK_SCORED_extra7136="NOT_SCORED" CHECK_TYPE_extra7136="EXTRA" CHECK_SEVERITY_extra7136="High" diff --git a/checks/check_extra7137 b/checks/check_extra7137 index 8014b442..754acc5f 100644 --- a/checks/check_extra7137 +++ b/checks/check_extra7137 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7137="7.137" -CHECK_TITLE_extra7137="[extra7137] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Windows SQL Server ports 1433 or 1434 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7137="[extra7137] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Windows SQL Server ports 1433 or 1434 " CHECK_SCORED_extra7137="NOT_SCORED" CHECK_TYPE_extra7137="EXTRA" CHECK_SEVERITY_extra7137="High" diff --git a/checks/check_extra7139 b/checks/check_extra7139 index bfb10568..0b635a10 100644 --- a/checks/check_extra7139 +++ b/checks/check_extra7139 @@ -10,7 +10,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7139="7.139" -CHECK_TITLE_extra7139="[extra7139] There are High severity GuardDuty findings (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7139="[extra7139] There are High severity GuardDuty findings " CHECK_SCORED_extra7139="NOT_SCORED" CHECK_TYPE_extra7139="EXTRA" CHECK_SEVERITY_extra7139="High" diff --git a/checks/check_extra714 b/checks/check_extra714 index fbe31dbc..27681e1f 100644 --- a/checks/check_extra714 +++ b/checks/check_extra714 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra714="7.14" -CHECK_TITLE_extra714="[extra714] Check if CloudFront distributions have logging enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra714="[extra714] Check if CloudFront distributions have logging enabled" CHECK_SCORED_extra714="NOT_SCORED" CHECK_TYPE_extra714="EXTRA" CHECK_SEVERITY_extra714="Medium" @@ -24,18 +24,18 @@ CHECK_DOC_extra714='https://docs.aws.amazon.com/AmazonCloudFront/latest/Develope CHECK_CAF_EPIC_extra714='Logging and Monitoring' extra714(){ - # "Check if CloudFront distributions have logging enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if CloudFront distributions have logging enabled " LIST_OF_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions $PROFILE_OPT --query 'DistributionList.Items[].Id' --output text | grep -v "^None") if [[ $LIST_OF_DISTRIBUTIONS ]]; then for dist in $LIST_OF_DISTRIBUTIONS; do LOG_ENABLED=$($AWSCLI cloudfront get-distribution $PROFILE_OPT --id "$dist" --query 'Distribution.DistributionConfig.Logging.Enabled' | grep true) if [[ $LOG_ENABLED ]]; then - textPass "CloudFront distribution $dist has logging enabled" "us-east-1" "$dist" + textPass "$REGION: CloudFront distribution $dist has logging enabled" "$REGION" "$dist" else - textFail "CloudFront distribution $dist has logging disabled" "us-east-1" "$dist" + textFail "$REGION: CloudFront distribution $dist has logging disabled" "$REGION" "$dist" fi done else - textInfo "No CloudFront distributions found" + textInfo "$REGION: No CloudFront distributions found" "$REGION" "$dist" fi } diff --git a/checks/check_extra716 b/checks/check_extra716 index f666b273..9a307f67 100644 --- a/checks/check_extra716 +++ b/checks/check_extra716 @@ -34,7 +34,7 @@ extra716(){ # If the endpoint starts with "vpc-" it is in a VPC then it is fine. if [[ "$ES_DOMAIN_ENDPOINT" =~ ^vpc-* ]];then ES_DOMAIN_VPC=$($AWSCLI es describe-elasticsearch-domain --domain-name $domain $PROFILE_OPT --region $regx --query 'DomainStatus.VPCOptions.VPCId' --output text) - textInfo "$regx: Amazon ES domain $domain is in VPC $ES_DOMAIN_VPC run extra779 to make sure it is not exposed using custom proxy" "$regx" + textInfo "$regx: Amazon ES domain $domain is in VPC $ES_DOMAIN_VPC run extra779 to make sure it is not exposed using custom proxy" "$regx" "$domain" else $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 a principal set up @@ -76,11 +76,11 @@ extra716(){ textFail "$regx: Amazon ES domain $domain policy allows access (Principal: \"*\" and network \"*\") - use extra788 to test AUTH" "$regx" "$domain" fi if [[ $CHECK_ES_DOMAIN_POLICY_HAS_CONDITION && ${CHECK_ES_DOMAIN_POLICY_CONDITION_PUBLIC_IP[@]} ]];then - textInfo "$regx: Amazon ES domain $domain policy allows access (Principal: \"*\" and Public IP or Network $(echo ${CONDITION_HAS_PUBLIC_IP_ARRAY[@]})) - use extra788 to test AUTH" "$regx" + textInfo "$regx: Amazon ES domain $domain policy allows access (Principal: \"*\" and Public IP or Network $(echo ${CONDITION_HAS_PUBLIC_IP_ARRAY[@]})) - use extra788 to test AUTH" "$regx" "$domain" fi else if [[ $CHECK_ES_DOMAIN_POLICY_HAS_CONDITION && ${CHECK_ES_DOMAIN_POLICY_CONDITION_PRIVATE_IP[@]} ]];then - textInfo "$regx: Amazon ES domain $domain policy allows access from a Private IP or CIDR RFC1918 $(echo ${CONDITION_HAS_PRIVATE_IP_ARRAY[@]})" "$regx" + textInfo "$regx: Amazon ES domain $domain policy allows access from a Private IP or CIDR RFC1918 $(echo ${CONDITION_HAS_PRIVATE_IP_ARRAY[@]})" "$regx" "$domain" else textPass "$regx: Amazon ES domain $domain does not allow anonymous access" "$regx" "$domain" fi diff --git a/checks/check_extra717 b/checks/check_extra717 index 53892197..f2f8996c 100644 --- a/checks/check_extra717 +++ b/checks/check_extra717 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra717="7.17" -CHECK_TITLE_extra717="[extra717] Check if Elastic Load Balancers have logging enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra717="[extra717] Check if Elastic Load Balancers have logging enabled" CHECK_SCORED_extra717="NOT_SCORED" CHECK_TYPE_extra717="EXTRA" CHECK_SEVERITY_extra717="Medium" @@ -24,7 +24,7 @@ CHECK_DOC_extra717='https://docs.aws.amazon.com/elasticloadbalancing/latest/appl CHECK_CAF_EPIC_extra717='Logging and Monitoring' extra717(){ - # "Check if Elastic Load Balancers have logging enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if Elastic Load Balancers have logging enabled " for regx in $REGIONS; do LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[*].LoadBalancerName' --output text|xargs -n1) LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text|xargs -n1) diff --git a/checks/check_extra718 b/checks/check_extra718 index 17b11b0b..8e1e8020 100644 --- a/checks/check_extra718 +++ b/checks/check_extra718 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra718="7.18" -CHECK_TITLE_extra718="[extra718] Check if S3 buckets have server access logging enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra718="[extra718] Check if S3 buckets have server access logging enabled" CHECK_SCORED_extra718="NOT_SCORED" CHECK_TYPE_extra718="EXTRA" CHECK_SEVERITY_extra718="Medium" @@ -24,22 +24,22 @@ CHECK_DOC_extra718='https://docs.aws.amazon.com/AmazonS3/latest/dev/security-bes CHECK_CAF_EPIC_extra718='Logging and Monitoring' extra718(){ - # "Check if S3 buckets have server access logging enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if S3 buckets have server access logging enabled " LIST_OF_BUCKETS=$($AWSCLI s3api list-buckets $PROFILE_OPT --query Buckets[*].Name --output text|xargs -n1) if [[ $LIST_OF_BUCKETS ]]; then for bucket in $LIST_OF_BUCKETS;do BUCKET_SERVER_LOG_ENABLED=$($AWSCLI s3api get-bucket-logging --bucket $bucket $PROFILE_OPT --query [LoggingEnabled] --output text 2>&1) if [[ $(echo "$BUCKET_SERVER_LOG_ENABLED" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to Get Bucket Logging for $bucket" + textFail "$REGION: Access Denied Trying to Get Bucket Logging for $bucket" "$REGION" "$bucket" continue fi if [[ $(echo "$BUCKET_SERVER_LOG_ENABLED" | grep "^None$") ]]; then - textFail "Bucket $bucket has server access logging disabled!" "us-east-1" "$bucket" + textFail "$REGION: Bucket $bucket has server access logging disabled!" "$REGION" "$bucket" else - textPass "Bucket $bucket has server access logging enabled" "us-east-1" "$bucket" + textPass "$REGION: Bucket $bucket has server access logging enabled" "$REGION" "$bucket" fi done else - textInfo "No S3 Buckets found" + textInfo "$REGION: No S3 Buckets found" "$REGION" "$bucket" fi } diff --git a/checks/check_extra719 b/checks/check_extra719 index ad148c3a..b3435656 100644 --- a/checks/check_extra719 +++ b/checks/check_extra719 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra719="7.19" -CHECK_TITLE_extra719="[extra719] Check if Route53 public hosted zones are logging queries to CloudWatch Logs (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra719="[extra719] Check if Route53 public hosted zones are logging queries to CloudWatch Logs" CHECK_SCORED_extra719="NOT_SCORED" CHECK_TYPE_extra719="EXTRA" CHECK_SEVERITY_extra719="Medium" @@ -30,12 +30,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 - textPass "Route53 public hosted zone Id $hostedzoneid has query logging enabled in Log Group $HOSTED_ZONE_QUERY_LOG_ENABLED" "us-east-1" "$hostedzoneid" + textPass "$REGION: Route53 public hosted zone Id $hostedzoneid has query logging enabled in Log Group $HOSTED_ZONE_QUERY_LOG_ENABLED" "$REGION" "$hostedzoneid" else - textFail "Route53 public hosted zone Id $hostedzoneid has query logging disabled!" "us-east-1" "$hostedzoneid" + textFail "$REGION: Route53 public hosted zone Id $hostedzoneid has query logging disabled!" "$REGION" "$hostedzoneid" fi done else - textInfo "No Route53 hosted zones found" + textInfo "$REGION: No Route53 hosted zones found" "$REGION" fi } diff --git a/checks/check_extra72 b/checks/check_extra72 index a7598b30..0d088896 100644 --- a/checks/check_extra72 +++ b/checks/check_extra72 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra72="7.2" -CHECK_TITLE_extra72="[extra72] Ensure there are no EBS Snapshots set as Public (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra72="[extra72] Ensure there are no EBS Snapshots set as Public" CHECK_SCORED_extra72="NOT_SCORED" CHECK_TYPE_extra72="EXTRA" CHECK_SEVERITY_extra72="Critical" @@ -26,8 +26,7 @@ CHECK_DOC_extra72='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-modif CHECK_CAF_EPIC_extra72='Data Protection' extra72(){ - # "Ensure there are no EBS Snapshots set as Public (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for EBS Snapshots in all regions... " + # "Ensure there are no EBS Snapshots set as Public " 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 diff --git a/checks/check_extra720 b/checks/check_extra720 index 5cef8b37..06608532 100644 --- a/checks/check_extra720 +++ b/checks/check_extra720 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra720="7.20" -CHECK_TITLE_extra720="[extra720] Check if Lambda functions invoke API operations are being recorded by CloudTrail (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra720="[extra720] Check if Lambda functions invoke API operations are being recorded by CloudTrail" CHECK_SCORED_extra720="NOT_SCORED" CHECK_TYPE_extra720="EXTRA" CHECK_SEVERITY_extra720="Low" @@ -24,17 +24,17 @@ CHECK_DOC_extra720='https://docs.aws.amazon.com/lambda/latest/dg/logging-using-c CHECK_CAF_EPIC_extra720='Logging and Monitoring' extra720(){ - # "Check if Lambda functions invoke API operations are being recorded by CloudTrail (Not Scored) (Not part of CIS benchmark)" + # "Check if Lambda functions invoke API operations are being recorded by CloudTrail " for regx in $REGIONS; do LIST_OF_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query 'Functions[*].FunctionName' --output text 2>&1) if [[ $(echo "$LIST_OF_FUNCTIONS" | grep AccessDenied) ]]; then - textFail "$regx: Access Denied trying to list functions" + textFail "$regx: Access Denied trying to list functions" "$regx" continue fi if [[ $LIST_OF_FUNCTIONS ]]; then LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].TrailARN' --output text 2>&1) if [[ $(echo "$LIST_OF_TRAILS" | grep AccessDenied) ]]; then - textFail "$regx: Access Denied trying to describe trails" + textFail "$regx: Access Denied trying to describe trails" "$regx" continue fi for lambdafunction in $LIST_OF_FUNCTIONS; do diff --git a/checks/check_extra721 b/checks/check_extra721 index 93d2ed92..8b2e54bf 100644 --- a/checks/check_extra721 +++ b/checks/check_extra721 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra721="7.21" -CHECK_TITLE_extra721="[extra721] Check if Redshift cluster has audit logging enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra721="[extra721] Check if Redshift cluster has audit logging enabled" CHECK_SCORED_extra721="NOT_SCORED" CHECK_TYPE_extra721="EXTRA" CHECK_SEVERITY_extra721="Medium" @@ -24,7 +24,7 @@ CHECK_DOC_extra721='https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing CHECK_CAF_EPIC_extra721='Logging and Monitoring' extra721(){ - # "Check if Redshift cluster has audit logging enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if Redshift cluster has audit logging enabled " for regx in $REGIONS; do LIST_OF_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[*].ClusterIdentifier' --output text) if [[ $LIST_OF_REDSHIFT_CLUSTERS ]]; then diff --git a/checks/check_extra722 b/checks/check_extra722 index 53dde9ed..4db8470c 100644 --- a/checks/check_extra722 +++ b/checks/check_extra722 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra722="7.22" -CHECK_TITLE_extra722="[extra722] Check if API Gateway has logging enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra722="[extra722] Check if API Gateway has logging enabled" CHECK_SCORED_extra722="NOT_SCORED" CHECK_TYPE_extra722="EXTRA" CHECK_SEVERITY_extra722="Medium" @@ -24,7 +24,7 @@ CHECK_DOC_extra722='https://docs.aws.amazon.com/apigateway/latest/developerguide CHECK_CAF_EPIC_extra722='Logging and Monitoring' extra722(){ - # "Check if API Gateway has logging enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if API Gateway has logging enabled " for regx in $REGIONS; do LIST_OF_API_GW=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query items[*].id --output text) if [[ $LIST_OF_API_GW ]];then diff --git a/checks/check_extra723 b/checks/check_extra723 index 3e0cbd04..9653b956 100644 --- a/checks/check_extra723 +++ b/checks/check_extra723 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra723="7.23" -CHECK_TITLE_extra723="[extra723] Check if RDS Snapshots and Cluster Snapshots are public (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra723="[extra723] Check if RDS Snapshots and Cluster Snapshots are public" CHECK_SCORED_extra723="NOT_SCORED" CHECK_TYPE_extra723="EXTRA" CHECK_SEVERITY_extra723="Critical" @@ -24,7 +24,7 @@ CHECK_DOC_extra723='https://docs.aws.amazon.com/config/latest/developerguide/rds CHECK_CAF_EPIC_extra723='Data Protection' extra723(){ - # "Check if RDS Snapshots are public (Not Scored) (Not part of CIS benchmark)" + # "Check if RDS Snapshots are public " for regx in $REGIONS; do # RDS snapshots LIST_OF_RDS_SNAPSHOTS=$($AWSCLI rds describe-db-snapshots $PROFILE_OPT --region $regx --query DBSnapshots[*].DBSnapshotIdentifier --output text) diff --git a/checks/check_extra724 b/checks/check_extra724 index f53e13fe..e0b2497f 100644 --- a/checks/check_extra724 +++ b/checks/check_extra724 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra724="7.24" -CHECK_TITLE_extra724="[extra724] Check if ACM certificates have Certificate Transparency logging enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra724="[extra724] Check if ACM certificates have Certificate Transparency logging enabled" CHECK_SCORED_extra724="NOT_SCORED" CHECK_TYPE_extra724="EXTRA" CHECK_SEVERITY_extra724="Medium" @@ -24,7 +24,7 @@ CHECK_DOC_extra724='https://aws.amazon.com/blogs/security/how-to-get-ready-for-c CHECK_CAF_EPIC_extra724='Logging and Monitoring' extra724(){ - # "Check if ACM certificates have Certificate Transparency logging enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if ACM certificates have Certificate Transparency logging enabled " for regx in $REGIONS; do LIST_OF_CERTS=$($AWSCLI acm list-certificates $PROFILE_OPT --region $regx --query CertificateSummaryList[].CertificateArn --output text) if [[ $LIST_OF_CERTS ]];then @@ -34,7 +34,7 @@ extra724(){ CERT_TYPE=$(aws acm describe-certificate $PROFILE_OPT --region $regx --certificate-arn $cert_arn --query Certificate.Type --output text) if [[ $CERT_TYPE == "IMPORTED" ]];then # Ignore imported certificate - textInfo "$regx: ACM Certificate $CERT_DOMAIN_NAME is imported." "$regx" + textInfo "$regx: ACM Certificate $CERT_DOMAIN_NAME is imported." "$regx" "$CERT_DOMAIN_NAME" else if [[ $CT_ENABLED == "ENABLED" ]];then textPass "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging enabled!" "$regx" "$CERT_DOMAIN_NAME" @@ -47,5 +47,4 @@ extra724(){ textInfo "$regx: No ACM Certificates found" "$regx" fi done - textInfo "*Read more about this here: https://aws.amazon.com/blogs/security/how-to-get-ready-for-certificate-transparency/" } diff --git a/checks/check_extra725 b/checks/check_extra725 index 8a90f8c9..4100b083 100644 --- a/checks/check_extra725 +++ b/checks/check_extra725 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra725="7.25" -CHECK_TITLE_extra725="[extra725] Check if S3 buckets have Object-level logging enabled in CloudTrail (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra725="[extra725] Check if S3 buckets have Object-level logging enabled in CloudTrail" CHECK_SCORED_extra725="NOT_SCORED" CHECK_TYPE_extra725="EXTRA" CHECK_SEVERITY_extra725="Medium" @@ -26,17 +26,15 @@ CHECK_CAF_EPIC_extra725='Logging and Monitoring' # per Object-level logging is not configured at Bucket level but at CloudTrail trail level extra725(){ - # "Check if S3 buckets have Object-level logging enabled in CloudTrail (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for S3 Buckets Object-level logging information in all trails... " - + # "Check if S3 buckets have Object-level logging enabled in CloudTrail " LIST_OF_BUCKETS=$($AWSCLI s3api list-buckets $PROFILE_OPT --region $REGION --query 'Buckets[*].{Name:Name}' --output text 2>&1) if [[ $(echo "$LIST_OF_BUCKETS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to list buckets" + textFail "$REGION: Access Denied trying to list buckets" return fi LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $REGION --query 'trailList[].TrailARN' --output text 2>&1) if [[ $(echo "$LIST_OF_TRAILS" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails" + textFail "$REGION: Access Denied trying to describe trails" return fi if [[ $LIST_OF_BUCKETS ]]; then @@ -53,17 +51,17 @@ extra725(){ if [[ ${#BUCKET_ENABLED_TRAILS[@]} -gt 0 ]]; then for trail in "${BUCKET_ENABLED_TRAILS[@]}"; do - textPass "$regx: S3 bucket $bucketName has Object-level logging enabled in trail $trail" "$regx" "$bucketName" + textPass "$REGION: S3 bucket $bucketName has Object-level logging enabled in trail $trail" "$REGION" "$bucketName" done else - textFail "$regx: S3 bucket $bucketName has Object-level logging disabled" "$regx" "$bucketName" + textFail "$REGION: S3 bucket $bucketName has Object-level logging disabled" "$REGION" "$bucketName" fi else - textFail "$regx: S3 bucket $bucketName is not being recorded no CloudTrail found!" "$regx" "$bucketName" + textFail "$REGION: S3 bucket $bucketName is not being recorded no CloudTrail found!" "$REGION" "$bucketName" fi done else - textInfo "$regx: No S3 buckets found" "$regx" + textInfo "$REGION: No S3 buckets found" "$REGION" fi } diff --git a/checks/check_extra726 b/checks/check_extra726 index 1119e526..76de3c84 100644 --- a/checks/check_extra726 +++ b/checks/check_extra726 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra726="7.26" -CHECK_TITLE_extra726="[extra726] Check Trusted Advisor for errors and warnings (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra726="[extra726] Check Trusted Advisor for errors and warnings" CHECK_SCORED_extra726="NOT_SCORED" CHECK_TYPE_extra726="EXTRA" CHECK_SEVERITY_extra726="Medium" @@ -25,32 +25,32 @@ CHECK_CAF_EPIC_extra726='IAM' extra726(){ trap "exit" INT - # forcing us-east-1 region only since support only works in that region - TA_CHECKS_ID=$($AWSCLI support describe-trusted-advisor-checks --language en $PROFILE_OPT --region us-east-1 --query checks[*].id --output text 2>&1) + # forcing REGION if not set will be us-east-1 region only since support only works in that region + TA_CHECKS_ID=$($AWSCLI support describe-trusted-advisor-checks --language en $PROFILE_OPT --region $REGION --query checks[*].id --output text 2>&1) if [[ $(echo "$TA_CHECKS_ID" | grep SubscriptionRequiredException) ]]; then - textInfo "Trusted Advisor requires AWS Premium Support Subscription" + textInfo "$REGION: Trusted Advisor requires AWS Premium Support Subscription" "$REGION" return fi for checkid in $TA_CHECKS_ID; do - TA_CHECKS_NAME=$($AWSCLI support describe-trusted-advisor-checks --language en $PROFILE_OPT --region us-east-1 --query "checks[?id==\`$checkid\`].{name:name}[*]" --output text) - QUERY_TA_CHECK_RESULT=$($AWSCLI support describe-trusted-advisor-check-result --check-id $checkid --language en $PROFILE_OPT --region us-east-1 --query 'result.status' --output text) + TA_CHECKS_NAME=$($AWSCLI support describe-trusted-advisor-checks --language en $PROFILE_OPT --region $REGION --query "checks[?id==\`$checkid\`].{name:name}[*]" --output text) + QUERY_TA_CHECK_RESULT=$($AWSCLI support describe-trusted-advisor-check-result --check-id $checkid --language en $PROFILE_OPT --region $REGION --query 'result.status' --output text) # Possible results - https://docs.aws.amazon.com/cli/latest/reference/support/describe-trusted-advisor-check-result.html case "$QUERY_TA_CHECK_RESULT" in "ok") - textPass "Trusted Advisor check $TA_CHECKS_NAME is in ok state $QUERY_TA_CHECK_RESULT" "us-east-1" "$TA_CHECKS_NAME" + textPass "$REGION: Trusted Advisor check $TA_CHECKS_NAME is in ok state $QUERY_TA_CHECK_RESULT" "$REGION" "$TA_CHECKS_NAME" ;; "error") - textFail "Trusted Advisor check $TA_CHECKS_NAME is in error state $QUERY_TA_CHECK_RESULT" "us-east-1" "$TA_CHECKS_NAME" + textFail "$REGION: Trusted Advisor check $TA_CHECKS_NAME is in error state $QUERY_TA_CHECK_RESULT" "$REGION" "$TA_CHECKS_NAME" ;; "warning") - textInfo "Trusted Advisor check $TA_CHECKS_NAME is in warning state $QUERY_TA_CHECK_RESULT" "us-east-1" "$TA_CHECKS_NAME" + textInfo "$REGION: Trusted Advisor check $TA_CHECKS_NAME is in warning state $QUERY_TA_CHECK_RESULT" "$REGION" "$TA_CHECKS_NAME" ;; "not_available") - textInfo "Trusted Advisor check $TA_CHECKS_NAME is in not_available state $QUERY_TA_CHECK_RESULT" "us-east-1" "$TA_CHECKS_NAME" + textInfo "$REGION: Trusted Advisor check $TA_CHECKS_NAME is in not_available state $QUERY_TA_CHECK_RESULT" "u$REGION" "$TA_CHECKS_NAME" ;; "*") - textFail "Trusted Advisor check $TA_CHECKS_NAME is in unknown state $QUERY_TA_CHECK_RESULT" "us-east-1" "$TA_CHECKS_NAME" + textFail "$REGION: Trusted Advisor check $TA_CHECKS_NAME is in unknown state $QUERY_TA_CHECK_RESULT" "$REGION" "$TA_CHECKS_NAME" ;; esac done diff --git a/checks/check_extra727 b/checks/check_extra727 index 63ad651e..797401be 100644 --- a/checks/check_extra727 +++ b/checks/check_extra727 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra727="7.27" -CHECK_TITLE_extra727="[extra727] Check if SQS queues have policy set as Public (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra727="[extra727] Check if SQS queues have policy set as Public" CHECK_SCORED_extra727="NOT_SCORED" CHECK_TYPE_extra727="EXTRA" CHECK_SEVERITY_extra727="Critical" @@ -41,7 +41,7 @@ extra727(){ | jq '"[Principal: " + (.Principal|tostring) + " Action: " + (.Action|tostring) + "]"' ) textFail "$regx: SQS $queue queue policy with public access: $SQS_POLICY_ALLOW_ALL_WITHOUT_CONDITION_DETAILS" "$regx" "$queue" else - textInfo "$regx: SQS $queue queue policy with public access but has a Condition" "$regx" + textInfo "$regx: SQS $queue queue policy with public access but has a Condition" "$regx" "$queue" fi else textPass "$regx: SQS $queue queue without public access" "$regx" "$queue" diff --git a/checks/check_extra728 b/checks/check_extra728 index 3fbaff2c..f7589af1 100644 --- a/checks/check_extra728 +++ b/checks/check_extra728 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra728="7.28" -CHECK_TITLE_extra728="[extra728] Check if SQS queues have Server Side Encryption enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra728="[extra728] Check if SQS queues have Server Side Encryption enabled" CHECK_SCORED_extra728="NOT_SCORED" CHECK_TYPE_extra728="EXTRA" CHECK_SEVERITY_extra728="Medium" diff --git a/checks/check_extra729 b/checks/check_extra729 index e3759bf2..743e568d 100644 --- a/checks/check_extra729 +++ b/checks/check_extra729 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra729="7.29" -CHECK_TITLE_extra729="[extra729] Ensure there are no EBS Volumes unencrypted (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra729="[extra729] Ensure there are no EBS Volumes unencrypted" CHECK_SCORED_extra729="NOT_SCORED" CHECK_TYPE_extra729="EXTRA" CHECK_SEVERITY_extra729="Medium" @@ -26,8 +26,7 @@ CHECK_DOC_extra729='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncry CHECK_CAF_EPIC_extra729='Data Protection' extra729(){ - # "Ensure there are no EBS Volumes unencrypted (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for EBS Volumes in all regions... " + # "Ensure there are no EBS Volumes unencrypted " for regx in $REGIONS; do LIST_OF_EBS_NON_ENC_VOLUMES=$($AWSCLI ec2 describe-volumes $PROFILE_OPT --region $regx --query 'Volumes[?Encrypted==`false`].VolumeId' --output text) if [[ $LIST_OF_EBS_NON_ENC_VOLUMES ]];then diff --git a/checks/check_extra73 b/checks/check_extra73 index 9a0b9162..c2329607 100644 --- a/checks/check_extra73 +++ b/checks/check_extra73 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra73="7.3" -CHECK_TITLE_extra73="[extra73] Ensure there are no S3 buckets open to Everyone or Any AWS user (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra73="[extra73] Ensure there are no S3 buckets open to Everyone or Any AWS user" CHECK_SCORED_extra73="NOT_SCORED" CHECK_TYPE_extra73="EXTRA" CHECK_SEVERITY_extra73="Critical" @@ -43,14 +43,12 @@ CHECK_CAF_EPIC_extra73='Data Protection' # for day to day usage that is probably desirable. extra73(){ - textInfo "Looking for open S3 Buckets (ACLs and Policies) in all regions... " - # # If public ACLs disabled at account level then look no further # ACCOUNT_PUBLIC_ACCESS_BLOCK=$($AWSCLI s3control get-public-access-block $PROFILE_OPT --region $REGION --account-id $ACCOUNT_NUM --output json 2>&1) if [[ $(echo "$ACCOUNT_PUBLIC_ACCESS_BLOCK" | grep AccessDenied) ]]; then - textFail "Access Denied getting PublicAccessBlock configuration for AWS account" + textFail "$REGION: Access Denied getting PublicAccessBlock configuration for AWS account" "$REGION" "$bucket" return fi if [[ $(echo "$ACCOUNT_PUBLIC_ACCESS_BLOCK" | grep NoSuchPublicAccessBlockConfiguration) ]]; then @@ -61,7 +59,7 @@ extra73(){ ACCOUNTRESTRICTPUBLICBUCKETS=$(echo "$ACCOUNT_PUBLIC_ACCESS_BLOCK" | jq -r '.PublicAccessBlockConfiguration.RestrictPublicBuckets') fi if [[ $ACCOUNTIGNOREPUBLICACLS == "true" && $ACCOUNTRESTRICTPUBLICBUCKETS == "true" ]]; then - textPass "All S3 public access blocked at account level" + textPass "$REGION: All S3 public access blocked at account level" "$REGION" "$bucket" return fi @@ -70,11 +68,11 @@ extra73(){ # ALL_BUCKETS_LIST=$($AWSCLI s3api list-buckets --query 'Buckets[*].{Name:Name}' $PROFILE_OPT --output text 2>&1) if [[ $(echo "$ALL_BUCKETS_LIST" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to List Buckets" + textFail "$REGION: Access Denied Trying to List Buckets" "$REGION" "$bucket" return fi if [[ "$ALL_BUCKETS_LIST" == "" ]]; then - textInfo "No buckets found" + textInfo "$REGION: No buckets found" "$REGION" "$bucket" return fi @@ -87,7 +85,7 @@ extra73(){ # BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location $PROFILE_OPT --region $REGION --bucket $bucket --output text 2>&1) if [[ $(echo "$BUCKET_LOCATION" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to Get Bucket Location for $bucket" + textFail "$REGION: Access Denied Trying to Get Bucket Location for $bucket" "$REGION" "$bucket" continue fi if [[ $BUCKET_LOCATION == "None" ]]; then @@ -101,7 +99,7 @@ extra73(){ # BUCKET_PUBLIC_ACCESS_BLOCK=$($AWSCLI s3api get-public-access-block $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --output json 2>&1) if [[ $(echo "$BUCKET_PUBLIC_ACCESS_BLOCK" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to Get Public Access Block for $bucket" + textFail "$BUCKET_LOCATION: Access Denied Trying to Get Public Access Block for $bucket" "$BUCKET_LOCATION" "$bucket" continue fi if [[ $(echo "$BUCKET_PUBLIC_ACCESS_BLOCK" | grep NoSuchPublicAccessBlockConfiguration) ]]; then @@ -112,7 +110,7 @@ extra73(){ BUCKETRESTRICTPUBLICBUCKETS=$(echo "$BUCKET_PUBLIC_ACCESS_BLOCK" | jq -r '.PublicAccessBlockConfiguration.RestrictPublicBuckets') fi if [[ $BUCKETIGNOREPUBLICACLS == "true" && $BUCKETRESTRICTPUBLICBUCKETS == "true" ]]; then - textPass "$BUCKET_LOCATION: $bucket bucket is not Public" "$BUCKET_LOCATION" + textPass "$BUCKET_LOCATION: $bucket bucket is not Public" "$BUCKET_LOCATION" "$bucket" continue fi @@ -121,7 +119,7 @@ extra73(){ # BUCKET_ACL=$($AWSCLI s3api get-bucket-acl $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --output json 2>&1) if [[ $(echo "$BUCKET_ACL" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to Get Bucket Acl for $bucket" + textFail "$BUCKET_LOCATION: Access Denied Trying to Get Bucket Acl for $bucket" "$BUCKET_LOCATION" "$bucket" continue fi @@ -142,7 +140,7 @@ extra73(){ # BUCKET_POLICY_STATUS=$($AWSCLI s3api get-bucket-policy-status $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query PolicyStatus.IsPublic --output text 2>&1) if [[ $(echo "$BUCKET_POLICY_STATUS" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to Get Bucket Policy Status for $bucket" + textFail "$BUCKET_LOCATION: Access Denied Trying to Get Bucket Policy Status for $bucket" "$BUCKET_LOCATION" "$bucket" continue fi if [[ $(echo "$BUCKET_POLICY_STATUS" | grep NoSuchBucketPolicy) ]]; then diff --git a/checks/check_extra730 b/checks/check_extra730 index f37e9a8f..706922fa 100644 --- a/checks/check_extra730 +++ b/checks/check_extra730 @@ -14,7 +14,7 @@ DAYS_TO_EXPIRE_THRESHOLD="7" CHECK_ID_extra730="7.30" -CHECK_TITLE_extra730="[extra730] Check if ACM Certificates are about to expire in $DAYS_TO_EXPIRE_THRESHOLD days or less (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra730="[extra730] Check if ACM Certificates are about to expire in $DAYS_TO_EXPIRE_THRESHOLD days or less" CHECK_SCORED_extra730="NOT_SCORED" CHECK_TYPE_extra730="EXTRA" CHECK_SEVERITY_extra730="High" diff --git a/checks/check_extra731 b/checks/check_extra731 index 69b4d81c..3a5eec01 100644 --- a/checks/check_extra731 +++ b/checks/check_extra731 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra731="7.31" -CHECK_TITLE_extra731="[extra731] Check if SNS topics have policy set as Public (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra731="[extra731] Check if SNS topics have policy set as Public" CHECK_SCORED_extra731="NOT_SCORED" CHECK_TYPE_extra731="EXTRA" CHECK_SEVERITY_extra731="Critical" diff --git a/checks/check_extra732 b/checks/check_extra732 index 75e4f9ab..3b584d34 100644 --- a/checks/check_extra732 +++ b/checks/check_extra732 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra732="7.32" -CHECK_TITLE_extra732="[extra732] Check if Geo restrictions are enabled in CloudFront distributions (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra732="[extra732] Check if Geo restrictions are enabled in CloudFront distributions" CHECK_SCORED_extra732="NOT_SCORED" CHECK_TYPE_extra732="EXTRA" CHECK_SEVERITY_extra732="Low" @@ -30,12 +30,12 @@ extra732(){ for dist in $LIST_DISTRIBUTIONS; do GEO_ENABLED=$($AWSCLI cloudfront get-distribution-config $PROFILE_OPT --id $dist --query DistributionConfig.Restrictions.GeoRestriction.RestrictionType --output text) if [[ $GEO_ENABLED == "none" ]]; then - textFail "CloudFront distribution $dist has not Geo restrictions" "us-east-1" "$dist" + textFail "$REGION: CloudFront distribution $dist has not Geo restrictions" "$REGION" "$dist" else - textPass "CloudFront distribution $dist has Geo restrictions enabled" "us-east-1" "$dist" + textPass "$REGION: CloudFront distribution $dist has Geo restrictions enabled" "$REGION" "$dist" fi done else - textInfo "No CloudFront distributions found" + textInfo "$REGION: No CloudFront distributions found" fi } diff --git a/checks/check_extra733 b/checks/check_extra733 index 32a05152..24ea3275 100644 --- a/checks/check_extra733 +++ b/checks/check_extra733 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra733="7.33" -CHECK_TITLE_extra733="[extra733] Check if there are SAML Providers then STS can be used (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra733="[extra733] Check if there are SAML Providers then STS can be used" CHECK_SCORED_extra733="NOT_SCORED" CHECK_TYPE_extra733="EXTRA" CHECK_SEVERITY_extra733="Low" @@ -29,9 +29,9 @@ extra733(){ if [[ $LIST_SAML_PROV ]]; then for provider in $LIST_SAML_PROV; do PROVIDER_NAME=$(echo $provider| cut -d/ -f2) - textInfo "SAML Provider $PROVIDER_NAME has been found" + textInfo "$REGION: SAML Provider $PROVIDER_NAME has been found" "$REGION" "$PROVIDER_NAME" done else - textFail "No SAML Provider found. Add one and use STS" + textFail "$REGION: No SAML Provider found. Add one and use STS" "$REGION" "$PROVIDER_NAME" fi } diff --git a/checks/check_extra734 b/checks/check_extra734 index cb64f335..bb6e2ae5 100644 --- a/checks/check_extra734 +++ b/checks/check_extra734 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra734="7.34" -CHECK_TITLE_extra734="[extra734] Check if S3 buckets have default encryption (SSE) enabled or use a bucket policy to enforce it (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra734="[extra734] Check if S3 buckets have default encryption (SSE) enabled or use a bucket policy to enforce it" CHECK_SCORED_extra734="NOT_SCORED" CHECK_TYPE_extra734="EXTRA" CHECK_SEVERITY_extra734="Medium" @@ -30,7 +30,7 @@ extra734(){ for bucket in $LIST_OF_BUCKETS;do BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location $PROFILE_OPT --region $REGION --bucket $bucket --output text 2>&1) if [[ $(echo "$BUCKET_LOCATION" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to Get Bucket Location for $bucket" + textFail "$BUCKET_LOCATION Access Denied Trying to Get Bucket Location for $bucket" "$BUCKET_LOCATION" "$bucket" continue fi if [[ $BUCKET_LOCATION == "None" ]]; then @@ -46,13 +46,13 @@ extra734(){ # query to get if has encryption enabled or not RESULT=$($AWSCLI s3api get-bucket-encryption $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query ServerSideEncryptionConfiguration.Rules[].ApplyServerSideEncryptionByDefault[].SSEAlgorithm --output text 2>&1) if [[ $(echo "$RESULT" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to Get Encryption for $bucket" + textFail "$BUCKET_LOCATION: Access Denied Trying to Get Encryption for $bucket" "$BUCKET_LOCATION" "$bucket" continue fi if [[ $RESULT == "AES256" || $RESULT == "aws:kms" ]]; then - textPass "Bucket $bucket is enabled for default encryption with $RESULT" "us-east-1" "$bucket" + textPass "$BUCKET_LOCATION: Bucket $bucket is enabled for default encryption with $RESULT" "$BUCKET_LOCATION" "$bucket" continue fi @@ -61,12 +61,12 @@ extra734(){ # get bucket policy $AWSCLI s3api get-bucket-policy $PROFILE_OPT --bucket $bucket --region $BUCKET_LOCATION --output text --query Policy > $TEMP_SSE_POLICY_FILE 2>&1 if [[ $(grep AccessDenied $TEMP_SSE_POLICY_FILE) ]]; then - textFail "Access Denied Trying to Get Bucket Policy for $bucket" + textFail "$BUCKET_LOCATION: Access Denied Trying to Get Bucket Policy for $bucket" "$BUCKET_LOCATION" "$bucket" rm -f $TEMP_SSE_POLICY_FILE continue fi if [[ $(grep NoSuchBucketPolicy $TEMP_SSE_POLICY_FILE) ]]; then - textFail "No bucket policy for $bucket" "us-east-1" "$bucket" "us-east-1" "$bucket" + textFail "$BUCKET_LOCATION: No bucket policy for $bucket" "$BUCKET_LOCATION" "$bucket" rm -f $TEMP_SSE_POLICY_FILE continue fi @@ -74,18 +74,18 @@ extra734(){ # check if the S3 policy forces SSE s3:x-amz-server-side-encryption:true CHECK_BUCKET_SSE_POLICY_PRESENT=$(cat $TEMP_SSE_POLICY_FILE | jq --arg arn "arn:${AWS_PARTITION}:s3:::${bucket}/*" '.Statement[]|select(.Effect=="Deny" and ((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*") and .Action=="s3:PutObject" and .Resource==$arn and .Condition.StringEquals."s3:x-amz-server-side-encryption" != null)') if [[ $CHECK_BUCKET_SSE_POLICY_PRESENT == "" ]]; then - textFail "Bucket $bucket does not enforce encryption!" "us-east-1" "$bucket" + textFail "$BUCKET_LOCATION: Bucket $bucket does not enforce encryption!" "$BUCKET_LOCATION" "$bucket" rm -f $TEMP_SSE_POLICY_FILE continue fi CHECK_BUCKET_SSE_POLICY_VALUE=$(echo "$CHECK_BUCKET_SSE_POLICY_PRESENT" | jq -r '.Condition.StringNotEquals."s3:x-amz-server-side-encryption"') - textPass "Bucket $bucket has S3 bucket policy to enforce encryption with $CHECK_BUCKET_SSE_POLICY_VALUE" + textPass "$BUCKET_LOCATION: Bucket $bucket has S3 bucket policy to enforce encryption with $CHECK_BUCKET_SSE_POLICY_VALUE" "$BUCKET_LOCATION" "$bucket" rm -f $TEMP_SSE_POLICY_FILE done else - textInfo "No S3 Buckets found" + textInfo "$REGION No S3 Buckets found" "$REGION" fi } diff --git a/checks/check_extra735 b/checks/check_extra735 index f1d07aba..72cb30f9 100644 --- a/checks/check_extra735 +++ b/checks/check_extra735 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra735="7.35" -CHECK_TITLE_extra735="[extra735] Check if RDS instances storage is encrypted (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra735="[extra735] Check if RDS instances storage is encrypted" CHECK_SCORED_extra735="NOT_SCORED" CHECK_TYPE_extra735="EXTRA" CHECK_SEVERITY_extra735="Medium" diff --git a/checks/check_extra736 b/checks/check_extra736 index 00d246c9..1c87be8e 100644 --- a/checks/check_extra736 +++ b/checks/check_extra736 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra736="7.36" -CHECK_TITLE_extra736="[extra736] Check exposed KMS keys (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra736="[extra736] Check exposed KMS keys" CHECK_SCORED_extra736="NOT_SCORED" CHECK_TYPE_extra736="EXTRA" CHECK_SEVERITY_extra736="Critical" @@ -25,7 +25,6 @@ CHECK_DOC_extra736='https://docs.aws.amazon.com/kms/latest/developerguide/determ CHECK_CAF_EPIC_extra736='Data Protection' extra736(){ - textInfo "Looking for KMS keys in all regions... " for regx in $REGIONS; do LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --query "Aliases[].[AliasName,TargetKeyId]" --output text |grep -v ^alias/aws/ |awk '{ print $2 }') if [[ $LIST_OF_CUSTOMER_KMS_KEYS ]];then diff --git a/checks/check_extra737 b/checks/check_extra737 index b3e751b8..056e7be6 100644 --- a/checks/check_extra737 +++ b/checks/check_extra737 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra737="7.37" -CHECK_TITLE_extra737="[extra737] Check KMS keys with key rotation disabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra737="[extra737] Check KMS keys with key rotation disabled" CHECK_SCORED_extra737="NOT_SCORED" CHECK_TYPE_extra737="EXTRA" CHECK_SEVERITY_extra737="Medium" @@ -25,7 +25,6 @@ CHECK_DOC_extra737='https://docs.aws.amazon.com/kms/latest/developerguide/rotate CHECK_CAF_EPIC_extra737='Data Protection' extra737(){ - textInfo "Looking for KMS keys in all regions... " for regx in $REGIONS; do LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --query "Aliases[].[AliasName,TargetKeyId]" --output text |grep -v ^alias/aws/ |awk '{ print $2 }') if [[ $LIST_OF_CUSTOMER_KMS_KEYS ]];then diff --git a/checks/check_extra738 b/checks/check_extra738 index da1f9840..2a637a9d 100644 --- a/checks/check_extra738 +++ b/checks/check_extra738 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra738="7.38" -CHECK_TITLE_extra738="[extra738] Check if CloudFront distributions are set to HTTPS (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra738="[extra738] Check if CloudFront distributions are set to HTTPS" CHECK_SCORED_extra738="NOT_SCORED" CHECK_TYPE_extra738="EXTRA" CHECK_SEVERITY_extra738="Medium" @@ -30,14 +30,14 @@ extra738(){ for dist in $LIST_OF_DISTRIBUTIONS; do CHECK_HTTPS_STATUS=$($AWSCLI cloudfront get-distribution --id $dist --query Distribution.DistributionConfig.DefaultCacheBehavior.ViewerProtocolPolicy $PROFILE_OPT --output text) if [[ $CHECK_HTTPS_STATUS == "allow-all" ]]; then - textFail "CloudFront distribution $dist viewers can use HTTP or HTTPS!" "$regx" "$dist" + textFail "$REGION: CloudFront distribution $dist viewers can use HTTP or HTTPS!" "$REGION" "$dist" elif [[ $CHECK_HTTPS_STATUS == "redirect-to-https" ]]; then - textPass "CloudFront distribution $dist has redirect to HTTPS" "$regx" "$dist" + textPass "$REGION: CloudFront distribution $dist has redirect to HTTPS" "$REGION" "$dist" else - textPass "CloudFront distribution $dist has HTTPS only" "$regx" "$dist" + textPass "$REGION: CloudFront distribution $dist has HTTPS only" "$REGION" "$dist" fi done else - textInfo "No CloudFront distributions found" "$regx" + textInfo "$REGION: No CloudFront distributions found" "$REGION" fi } diff --git a/checks/check_extra739 b/checks/check_extra739 index 0cf5eb98..0dea5d78 100644 --- a/checks/check_extra739 +++ b/checks/check_extra739 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra739="7.39" -CHECK_TITLE_extra739="[extra739] Check if RDS instances have backup enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra739="[extra739] Check if RDS instances have backup enabled" CHECK_SCORED_extra739="NOT_SCORED" CHECK_TYPE_extra739="EXTRA" CHECK_SEVERITY_extra739="Medium" diff --git a/checks/check_extra74 b/checks/check_extra74 index fde3b648..7d94a6a9 100644 --- a/checks/check_extra74 +++ b/checks/check_extra74 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra74="7.4" -CHECK_TITLE_extra74="[extra74] Ensure there are no Security Groups without ingress filtering being used (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra74="[extra74] Ensure there are no Security Groups without ingress filtering being used" CHECK_SCORED_extra74="NOT_SCORED" CHECK_TYPE_extra74="EXTRA" CHECK_SEVERITY_extra74="High" @@ -27,8 +27,7 @@ CHECK_DOC_extra74='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security CHECK_CAF_EPIC_extra74='Infrastructure Security' extra74(){ - # "Ensure there are no Security Groups without ingress filtering being used (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for Security Groups in all regions... " + # "Ensure there are no Security Groups without ingress filtering being used " 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 @@ -36,7 +35,7 @@ extra74(){ if [[ $SG_NO_INGRESS_FILTER -ne 0 ]];then textFail "$regx: $SG_ID has no ingress filtering and it is being used!" "$regx" "$SG_ID" else - textInfo "$regx: $SG_ID has no ingress filtering but it is not being used" "$regx" + textInfo "$regx: $SG_ID has no ingress filtering but it is not being used" "$regx" "$SG_ID" fi done done diff --git a/checks/check_extra740 b/checks/check_extra740 index 37f81434..7f771663 100644 --- a/checks/check_extra740 +++ b/checks/check_extra740 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra740="7.40" -CHECK_TITLE_extra740="[extra740] Check if EBS snapshots are encrypted (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra740="[extra740] Check if EBS snapshots are encrypted" CHECK_SCORED_extra740="NOT_SCORED" CHECK_TYPE_extra740="EXTRA" CHECK_SEVERITY_extra740="Medium" @@ -25,7 +25,6 @@ CHECK_DOC_extra740='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncry CHECK_CAF_EPIC_extra740='Data Protection' extra740(){ - textInfo "Examining EBS Volume Snapshots ..." # This does NOT use max-items, which would limit the number of items # considered. It considers all snapshots, but only reports at most # max-items passing and max-items failing. @@ -47,7 +46,7 @@ extra740(){ for snapshot in ${UNENCRYPTED_SNAPSHOTS}; do unencrypted=${unencrypted}+1 if [ "${unencrypted}" -le "${MAXITEMS}" ]; then - textFail "${regx}: ${snapshot} is not encrypted!" "${regx}" + textFail "${regx}: ${snapshot} is not encrypted!" "${regx}" "${snapshot}" fi done fi @@ -55,7 +54,7 @@ extra740(){ for snapshot in ${ENCRYPTED_SNAPSHOTS}; do encrypted=${encrypted}+1 if [ "${encrypted}" -le "${MAXITEMS}" ]; then - textPass "${regx}: ${snapshot} is encrypted." "${regx}" + textPass "${regx}: ${snapshot} is encrypted." "${regx}" "${snapshot}" fi done fi diff --git a/checks/check_extra741 b/checks/check_extra741 index 3fbd71e9..ebf12543 100644 --- a/checks/check_extra741 +++ b/checks/check_extra741 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra741="7.41" -CHECK_TITLE_extra741="[extra741] Find secrets in EC2 User Data (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra741="[extra741] Find secrets in EC2 User Data" CHECK_SCORED_extra741="NOT_SCORED" CHECK_TYPE_extra741="EXTRA" CHECK_SEVERITY_extra741="Critical" @@ -30,7 +30,6 @@ extra741(){ mkdir $SECRETS_TEMP_FOLDER fi - textInfo "Looking for secrets in EC2 User Data in instances across all regions... (max 100 instances per region use -m to increase it) " for regx in $REGIONS; do LIST_OF_EC2_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query Reservations[*].Instances[*].InstanceId --output text --max-items $MAXITEMS | grep -v None) if [[ $LIST_OF_EC2_INSTANCES ]];then @@ -47,7 +46,7 @@ extra741(){ fi FINDINGS=$(secretsDetector file "$EC2_USERDATA_FILE") if [[ $FINDINGS -eq 0 ]]; then - textPass "$regx: No secrets found in $instance User Data" "$regx" + textPass "$regx: No secrets found in $instance User Data" "$regx" "$instance" # delete file if nothing interesting is there rm -f "$EC2_USERDATA_FILE" else diff --git a/checks/check_extra742 b/checks/check_extra742 index 92cd10b3..6c78c7a9 100644 --- a/checks/check_extra742 +++ b/checks/check_extra742 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra742="7.42" -CHECK_TITLE_extra742="[extra742] Find secrets in CloudFormation outputs (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra742="[extra742] Find secrets in CloudFormation outputs" CHECK_SCORED_extra742="NOT_SCORED" CHECK_TYPE_extra742="EXTRA" CHECK_SEVERITY_extra742="Critical" @@ -30,7 +30,6 @@ extra742(){ mkdir $SECRETS_TEMP_FOLDER fi - textInfo "Looking for secrets in CloudFormation output across all regions... " for regx in $REGIONS; do CFN_STACKS=$($AWSCLI cloudformation describe-stacks $PROFILE_OPT --region $regx --output json) LIST_OF_CFN_STACKS=$(echo $CFN_STACKS | jq -r '.Stacks[].StackName') diff --git a/checks/check_extra743 b/checks/check_extra743 index fb98bec4..b5c365a4 100644 --- a/checks/check_extra743 +++ b/checks/check_extra743 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra743="7.43" -CHECK_TITLE_extra743="[extra743] Check if API Gateway has client certificate enabled to access your backend endpoint (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra743="[extra743] Check if API Gateway has client certificate enabled to access your backend endpoint" CHECK_SCORED_extra743="NOT_SCORED" CHECK_TYPE_extra743="EXTRA" CHECK_SEVERITY_extra743="Medium" diff --git a/checks/check_extra744 b/checks/check_extra744 index 6d0d219b..48cf6f11 100644 --- a/checks/check_extra744 +++ b/checks/check_extra744 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra744="7.44" -CHECK_TITLE_extra744="[extra744] Check if API Gateway has a WAF ACL attached (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra744="[extra744] Check if API Gateway has a WAF ACL attached" CHECK_SCORED_extra744="NOT_SCORED" CHECK_TYPE_extra744="EXTRA" CHECK_SEVERITY_extra744="Medium" diff --git a/checks/check_extra745 b/checks/check_extra745 index 743bf12a..1ee49e72 100644 --- a/checks/check_extra745 +++ b/checks/check_extra745 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra745="7.45" -CHECK_TITLE_extra745="[extra745] Check if API Gateway endpoint is public or private (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra745="[extra745] Check if API Gateway endpoint is public or private" CHECK_SCORED_extra745="NOT_SCORED" CHECK_TYPE_extra745="EXTRA" CHECK_SEVERITY_extra745="Medium" diff --git a/checks/check_extra746 b/checks/check_extra746 index 91d3052a..638d15ef 100644 --- a/checks/check_extra746 +++ b/checks/check_extra746 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra746="7.46" -CHECK_TITLE_extra746="[extra746] Check if API Gateway has configured authorizers (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra746="[extra746] Check if API Gateway has configured authorizers" CHECK_SCORED_extra746="NOT_SCORED" CHECK_TYPE_extra746="EXTRA" CHECK_SEVERITY_extra746="Medium" diff --git a/checks/check_extra747 b/checks/check_extra747 index ec6a86d8..2b2ede3b 100644 --- a/checks/check_extra747 +++ b/checks/check_extra747 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra747="7.47" -CHECK_TITLE_extra747="[extra747] Check if RDS instances is integrated with CloudWatch Logs (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra747="[extra747] Check if RDS instances is integrated with CloudWatch Logs" CHECK_SCORED_extra747="NOT_SCORED" CHECK_TYPE_extra747="EXTRA" CHECK_SEVERITY_extra747="Medium" diff --git a/checks/check_extra748 b/checks/check_extra748 index 925f5173..f46ef6c5 100644 --- a/checks/check_extra748 +++ b/checks/check_extra748 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra748="7.48" -CHECK_TITLE_extra748="[extra748] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to any port (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra748="[extra748] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to any port" CHECK_SCORED_extra748="NOT_SCORED" CHECK_TYPE_extra748="EXTRA" CHECK_SEVERITY_extra748="High" diff --git a/checks/check_extra749 b/checks/check_extra749 index 72bbb129..820d2f68 100644 --- a/checks/check_extra749 +++ b/checks/check_extra749 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra749="7.49" -CHECK_TITLE_extra749="[extra749] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Oracle ports 1521 or 2483 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra749="[extra749] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Oracle ports 1521 or 2483" CHECK_SCORED_extra749="NOT_SCORED" CHECK_TYPE_extra749="EXTRA" CHECK_SEVERITY_extra749="High" diff --git a/checks/check_extra75 b/checks/check_extra75 index f2ae8842..34a05fb8 100644 --- a/checks/check_extra75 +++ b/checks/check_extra75 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra75="7.5" -CHECK_TITLE_extra75="[extra75] Ensure there are no Security Groups not being used (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra75="[extra75] Ensure there are no Security Groups not being used" CHECK_SCORED_extra75="NOT_SCORED" CHECK_TYPE_extra75="EXTRA" CHECK_SEVERITY_extra75="Informational" @@ -27,9 +27,7 @@ CHECK_DOC_extra75='https://aws.amazon.com/premiumsupport/knowledge-center/ec2-fi CHECK_CAF_EPIC_extra75='Infrastructure Security' extra75(){ - # "Ensure there are no Security Groups not being used (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for Security Groups in all regions... " - + # "Ensure there are no Security Groups not being used " for regx in $REGIONS; do SECURITYGROUPS=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --max-items $MAXITEMS --output json | jq '.SecurityGroups|map({(.GroupId): (.GroupName)})|add') if [[ $SECURITYGROUPS == "null" ]]; @@ -46,7 +44,7 @@ extra75(){ then textFail "$regx: $SG_ID is not being used!" "$regx" "$SG_ID" else - textInfo "$regx: $SG_ID is not being used - default security group" "$regx" + textInfo "$regx: $SG_ID is not being used - default security group" "$regx" "$SG_ID" fi else textPass "$regx: $SG_ID is being used" "$regx" "$SG_ID" diff --git a/checks/check_extra750 b/checks/check_extra750 index d8352433..62dcf115 100644 --- a/checks/check_extra750 +++ b/checks/check_extra750 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra750="7.50" -CHECK_TITLE_extra750="[extra750] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to MySQL port 3306 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra750="[extra750] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to MySQL port 3306" CHECK_SCORED_extra750="NOT_SCORED" CHECK_TYPE_extra750="EXTRA" CHECK_SEVERITY_extra750="High" diff --git a/checks/check_extra751 b/checks/check_extra751 index c9772ccb..c98cd4fe 100644 --- a/checks/check_extra751 +++ b/checks/check_extra751 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra751="7.51" -CHECK_TITLE_extra751="[extra751] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Postgres port 5432 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra751="[extra751] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Postgres port 5432" CHECK_SCORED_extra751="NOT_SCORED" CHECK_TYPE_extra751="EXTRA" CHECK_SEVERITY_extra751="High" diff --git a/checks/check_extra752 b/checks/check_extra752 index 17217098..07aa549d 100644 --- a/checks/check_extra752 +++ b/checks/check_extra752 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra752="7.52" -CHECK_TITLE_extra752="[extra752] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Redis port 6379 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra752="[extra752] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Redis port 6379" CHECK_SCORED_extra752="NOT_SCORED" CHECK_TYPE_extra752="EXTRA" CHECK_SEVERITY_extra752="High" diff --git a/checks/check_extra753 b/checks/check_extra753 index 045af6bf..34042b6e 100644 --- a/checks/check_extra753 +++ b/checks/check_extra753 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra753="7.53" -CHECK_TITLE_extra753="[extra753] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to MongoDB ports 27017 and 27018 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra753="[extra753] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to MongoDB ports 27017 and 27018" CHECK_SCORED_extra753="NOT_SCORED" CHECK_TYPE_extra753="EXTRA" CHECK_SEVERITY_extra753="High" diff --git a/checks/check_extra754 b/checks/check_extra754 index 03400ba1..4277fe4f 100644 --- a/checks/check_extra754 +++ b/checks/check_extra754 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra754="7.54" -CHECK_TITLE_extra754="[extra754] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Cassandra ports 7199 or 9160 or 8888 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra754="[extra754] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Cassandra ports 7199 or 9160 or 8888" CHECK_SCORED_extra754="NOT_SCORED" CHECK_TYPE_extra754="EXTRA" CHECK_SEVERITY_extra754="High" diff --git a/checks/check_extra755 b/checks/check_extra755 index e0e55079..50430f1a 100644 --- a/checks/check_extra755 +++ b/checks/check_extra755 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra755="7.55" -CHECK_TITLE_extra755="[extra755] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Memcached port 11211 (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra755="[extra755] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Memcached port 11211" CHECK_SCORED_extra755="NOT_SCORED" CHECK_TYPE_extra755="EXTRA" CHECK_SEVERITY_extra755="High" diff --git a/checks/check_extra756 b/checks/check_extra756 index ba4bb323..a931904f 100644 --- a/checks/check_extra756 +++ b/checks/check_extra756 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra756="7.56" -CHECK_TITLE_extra756="[extra756] Check if Redshift cluster is Public Accessible (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra756="[extra756] Check if Redshift cluster is Public Accessible" CHECK_SCORED_extra756="NOT_SCORED" CHECK_TYPE_extra756="EXTRA" CHECK_SEVERITY_extra756="High" diff --git a/checks/check_extra757 b/checks/check_extra757 index 9277f030..364caab7 100644 --- a/checks/check_extra757 +++ b/checks/check_extra757 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra757="7.57" -CHECK_TITLE_extra757="[extra757] Check EC2 Instances older than 6 months (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra757="[extra757] Check EC2 Instances older than 6 months" CHECK_SCORED_extra757="NOT_SCORED" CHECK_TYPE_extra757="EXTRA" CHECK_SEVERITY_extra757="Medium" @@ -25,7 +25,6 @@ CHECK_CAF_EPIC_extra757='Infrastructure Security' extra757(){ OLDAGE="$(get_date_previous_than_months 6)" - textInfo "Looking for EC2 instances in all regions..." for regx in $REGIONS; do EC2_RUNNING="$($AWSCLI ec2 describe-instances --query "Reservations[*].Instances[*].[InstanceId]" $PROFILE_OPT --region $regx --output text)" if [[ $EC2_RUNNING ]]; then diff --git a/checks/check_extra758 b/checks/check_extra758 index 17b47776..0beabcf4 100644 --- a/checks/check_extra758 +++ b/checks/check_extra758 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra758="7.58" -CHECK_TITLE_extra758="[extra758] Check EC2 Instances older than 12 months (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra758="[extra758] Check EC2 Instances older than 12 months " CHECK_SCORED_extra758="NOT_SCORED" CHECK_TYPE_extra758="EXTRA" CHECK_SEVERITY_extra758="Medium" @@ -25,7 +25,6 @@ CHECK_CAF_EPIC_extra758='Infrastructure Security' extra758(){ OLDAGE="$(get_date_previous_than_months 12)" - textInfo "Looking for EC2 instances in all regions..." for regx in $REGIONS; do EC2_RUNNING="$($AWSCLI ec2 describe-instances --query "Reservations[*].Instances[*].[InstanceId]" $PROFILE_OPT --region $regx --output text)" if [[ $EC2_RUNNING ]]; then diff --git a/checks/check_extra759 b/checks/check_extra759 index aa557e46..15f73fcd 100644 --- a/checks/check_extra759 +++ b/checks/check_extra759 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra759="7.59" -CHECK_TITLE_extra759="[extra759] Find secrets in Lambda functions variables (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra759="[extra759] Find secrets in Lambda functions variables " CHECK_SCORED_extra759="NOT_SCORED" CHECK_TYPE_extra759="EXTRA" CHECK_SEVERITY_extra759="Critical" @@ -30,7 +30,6 @@ extra759(){ mkdir $SECRETS_TEMP_FOLDER fi - textInfo "Looking for secrets in Lambda variables across all regions... " for regx in $REGIONS; do LIST_OF_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text) if [[ $LIST_OF_FUNCTIONS ]]; then diff --git a/checks/check_extra76 b/checks/check_extra76 index c8348216..9124b8cb 100644 --- a/checks/check_extra76 +++ b/checks/check_extra76 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra76="7.6" -CHECK_TITLE_extra76="[extra76] Ensure there are no EC2 AMIs set as Public (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra76="[extra76] Ensure there are no EC2 AMIs set as Public" CHECK_SCORED_extra76="NOT_SCORED" CHECK_TYPE_extra76="EXTRA" CHECK_SEVERITY_extra76="Critical" @@ -25,8 +25,7 @@ CHECK_DOC_extra76='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/usingshar CHECK_CAF_EPIC_extra76='Infrastructure Security' extra76(){ - # "Ensure there are no EC2 AMIs set as Public (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for AMIs in all regions... " + # "Ensure there are no EC2 AMIs set as Public " 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 diff --git a/checks/check_extra760 b/checks/check_extra760 index f770e5b4..ca70b83f 100644 --- a/checks/check_extra760 +++ b/checks/check_extra760 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra760="7.60" -CHECK_TITLE_extra760="[extra760] Find secrets in Lambda functions code (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra760="[extra760] Find secrets in Lambda functions code " CHECK_SCORED_extra760="NOT_SCORED" CHECK_TYPE_extra760="EXTRA" CHECK_SEVERITY_extra760="Critical" @@ -30,8 +30,6 @@ extra760(){ mkdir $SECRETS_TEMP_FOLDER fi - textInfo "Looking for secrets in Lambda functions code across all regions... " - textInfo "This check may take a while depending on your functions size! " for regx in $REGIONS; do LIST_OF_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text) if [[ $LIST_OF_FUNCTIONS ]]; then diff --git a/checks/check_extra761 b/checks/check_extra761 index a8504632..34ecb953 100644 --- a/checks/check_extra761 +++ b/checks/check_extra761 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra761="7.61" -CHECK_TITLE_extra761="[extra761] Check if EBS Default Encryption is activated (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra761="[extra761] Check if EBS Default Encryption is activated " CHECK_SCORED_extra761="NOT_SCORED" CHECK_TYPE_extra761="EXTRA" CHECK_SEVERITY_extra761="Medium" @@ -24,15 +24,14 @@ CHECK_DOC_extra761='https://aws.amazon.com/premiumsupport/knowledge-center/ebs-a CHECK_CAF_EPIC_extra761='Data Protection' extra761(){ - textInfo "Looking for EBS Default Encryption activation in all regions... " for regx in $REGIONS; do EBS_DEFAULT_ENCRYPTION=$($AWSCLI ec2 get-ebs-encryption-by-default $PROFILE_OPT --region $regx --query 'EbsEncryptionByDefault' 2>&1) if [[ $(echo "$EBS_DEFAULT_ENCRYPTION" | grep "argument operation: Invalid choice") ]]; then - textFail "Newer aws cli needed for get-ebs-encryption-by-default" + textFail "$regx: Newer aws cli needed for get-ebs-encryption-by-default" "$regx" continue fi if [[ $(echo "$EBS_DEFAULT_ENCRYPTION" | grep UnauthorizedOperation) ]]; then - textFail "Prowler needs ec2:GetEbsEncryptionByDefault permission for this check" + textFail "$regx: Prowler needs ec2:GetEbsEncryptionByDefault permission for this check" "$regx" continue fi if [[ $EBS_DEFAULT_ENCRYPTION == "true" ]];then diff --git a/checks/check_extra762 b/checks/check_extra762 index 92389bc2..2345f058 100644 --- a/checks/check_extra762 +++ b/checks/check_extra762 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra762="7.62" -CHECK_TITLE_extra762="[extra762] Find obsolete Lambda runtimes (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra762="[extra762] Find obsolete Lambda runtimes " CHECK_SCORED_extra762="NOT_SCORED" CHECK_TYPE_extra762="EXTRA" CHECK_SEVERITY_extra762="Medium" diff --git a/checks/check_extra763 b/checks/check_extra763 index 7c8b74ce..d2d53e0d 100644 --- a/checks/check_extra763 +++ b/checks/check_extra763 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra763="7.63" -CHECK_TITLE_extra763="[extra763] Check if S3 buckets have object versioning enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra763="[extra763] Check if S3 buckets have object versioning enabled " CHECK_SCORED_extra763="NOT_SCORED" CHECK_TYPE_extra763="EXTRA" CHECK_SEVERITY_extra763="Medium" @@ -24,7 +24,7 @@ CHECK_DOC_extra763='https://docs.aws.amazon.com/AmazonS3/latest/dev-retired/Vers CHECK_CAF_EPIC_extra763='Data Protection' extra763(){ - # "Check if S3 buckets have object versioning enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if S3 buckets have object versioning enabled " LIST_OF_BUCKETS=$($AWSCLI s3api list-buckets $PROFILE_OPT --query Buckets[*].Name --output text|xargs -n1) if [[ $LIST_OF_BUCKETS ]]; then for bucket in $LIST_OF_BUCKETS;do diff --git a/checks/check_extra764 b/checks/check_extra764 index 7e1153c4..67a6158c 100644 --- a/checks/check_extra764 +++ b/checks/check_extra764 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra764="7.64" -CHECK_TITLE_extra764="[extra764] Check if S3 buckets have secure transport policy (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra764="[extra764] Check if S3 buckets have secure transport policy " CHECK_SCORED_extra764="NOT_SCORED" CHECK_TYPE_extra764="EXTRA" CHECK_SEVERITY_extra764="Medium" diff --git a/checks/check_extra765 b/checks/check_extra765 index e00d272c..38cdc508 100644 --- a/checks/check_extra765 +++ b/checks/check_extra765 @@ -21,7 +21,7 @@ # --image-scanning-configuration scanOnPush=true CHECK_ID_extra765="7.65" -CHECK_TITLE_extra765="[extra765] Check if ECR image scan on push is enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra765="[extra765] Check if ECR image scan on push is enabled " CHECK_SCORED_extra765="NOT_SCORED" CHECK_TYPE_extra765="EXTRA" CHECK_SEVERITY_extra765="Medium" diff --git a/checks/check_extra767 b/checks/check_extra767 index b97bbdae..7bff69fd 100644 --- a/checks/check_extra767 +++ b/checks/check_extra767 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra767="7.67" -CHECK_TITLE_extra767="[extra767] Check if CloudFront distributions have Field Level Encryption enabled (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra767="[extra767] Check if CloudFront distributions have Field Level Encryption enabled " CHECK_SCORED_extra767="NOT_SCORED" CHECK_TYPE_extra767="EXTRA" CHECK_SEVERITY_extra767="Low" diff --git a/checks/check_extra768 b/checks/check_extra768 index c1806dd3..dc222b5d 100644 --- a/checks/check_extra768 +++ b/checks/check_extra768 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra768="7.68" -CHECK_TITLE_extra768="[extra768] Find secrets in ECS task definitions variables (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra768="[extra768] Find secrets in ECS task definitions variables " CHECK_SCORED_extra768="NOT_SCORED" CHECK_TYPE_extra768="EXTRA" CHECK_SEVERITY_extra768="Critical" @@ -29,7 +29,6 @@ extra768(){ # this folder is deleted once this check is finished mkdir $SECRETS_TEMP_FOLDER fi - textInfo "Looking for secrets in ECS task definitions' environment variables across all regions... " for regx in $REGIONS; do # Get a list of all families first: FAMILIES=$($AWSCLI ecs list-task-definition-families $PROFILE_OPT --region $regx --status ACTIVE | jq -r .families[]) @@ -53,7 +52,7 @@ extra768(){ textFail "$regx: Potential secret found in ECS task definition $TASK_DEFINITION variables" "$regx" "$TASK_DEFINITION" fi else - textInfo "$regx: ECS task definition $TASK_DEFINITION has no variables" "$regx" + textInfo "$regx: ECS task definition $TASK_DEFINITION has no variables" "$regx" "$TASK_DEFINITION" rm -f $TASK_DEFINITION_ENV_VARIABLES_FILE fi done diff --git a/checks/check_extra769 b/checks/check_extra769 index f9f5308f..00e34e00 100644 --- a/checks/check_extra769 +++ b/checks/check_extra769 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra769="7.69" -CHECK_TITLE_extra769="[extra769] Check if IAM Access Analyzer is enabled and its findings (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra769="[extra769] Check if IAM Access Analyzer is enabled and its findings " CHECK_SCORED_extra769="NOT_SCORED" CHECK_TYPE_extra769="EXTRA" CHECK_SEVERITY_extra769="High" diff --git a/checks/check_extra77 b/checks/check_extra77 index b9624616..d3cc4a50 100644 --- a/checks/check_extra77 +++ b/checks/check_extra77 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra77="7.7" -CHECK_TITLE_extra77="[extra77] Ensure there are no ECR repositories set as Public (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra77="[extra77] Ensure there are no ECR repositories set as Public" CHECK_SCORED_extra77="NOT_SCORED" CHECK_TYPE_extra77="EXTRA" CHECK_SEVERITY_extra77="Critical" @@ -26,43 +26,43 @@ CHECK_DOC_extra77='https://docs.aws.amazon.com/AmazonECR/latest/public/security_ CHECK_CAF_EPIC_extra77='Data Protection' extra77(){ - # "Ensure there are no ECR repositories set as Public (Not Scored) (Not part of CIS benchmark)" - for region in $REGIONS; do - LIST_ECR_REPOS=$($AWSCLI ecr describe-repositories $PROFILE_OPT --region $region --query "repositories[*].[repositoryName]" --output text 2>&1) + # "Ensure there are no ECR repositories set as Public " + for regx in $REGIONS; do + LIST_ECR_REPOS=$($AWSCLI ecr describe-repositories $PROFILE_OPT --region $regx --query "repositories[*].[repositoryName]" --output text 2>&1) if [[ $(echo "$LIST_ECR_REPOS" | grep AccessDenied) ]]; then - textFail "Access Denied Trying to describe ECR repositories" + textFail "$regx: Access Denied Trying to describe ECR repositories" "$regx" "$repo" continue fi if [[ $(echo "$LIST_ECR_REPOS" | grep SubscriptionRequiredException) ]]; then - textFail "Subscription Required Exception trying to describe ECR repositories" + textFail "$regx: Subscription Required Exception trying to describe ECR repositories" "$regx" "$repo" continue fi if [[ ! -z "$LIST_ECR_REPOS" ]]; then for repo in $LIST_ECR_REPOS; do TEMP_POLICY_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-ecr-repo.policy.XXXXXXXXXX) - $AWSCLI ecr get-repository-policy $PROFILE_OPT --region $region --repository-name $repo --query "policyText" --output text > $TEMP_POLICY_FILE 2>&1 + $AWSCLI ecr get-repository-policy $PROFILE_OPT --region $regx --repository-name $repo --query "policyText" --output text > $TEMP_POLICY_FILE 2>&1 if [[ $(grep AccessDenied $TEMP_POLICY_FILE) ]]; then - textFail "$region: $repo Access Denied for get-repository-policy" + textFail "$regx: $repo Access Denied for get-repository-policy" "$regx" "$repo" rm -f $TEMP_POLICY_FILE continue fi # https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html - "By default, only the repository owner has access to a repository." if [[ $(grep RepositoryPolicyNotFoundException $TEMP_POLICY_FILE) ]]; then - textPass "$region: $repo is not open" "$region" "$repo" + textPass "$regx: $repo is not open" "$regx" "$repo" rm -f $TEMP_POLICY_FILE continue fi # check if the policy has Principal as * CHECK_ECR_REPO_ALLUSERS_POLICY=$(cat $TEMP_POLICY_FILE | jq '.Statement[]|select(.Effect=="Allow" and (((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")))') if [[ $CHECK_ECR_REPO_ALLUSERS_POLICY ]]; then - textFail "$region: $repo policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$region" + textFail "$regx: $repo policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx" else - textPass "$region: $repo is not open" "$region" "$repo" + textPass "$regx: $repo is not open" "$regx" "$repo" fi rm -f $TEMP_POLICY_FILE done else - textInfo "$region: No ECR repositories found" "$region" "$repo" + textInfo "$regx: No ECR repositories found" "$regx" "$repo" fi done } diff --git a/checks/check_extra770 b/checks/check_extra770 index e8d023a4..c1e9694b 100644 --- a/checks/check_extra770 +++ b/checks/check_extra770 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra770="7.70" -CHECK_TITLE_extra770="[extra770] Check for internet facing EC2 instances with Instance Profiles attached (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra770="[extra770] Check for internet facing EC2 instances with Instance Profiles attached " CHECK_SCORED_extra770="NOT_SCORED" CHECK_TYPE_extra770="EXTRA" CHECK_SEVERITY_extra770="Medium" @@ -24,8 +24,7 @@ CHECK_DOC_extra770='https://aws.amazon.com/blogs/aws/aws-web-application-firewal CHECK_CAF_EPIC_extra770='Infrastructure Security' extra770(){ - # "Check for internet facing EC2 Instances (Not Scored) (Not part of CIS benchmark)" - textInfo "Looking for instances in all regions... " + # "Check for internet facing EC2 Instances " for regx in $REGIONS; do LIST_OF_PUBLIC_INSTANCES_WITH_INSTANCE_PROFILES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[*].Instances[?((IamInstanceProfile!=`null` && PublicIpAddress!=`null`))].[InstanceId,PublicIpAddress,IamInstanceProfile.Arn]' --output text) if [[ $LIST_OF_PUBLIC_INSTANCES_WITH_INSTANCE_PROFILES ]];then diff --git a/checks/check_extra771 b/checks/check_extra771 index 9bcaea71..a2236c00 100644 --- a/checks/check_extra771 +++ b/checks/check_extra771 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra771="7.71" -CHECK_TITLE_extra771="[extra771] Check if S3 buckets have policies which allow WRITE access (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra771="[extra771] Check if S3 buckets have policies which allow WRITE access " CHECK_SCORED_extra771="NOT_SCORED" CHECK_TYPE_extra771="EXTRA" CHECK_SEVERITY_extra771="Critical" diff --git a/checks/check_extra772 b/checks/check_extra772 index 9f3dbcd9..93b36041 100644 --- a/checks/check_extra772 +++ b/checks/check_extra772 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra772="7.72" -CHECK_TITLE_extra772="[extra772] Check if elastic IPs are unused (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra772="[extra772] Check if elastic IPs are unused " CHECK_SCORED_extra772="NOT_SCORED" CHECK_TYPE_extra772="EXTRA" CHECK_SEVERITY_extra772="Low" diff --git a/checks/check_extra773 b/checks/check_extra773 index b8eee770..7c168fcd 100644 --- a/checks/check_extra773 +++ b/checks/check_extra773 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra773="7.73" -CHECK_TITLE_extra773="[extra773] Check if CloudFront distributions are using WAF (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra773="[extra773] Check if CloudFront distributions are using WAF " CHECK_SCORED_extra773="NOT_SCORED" CHECK_TYPE_extra773="EXTRA" CHECK_SEVERITY_extra773="Medium" @@ -25,7 +25,7 @@ CHECK_DOC_extra773='https://docs.aws.amazon.com/waf/latest/developerguide/cloudf CHECK_CAF_EPIC_extra773='Infrastructure Security' extra773(){ - # "Check if CloudFront distributions have logging enabled (Not Scored) (Not part of CIS benchmark)" + # "Check if CloudFront distributions have logging enabled " LIST_OF_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions $PROFILE_OPT --query 'DistributionList.Items[].Id' --output text | grep -v "^None") if [[ $LIST_OF_DISTRIBUTIONS ]]; then for dist in $LIST_OF_DISTRIBUTIONS; do diff --git a/checks/check_extra775 b/checks/check_extra775 index dbb50c8d..96d0d3b4 100644 --- a/checks/check_extra775 +++ b/checks/check_extra775 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra775="7.75" -CHECK_TITLE_extra775="[extra775] Find secrets in EC2 Auto Scaling Launch Configuration (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra775="[extra775] Find secrets in EC2 Auto Scaling Launch Configuration " CHECK_SCORED_extra775="NOT_SCORED" CHECK_TYPE_extra775="EXTRA" CHECK_SEVERITY_extra775="Critical" @@ -29,7 +29,6 @@ extra775(){ mkdir $SECRETS_TEMP_FOLDER fi - textInfo "Looking for secrets in EC2 Auto Scaling Launch Configuration across all regions... (max 100 autoscaling_configurations per region use -m to increase it) " for regx in $REGIONS; do LIST_OF_EC2_AUTOSCALING=$($AWSCLI autoscaling describe-launch-configurations $PROFILE_OPT --region $regx --query LaunchConfigurations[*].LaunchConfigurationName --output text --max-items $MAXITEMS | grep -v None) if [[ $LIST_OF_EC2_AUTOSCALING ]];then diff --git a/checks/check_extra776 b/checks/check_extra776 index a572afe4..f234bb0b 100644 --- a/checks/check_extra776 +++ b/checks/check_extra776 @@ -26,7 +26,7 @@ # --image-id imageTag= CHECK_ID_extra776="7.76" -CHECK_TITLE_extra776="[extra776] Check if ECR image scan found vulnerabilities in the newest image version (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra776="[extra776] Check if ECR image scan found vulnerabilities in the newest image version " CHECK_SCORED_extra776="NOT_SCORED" CHECK_TYPE_extra776="EXTRA" CHECK_SEVERITY_extra776="Medium" diff --git a/checks/check_extra777 b/checks/check_extra777 index fe784968..f79d907e 100644 --- a/checks/check_extra777 +++ b/checks/check_extra777 @@ -15,7 +15,7 @@ # Reference: https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html CHECK_ID_extra777="7.77" -CHECK_TITLE_extra777="[extra777] Find VPC security groups with many ingress or egress rules (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra777="[extra777] Find VPC security groups with many ingress or egress rules " CHECK_SCORED_extra777="NOT_SCORED" CHECK_TYPE_extra777="EXTRA" CHECK_SEVERITY_extra777="Medium" @@ -29,7 +29,6 @@ CHECK_CAF_EPIC_extra777='Infrastructure Security' extra777(){ THRESHOLD=50 - textInfo "Looking for VPC security groups with more than ${THRESHOLD} rules across all regions... " for regx in ${REGIONS}; do SECURITY_GROUP_IDS=$(${AWSCLI} ec2 describe-security-groups \ diff --git a/checks/check_extra778 b/checks/check_extra778 index 14383912..63cb12cd 100644 --- a/checks/check_extra778 +++ b/checks/check_extra778 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_extra778="7.78" -CHECK_TITLE_extra778="[extra778] Find VPC security groups with wide-open public IPv4 CIDR ranges (non-RFC1918) (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra778="[extra778] Find VPC security groups with wide-open public IPv4 CIDR ranges (non-RFC1918) " CHECK_SCORED_extra778="NOT_SCORED" CHECK_TYPE_extra778="EXTRA" CHECK_SEVERITY_extra778="Medium" @@ -27,7 +27,6 @@ CHECK_CAF_EPIC_extra778='Infrastructure Security' extra778(){ CIDR_THRESHOLD=24 RFC1918_REGEX="(^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)" - textInfo "Looking for VPC security groups with wide-open (&1) if [[ $(echo "$DESCRIBE_TRAILS_CACHE" | grep AccessDenied) ]]; then - textFail "Access Denied trying to describe trails in $REGION" + textFail "$REGION: Access Denied trying to describe trails in $REGION" "$REGION" "$group" return fi @@ -63,7 +63,7 @@ check3x(){ for group in $CHECK_OK; do metric=${group#*:} group=${group%:*} - textPass "CloudWatch group $group found with metric filter $metric and alarms set" + textPass "$REGION: CloudWatch group $group found with metric filter $metric and alarms set" "$REGION" "$group" done fi if [[ $CHECK_WARN ]]; then @@ -72,15 +72,15 @@ check3x(){ *:*) metric=${group#*:} group=${group%:*} if [[ $pass_count == 0 ]]; then - textFail "CloudWatch group $group found with metric filter $metric but no alarms associated" + textFail "$REGION: CloudWatch group $group found with metric filter $metric but no alarms associated" "$REGION" "$group" else - textInfo "CloudWatch group $group found with metric filter $metric but no alarms associated" + textInfo "$REGION: CloudWatch group $group found with metric filter $metric but no alarms associated" "$REGION" "$group" fi ;; *) if [[ $pass_count == 0 ]]; then - textFail "CloudWatch group $group found but no metric filters or alarms associated" + textFail "$REGION: CloudWatch group $group found but no metric filters or alarms associated" "$REGION" "$group" else - textInfo "CloudWatch group $group found but no metric filters or alarms associated" + textInfo "$REGION: CloudWatch group $group found but no metric filters or alarms associated" "$REGION" "$group" fi ;; esac @@ -88,10 +88,10 @@ check3x(){ fi if [[ $CHECK_CROSS_ACCOUNT_WARN ]]; then for group in $CHECK_CROSS_ACCOUNT_WARN; do - textInfo "CloudWatch group $group is not in this account" + textInfo "$REGION: CloudWatch group $group is not in this account" "$REGION" "$group" done fi else - textFail "No CloudWatch group found for CloudTrail events" + textFail "$REGION: No CloudWatch group found for CloudTrail events" "$REGION" "$group" fi } diff --git a/include/check_creds_last_used b/include/check_creds_last_used index 4f8633b3..09c64632 100644 --- a/include/check_creds_last_used +++ b/include/check_creds_last_used @@ -69,23 +69,23 @@ check_passwords_used_in_last_days() { # "When password_enabled is set to TRUE and password_last_used is set to no_information, ensure password_last_changed is less than X days ago" if [[ "$days_since_password_last_changed" -ge "$max_days" ]]; then - textFail "User $user has never logged into the console since creation and their password not changed in the past ${max_days} days" + textFail "$REGION: User $user has never logged into the console since creation and their password not changed in the past ${max_days} days" "$REGION" "$user" else - textInfo "User $user has not logged into the console since creation" + textInfo "$REGION: User $user has not logged into the console since creation" "$REGION" "$user" fi else days_password_not_in_use=$(how_older_from_today "${last_login_date%T*}") # "For each user having password_enabled set to TRUE, ensure password_last_used_date is less than X days ago." if [[ "$days_password_not_in_use" -ge "$max_days" ]]; then - textFail "User $user has not logged into the console in the past ${max_days} days" + textFail "$REGION: User $user has not logged into the console in the past ${max_days} days" "$REGION" "$user" else - textPass "User $user has logged into the console in the past ${max_days} days" + textPass "$REGION: User $user has logged into the console in the past ${max_days} days" "$REGION" "$user" fi fi done else - textPass "No users found with password enabled" + textPass "$REGION: No users found with password enabled" "$REGION" "$user" fi } @@ -122,22 +122,22 @@ check_access_key_used_in_last_days() { # "When a user having an access_key_x_active (where x is 1 or 2) to TRUE and corresponding access_key_x_last_used_date is set to N/A, # ensure access_key_x_last_rotated is less than X days ago" if [[ "$days_since_access_key_rotated" -ge "$max_days" ]]; then - textFail "User $user has never used access key $access_key_name since creation and not rotated it in the past ${max_days} days" + textFail "$REGION: User $user has never used access key $access_key_name since creation and not rotated it in the past ${max_days} days" "$REGION" "$user" else - textInfo "User $user has not used access key $access_key_name since creation" + textInfo "$REGION: User $user has not used access key $access_key_name since creation" "$REGION" "$user" fi else days_since_access_key_used=$(how_older_from_today "${access_key_last_used_date%T*}") # "For each user having an access_key_1_active or access_key_2_active to TRUE, ensure the corresponding access_key_n_last_used_date is less than X days ago" if [[ "$days_since_access_key_used" -ge "$max_days" ]]; then - textFail "User $user has not used access key $access_key_name in the past ${max_days} days" + textFail "$REGION: User $user has not used access key $access_key_name in the past ${max_days} days" "$REGION" "$user" else - textPass "User $user has used access key $access_key_name in the past ${max_days} days" + textPass "$REGION: User $user has used access key $access_key_name in the past ${max_days} days" "$REGION" "$user" fi fi done else - textPass "No users found with access key $access_key_name enabled" + textPass "$REGION: No users found with access key $access_key_name enabled" "$REGION" "$user" fi } diff --git a/include/outputs b/include/outputs index 525301ce..712745c3 100644 --- a/include/outputs +++ b/include/outputs @@ -15,7 +15,7 @@ EXTENSION_CSV="csv" EXTENSION_JSON="json" -EXTENSION_ASFF="asff-json" +EXTENSION_ASFF="asff.json" EXTENSION_TEXT="txt" EXTENSION_HTML="html" OUTPUT_DATE=$(date -u +"%Y%m%d%H%M%S") @@ -72,6 +72,11 @@ if [[ $MODE ]];then fi fi +# textInfo "HTML report will be saved: ${OUTPUT_FILE_NAME}.$EXTENSION_HTML" +# textInfo "JSON ASFF report will be saved: ${OUTPUT_FILE_NAME}.$EXTENSION_ASFF" +# textInfo "CSV report will be saved: ${OUTPUT_FILE_NAME}.$EXTENSION_CSV" +# textInfo "JSON report will be saved: ${OUTPUT_FILE_NAME}.$EXTENSION_JSON" + if [[ $PROFILE == "" ]];then PROFILE="ENV" fi @@ -92,23 +97,23 @@ textPass(){ REPREGION=$REGION fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then - generateJsonOutput "$1" "Pass" "$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_JSON + generateJsonOutput "$1" "Pass" "$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_JSON fi if [[ "${MODES[@]}" =~ "json-asff" ]]; then JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "PASSED" "$CHECK_RESOURCE_ID") - echo "${JSON_ASFF_OUTPUT}" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_ASFF + echo "${JSON_ASFF_OUTPUT}" >> $OUTPUT_FILE_NAME.$EXTENSION_ASFF if [[ "${SEND_TO_SECURITY_HUB}" -eq 1 ]]; then - sendToSecurityHub "${JSON_ASFF_OUTPUT}" "${REPREGION}" + sendToSecurityHub "${JSON_ASFF_OUTPUT}" "${REPREGION}" fi fi if is_junit_output_enabled; then output_junit_success "$1" fi if [[ "${MODES[@]}" =~ "mono" ]]; then - echo " $OK PASS!$NORMAL $1" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT + echo " $OK PASS!$NORMAL $1" >> ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT fi if [[ "${MODES[@]}" =~ "text" || "${MODES[@]}" =~ "mono" ]]; then echo " $OK PASS!$NORMAL $1" @@ -133,16 +138,16 @@ textInfo(){ REPREGION=$REGION fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then - generateJsonOutput "$1" "Info" "$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} + generateJsonOutput "$1" "Info" "$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} fi if is_junit_output_enabled; then output_junit_info "$1" fi if [[ "${MODES[@]}" =~ "mono" ]]; then - echo " $NOTICE INFO! $1 $NORMAL" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT + echo " $NOTICE INFO! $1 $NORMAL" >> ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT fi if [[ "${MODES[@]}" =~ "text" ]]; then echo " $NOTICE INFO! $1 $NORMAL" @@ -189,14 +194,14 @@ textFail(){ fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then - generateJsonOutput "$1" "${level}" "$CHECK_RESOURCE_ID"| tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} + generateJsonOutput "$1" "${level}" "$CHECK_RESOURCE_ID">> ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} fi if [[ "${MODES[@]}" =~ "json-asff" ]]; then JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "$1" "${level}" "$CHECK_RESOURCE_ID") - echo "${JSON_ASFF_OUTPUT}" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_ASFF} + echo "${JSON_ASFF_OUTPUT}" >> ${OUTPUT_FILE_NAME}.${EXTENSION_ASFF} if [[ "${SEND_TO_SECURITY_HUB}" -eq 1 ]]; then sendToSecurityHub "${JSON_ASFF_OUTPUT}" "${REPREGION}" fi @@ -209,7 +214,7 @@ textFail(){ fi fi if [[ "${MODES[@]}" =~ "mono" ]]; then - echo " $colorcode ${level}! $1 $NORMAL" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT + echo " $colorcode ${level}! $1 $NORMAL" >> ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT fi if [[ "${MODES[@]}" =~ "text" ]]; then echo " $colorcode ${level}! $1 $NORMAL" @@ -257,7 +262,7 @@ textTitle(){ # fi if [[ "${MODES[@]}" =~ "csv" ]]; then - >&2 echo "$TITLE_ID $TITLE_TEXT" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_CSV} + >&2 echo "$TITLE_ID $TITLE_TEXT" >> ${OUTPUT_FILE_NAME}.${EXTENSION_CSV} elif [[ "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then : else @@ -279,7 +284,7 @@ generateJsonOutput(){ --arg TITLE_TEXT "$TITLE_TEXT" \ --arg MESSAGE "$(echo -e "${message}" | sed -e 's/^[[:space:]]*//')" \ --arg STATUS "$status" \ - --arg SEVERITY "$CHECK_SEVERITY" \ + --arg SEVERITY "$(echo $CHECK_SEVERITY | sed 's/[][]//g')" \ --arg SCORED "$ITEM_SCORED" \ --arg ITEM_LEVEL "$ITEM_LEVEL" \ --arg TITLE_ID "$TITLE_ID" \ @@ -321,10 +326,9 @@ generateJsonAsffOutput(){ local status=$2 #Checks to determine if the rule passes in a resource name that prowler uses to track the AWS Resource for whitelisting purposes - if [ -z $3 ] - then + if [ -z $3 ]; then local resource_id="NONE_PROVIDED" - else + else local resource_id=$3 fi @@ -374,7 +378,7 @@ generateJsonAsffOutput(){ "Resources": [ { "Type": $RESOURCE_TYPE, - "Id": "AWS::::Account:\($ACCOUNT_NUM)", + "Id": $CHECK_RESOURCE_ID, "Partition": $AWS_PARTITION, "Region": $REPREGION } @@ -403,6 +407,8 @@ generateHtmlOutput(){ if [[ $status == "WARN" ]];then local ROW_CLASS='table-warning' fi + + local CHECK_SEVERITY="$(echo $CHECK_SEVERITY | sed 's/[][]//g')" echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ' '$status'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML diff --git a/prowler b/prowler index b3cc2e09..a67bf35d 100755 --- a/prowler +++ b/prowler @@ -32,7 +32,7 @@ OPTRED="" OPTNORMAL="" # Set the defaults variables -PROWLER_VERSION=2.5.0-15042021 +PROWLER_VERSION=2.5.0-05July2021 PROWLER_DIR=$(dirname "$0") REGION="" From 5670e4a9723dba83bae5b92fc86f4933b08c8cbd Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Wed, 7 Jul 2021 16:00:09 +0200 Subject: [PATCH 56/82] Removed CSV header stdout and add bucket-owner-full-control --- include/csv_header | 2 +- include/outputs | 2 +- include/outputs_bucket | 12 ++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/csv_header b/include/csv_header index 3ab095c3..30d731db 100644 --- a/include/csv_header +++ b/include/csv_header @@ -15,6 +15,6 @@ printCsvHeader() { # >&2 echo "" # >&2 echo "Generating \"${SEP}\" delimited report on stdout for profile $PROFILE, account $ACCOUNT_NUM" - echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}CHECK_RESULT${SEP}ITEM_SCORED${SEP}ITEM_LEVEL${SEP}TITLE_TEXT${SEP}CHECK_RESULT_EXTENDED${SEP}CHECK_ASFF_COMPLIANCE_TYPE${SEP}CHECK_SEVERITY${SEP}CHECK_SERVICENAME${SEP}CHECK_ASFF_RESOURCE_TYPE${SEP}CHECK_ASFF_TYPE${SEP}CHECK_RISK${SEP}CHECK_REMEDIATION${SEP}CHECK_DOC${SEP}CHECK_CAF_EPIC${SEP}CHECK_RESOURCE_ID" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}CHECK_RESULT${SEP}ITEM_SCORED${SEP}ITEM_LEVEL${SEP}TITLE_TEXT${SEP}CHECK_RESULT_EXTENDED${SEP}CHECK_ASFF_COMPLIANCE_TYPE${SEP}CHECK_SEVERITY${SEP}CHECK_SERVICENAME${SEP}CHECK_ASFF_RESOURCE_TYPE${SEP}CHECK_ASFF_TYPE${SEP}CHECK_RISK${SEP}CHECK_REMEDIATION${SEP}CHECK_DOC${SEP}CHECK_CAF_EPIC${SEP}CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV # echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}RESULT${SEP}SCORED${SEP}LEVEL${SEP}TITLE_TEXT${SEP}NOTES${SEP}COMPLIANCE${SEP}SEVERITY${SEP}SERVICENAME" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV } diff --git a/include/outputs b/include/outputs index 712745c3..d1dccad2 100644 --- a/include/outputs +++ b/include/outputs @@ -234,7 +234,7 @@ textTitle(){ TITLE_TEXT=$2 CHECK_SERVICENAME="$MAGENTA$3$NORMAL" - CHECK_SEVERITY="$BROWN[$4]$NORMAL" + local CHECK_SEVERITY="$BROWN[$4]$NORMAL" # case "$3" in # 0|No|NOT_SCORED) diff --git a/include/outputs_bucket b/include/outputs_bucket index 41cbefe1..f89a7fd4 100644 --- a/include/outputs_bucket +++ b/include/outputs_bucket @@ -38,16 +38,20 @@ copyToS3(){ # and processing by Quicksight or others. if [[ $OUTPUT_BUCKET ]]; then if [[ "${MODES[@]}" =~ "csv" ]]; then - $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_CSV s3://$OUTPUT_BUCKET/csv/ + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_CSV \ + s3://$OUTPUT_BUCKET/csv/ --acl bucket-owner-full-control fi if [[ "${MODES[@]}" =~ "html" ]]; then - $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_HTML s3://$OUTPUT_BUCKET/html/ + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_HTML \ + s3://$OUTPUT_BUCKET/html/ --acl bucket-owner-full-control fi if [[ "${MODES[@]}" =~ "json" ]]; then - $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_JSON s3://$OUTPUT_BUCKET/json/ + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_JSON \ + s3://$OUTPUT_BUCKET/json/ --acl bucket-owner-full-control fi if [[ "${MODES[@]}" =~ "json-asff" ]]; then - $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_ASFF s3://$OUTPUT_BUCKET/json-asff/ + $AWSCLI s3 cp $OUTPUT_DIR/prowler-output-${ACCOUNT_NUM}-${OUTPUT_DATE}.$EXTENSION_ASFF \ + s3://$OUTPUT_BUCKET/json-asff/ --acl bucket-owner-full-control fi fi } \ No newline at end of file From 85cb2085b91fe3b83e849fcc51695499eb03fc4b Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Wed, 7 Jul 2021 16:15:53 +0200 Subject: [PATCH 57/82] Output consolidation --- checks/check_extra7114 | 2 +- checks/check_extra7118 | 4 ++-- checks/check_extra7119 | 2 +- checks/check_extra7122 | 2 +- checks/check_extra7123 | 2 +- checks/check_extra7125 | 4 ++-- checks/check_extra7126 | 4 ++-- checks/check_extra7128 | 4 ++-- checks/check_extra7129 | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/checks/check_extra7114 b/checks/check_extra7114 index a6f08e20..93c7906a 100644 --- a/checks/check_extra7114 +++ b/checks/check_extra7114 @@ -36,7 +36,7 @@ extra7114(){ if [[ "$ENDPOINT_SC_ENCRYPTION" == "DISABLED" ]]; then textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have S3 encryption enabled!" "$regx" "$ENDPOINT_NAME" else - textPass "$regx: Glue development endpoint $ENDPOINT_NAME has S3 encryption enabled" "$regx" + textPass "$regx: Glue development endpoint $ENDPOINT_NAME has S3 encryption enabled" "$regx" "$ENDPOINT_NAME" fi else textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have security configuration" "$regx" "$ENDPOINT_NAME" diff --git a/checks/check_extra7118 b/checks/check_extra7118 index da129972..12cc7b08 100644 --- a/checks/check_extra7118 +++ b/checks/check_extra7118 @@ -40,10 +40,10 @@ extra7118(){ textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" "$JOB_NAME" fi else - textPass "$regx: Glue job $JOB_NAME does have $S3_ENCRYPTION for S3 encryption enabled" "$regx" + textPass "$regx: Glue job $JOB_NAME does have $S3_ENCRYPTION for S3 encryption enabled" "$regx" "$JOB_NAME" fi elif [[ ! -z "$JOB_ENCRYPTION" ]]; then - textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" + textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" "$JOB_NAME" else textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" "$JOB_NAME" fi diff --git a/checks/check_extra7119 b/checks/check_extra7119 index 954908a1..4f6e904b 100644 --- a/checks/check_extra7119 +++ b/checks/check_extra7119 @@ -36,7 +36,7 @@ extra7119(){ if [[ $ENDPOINT_SC_ENCRYPTION == "DISABLED" ]]; then textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have CloudWatch logs encryption enabled!" "$regx" "$ENDPOINT_NAME" else - textPass "$regx: Glue development endpoint $ENDPOINT_NAME has CloudWatch logs encryption enabled" "$regx" + textPass "$regx: Glue development endpoint $ENDPOINT_NAME has CloudWatch logs encryption enabled" "$regx" "$ENDPOINT_NAME" fi else textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have security configuration" "$regx" "$ENDPOINT_NAME" diff --git a/checks/check_extra7122 b/checks/check_extra7122 index 738efc2d..1b4f8d27 100644 --- a/checks/check_extra7122 +++ b/checks/check_extra7122 @@ -35,7 +35,7 @@ extra7122(){ if [[ "$JOB_BOOKMARK_ENCRYPTION" == "DISABLED" ]]; then textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" "$JOB_NAME" else - textPass "$regx: Glue job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION for Job bookmark encryption enabled" "$regx" + textPass "$regx: Glue job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION for Job bookmark encryption enabled" "$regx" "$JOB_NAME" fi else textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" "$JOB_NAME" diff --git a/checks/check_extra7123 b/checks/check_extra7123 index 02a83000..c462f749 100644 --- a/checks/check_extra7123 +++ b/checks/check_extra7123 @@ -30,7 +30,7 @@ extra7123(){ if [[ $LIST_OF_USERS_WITH_2ACCESS_KEYS ]]; then # textFail "Users with access key 1 older than 90 days:" for user in $LIST_OF_USERS_WITH_2ACCESS_KEYS; do - textFail "User $user has 2 active access keys" "us-east-1" "$user" + textFail "User $user has 2 active access keys" "$REGION" "$user" done else textPass "No users with 2 active access keys" diff --git a/checks/check_extra7125 b/checks/check_extra7125 index 7e7cd722..545d6d8b 100644 --- a/checks/check_extra7125 +++ b/checks/check_extra7125 @@ -34,9 +34,9 @@ extra7125(){ if [[ $MFA_TYPE == "mfa" || $MFA_TYPE == "sms-mfa" ]]; then textInfo "User $user has virtual MFA enabled" elif [[ $MFA_TYPE == "" ]]; then - textFail "User $user has not hardware MFA enabled" "us-east-1" "$user" + textFail "User $user has not hardware MFA enabled" "$REGION" "$user" else - textPass "User $user has hardware MFA enabled" "us-east-1" "$user" + textPass "User $user has hardware MFA enabled" "$REGION" "$user" fi done else diff --git a/checks/check_extra7126 b/checks/check_extra7126 index 7b91e0e2..6017afa4 100644 --- a/checks/check_extra7126 +++ b/checks/check_extra7126 @@ -33,9 +33,9 @@ extra7126(){ if [[ $CHECK_STATUS == "PendingDeletion" ]]; then textInfo "$regx: KMS key $key is pending deletion" "$regx" elif [[ $CHECK_STATUS == "Disabled" ]]; then - textInfo "$regx: KMS key $key is disabled" "$regx" + textInfo "$regx: KMS key $key is disabled" "$regx" "$key" else - textPass "$regx: KMS key $key is not disabled or pending deletion" "$regx" + textPass "$regx: KMS key $key is not disabled or pending deletion" "$regx" "$key" fi done else diff --git a/checks/check_extra7128 b/checks/check_extra7128 index 27be1f66..20182e8c 100644 --- a/checks/check_extra7128 +++ b/checks/check_extra7128 @@ -31,9 +31,9 @@ extra7128(){ for table in $DDB_TABLES_LIST; do DDB_TABLE_WITH_KMS=$($AWSCLI dynamodb describe-table --table-name $table $PROFILE_OPT --region $regx --query Table.SSEDescription.SSEType --output text) if [[ $DDB_TABLE_WITH_KMS == "KMS" ]]; then - textPass "$regx: DynamoDB table $table does have KMS encryption enabled" "$regx" + textPass "$regx: DynamoDB table $table does have KMS encryption enabled" "$regx" "$table" else - textInfo "$regx: DynamoDB table $table does have DEFAULT encryption enabled" "$regx" + textInfo "$regx: DynamoDB table $table does have DEFAULT encryption enabled" "$regx" "$table" fi done else diff --git a/checks/check_extra7129 b/checks/check_extra7129 index 44ef5f60..ddeb1c77 100644 --- a/checks/check_extra7129 +++ b/checks/check_extra7129 @@ -50,12 +50,12 @@ extra7129(){ if [[ ${#WAF_PROTECTED_ALBS[@]} -gt 0 ]]; then for wafaclarn in "${WAF_PROTECTED_ALBS[@]}"; do WAFV2_WEBACL_ARN_SHORT=$(echo $wafaclarn | awk -F'/' '{ print $3 }') - textPass "$regx: Application Load Balancer $alb is protected by WAFv2 ACL $WAFV2_WEBACL_ARN_SHORT" "$regx" + textPass "$regx: Application Load Balancer $alb is protected by WAFv2 ACL $WAFV2_WEBACL_ARN_SHORT" "$regx" "$alb" done fi if [[ ${#WAFv1_PROTECTED_ALBS[@]} -gt 0 ]]; then for wafv1aclid in "${WAFv1_PROTECTED_ALBS[@]}"; do - textPass "$regx: Application Load Balancer $alb is protected by WAFv1 ACL $wafv1aclid" "$regx" + textPass "$regx: Application Load Balancer $alb is protected by WAFv1 ACL $wafv1aclid" "$regx" "$alb" done fi else From 265f494b0dbc340672821c44e6947a004af5a9f5 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 8 Jul 2021 17:09:22 +0200 Subject: [PATCH 58/82] Fixed check21 to fail if trail is off --- checks/check21 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/checks/check21 b/checks/check21 index bf7d2064..0446243e 100644 --- a/checks/check21 +++ b/checks/check21 @@ -48,7 +48,12 @@ check21(){ if [[ "$MULTIREGION_TRAIL_STATUS" == 'False' ]];then textFail "$regx: Trail $trail is not enabled for all regions" "$regx" "$trail" else - textPass "$regx: Trail $trail is enabled for all regions" "$regx" "$trail" + TRAIL_ON_OFF_STATUS=$($AWSCLI cloudtrail get-trail-status $PROFILE_OPT --region $TRAIL_REGION --name $trail --query IsLogging --output text) + if [[ "$TRAIL_ON_OFF_STATUS" == 'False' ]];then + textFail "$regx: Trail $trail is configured for all regions but it is OFF" "$regx" "$trail" + else + textPass "$regx: Trail $trail is enabled for all regions" "$regx" "$trail" + fi fi done From ab1407217dde87e491825ad067a6371f409a8976 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Fri, 9 Jul 2021 13:57:35 +0200 Subject: [PATCH 59/82] Enhanced Dockerfile with py3-pip --- util/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/Dockerfile b/util/Dockerfile index 87911e46..6fbed17c 100644 --- a/util/Dockerfile +++ b/util/Dockerfile @@ -5,9 +5,9 @@ ARG USERID=34000 RUN addgroup -g ${USERID} ${USERNAME} && \ adduser -s /bin/sh -G ${USERNAME} -D -u ${USERID} ${USERNAME} && \ - apk --update --no-cache add python3 bash curl jq file coreutils && \ + apk --update --no-cache add python3 bash curl jq file coreutils py3-pip && \ pip3 install --upgrade pip && \ - pip install awscli boto3 detect-secrets + pip3 install awscli boto3 detect-secrets WORKDIR /prowler From 0a4ca0d2ed92096bc95216b9267d7f61ad458e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Le=C5=9Bniak?= Date: Fri, 16 Jul 2021 01:35:46 +0200 Subject: [PATCH 60/82] Update check12 Added missing MFA in remediation description. --- checks/check12 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check12 b/checks/check12 index 1d8f572f..fb328063 100644 --- a/checks/check12 +++ b/checks/check12 @@ -19,7 +19,7 @@ CHECK_ALTERNATE_check102="check12" CHECK_ASFF_COMPLIANCE_TYPE_check12="ens-op.acc.5.aws.iam.1" CHECK_SERVICENAME_check12="iam" CHECK_RISK_check12='Unauthorized access to this critical account if password is not secure or it is disclosed in any way.' -CHECK_REMEDIATION_check12='Enable MFA for root account. is a simple best practice that adds an extra layer of protection on top of your user name and password. Recommended to use hardware keys over virtual MFA.' +CHECK_REMEDIATION_check12='Enable MFA for root account. MFA is a simple best practice that adds an extra layer of protection on top of your user name and password. Recommended to use hardware keys over virtual MFA.' CHECK_DOC_check12='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html' CHECK_CAF_EPIC_check12='IAM' From 8c70efde5fe35e2b1a737fc60f3e6f696f261f1b Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 16 Jul 2021 12:03:39 +0200 Subject: [PATCH 61/82] delete check extra756 and its references --- checks/check_extra756 | 42 ---------------------------------- groups/group15_pci | 4 ++-- groups/group17_internetexposed | 3 +-- groups/group18_iso27001 | 4 ++-- groups/group7_extras | 2 +- 5 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 checks/check_extra756 diff --git a/checks/check_extra756 b/checks/check_extra756 deleted file mode 100644 index a931904f..00000000 --- a/checks/check_extra756 +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash - -# Prowler - the handy cloud security tool (copyright 2019) 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_extra756="7.56" -CHECK_TITLE_extra756="[extra756] Check if Redshift cluster is Public Accessible" -CHECK_SCORED_extra756="NOT_SCORED" -CHECK_TYPE_extra756="EXTRA" -CHECK_SEVERITY_extra756="High" -CHECK_ASFF_RESOURCE_TYPE_extra756="AwsRedshiftCluster" -CHECK_ALTERNATE_check756="extra756" -CHECK_SERVICENAME_extra756="redshift" -CHECK_RISK_extra756='Publicly accessible services could expose sensible data to bad actors.' -CHECK_REMEDIATION_extra756='Ensure there is a business requirement for service to be public. Use the cluster security group to control access to the service.' -CHECK_DOC_extra756='https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-security-groups.html' -CHECK_CAF_EPIC_extra756='Infrastructure Security' - -extra756(){ - for regx in $REGIONS; do - LIST_OF_RS_CLUSTERS=$($AWSCLI $PROFILE_OPT redshift describe-clusters --region $regx --query Clusters[*].ClusterIdentifier --output text) - if [[ $LIST_OF_RS_CLUSTERS ]];then - for cluster in $LIST_OF_RS_CLUSTERS; do - IS_PUBLICLY_ACCESSIBLE=$($AWSCLI $PROFILE_OPT redshift describe-clusters --region $regx --cluster-identifier $cluster --query Clusters[*].PubliclyAccessible --output text|grep True) - if [[ $IS_PUBLICLY_ACCESSIBLE ]]; then - textFail "$regx: Redshift cluster $cluster is publicly accessible" "$regx" "$cluster" - else - textPass "$regx: Redshift cluster $cluster is not publicly accessible" "$regx" "$cluster" - fi - done - else - textInfo "$regx: No Redshift clusters found" "$regx" - fi - done -} diff --git a/groups/group15_pci b/groups/group15_pci index 6a834bbc..82f64bb2 100644 --- a/groups/group15_pci +++ b/groups/group15_pci @@ -15,7 +15,7 @@ GROUP_ID[15]='pci' GROUP_NUMBER[15]='15.0' GROUP_TITLE[15]='PCI-DSS v3.2.1 Readiness - ONLY AS REFERENCE - [pci] **********' GROUP_RUN_BY_DEFAULT[15]='N' # run it when execute_all is called -GROUP_CHECKS[15]='check11,check12,check13,check14,check15,check16,check17,check18,check19,check110,check112,check113,check114,check116,check21,check23,check25,check26,check27,check28,check29,check314,check36,check38,check43,extra713,extra717,extra718,extra72,extra729,extra735,extra738,extra740,extra744,extra748,extra75,extra750,extra751,extra753,extra754,extra755,extra756,extra773,extra78,extra780,extra781,extra782,extra783,extra784,extra785,extra787,extra788,extra798' +GROUP_CHECKS[15]='check11,check12,check13,check14,check15,check16,check17,check18,check19,check110,check112,check113,check114,check116,check21,check23,check25,check26,check27,check28,check29,check314,check36,check38,check43,extra711,extra713,extra717,extra718,extra72,extra729,extra735,extra738,extra740,extra744,extra748,extra75,extra750,extra751,extra753,extra754,extra755,extra773,extra78,extra780,extra781,extra782,extra783,extra784,extra785,extra787,extra788,extra798' # Resources: # https://github.com/toniblyx/prowler/issues/296 @@ -39,7 +39,7 @@ GROUP_CHECKS[15]='check11,check12,check13,check14,check15,check16,check17,check1 # Ensure the default security group restricts all traffic check43 # Remove unused security groups extra75 # RDS should not have Public interface open to a public scope extra78 -# Check for Publicly Accessible Redshift Clusters extra756 +# Check for Publicly Accessible Redshift Clusters extra711 # Ensure Lambda Functions are not publicly accessible extra798 # 3.2 Requirement 2: Do Not Use Vendor-Supplied Defaults for System Passwords and Other Security Parameters diff --git a/groups/group17_internetexposed b/groups/group17_internetexposed index b76a5c53..bb482a0f 100644 --- a/groups/group17_internetexposed +++ b/groups/group17_internetexposed @@ -15,7 +15,7 @@ GROUP_ID[17]='internet-exposed' GROUP_NUMBER[17]='17.0' GROUP_TITLE[17]='Find resources exposed to the internet - [internet-exposed] ***' GROUP_RUN_BY_DEFAULT[17]='N' # run it when execute_all is called -GROUP_CHECKS[17]='check41,check42,check45,check46,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102,extra7134,extra7135,extra7136,extra7137,extra7138' +GROUP_CHECKS[17]='check41,check42,check45,check46,extra72,extra73,extra74,extra76,extra77,extra78,extra79,extra710,extra711,extra716,extra723,extra727,extra731,extra736,extra738,extra745,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra770,extra771,extra778,extra779,extra787,extra788,extra795,extra796,extra798,extra7102,extra7134,extra7135,extra7136,extra7137,extra7138' # 4.1 [check41] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored) [group4, cislevel1, cislevel2] # 4.2 [check42] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored) [group4, cislevel1, cislevel2] @@ -42,7 +42,6 @@ GROUP_CHECKS[17]='check41,check42,check45,check46,extra72,extra73,extra74,extra7 # 7.53 [extra753] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to MongoDB ports 27017 and 27018 [extras] # 7.54 [extra754] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Cassandra ports 7199 or 9160 or 8888 [extras] # 7.55 [extra755] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Memcached port 11211 [extras] -# redundant 7.56 [extra756] Check if Redshift cluster is Public Accessible [extras] # 7.70 [extra770] Check for internet facing EC2 instances with Instance Profiles attached [extras] # 7.78 [extra778] Find VPC security groups with wide-open public IPv4 CIDR ranges (non-RFC1918) [extras] # 7.79 [extra779] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Elasticsearch/Kibana ports [extras, elasticsearch] diff --git a/groups/group18_iso27001 b/groups/group18_iso27001 index e451fabb..60196080 100644 --- a/groups/group18_iso27001 +++ b/groups/group18_iso27001 @@ -15,7 +15,7 @@ GROUP_ID[18]='iso27001' GROUP_NUMBER[18]='18.0' GROUP_TITLE[18]='ISO 27001:2013 Readiness - ONLY AS REFERENCE - [iso27001] *****' GROUP_RUN_BY_DEFAULT[18]='N' # run it when execute_all is called -GROUP_CHECKS[18]='check11,check110,check111,check112,check113,check114,check115,check116,check119,check12,check122,check13,check14,check15,check16,check17,check18,check19,check21,check22,check23,check24,check25,check26,check27,check28,check29,check31,check310,check311,check312,check313,check314,check32,check33,check34,check35,check36,check37,check38,check39,check41,check42,check43,check44,extra71,extra710,extra7100,extra711,extra7113,extra7123,extra7125,extra7126,extra7128,extra7129,extra713,extra714,extra7130,extra718,extra719,extra72,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra731,extra73,extra731,extra735,extra739,extra74,extra741,extra747,extra748,extra75,extra756,extra757,extra758,extra759,extra76,extra760,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra77,extra771,extra772,extra774,extra776,extra777,extra778,extra78,extra789,extra79,extra790,extra792,extra793,extra794,extra795,extra796,extra798' +GROUP_CHECKS[18]='check11,check110,check111,check112,check113,check114,check115,check116,check119,check12,check122,check13,check14,check15,check16,check17,check18,check19,check21,check22,check23,check24,check25,check26,check27,check28,check29,check31,check310,check311,check312,check313,check314,check32,check33,check34,check35,check36,check37,check38,check39,check41,check42,check43,check44,extra71,extra710,extra7100,extra711,extra7113,extra7123,extra7125,extra7126,extra7128,extra7129,extra713,extra714,extra7130,extra718,extra719,extra72,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra731,extra73,extra731,extra735,extra739,extra74,extra741,extra747,extra748,extra75,extra757,extra758,extra759,extra76,extra760,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra77,extra771,extra772,extra774,extra776,extra777,extra778,extra78,extra789,extra79,extra790,extra792,extra793,extra794,extra795,extra796,extra798' # # Category Objective ID Objective Name Prowler check ID Check Summary # 1 A.9 Access Control A.9.2 User Access Management check122 Ensure IAM policies that allow full "*:*" administrative privileges are not created. @@ -66,13 +66,13 @@ GROUP_CHECKS[18]='check11,check110,check111,check112,check113,check114,check115, # 46 A.9 Access Control A.9.4 System and Application Access Control check14 Ensure access keys are rotated every 90 days or less # 47 A.9 Access Control A.9.4 System and Application Access Control check13 Ensure credentials unused for 90 days or greater are disabled # 48 A.9 Access Control A.9.4 System and Application Access Control check112 Ensure no root account access key exists +# 55 A.9 Access Control A.9.4 System and Application Access Control extra711 Check if Redshift cluster is Public Accessible # 49 A.9 Access Control A.9.4 System and Application Access Control extra7113 Check if RDS instances have deletion protection enabled # 50 A.9 Access Control A.9.4 System and Application Access Control extra72 Ensure there are no EBS Snapshots set as Public # 51 A.9 Access Control A.9.4 System and Application Access Control extra723 Check if RDS Snapshots and Cluster Snapshots are public # 52 A.9 Access Control A.9.4 System and Application Access Control extra727 Check if SQS queues have policy set as Public # 53 A.9 Access Control A.9.4 System and Application Access Control extra73 Ensure there are no S3 buckets open to Everyone or Any AWS user # 54 A.9 Access Control A.9.4 System and Application Access Control extra731 Check if SNS topics have policy set as Public -# 55 A.9 Access Control A.9.4 System and Application Access Control extra756 Check if Redshift cluster is Public Accessible # 56 A.9 Access Control A.9.4 System and Application Access Control extra76 Ensure there are no EC2 AMIs set as Public # 57 A.9 Access Control A.9.4 System and Application Access Control extra77 Ensure there are no ECR repositories set as Public # 58 A.9 Access Control A.9.4 System and Application Access Control extra771 Check if S3 buckets have policies which allow WRITE access diff --git a/groups/group7_extras b/groups/group7_extras index 2ecde56a..2441ec49 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 0d9ec6320e01714f2a30633c033e0423941815ba Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 16 Jul 2021 12:09:54 +0200 Subject: [PATCH 62/82] delete check extra737 and its references --- checks/check_extra737 | 46 ------------------------------------------- groups/group23_ens | 6 +++--- groups/group7_extras | 2 +- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 checks/check_extra737 diff --git a/checks/check_extra737 b/checks/check_extra737 deleted file mode 100644 index 056e7be6..00000000 --- a/checks/check_extra737 +++ /dev/null @@ -1,46 +0,0 @@ -#!/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_extra737="7.37" -CHECK_TITLE_extra737="[extra737] Check KMS keys with key rotation disabled" -CHECK_SCORED_extra737="NOT_SCORED" -CHECK_TYPE_extra737="EXTRA" -CHECK_SEVERITY_extra737="Medium" -CHECK_ASFF_RESOURCE_TYPE_extra737="AwsKmsKey" -CHECK_ALTERNATE_check737="extra737" -CHECK_ASFF_COMPLIANCE_TYPE_extra737="ens-op.exp.11.aws.kms.3" -CHECK_SERVICENAME_extra737="kms" -CHECK_RISK_extra737='Cryptographic best practices discourage extensive reuse of encryption keys. Consequently; Customer Master Keys (CMKs) should be rotated to prevent usage of compromised keys.' -CHECK_REMEDIATION_extra737='For every KMS Customer Master Keys (CMKs); ensure that Rotate this key every year is enabled.' -CHECK_DOC_extra737='https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html' -CHECK_CAF_EPIC_extra737='Data Protection' - -extra737(){ - for regx in $REGIONS; do - LIST_OF_CUSTOMER_KMS_KEYS=$($AWSCLI kms list-aliases $PROFILE_OPT --region $regx --query "Aliases[].[AliasName,TargetKeyId]" --output text |grep -v ^alias/aws/ |awk '{ print $2 }') - if [[ $LIST_OF_CUSTOMER_KMS_KEYS ]];then - for key in $LIST_OF_CUSTOMER_KMS_KEYS; do - CHECK_ROTATION=$($AWSCLI kms get-key-rotation-status --key-id $key $PROFILE_OPT --region $regx --output text) - CHECK_STATUS=$($AWSCLI kms describe-key --key-id $key $PROFILE_OPT --region $regx --output json | jq -r '.KeyMetadata.KeyState') - if [[ $CHECK_STATUS == "PendingDeletion" ]]; then - textInfo "$regx: KMS key $key is pending deletion and cannot be rotated" "$regx" - elif [[ $CHECK_ROTATION == "False" ]]; then - textFail "$regx: KMS key $key has rotation disabled!" "$regx" "$key" - else - textPass "$regx: KMS key $key has rotation enabled" "$regx" "$key" - fi - done - else - textInfo "$regx: No KMS keys found" "$regx" - fi - done -} diff --git a/groups/group23_ens b/groups/group23_ens index e48efed3..098ddc61 100644 --- a/groups/group23_ens +++ b/groups/group23_ens @@ -15,7 +15,7 @@ GROUP_ID[23]='ens' GROUP_NUMBER[23]='23.0' GROUP_TITLE[23]='ENS Esquema Nacional de Seguridad security checks - [ens] *****' GROUP_RUN_BY_DEFAULT[23]='N' # run it when execute_all is called -GROUP_CHECKS[23]='extra733,extra7123,check13,check14,check121,extra7100,check120,check116,extra7124,check12,extra7125,check14,check13,check21,check25,extra7127,check35,check24,check31,check36,check32,check33,check34,check22,extra71,check23,check23,check27,check37,extra736,extra737,extra713,check21,check29,extra793,extra792,extra764,extra738,check43,extra74,extra710,extra75,check41,check42,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra7128,extra729,extra761,extra740,extra735,extra734,extra728,extra781,extra773,extra744,extra7126,extra7129' +GROUP_CHECKS[23]='extra733,extra7123,check13,check14,check121,extra7100,check120,check116,extra7124,check12,extra7125,check14,check13,check21,check25,extra7127,check35,check24,check31,check36,check32,check33,check34,check22,extra71,check23,check23,check27,check37,extra736,check28,extra713,check21,check29,extra793,extra792,extra764,extra738,check43,extra74,extra710,extra75,check41,check42,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra7128,extra729,extra761,extra740,extra735,extra734,extra728,extra781,extra773,extra744,extra7126,extra7129' # ENS Control ID for AWS;Prowler checks that apply # ens-op.acc.1.aws.iam.1;extra733 @@ -49,7 +49,7 @@ GROUP_CHECKS[23]='extra733,extra7123,check13,check14,check121,extra7100,check120 # ens-op.exp.10.aws.trail.5;check27 # ens-op.exp.11.aws.kms.1;check37 # ens-op.exp.11.aws.kms.2;extra736* -# ens-op.exp.11.aws.kms.3;extra737 +# ens-op.exp.11.aws.kms.3;check28 # ens-op.mon.1.aws.duty.1;extra713 # ens-op.mon.1.aws.trail.1;check21 # ens-op.mon.1.aws.flow.1;check29 @@ -80,4 +80,4 @@ GROUP_CHECKS[23]='extra733,extra7123,check13,check14,check121,extra7100,check120 # ens-mp.info.3.aws.au.1;extra781 # ens-mp.s.2.aws.waf.1;extra773 # ens-mp.s.2.aws.waf.2;extra744 -# ens-mp.s.2.aws.waf.3;extra7129 \ No newline at end of file +# ens-mp.s.2.aws.waf.3;extra7129 diff --git a/groups/group7_extras b/groups/group7_extras index 2ecde56a..be5b4a42 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,7 +15,7 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra737,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` From 9ddb31f9c3e325555ca639cb1e579c7c51bb4612 Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 16 Jul 2021 12:26:46 +0200 Subject: [PATCH 63/82] fix grammar issue --- include/scoring | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/scoring b/include/scoring index b6fc7f08..3023d395 100644 --- a/include/scoring +++ b/include/scoring @@ -22,7 +22,7 @@ scoring(){ # TOTAL_RESOURCES=$(awk "BEGIN {print $FAIL_COUNTER+$PASS_COUNTER; exit}") TOTAL_RESOURCES=$(($FAIL_COUNTER + $PASS_COUNTER)) - # Score is % of passed compared to failures. The higher score, the better + # Score is % of passed compared to failures. The higher the better PROWLER_SCORE=$(( $PASS_COUNTER * 100 / $TOTAL_RESOURCES )) if [[ $SCORING == "1" ]]; then @@ -47,7 +47,7 @@ scoring(){ echo -e "$BLUE------------------------------------------------------------------ $NORMAL" echo -e " Checks Performed =$NOTICE $CHECKS_COUNTER $NORMAL" echo -e "$BLUE------------------------------------------------------------------ $NORMAL" - echo -e " * the highest the better (0 to 100)$NORMAL" + echo -e " * the higher the better (0 to 100)$NORMAL" echo -e " Prowler scoring uses any check, including CIS not scored checks$NORMAL" fi if [[ "${MODES[@]}" =~ "html" ]]; then From c32fa9aa1fd53e20f16af5b3e166839beb4dc817 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 27 Jul 2021 14:43:20 +0200 Subject: [PATCH 64/82] Added s3 and glue required permissions --- iam/create_role_to_assume_cfn.yaml | 2 ++ iam/prowler-additions-policy.json | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/iam/create_role_to_assume_cfn.yaml b/iam/create_role_to_assume_cfn.yaml index 6414f810..99e0a767 100644 --- a/iam/create_role_to_assume_cfn.yaml +++ b/iam/create_role_to_assume_cfn.yaml @@ -63,4 +63,6 @@ Resources: - 'support:Describe*' - 'tag:GetTagKeys' - 'lambda:GetFunction' + - 'glue:GetConnections', + - 's3:GetAccountPublicAccessBlock' Resource: '*' diff --git a/iam/prowler-additions-policy.json b/iam/prowler-additions-policy.json index 33eacc35..441104ff 100644 --- a/iam/prowler-additions-policy.json +++ b/iam/prowler-additions-policy.json @@ -10,7 +10,9 @@ "ecr:Describe*", "support:Describe*", "tag:GetTagKeys", - "lambda:GetFunction" + "lambda:GetFunction", + "glue:GetConnections", + "s3:GetAccountPublicAccessBlock" ], "Resource": "*", "Effect": "Allow", From ffe147b5b5dd5a0aca7720fccdecafc017e1179d Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 27 Jul 2021 14:49:58 +0200 Subject: [PATCH 65/82] Added s3 and glue required permissions and removed obsoletes --- iam/create_role_to_assume_cfn.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iam/create_role_to_assume_cfn.yaml b/iam/create_role_to_assume_cfn.yaml index 99e0a767..1e1140a1 100644 --- a/iam/create_role_to_assume_cfn.yaml +++ b/iam/create_role_to_assume_cfn.yaml @@ -55,14 +55,12 @@ Resources: Statement: - Effect: Allow Action: - - 'dax:ListTables' - 'ds:ListAuthorizedApplications' - - 'ds:DescribeRoles' - 'ec2:GetEbsEncryptionByDefault' - 'ecr:Describe*' - 'support:Describe*' - 'tag:GetTagKeys' - 'lambda:GetFunction' - - 'glue:GetConnections', + - 'glue:GetConnections' - 's3:GetAccountPublicAccessBlock' Resource: '*' From 4d6285f1679a9409b04c9188862daa99846e3088 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 27 Jul 2021 14:52:23 +0200 Subject: [PATCH 66/82] Added s3 and glue required permissions and removed obsoletes --- iam/prowler-additions-policy.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/iam/prowler-additions-policy.json b/iam/prowler-additions-policy.json index 441104ff..4ef43c5a 100644 --- a/iam/prowler-additions-policy.json +++ b/iam/prowler-additions-policy.json @@ -3,9 +3,7 @@ "Statement": [ { "Action": [ - "dax:ListTables", "ds:ListAuthorizedApplications", - "ds:DescribeRoles", "ec2:GetEbsEncryptionByDefault", "ecr:Describe*", "support:Describe*", From 3f63b831793d48891b7973be0e07b17a38356a2e Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 27 Jul 2021 15:12:14 +0200 Subject: [PATCH 67/82] Added section with info about regions --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 57d04e6b..727b7242 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,12 @@ Prowler has been written in bash using AWS-CLI and it works in Linux and OSX. Valid check numbers are based on the AWS CIS Benchmark guide, so 1.1 is check11 and 3.10 is check310 +### Regions + +By default Prowler scans all opt-in regions available, that might take a long execution time depending on the number of resources and regions used. Same applies for GovCloud or China regions. See below Advance usage for examples. + +Prowler has to parameters related to regions: `-r` that is used query AWS services API endpoints (it uses `us-east-1` by default and required for GovCloud or China) and the option `-f` that is to filter those regions you only want to scan. For example if you want to scan Dublin only use `-f eu-west-1` and if you want to scan Dublin and Ohio `-f 'eu-west-1 us-east-s'`, note the single quotes and space between regions. + ## Screenshots - Sample screenshot of report first lines: From 52e04406dcb59fda6756b376bfb513eab983420d Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 29 Jul 2021 17:03:04 +0200 Subject: [PATCH 68/82] Added servicename to the title for ASFF --- include/outputs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/outputs b/include/outputs index d1dccad2..d9c53d02 100644 --- a/include/outputs +++ b/include/outputs @@ -326,7 +326,7 @@ generateJsonAsffOutput(){ local status=$2 #Checks to determine if the rule passes in a resource name that prowler uses to track the AWS Resource for whitelisting purposes - if [ -z $3 ]; then + if [[ -z $3 ]]; then local resource_id="NONE_PROVIDED" else local resource_id=$3 @@ -337,7 +337,7 @@ generateJsonAsffOutput(){ fi jq -M -c \ --arg ACCOUNT_NUM "$ACCOUNT_NUM" \ - --arg TITLE_TEXT "$TITLE_TEXT" \ + --arg TITLE_TEXT "$CHECK_SERVICENAME.$TITLE_TEXT" \ --arg MESSAGE "$(echo -e "${message}")" \ --arg UNIQUE_ID "$(LC_ALL=C echo -e -n "${message}" | tr -cs '[:alnum:]._~-' '_')" \ --arg STATUS "$status" \ From 26d310e35b50f783603882568f11c83f0e948a37 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 29 Jul 2021 18:37:57 +0200 Subject: [PATCH 69/82] Updated Prowler additions policy --- iam/prowler-additions-policy.json | 1 + .../codebuild-prowler-audit-account-cfn.yaml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/iam/prowler-additions-policy.json b/iam/prowler-additions-policy.json index 4ef43c5a..f0285c24 100644 --- a/iam/prowler-additions-policy.json +++ b/iam/prowler-additions-policy.json @@ -10,6 +10,7 @@ "tag:GetTagKeys", "lambda:GetFunction", "glue:GetConnections", + "glue:SearchTables", "s3:GetAccountPublicAccessBlock" ], "Resource": "*", diff --git a/util/codebuild/codebuild-prowler-audit-account-cfn.yaml b/util/codebuild/codebuild-prowler-audit-account-cfn.yaml index 1022da6e..1af61a7a 100644 --- a/util/codebuild/codebuild-prowler-audit-account-cfn.yaml +++ b/util/codebuild/codebuild-prowler-audit-account-cfn.yaml @@ -179,6 +179,22 @@ Resources: - s3:GetBucketLocation Effect: Allow Resource: !Sub 'arn:aws:s3:::${ArtifactBucket}/*' + - PolicyName: ProwlerAdditions + PolicyDocument: + Version: '2012-10-17' + Statement: + - Action: + - s3:GetAccountPublicAccessBlock + - glue:GetConnections + - glue:SearchTables + - ds:ListAuthorizedApplications + - ec2:GetEbsEncryptionByDefault + - ecr:Describe* + - support:Describe* + - tag:GetTagKeys + - lambda:GetFunction + Effect: Allow + Resource: !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:catalog' - PolicyName: CodeBuild PolicyDocument: Version: '2012-10-17' From 3a66ca336ae23fb38f7c5ceef712a607b23e7289 Mon Sep 17 00:00:00 2001 From: daniel Date: Mon, 2 Aug 2021 13:23:16 +0200 Subject: [PATCH 70/82] changes made so there is enough colour contrast for WCAG 2.1 accessibility standards --- include/html_report | 4 ++++ include/outputs | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/html_report b/include/html_report index 42db8626..3dec6ae6 100644 --- a/include/html_report +++ b/include/html_report @@ -25,6 +25,10 @@ addHtmlHeader() { + diff --git a/include/outputs b/include/outputs index 9d51f823..1f6e9178 100644 --- a/include/outputs +++ b/include/outputs @@ -362,11 +362,11 @@ generateHtmlOutput(){ echo ''$CHECK_CAF_EPIC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML - echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi if [[ $status == "PASS" ]];then - echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo 'PASS' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''$CHECK_SEVERITY'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML @@ -380,7 +380,7 @@ generateHtmlOutput(){ echo ''$CHECK_CAF_EPIC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML - echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi if [[ $status == "FAIL" ]];then @@ -398,7 +398,7 @@ generateHtmlOutput(){ echo ''$CHECK_CAF_EPIC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML - echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi if [[ $status == "WARNING" ]];then @@ -416,7 +416,7 @@ generateHtmlOutput(){ echo ''$CHECK_CAF_EPIC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_RISK'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '

'$CHECK_REMEDIATION'

' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML - echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML + echo ''$CHECK_DOC'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo ''>> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML fi -} \ No newline at end of file +} From 558a9b5f2edaafdd4837be7f291f5987681e4454 Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 6 Aug 2021 11:46:45 +0200 Subject: [PATCH 71/82] ignore secrets folder when scanning for secrets --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 7644e14e..f6e46e88 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ Sessionx.vim *~ # Auto-generated tag files tags + # Persistent undo [._]*.un~ @@ -23,6 +24,9 @@ tags # Prowler output output/ +# Prowler found secrets +secrets-*/ + # JUnit Reports junit-reports/ From 62050e2e349f64bfd8088eb0aadd4bae89f8ef5e Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 14:01:40 +0200 Subject: [PATCH 72/82] Added PROWLER_START_TIME to CSV for reports --- include/csv_header | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/csv_header b/include/csv_header index 30d731db..1c01f93d 100644 --- a/include/csv_header +++ b/include/csv_header @@ -15,6 +15,6 @@ printCsvHeader() { # >&2 echo "" # >&2 echo "Generating \"${SEP}\" delimited report on stdout for profile $PROFILE, account $ACCOUNT_NUM" - echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}CHECK_RESULT${SEP}ITEM_SCORED${SEP}ITEM_LEVEL${SEP}TITLE_TEXT${SEP}CHECK_RESULT_EXTENDED${SEP}CHECK_ASFF_COMPLIANCE_TYPE${SEP}CHECK_SEVERITY${SEP}CHECK_SERVICENAME${SEP}CHECK_ASFF_RESOURCE_TYPE${SEP}CHECK_ASFF_TYPE${SEP}CHECK_RISK${SEP}CHECK_REMEDIATION${SEP}CHECK_DOC${SEP}CHECK_CAF_EPIC${SEP}CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}CHECK_RESULT${SEP}ITEM_SCORED${SEP}ITEM_LEVEL${SEP}TITLE_TEXT${SEP}CHECK_RESULT_EXTENDED${SEP}CHECK_ASFF_COMPLIANCE_TYPE${SEP}CHECK_SEVERITY${SEP}CHECK_SERVICENAME${SEP}CHECK_ASFF_RESOURCE_TYPE${SEP}CHECK_ASFF_TYPE${SEP}CHECK_RISK${SEP}CHECK_REMEDIATION${SEP}CHECK_DOC${SEP}CHECK_CAF_EPIC${SEP}CHECK_RESOURCE_ID${SEP}PROWLER_START_TIME" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV # echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}RESULT${SEP}SCORED${SEP}LEVEL${SEP}TITLE_TEXT${SEP}NOTES${SEP}COMPLIANCE${SEP}SEVERITY${SEP}SERVICENAME" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV } From c6203bf9e313277c9982ca367fe270a4b514397f Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 14:02:21 +0200 Subject: [PATCH 73/82] Clean up redentials report output --- include/credentials_report | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/credentials_report b/include/credentials_report index 8a98e2de..3741e89a 100644 --- a/include/credentials_report +++ b/include/credentials_report @@ -13,7 +13,7 @@ # Generate Credential Report genCredReport() { - textTitle "0.1" "Generating AWS IAM Credential Report..." "NOT_SCORED" "SUPPORT" + textTitle "" "Generating AWS IAM Credential Report..." for i in $(seq 1 60); do GENERATECREDENTIALREPORTOUTPUT=$($AWSCLI iam generate-credential-report --output text --query 'State' $PROFILE_OPT --region $REGION 2>&1) if [[ $(echo "$GENERATECREDENTIALREPORTOUTPUT" | grep AccessDenied) ]]; then From cdf99c96000f8748b7848300ee60f82c069c73a9 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 14:03:13 +0200 Subject: [PATCH 74/82] Removed scored info from title --- prowler | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prowler b/prowler index a67bf35d..23a7fb7b 100755 --- a/prowler +++ b/prowler @@ -45,7 +45,7 @@ SEP=',' KEEPCREDREPORT=0 EXITCODE=0 SEND_TO_SECURITY_HUB=0 -SCRIPT_START_TIME=$( date -u +"%Y-%m-%dT%H:%M:%S%z" ) +PROWLER_START_TIME=$( date -u +"%Y-%m-%dT%H:%M:%S%z" ) TITLE_ID="" TITLE_TEXT="CALLER ERROR - UNSET TITLE" WHITELIST_FILE="" @@ -357,7 +357,7 @@ show_check_title() { show_group_title() { # when csv mode is used, no group title is shown if [[ "$MODE" != "csv" ]]; then - textTitle "${GROUP_NUMBER[$1]}" "${GROUP_TITLE[$1]}" "NOT_SCORED" "SUPPORT" + textTitle "${GROUP_NUMBER[$1]}" "${GROUP_TITLE[$1]}" fi } From d869c748fb23e98ed777961a99601e0f8de3ad92 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 14:07:31 +0200 Subject: [PATCH 75/82] Now shows default output regardless custom outputs called with -M --- include/outputs | 42 ++++++++++++++++++++++-------------------- prowler | 4 ++-- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/include/outputs b/include/outputs index 6e28afd6..e1971d0a 100644 --- a/include/outputs +++ b/include/outputs @@ -97,7 +97,7 @@ textPass(){ REPREGION=$REGION fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID${SEP}$PROWLER_START_TIME" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then generateJsonOutput "$1" "Pass" "$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_JSON @@ -115,9 +115,10 @@ textPass(){ if [[ "${MODES[@]}" =~ "mono" ]]; then echo " $OK PASS!$NORMAL $1" >> ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT fi - if [[ "${MODES[@]}" =~ "text" || "${MODES[@]}" =~ "mono" ]]; then + # if [[ "${MODES[@]}" =~ "text" || "${MODES[@]}" =~ "mono" ]]; then + # runs showing console output no mater what output is selected echo " $OK PASS!$NORMAL $1" - fi + # fi if [[ "${MODES[@]}" =~ "html" ]]; then generateHtmlOutput "$1" "PASS" fi @@ -138,7 +139,7 @@ textInfo(){ REPREGION=$REGION fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID${SEP}$PROWLER_START_TIME" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then generateJsonOutput "$1" "Info" "$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} @@ -149,9 +150,9 @@ textInfo(){ if [[ "${MODES[@]}" =~ "mono" ]]; then echo " $NOTICE INFO! $1 $NORMAL" >> ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT fi - if [[ "${MODES[@]}" =~ "text" ]]; then + # if [[ "${MODES[@]}" =~ "text" ]]; then echo " $NOTICE INFO! $1 $NORMAL" - fi + # fi if [[ "${MODES[@]}" =~ "html" ]]; then generateHtmlOutput "$1" "INFO" "$CHECK_RESOURCE_ID" fi @@ -194,7 +195,7 @@ textFail(){ fi if [[ "${MODES[@]}" =~ "csv" ]]; then - echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV + echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}$CHECK_RESULT${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$CHECK_RESULT_EXTENDED${SEP}$CHECK_ASFF_COMPLIANCE_TYPE${SEP}$CHECK_SEVERITY${SEP}$CHECK_SERVICENAME${SEP}$CHECK_ASFF_RESOURCE_TYPE${SEP}$CHECK_ASFF_TYPE${SEP}$CHECK_RISK${SEP}$CHECK_REMEDIATION${SEP}$CHECK_DOC${SEP}$CHECK_CAF_EPIC${SEP}$CHECK_RESOURCE_ID${SEP}$PROWLER_START_TIME" >> ${OUTPUT_FILE_NAME}.$EXTENSION_CSV fi if [[ "${MODES[@]}" =~ "json" ]]; then generateJsonOutput "$1" "${level}" "$CHECK_RESOURCE_ID">> ${OUTPUT_FILE_NAME}.${EXTENSION_JSON} @@ -216,9 +217,9 @@ textFail(){ if [[ "${MODES[@]}" =~ "mono" ]]; then echo " $colorcode ${level}! $1 $NORMAL" >> ${OUTPUT_FILE_NAME}.$EXTENSION_TEXT fi - if [[ "${MODES[@]}" =~ "text" ]]; then + # if [[ "${MODES[@]}" =~ "text" ]]; then echo " $colorcode ${level}! $1 $NORMAL" - fi + # fi if [[ "${MODES[@]}" =~ "html" ]]; then generateHtmlOutput "$1" "${level}" "$CHECK_RESOURCE_ID" fi @@ -261,17 +262,18 @@ textTitle(){ group_ids="$CYAN[$5]$NORMAL" # fi - if [[ "${MODES[@]}" =~ "csv" ]]; then - >&2 echo "$TITLE_ID $TITLE_TEXT" >> ${OUTPUT_FILE_NAME}.${EXTENSION_CSV} - elif [[ "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then - : - else - # if [[ "$ITEM_SCORED" == "Scored" ]]; then - echo -e "$TITLE_ID $CHECK_SERVICENAME $TITLE_TEXT $CHECK_SEVERITY $group_ids " - # else - # echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $6 $NORMAL $group_ids " - # fi - fi + # if [[ "${MODES[@]}" =~ "csv" ]]; then + # >&2 echo "$TITLE_ID $TITLE_TEXT" >> ${OUTPUT_FILE_NAME}.${EXTENSION_CSV} + # elif [[ "${MODES[@]}" =~ "json" || "${MODES[@]}" =~ "json-asff" ]]; then + # : + # else + # # if [[ "$ITEM_SCORED" == "Scored" ]]; then + # echo -e "$TITLE_ID $CHECK_SERVICENAME $TITLE_TEXT $CHECK_SEVERITY $group_ids " + echo -e "$TITLE_ID $TITLE_TEXT $CHECK_SERVICENAME $CHECK_SEVERITY" + # # else + # # echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $6 $NORMAL $group_ids " + # # fi + # fi } generateJsonOutput(){ diff --git a/prowler b/prowler index 23a7fb7b..6b3f2798 100755 --- a/prowler +++ b/prowler @@ -580,9 +580,9 @@ get_all_checks_without_exclusion() { } ### All functions defined above ... run the workflow -if [[ " ${MODES[@]} " =~ " mono " || " ${MODES[@]} " =~ " text " ]]; then +#if [[ " ${MODES[@]} " =~ " mono " || " ${MODES[@]} " =~ " text " ]]; then prowlerBanner -fi +#fi # List only check tittles if [[ $PRINTCHECKSONLY == "1" ]]; then From f418c706b5009888bebd32eea76e20b1ff9c2204 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 15:13:14 +0200 Subject: [PATCH 76/82] Removed extra756 from extras as duplicated --- groups/group7_extras | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/groups/group7_extras b/groups/group7_extras index c61e7980..a8359bb6 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,11 +15,11 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` # Extras 789 and 790 VPC trust boundaries are not included by default in Extras # to run trust-boundaries use `./prowler -g trustboundaries` -# read more in https://github.com/toniblyx/prowler/#trust-boundaries-checks \ No newline at end of file +# read more in https://github.com/toniblyx/prowler/#trust-boundaries-checks From c8e9cf2e77af3d284eed5a4ee01fda527a25620e Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 17:00:18 +0200 Subject: [PATCH 77/82] Tested new checks 7143 to 7147 --- checks/check_extra7142 | 60 ++++++++++++++++++++---------------------- checks/check_extra7143 | 16 +++++------ checks/check_extra7144 | 8 +++--- checks/check_extra7145 | 22 ++++++++-------- checks/check_extra7146 | 42 ++++++++++++++--------------- checks/check_extra7147 | 47 +++++++++++++++++++++++++++++++++ groups/group7_extras | 4 +-- 7 files changed, 121 insertions(+), 78 deletions(-) create mode 100644 checks/check_extra7147 diff --git a/checks/check_extra7142 b/checks/check_extra7142 index c246aa2d..5fbd6922 100644 --- a/checks/check_extra7142 +++ b/checks/check_extra7142 @@ -10,39 +10,35 @@ # 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_extra7147="7.147" -CHECK_TITLE_extra7147="[extra7147] Check if S3 Glacier vaults have policies which allow access to everyone" -CHECK_SCORED_extra7147="NOT_SCORED" -CHECK_TYPE_extra7147="EXTRA" -CHECK_SEVERITY_extra7147="Critical" -CHECK_ASFF_RESOURCE_TYPE_extra7147="AwsS3Glacier" -CHECK_ALTERNATE_check7147="extra7142" -CHECK_SERVICENAME_extra7147="s3glacier" -CHECK_RISK_extra7147='Vaults accessible to everyone could expose sensible data to bad actors' -CHECK_REMEDIATION_extra7147='Ensure vault policy does not have principle as *' -CHECK_DOC_extra7147='https://docs.aws.amazon.com/amazonglacier/latest/dev/access-control-overview.html' -CHECK_CAF_EPIC_extra7147='Data Protection' +CHECK_ID_extra7142="7.142" +CHECK_TITLE_extra7142="[extra7142] Check if Application Load Balancer is dropping invalid packets to prevent header based http request smuggling" +CHECK_SCORED_extra7142="NOT_SCORED" +CHECK_TYPE_extra7142="EXTRA" +CHECK_SEVERITY_extra7142="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7142="AwsElasticLoadBalancingV2LoadBalancer" +CHECK_ALTERNATE_check7142="extra7142" +CHECK_ASFF_COMPLIANCE_TYPE_extra7142="" +CHECK_SERVICENAME_extra7142="elb" +CHECK_RISK_extra7142='ALB can be target of actors sendingn bad http headers' +CHECK_REMEDIATION_extra7142='Ensure Application Load Balancer is configured for HTTP headers with header fields that are not valid are removed by the load balancer (true)' +CHECK_DOC_extra7142='https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#desync-mitigation-mode' +CHECK_CAF_EPIC_extra7142='Data Protection' -extra7147(){ + +extra7142(){ for regx in $REGIONS; do - LIST_OF_VAULTS=$($AWSCLI glacier list-vaults $PROFILE_OPT --region $regx --account-id $ACCOUNT_NUM --query VaultList[*].VaultName --output text|xargs -n1) - if [[ $LIST_OF_VAULTS ]]; then - for vault in $LIST_OF_VAULTS;do - VAULT_POLICY_STATEMENTS=$($AWSCLI glacier $PROFILE_OPT get-vault-access-policy --region $regx --account-id $ACCOUNT_NUM --vault-name $vault --output json --query policy.Policy 2>&1) - if [[ $VAULT_POLICY_STATEMENTS == *GetVaultAccessPolicy* ]]; then - textInfo "$regx: Vault $vault doesn't have any policy" "$regx" "$vault" - else - VAULT_POLICY_BAD_STATEMENTS=$(echo $VAULT_POLICY_STATEMENTS | jq '. | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') - if [[ $VAULT_POLICY_BAD_STATEMENTS != "" ]]; then - textFail "$regx: Vault $vault has policy which allows access to everyone" "$regx" "$vault" + LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application`].[LoadBalancerArn]' --output text) + if [[ $LIST_OF_ELBSV2 ]];then + for alb in $LIST_OF_ELBSV2;do + CHECK_IF_DROP_INVALID_HEADER_FIELDS=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $alb --query 'Attributes[6]' --output text|grep -i true) + if [[ $CHECK_IF_DROP_INVALID_HEADER_FIELDS ]];then + textPass "$regx: Application Load Balancer $alb is dropping invalid header fields." "$regx" "$alb" else - textPass "$regx: Vault $vault has policy which does not allow access to everyone" "$regx" "$vault" + textFail "$regx: Application Load Balancer $alb is not dropping invalid header fields" "$regx" "$alb" fi - fi - done - - else - textInfo "$regx: No Glacier vaults found" "$regx" - fi - done -} \ No newline at end of file + done + else + textInfo "$regx: no ALBs found" + fi + done +} diff --git a/checks/check_extra7143 b/checks/check_extra7143 index fbd1c324..09f24131 100644 --- a/checks/check_extra7143 +++ b/checks/check_extra7143 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7143="7.143" -CHECK_TITLE_extra7143="[extra7143] Check if EFS have policies which allow access to everyone (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7143="[extra7143] Check if EFS have policies which allow access to everyone" CHECK_SCORED_extra7143="NOT_SCORED" CHECK_TYPE_extra7143="EXTRA" CHECK_SEVERITY_extra7143="Critical" @@ -25,25 +25,25 @@ CHECK_CAF_EPIC_extra7143='Data Protection' extra7143(){ # "Check if EFS have policies which allow access to everyone (Not Scored) (Not part of CIS benchmark)" - for region in $REGIONS; do - LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $region --query FileSystems[*].FileSystemId --output text|xargs -n1) + for regx in $REGIONS; do + LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query FileSystems[*].FileSystemId --output text|xargs -n1) if [[ $LIST_OF_EFS_IDS ]]; then for efsId in $LIST_OF_EFS_IDS;do - EFS_POLICY_STATEMENTS=$($AWSCLI efs $PROFILE_OPT describe-file-system-policy --region $region --file-system-id $efsId --output json --query Policy 2>&1) + EFS_POLICY_STATEMENTS=$($AWSCLI efs $PROFILE_OPT describe-file-system-policy --region $regx --file-system-id $efsId --output json --query Policy 2>&1) if [[ $EFS_POLICY_STATEMENTS == *PolicyNotFound* ]]; then - textFail "$region: EFS: $efsId doesn't have any policy which means it grants full access to any client" "$region" "$efsId" + textFail "$regx: EFS: $efsId doesn't have any policy which means it grants full access to any client" "$regx" "$efsId" else EFS_POLICY_BAD_STATEMENTS=$(echo $EFS_POLICY_STATEMENTS | jq '. | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') if [[ $EFS_POLICY_BAD_STATEMENTS != "" ]]; then - textFail "$region: EFS: $efsId has policy which allows access to everyone" "$region" "$efsId" + textFail "$regx: EFS $efsId has policy which allows access to everyone" "$regx" "$efsId" else - textPass "$region: EFS: $efsId has policy which does not allow access to everyone" "$region" "$efsId" + textPass "$regx: EFS $efsId has policy which does not allow access to everyone" "$regx" "$efsId" fi fi done else - textInfo "$region: No EFS found" "$region" + textInfo "$regx: No EFS found" "$regx" fi done } diff --git a/checks/check_extra7144 b/checks/check_extra7144 index 7f8192e9..5fc9a270 100644 --- a/checks/check_extra7144 +++ b/checks/check_extra7144 @@ -11,7 +11,7 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7144="7.144" -CHECK_TITLE_extra7144="[extra7144] Check if aws cloudwatch has allowed sharing with other accounts (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7144="[extra7144] Check if CloudWatch has allowed cross-account sharing" CHECK_SCORED_extra7144="NOT_SCORED" CHECK_TYPE_extra7144="EXTRA" CHECK_SEVERITY_extra7144="Medium" @@ -21,15 +21,15 @@ CHECK_SERVICENAME_extra7144="cloudwatch" CHECK_RISK_extra7144='' CHECK_REMEDIATION_extra7144='' CHECK_DOC_extra7144='https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Cross-Account-Cross-Region.html' -CHECK_CAF_EPIC_extra7144='' +CHECK_CAF_EPIC_extra7144='Logging and Monitoring' extra7144(){ # "Check if aws cloudwatch has allowed sharing with other accounts (Not Scored) (Not part of CIS benchmark)" CLOUDWATCH_CROSS_ACCOUNT_ROLE=$($AWSCLI iam get-role $PROFILE_OPT --role-name=CloudWatch-CrossAccountSharingRole --output json --query Role 2>&1) if [[ $CLOUDWATCH_CROSS_ACCOUNT_ROLE != *NoSuchEntity* ]]; then CLOUDWATCH_POLICY_BAD_STATEMENTS=$(echo $CLOUDWATCH_CROSS_ACCOUNT_ROLE | jq '.AssumeRolePolicyDocument') - textInfo "Cloudwatch has allowed cross account sharing" + textInfo "$REGION: CloudWatch has allowed cross-account sharing" "$REGION" else - textPass "CloudWatch doesn't allows cross account sharing" + textPass "$REGION: CloudWatch doesn't allows cross-account sharing" "$REGION" fi } diff --git a/checks/check_extra7145 b/checks/check_extra7145 index d608d8c4..fa74b27b 100644 --- a/checks/check_extra7145 +++ b/checks/check_extra7145 @@ -11,39 +11,39 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7145="7.145" -CHECK_TITLE_extra7145="[extra7145] Check if lambda functions have policies which allow access to every aws account (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7145="[extra7145] Check if Lambda functions have policies which allow access to any AWS account" CHECK_SCORED_extra7145="NOT_SCORED" CHECK_TYPE_extra7145="EXTRA" CHECK_SEVERITY_extra7145="Critical" CHECK_ASFF_RESOURCE_TYPE_extra7145="AwsLambda" CHECK_ALTERNATE_check7145="extra7145" CHECK_SERVICENAME_extra7145="lambda" -CHECK_RISK_extra7145='Lambda function access to any aws account may result security issues' -CHECK_REMEDIATION_extra7145='Ensure lambda function policiy does not allow access to any account' +CHECK_RISK_extra7145='Lambda function access to any AWS account may result security issues' +CHECK_REMEDIATION_extra7145='Ensure Lambda function policiy does not allow access to any account' CHECK_DOC_extra7145='https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html' -CHECK_CAF_EPIC_extra7145='' +CHECK_CAF_EPIC_extra7145='IAM' extra7145(){ # "Check if lambda functions have policies which allow access to every aws account (Not Scored) (Not part of CIS benchmark)" - for region in $REGIONS; do - LIST_OF_LAMBDA_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $region --query Functions[*].FunctionName --output text) + for regx in $REGIONS; do + LIST_OF_LAMBDA_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text) if [[ $LIST_OF_LAMBDA_FUNCTIONS ]]; then for lambdaFunction in $LIST_OF_LAMBDA_FUNCTIONS;do - FUNCTION_POLICY_STATEMENTS=$($AWSCLI lambda $PROFILE_OPT get-policy --region $region --function-name $lambdaFunction --output json --query Policy 2>&1) + FUNCTION_POLICY_STATEMENTS=$($AWSCLI lambda $PROFILE_OPT get-policy --region $regx --function-name $lambdaFunction --output json --query Policy 2>&1) if [[ $FUNCTION_POLICY_STATEMENTS == *ResourceNotFoundException* ]]; then - textInfo "$region : Lambda function: $lambdaFunction doesn't have any policy" "$region" "$lambdaFunction" + textInfo "$regx: Lambda function $lambdaFunction doesn't have any policy" "$regx" "$lambdaFunction" else FUNCTION_POLICY_BAD_STATEMENTS=$(echo $FUNCTION_POLICY_STATEMENTS | jq '. | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') if [[ $FUNCTION_POLICY_BAD_STATEMENTS != "" ]]; then - textFail "$region: Lambda function: $lambdaFunction allows public access to every aws account" "$region" "$lambdaFunction" + textFail "$regx: Lambda function $lambdaFunction allows public access to any AWS account" "$regx" "$lambdaFunction" else - textPass "$region: Lambda function: $lambdaFunction has policy which doesn't allow access to everyone having an aws account" "$region" "$lambdaFunction" + textPass "$regx: Lambda function $lambdaFunction has policy which doesn't allow access to everyone having an AWS account" "$regx" "$lambdaFunction" fi fi done else - textInfo "$region: No lambda functions found" "$region" + textInfo "$regx: No lambda functions found" "$regx" fi done } diff --git a/checks/check_extra7146 b/checks/check_extra7146 index 980b9fa4..92ffb813 100644 --- a/checks/check_extra7146 +++ b/checks/check_extra7146 @@ -11,33 +11,33 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. CHECK_ID_extra7146="7.146" -CHECK_TITLE_extra7146="[extra7146] Check if there is any unassigned elastic ip's (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7146="[extra7146] Check if there is any unassigned Elastic IP" CHECK_SCORED_extra7146="NOT_SCORED" CHECK_TYPE_extra7146="EXTRA" -CHECK_SEVERITY_extra7146="Medium" +CHECK_SEVERITY_extra7146="Low" CHECK_ASFF_RESOURCE_TYPE_extra7146="AwsElasticIPs" CHECK_ALTERNATE_check7146="extra7146" -CHECK_SERVICENAME_extra7146="elasticip" -CHECK_RISK_extra7146='Unassigned elastic ips may result in extra cost' -CHECK_REMEDIATION_extra7146='Ensure elastic ips are not unassigned' +CHECK_SERVICENAME_extra7146="ec2" +CHECK_RISK_extra7146='Unassigned Elastic IPs may result in extra cost' +CHECK_REMEDIATION_extra7146='Ensure Elastic IPs are not unassigned' CHECK_DOC_extra7146='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html' -CHECK_CAF_EPIC_extra7146='' +CHECK_CAF_EPIC_extra7146='Infrastructure Security' extra7146(){ # "Check if there is any unassigned elastic ip (Not Scored) (Not part of CIS benchmark)" - for region in $REGIONS; do - ELASTIC_IP_ADDRESSES=$($AWSCLI ec2 describe-addresses $PROFILE_OPT --region $region --query Addresses --output json) - if [[ $ELASTIC_IP_ADDRESSES != [] ]]; then - LIST_OF_ASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId!=null) | .PublicIp') - LIST_OF_UNASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId==null) | .PublicIp') - for ass_ip in $LIST_OF_ASSOCIATED_IPS; do - textPass "$region: Elastic IP: $ass_ip is associated with an instance or network interface" "$region" "$ass_ip" - done - for unass_ip in $LIST_OF_UNASSOCIATED_IPS; do - textInfo "$region: Elastic IP: $unass_ip is not associated with any instance or network interface, it may incurr extra cost" "$region" "$unass_ip" - done - else - textInfo "$region: No elastic ip's found" "$region" - fi - done + for regx in $REGIONS; do + ELASTIC_IP_ADDRESSES=$($AWSCLI ec2 describe-addresses $PROFILE_OPT --region $regx --query Addresses --output json) + if [[ $ELASTIC_IP_ADDRESSES != [] ]]; then + LIST_OF_ASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId!=null) | .PublicIp') + LIST_OF_UNASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId==null) | .PublicIp') + for ass_ip in $LIST_OF_ASSOCIATED_IPS; do + textPass "$regx: Elastic IP $ass_ip is associated with an instance or network interface" "$regx" "$ass_ip" + done + for unass_ip in $LIST_OF_UNASSOCIATED_IPS; do + textInfo "$regx: Elastic IP $unass_ip is not associated with any instance or network interface and it may incurr extra cost" "$regx" "$unass_ip" + done + else + textInfo "$regx: No Elastic IPs found" "$regx" + fi + done } diff --git a/checks/check_extra7147 b/checks/check_extra7147 new file mode 100644 index 00000000..cff62c59 --- /dev/null +++ b/checks/check_extra7147 @@ -0,0 +1,47 @@ +#!/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_extra7147="7.147" +CHECK_TITLE_extra7147="[extra7147] Check if S3 Glacier vaults have policies which allow access to everyone" +CHECK_SCORED_extra7147="NOT_SCORED" +CHECK_TYPE_extra7147="EXTRA" +CHECK_SEVERITY_extra7147="Critical" +CHECK_ASFF_RESOURCE_TYPE_extra7147="AwsGlacierVault" +CHECK_ALTERNATE_check7147="extra7142" +CHECK_SERVICENAME_extra7147="glacier" +CHECK_RISK_extra7147='Vaults accessible to everyone could expose sensible data to bad actors' +CHECK_REMEDIATION_extra7147='Ensure vault policy does not have principle as *' +CHECK_DOC_extra7147='https://docs.aws.amazon.com/amazonglacier/latest/dev/access-control-overview.html' +CHECK_CAF_EPIC_extra7147='Data Protection' + +extra7147(){ + for regx in $REGIONS; do + LIST_OF_VAULTS=$($AWSCLI glacier list-vaults $PROFILE_OPT --region $regx --account-id $ACCOUNT_NUM --query VaultList[*].VaultName --output text|xargs -n1) + if [[ $LIST_OF_VAULTS ]]; then + for vault in $LIST_OF_VAULTS;do + VAULT_POLICY_STATEMENTS=$($AWSCLI glacier $PROFILE_OPT get-vault-access-policy --region $regx --account-id $ACCOUNT_NUM --vault-name $vault --output json --query policy.Policy 2>&1) + if [[ $VAULT_POLICY_STATEMENTS == *GetVaultAccessPolicy* ]]; then + textInfo "$regx: Vault $vault doesn't have any policy" "$regx" "$vault" + else + VAULT_POLICY_BAD_STATEMENTS=$(echo $VAULT_POLICY_STATEMENTS | jq '. | fromjson' | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') + if [[ $VAULT_POLICY_BAD_STATEMENTS != "" ]]; then + textFail "$regx: Vault $vault has policy which allows access to everyone" "$regx" "$vault" + else + textPass "$regx: Vault $vault has policy which does not allow access to everyone" "$regx" "$vault" + fi + fi + done + else + textInfo "$regx: No Glacier vaults found" "$regx" + fi + done +} \ No newline at end of file diff --git a/groups/group7_extras b/groups/group7_extras index 0276affc..9cc03fa8 100644 --- a/groups/group7_extras +++ b/groups/group7_extras @@ -15,11 +15,11 @@ GROUP_ID[7]='extras' GROUP_NUMBER[7]='7.0' GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called -GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra756,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142,extra7143,extra7144,extra7145,extra7146' +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142,extra7143,extra7144,extra7145,extra7146,extra7147' # Extras 759 and 760 (lambda variables and code secrets finder are not included) # to run detect-secrets use `./prowler -g secrets` # Extras 789 and 790 VPC trust boundaries are not included by default in Extras # to run trust-boundaries use `./prowler -g trustboundaries` -# read more in https://github.com/toniblyx/prowler/#trust-boundaries-checks \ No newline at end of file +# read more in https://github.com/toniblyx/prowler/#trust-boundaries-checks From 9c3ab79510f314170ed3634535572955a860e707 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 18:45:39 +0200 Subject: [PATCH 78/82] Removed Scored from title --- checks/check19 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check19 b/checks/check19 index 27a61f9d..e8b92818 100644 --- a/checks/check19 +++ b/checks/check19 @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. CHECK_ID_check19="1.9" -CHECK_TITLE_check19="[check19] Ensure IAM password policy requires minimum length of 14 or greater (Scored)" +CHECK_TITLE_check19="[check19] Ensure IAM password policy requires minimum length of 14 or greater" CHECK_SCORED_check19="SCORED" CHECK_TYPE_check19="LEVEL1" CHECK_SEVERITY_check19="Medium" From 3297fba2098298135857474e96e92240b5e7b9e2 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Tue, 10 Aug 2021 23:11:50 +0200 Subject: [PATCH 79/82] Added new checks to extras --- groups/group7_extras | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 groups/group7_extras diff --git a/groups/group7_extras b/groups/group7_extras new file mode 100644 index 00000000..5c2b7010 --- /dev/null +++ b/groups/group7_extras @@ -0,0 +1,27 @@ +#!/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. + +GROUP_ID[7]='extras' +GROUP_NUMBER[7]='7.0' +GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************' +GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called +GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142,extra7143,extra7144,extra7145,extra7146,extra7147' + +# Extras 759 and 760 (lambda variables and code secrets finder are not included) +# to run detect-secrets use `./prowler -g secrets` + +# Extras 789 and 790 VPC trust boundaries are not included by default in Extras +# to run trust-boundaries use `./prowler -g trustboundaries` +# read more in https://github.com/toniblyx/prowler/#trust-boundaries-checks + + From 63233c9333288e9fd06e10c2eaf48911c1cf501e Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 12 Aug 2021 10:37:36 +0200 Subject: [PATCH 80/82] Changed check textTitle format for default output --- include/outputs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/outputs b/include/outputs index e1971d0a..830404d2 100644 --- a/include/outputs +++ b/include/outputs @@ -227,7 +227,7 @@ textFail(){ textTitle(){ CHECKS_COUNTER=$((CHECKS_COUNTER+1)) - TITLE_ID="$BLUE$1$NORMAL" + TITLE_ID="$1" if [[ $NUMERAL ]]; then # Left-pad the check ID with zeros to simplify sorting, e.g. 1.1 -> 1.01 TITLE_ID=$(awk -F'.' '{ printf "%d.%02d", $1, $2 }' <<< "$TITLE_ID") @@ -269,7 +269,7 @@ textTitle(){ # else # # if [[ "$ITEM_SCORED" == "Scored" ]]; then # echo -e "$TITLE_ID $CHECK_SERVICENAME $TITLE_TEXT $CHECK_SEVERITY $group_ids " - echo -e "$TITLE_ID $TITLE_TEXT $CHECK_SERVICENAME $CHECK_SEVERITY" + echo -e "$TITLE_ID $TITLE_TEXT - $CHECK_SERVICENAME $CHECK_SEVERITY" # # else # # echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $6 $NORMAL $group_ids " # # fi @@ -429,4 +429,4 @@ generateHtmlOutput(){ echo ' '$CHECK_RESOURCE_ID'' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML -} \ No newline at end of file +} From e39ff9683ced09b1ac33f3db204d8cba810dc21b Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 12 Aug 2021 10:38:59 +0200 Subject: [PATCH 81/82] Set new version 2.5.0-12August2021 --- prowler | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prowler b/prowler index 6b3f2798..879f73b9 100755 --- a/prowler +++ b/prowler @@ -32,7 +32,7 @@ OPTRED="" OPTNORMAL="" # Set the defaults variables -PROWLER_VERSION=2.5.0-05July2021 +PROWLER_VERSION=2.5.0-12August2021 PROWLER_DIR=$(dirname "$0") REGION="" From e0f60114f4465205cf782aea108c521d84a7f78d Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Fri, 13 Aug 2021 10:05:56 +0200 Subject: [PATCH 82/82] Consolidated license file --- LICENSE | 6 +----- LICENSE-APACHE-2.0 | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/LICENSE b/LICENSE index f764ae67..b9b7f40f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,2 @@ -All CIS based checks in the checks folder are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License. -The link to the license terms can be found at -https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode - -Any other piece of code is licensed as Apache License 2.0 as specified in each file. You may obtain a copy of the License at +Apache License 2.0 as specified in each file. You may obtain a copy of the License at LICENSE-APACHE-2.0 and http://www.apache.org/licenses/LICENSE-2.0 diff --git a/LICENSE-APACHE-2.0 b/LICENSE-APACHE-2.0 index cd482d89..46de5eb1 100644 --- a/LICENSE-APACHE-2.0 +++ b/LICENSE-APACHE-2.0 @@ -186,7 +186,7 @@ file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright [yyyy] [name of copyright owner] +Copyright 2021 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.