mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
rename(provider): keep old version
This commit is contained in:
@@ -1,50 +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_extra769="7.69"
|
||||
CHECK_TITLE_extra769="[extra769] Check if IAM Access Analyzer is enabled and its findings "
|
||||
CHECK_SCORED_extra769="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra769="EXTRA"
|
||||
CHECK_SEVERITY_extra769="High"
|
||||
CHECK_ALTERNATE_check769="extra769"
|
||||
CHECK_SERVICENAME_extra769="accessanalyzer"
|
||||
CHECK_RISK_extra769='AWS IAM Access Analyzer helps you identify the resources in your organization and accounts; such as Amazon S3 buckets or IAM roles; that are shared with an external entity. This lets you identify unintended access to your resources and data; which is a security risk. IAM Access Analyzer uses a form of mathematical analysis called automated reasoning; which applies logic and mathematical inference to determine all possible access paths allowed by a resource policy.'
|
||||
CHECK_REMEDIATION_extra769='Enable IAM Access Analyzer for all accounts; create analyzer and take action over it is recommendations (IAM Access Analyzer is available at no additional cost).'
|
||||
CHECK_DOC_extra769='https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html'
|
||||
CHECK_CAF_EPIC_extra769='IAM'
|
||||
|
||||
extra769(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ACCESS_ANALYZERS=$($AWSCLI accessanalyzer list-analyzers $PROFILE_OPT --region $regx --query analyzers[*].arn --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_ACCESS_ANALYZERS" | grep -i "argument command: Invalid choice") ]]; then
|
||||
textInfo "$regx: list-analyzers not supported: newer awscli needed" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $(echo "$LIST_OF_ACCESS_ANALYZERS" | grep -i "AccessDeniedException") ]]; then
|
||||
textInfo "$regx: Access Denied trying to list-analyzers" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ACCESS_ANALYZERS ]]; then
|
||||
for accessAnalyzerArn in $LIST_OF_ACCESS_ANALYZERS;do
|
||||
ANALYZER_ACTIVE_FINDINGS_COUNT=$($AWSCLI accessanalyzer list-findings $PROFILE_OPT --region $regx --analyzer-arn $accessAnalyzerArn --query 'findings[?status == `ACTIVE`].[id,status]' --output text | wc -l | tr -d ' ')
|
||||
if [[ $ANALYZER_ACTIVE_FINDINGS_COUNT -eq 0 ]];then
|
||||
textPass "$regx: IAM Access Analyzer $accessAnalyzerArn has no active findings" "$regx" "$accessAnalyzerArn"
|
||||
else
|
||||
textInfo "$regx: IAM Access Analyzer $accessAnalyzerArn has $ANALYZER_ACTIVE_FINDINGS_COUNT active findings" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No IAM Access Analyzers found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,50 +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_extra724="7.24"
|
||||
CHECK_TITLE_extra724="[extra724] Check if ACM certificates have Certificate Transparency logging enabled"
|
||||
CHECK_SCORED_extra724="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra724="EXTRA"
|
||||
CHECK_SEVERITY_extra724="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra724="AwsCertificateManagerCertificate"
|
||||
CHECK_ALTERNATE_check724="extra724"
|
||||
CHECK_SERVICENAME_extra724="acm"
|
||||
CHECK_RISK_extra724='Domain owners can search the log to identify unexpected certificates; whether issued by mistake or malice. Domain owners can also identify Certificate Authorities (CAs) that are improperly issuing certificates.'
|
||||
CHECK_REMEDIATION_extra724='Make sure you are logging information about Lambda operations. Create a lifecycle and use cases for each trail.'
|
||||
CHECK_DOC_extra724='https://aws.amazon.com/blogs/security/how-to-get-ready-for-certificate-transparency/'
|
||||
CHECK_CAF_EPIC_extra724='Logging and Monitoring'
|
||||
|
||||
extra724(){
|
||||
# "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
|
||||
for cert_arn in $LIST_OF_CERTS;do
|
||||
CT_ENABLED=$($AWSCLI acm describe-certificate $PROFILE_OPT --region $regx --certificate-arn $cert_arn --query Certificate.Options.CertificateTransparencyLoggingPreference --output text)
|
||||
CERT_DOMAIN_NAME=$(aws acm describe-certificate $PROFILE_OPT --region $regx --certificate-arn $cert_arn --query Certificate.DomainName --output text)
|
||||
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" "$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"
|
||||
else
|
||||
textFail "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging disabled!" "$regx" "$CERT_DOMAIN_NAME"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No ACM Certificates found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,60 +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.
|
||||
|
||||
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"
|
||||
CHECK_SCORED_extra730="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra730="EXTRA"
|
||||
CHECK_SEVERITY_extra730="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra730="AwsCertificateManagerCertificate"
|
||||
CHECK_ALTERNATE_check730="extra730"
|
||||
CHECK_SERVICENAME_extra730="acm"
|
||||
CHECK_RISK_extra730='Expired certificates can impact service availability.'
|
||||
CHECK_REMEDIATION_extra730='Monitor certificate expiration and take automated action to renew; replace or remove. Having shorter TTL for any security artifact is a general recommendation; but requires additional automation in place. If not longer required delete certificate. Use AWS config using the managed rule: acm-certificate-expiration-check.'
|
||||
CHECK_DOC_extra730='https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html'
|
||||
CHECK_CAF_EPIC_extra730='Data Protection'
|
||||
|
||||
extra730(){
|
||||
# Only RSA key types, needed to recover Amazon Issued, Imported and Private PKIs
|
||||
local ACM_KEY_TYPES="RSA_1024,RSA_2048,RSA_3072,RSA_4096"
|
||||
local ACM_CERTIFICATE_STATUSES="ISSUED"
|
||||
|
||||
# "Check if ACM Certificates are about to expire in $DAYS_TO_EXPIRE_THRESHOLD days or less"
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ACM_CERTS=$("${AWSCLI}" acm list-certificates ${PROFILE_OPT} --region "${regx}" --include keyTypes="${ACM_KEY_TYPES}" --certificate-statuses "${ACM_CERTIFICATE_STATUSES}" --query 'CertificateSummaryList[].CertificateArn' --output text)
|
||||
if [[ $LIST_OF_ACM_CERTS ]]; then
|
||||
for cert in $LIST_OF_ACM_CERTS; do
|
||||
CERT_DATA=$("${AWSCLI}" acm describe-certificate ${PROFILE_OPT} --region "${regx}" --certificate-arn "${cert}" --query 'Certificate.[DomainName,NotAfter]' --output text)
|
||||
# Format: domain.test.com YYYY-MM-DDTHH:MM:SS
|
||||
echo "$CERT_DATA" | while read -r FQDN NOTAFTER; do
|
||||
EXPIRES_DATE=$(timestamp_to_date "${NOTAFTER}")
|
||||
if [[ "${EXPIRES_DATE}" == "" ]]
|
||||
then
|
||||
textInfo "${regx}: Certificate for ${FQDN} has an incorrect timestamp format: ${NOTAFTER}" "${regx}" "${FQDN}"
|
||||
else
|
||||
COUNTER_DAYS=$(how_many_days_from_today "${EXPIRES_DATE}")
|
||||
if [[ $COUNTER_DAYS -le $DAYS_TO_EXPIRE_THRESHOLD ]]; then
|
||||
textFail "${regx}: Certificate for ${FQDN} is about to expire in ${COUNTER_DAYS} days!" "${regx}" "${FQDN}"
|
||||
else
|
||||
textPass "${regx}: Certificate for ${FQDN} expires in ${COUNTER_DAYS} days" "${regx}" "{$FQDN}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
else
|
||||
textInfo "${regx}: No certificates found" "${regx}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,57 +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_extra7156="7.156"
|
||||
CHECK_TITLE_extra7156="[extra7156] Checks if API Gateway V2 has Access Logging enabled"
|
||||
CHECK_SCORED_extra7156="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7156="EXTRA"
|
||||
CHECK_SEVERITY_extra7156="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7156="AwsApiGatewayV2Api"
|
||||
CHECK_ALTERNATE_check7156="extra7156"
|
||||
CHECK_SERVICENAME_extra7156="apigateway"
|
||||
CHECK_RISK_extra7156="If not enabled the logging of API calls is not possible. This information is important for monitoring API access."
|
||||
CHECK_REMEDIATION_extra7156="Enable Access Logging in the API stage."
|
||||
CHECK_DOC_extra7156="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-stage-accesslogsettings.html"
|
||||
CHECK_CAF_EPIC_extra7156="Logging and Monitoring"
|
||||
|
||||
extra7156(){
|
||||
|
||||
# "Check if API Gateway V2 has Access Logging enabled "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_API_GW=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query Items[*].ApiId --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_API_GW" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to get APIs" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_API_GW ]];then
|
||||
for apigwid in $LIST_OF_API_GW;do
|
||||
API_GW_NAME=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query "Items[?ApiId==\`$apigwid\`].Name" --output text)
|
||||
CHECK_STAGES_NAME=$($AWSCLI apigatewayv2 get-stages $PROFILE_OPT --region $regx --api-id $apigwid --query "Items[*].StageName" --output text)
|
||||
if [[ $CHECK_STAGES_NAME ]];then
|
||||
for stagename in $CHECK_STAGES_NAME;do
|
||||
CHECK_STAGE_METHOD_LOGGING=$($AWSCLI apigatewayv2 get-stages $PROFILE_OPT --region $regx --api-id $apigwid --query "Items[?StageName == \`$stagename\` ].AccessLogSettings.DestinationArn" --output text)
|
||||
if [[ $CHECK_STAGE_METHOD_LOGGING ]];then
|
||||
textPass "$regx: API Gateway V2 $API_GW_NAME ID: $apigwid with stage: $stagename has access logging enabled to $CHECK_STAGE_METHOD_LOGGING" "$regx" "$API_GW_NAME"
|
||||
else
|
||||
textFail "$regx: API Gateway V2 $API_GW_NAME ID: $apigwid with stage: $stagename has access logging disabled" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textFail "$regx: No Stage name found for $API_GW_NAME" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No API Gateway found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_extra7157="7.157"
|
||||
CHECK_TITLE_extra7157="[extra7157] Check if API Gateway V2 has configured authorizers"
|
||||
CHECK_SCORED_extra7157="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7157="EXTRA"
|
||||
CHECK_SEVERITY_extra7157="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7157="AwsApiGatewayV2Api"
|
||||
CHECK_ALTERNATE_check746="extra7157"
|
||||
CHECK_SERVICENAME_extra7157="apigateway"
|
||||
CHECK_RISK_extra7157='If no authorizer is enabled anyone can use the service.'
|
||||
CHECK_REMEDIATION_extra7157='Implement JWT or Lambda Function to control access to your API.'
|
||||
CHECK_DOC_extra7157='https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers.html'
|
||||
CHECK_CAF_EPIC_extra7157='IAM'
|
||||
|
||||
extra7157(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_API_GW=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query "Items[*].ApiId" --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_API_GW" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to get APIs" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_API_GW ]];then
|
||||
for api in $LIST_OF_API_GW; do
|
||||
API_GW_NAME=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query "Items[?ApiId==\`$api\`].Name" --output text)
|
||||
AUTHORIZER_CONFIGURED=$($AWSCLI apigatewayv2 --region $regx get-authorizers --api-id $api --query "Items[*].AuthorizerType" --output text)
|
||||
if [[ $AUTHORIZER_CONFIGURED ]]; then
|
||||
textPass "$regx: API Gateway V2 $API_GW_NAME ID $api has authorizer configured" "$regx" "$API_GW_NAME"
|
||||
else
|
||||
textFail "$regx: API Gateway V2 $API_GW_NAME ID $api has no authorizer configured" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No API Gateways found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,55 +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_extra722="7.22"
|
||||
CHECK_TITLE_extra722="[extra722] Check if API Gateway has logging enabled"
|
||||
CHECK_SCORED_extra722="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra722="EXTRA"
|
||||
CHECK_SEVERITY_extra722="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra722="AwsApiGatewayRestApi"
|
||||
CHECK_ALTERNATE_check722="extra722"
|
||||
CHECK_SERVICENAME_extra722="apigateway"
|
||||
CHECK_RISK_extra722='If not enabled; monitoring of service use is not possible. Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms.'
|
||||
CHECK_REMEDIATION_extra722='Monitoring is an important part of maintaining the reliability; availability; and performance of API Gateway and your AWS solutions. You should collect monitoring data from all of the parts of your AWS solution. CloudTrail provides a record of actions taken by a user; role; or an AWS service in API Gateway. Using the information collected by CloudTrail; you can determine the request that was made to API Gateway; the IP address from which the request was made; who made the request; etc.'
|
||||
CHECK_DOC_extra722='https://docs.aws.amazon.com/apigateway/latest/developerguide/security-monitoring.html'
|
||||
CHECK_CAF_EPIC_extra722='Logging and Monitoring'
|
||||
|
||||
extra722(){
|
||||
# "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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_API_GW" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to get rest APIs" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_API_GW ]];then
|
||||
for apigwid in $LIST_OF_API_GW;do
|
||||
API_GW_NAME=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query "items[?id==\`$apigwid\`].name" --output text)
|
||||
CHECK_STAGES_NAME=$($AWSCLI apigateway get-stages $PROFILE_OPT --region $regx --rest-api-id $apigwid --query "item[*].stageName" --output text)
|
||||
if [[ $CHECK_STAGES_NAME ]];then
|
||||
for stagname in $CHECK_STAGES_NAME;do
|
||||
CHECK_STAGE_METHOD_LOGGING=$($AWSCLI apigateway get-stages $PROFILE_OPT --region $regx --rest-api-id $apigwid --query "item[?stageName == \`$stagname\` ].methodSettings" --output text |awk '{ print $6 }' |egrep 'ERROR|INFO')
|
||||
if [[ $CHECK_STAGE_METHOD_LOGGING ]];then
|
||||
textPass "$regx: API Gateway $API_GW_NAME ID $apigwid in $stagname has logging enabled as $CHECK_STAGE_METHOD_LOGGING" "$regx" "$API_GW_NAME"
|
||||
else
|
||||
textFail "$regx: API Gateway $API_GW_NAME ID $apigwid in $stagname has logging disabled" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textFail "$regx: No Stage name found for $API_GW_NAME" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No API Gateway found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,52 +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_extra743="7.43"
|
||||
CHECK_TITLE_extra743="[extra743] Check if API Gateway has client certificate enabled to access your backend endpoint"
|
||||
CHECK_SCORED_extra743="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra743="EXTRA"
|
||||
CHECK_SEVERITY_extra743="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra743="AwsApiGatewayRestApi"
|
||||
CHECK_ALTERNATE_check743="extra743"
|
||||
CHECK_SERVICENAME_extra743="apigateway"
|
||||
CHECK_RISK_extra743='Possible man in the middle attacks and other similar risks.'
|
||||
CHECK_REMEDIATION_extra743='Enable client certificate. Mutual TLS is recommended and commonly used for business-to-business (B2B) applications. It’s used in standards such as Open Banking. API Gateway now provides integrated mutual TLS authentication at no additional cost.'
|
||||
CHECK_DOC_extra743='https://aws.amazon.com/blogs/compute/introducing-mutual-tls-authentication-for-amazon-api-gateway/'
|
||||
CHECK_CAF_EPIC_extra743='Data Protection'
|
||||
|
||||
extra743(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_REST_APIS=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-rest-apis --query 'items[*].id' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_REST_APIS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to get rest APIs" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_REST_APIS ]];then
|
||||
for api in $LIST_OF_REST_APIS; do
|
||||
API_GW_NAME=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query "items[?id==\`$api\`].name" --output text)
|
||||
LIST_OF_STAGES=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-stages --rest-api-id $api --query 'item[*].stageName' --output text)
|
||||
if [[ $LIST_OF_STAGES ]]; then
|
||||
for stage in $LIST_OF_STAGES; do
|
||||
CHECK_CERTIFICATE=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-stages --rest-api-id $api --query "item[?stageName==\`$stage\`].clientCertificateId" --output text)
|
||||
if [[ $CHECK_CERTIFICATE ]]; then
|
||||
textPass "$regx: API Gateway $API_GW_NAME ID $api in $stage has client certificate enabled" "$regx" "$API_GW_NAME"
|
||||
else
|
||||
textFail "$regx: API Gateway $API_GW_NAME ID $api in $stage has not client certificate enabled" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No API Gateways found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,53 +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_extra744="7.44"
|
||||
CHECK_TITLE_extra744="[extra744] Check if API Gateway has a WAF ACL attached"
|
||||
CHECK_SCORED_extra744="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra744="EXTRA"
|
||||
CHECK_SEVERITY_extra744="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra744="AwsApiGatewayRestApi"
|
||||
CHECK_ALTERNATE_check744="extra744"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra744="ens-mp.s.2.aws.waf.2"
|
||||
CHECK_SERVICENAME_extra744="apigateway"
|
||||
CHECK_RISK_extra744='Potential attacks and / or abuse of service; more even for even for internet reachable services.'
|
||||
CHECK_REMEDIATION_extra744='Use AWS WAF to protect your API Gateway API from common web exploits; such as SQL injection and cross-site scripting (XSS) attacks. These could affect API availability and performance; compromise security; or consume excessive resources.'
|
||||
CHECK_DOC_extra744='https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html'
|
||||
CHECK_CAF_EPIC_extra744='Infrastructure Security'
|
||||
|
||||
extra744(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_REST_APIS=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-rest-apis --query 'items[*].id' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_REST_APIS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to get rest APIs" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_REST_APIS ]];then
|
||||
for api in $LIST_OF_REST_APIS; do
|
||||
API_GW_NAME=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query "items[?id==\`$api\`].name" --output text)
|
||||
LIST_OF_STAGES=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-stages --rest-api-id $api --query 'item[*].stageName' --output text)
|
||||
if [[ $LIST_OF_STAGES ]]; then
|
||||
for stage in $LIST_OF_STAGES; do
|
||||
CHECK_WAFACL=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-stages --rest-api-id $api --query "item[?stageName==\`$stage\`].webAclArn" --output text)
|
||||
if [[ $CHECK_WAFACL ]]; then
|
||||
textPass "$regx: API Gateway $API_GW_NAME ID $api in $stage has $CHECK_WAFACL WAF ACL attached" "$regx" "$API_GW_NAME"
|
||||
else
|
||||
textFail "$regx: API Gateway $API_GW_NAME ID $api in $stage has not WAF ACL attached" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No API Gateways found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,54 +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_extra745="7.45"
|
||||
CHECK_TITLE_extra745="[extra745] Check if API Gateway endpoint is public or private"
|
||||
CHECK_SCORED_extra745="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra745="EXTRA"
|
||||
CHECK_SEVERITY_extra745="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra745="AwsApiGatewayRestApi"
|
||||
CHECK_ALTERNATE_check745="extra745"
|
||||
CHECK_SERVICENAME_extra745="apigateway"
|
||||
CHECK_RISK_extra745='If accessible from internet without restrictions opens up attack / abuse surface for any malicious user.'
|
||||
CHECK_REMEDIATION_extra745='Verify that any public Api Gateway is protected and audited. Detective controls for common risks should be implemented.'
|
||||
CHECK_DOC_extra745='https://d1.awsstatic.com/whitepapers/api-gateway-security.pdf?svrd_sip6'
|
||||
CHECK_CAF_EPIC_extra745='Infrastructure Security'
|
||||
|
||||
extra745(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_REST_APIS=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-rest-apis --query 'items[*].id' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_REST_APIS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to get rest APIs" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_REST_APIS ]];then
|
||||
for api in $LIST_OF_REST_APIS; do
|
||||
API_GW_NAME=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query "items[?id==\`$api\`].name" --output text)
|
||||
ENDPOINT_CONFIG_TYPE=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-rest-api --rest-api-id $api --query endpointConfiguration.types --output text)
|
||||
if [[ $ENDPOINT_CONFIG_TYPE ]]; then
|
||||
case $ENDPOINT_CONFIG_TYPE in
|
||||
PRIVATE )
|
||||
textPass "$regx: API Gateway $API_GW_NAME ID $api is set as $ENDPOINT_CONFIG_TYPE" "$regx" "$API_GW_NAME"
|
||||
;;
|
||||
REGIONAL )
|
||||
textFail "$regx: API Gateway $API_GW_NAME ID $api is internet accesible as $ENDPOINT_CONFIG_TYPE" "$regx" "$API_GW_NAME"
|
||||
;;
|
||||
EDGE )
|
||||
textFail "$regx: API Gateway $API_GW_NAME ID $api is internet accesible as $ENDPOINT_CONFIG_TYPE" "$regx" "$API_GW_NAME"
|
||||
esac
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No API Gateways found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_extra746="7.46"
|
||||
CHECK_TITLE_extra746="[extra746] Check if API Gateway has configured authorizers"
|
||||
CHECK_SCORED_extra746="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra746="EXTRA"
|
||||
CHECK_SEVERITY_extra746="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra746="AwsApiGatewayRestApi"
|
||||
CHECK_ALTERNATE_check746="extra746"
|
||||
CHECK_SERVICENAME_extra746="apigateway"
|
||||
CHECK_RISK_extra746='If no authorizer is enabled anyone can use the service.'
|
||||
CHECK_REMEDIATION_extra746='Implement Amazon Cognito or a Lambda function to control access to your API.'
|
||||
CHECK_DOC_extra746='https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html'
|
||||
CHECK_CAF_EPIC_extra746='IAM'
|
||||
|
||||
extra746(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_REST_APIS=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-rest-apis --query 'items[*].id' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_REST_APIS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to get rest APIs" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_REST_APIS ]];then
|
||||
for api in $LIST_OF_REST_APIS; do
|
||||
API_GW_NAME=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query "items[?id==\`$api\`].name" --output text)
|
||||
AUTHORIZER_CONFIGURED=$($AWSCLI $PROFILE_OPT --region $regx apigateway get-authorizers --rest-api-id $api --query items[*].type --output text)
|
||||
if [[ $AUTHORIZER_CONFIGURED ]]; then
|
||||
textPass "$regx: API Gateway $API_GW_NAME ID $api has authorizer configured" "$regx" "$API_GW_NAME"
|
||||
else
|
||||
textFail "$regx: API Gateway $API_GW_NAME ID $api has not authorizer configured" "$regx" "$API_GW_NAME"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No API Gateways found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,82 +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_extra775="7.75"
|
||||
CHECK_TITLE_extra775="[extra775] Find secrets in EC2 Auto Scaling Launch Configuration "
|
||||
CHECK_SCORED_extra775="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra775="EXTRA"
|
||||
CHECK_SEVERITY_extra775="Critical"
|
||||
CHECK_ALTERNATE_check775="extra775"
|
||||
CHECK_SERVICENAME_extra775="autoscaling"
|
||||
CHECK_RISK_extra775='The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used; it is possible that malicious users gain access through the account in question.'
|
||||
CHECK_REMEDIATION_extra775='Use Secrets Manager to securely provide database credentials to Lambda functions and secure the databases as well as use the credentials to connect and query them without hardcoding the secrets in code or passing them through environmental variables. '
|
||||
CHECK_DOC_extra775='https://docs.aws.amazon.com/secretsmanager/latest/userguide/lambda-functions.html'
|
||||
CHECK_CAF_EPIC_extra775='IAM'
|
||||
|
||||
extra775(){
|
||||
SECRETS_TEMP_FOLDER="$PROWLER_DIR/secrets-$ACCOUNT_NUM-$PROWLER_START_TIME"
|
||||
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
|
||||
CHECK_DETECT_SECRETS_INSTALLATION=$(secretsDetector)
|
||||
if [[ $? -eq 241 ]]; then
|
||||
textInfo "$regx: python library detect-secrets not found. Make sure it is installed correctly." "$regx"
|
||||
else
|
||||
LIST_OF_EC2_AUTOSCALING=$($AWSCLI autoscaling describe-launch-configurations $PROFILE_OPT --region $regx --query LaunchConfigurations[*].LaunchConfigurationName --output text --max-items $MAXITEMS 2>&1 | grep -v None )
|
||||
if [[ $(echo "$LIST_OF_EC2_AUTOSCALING" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe launch configurations" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_EC2_AUTOSCALING ]];then
|
||||
for autoscaling_configuration in $LIST_OF_EC2_AUTOSCALING; do
|
||||
EC2_AUTOSCALING_USERDATA_FILE="$SECRETS_TEMP_FOLDER/extra775-$autoscaling_configuration-userData.decoded"
|
||||
EC2_AUTOSCALING_USERDATA=$($AWSCLI autoscaling describe-launch-configurations $PROFILE_OPT --launch-configuration-names $autoscaling_configuration --region $regx --query LaunchConfigurations[*].UserData --output text| grep -v ^None | decode_report > $EC2_AUTOSCALING_USERDATA_FILE)
|
||||
if [ -s $EC2_AUTOSCALING_USERDATA_FILE ];then
|
||||
FILE_FORMAT_ASCII=$(file -b $EC2_AUTOSCALING_USERDATA_FILE | grep ASCII)
|
||||
# This finds ftp or http URLs with credentials and common keywords
|
||||
# FINDINGS=$(egrep -i '[[:alpha:]]*://[[:alnum:]]*:[[:alnum:]]*@.*/|key|secret|token|pass' $EC2_AUTOSCALING_USERDATA_FILE |wc -l|tr -d '\ ')
|
||||
# New implementation using https://github.com/Yelp/detect-secrets
|
||||
if [[ $FILE_FORMAT_ASCII ]]; then
|
||||
FINDINGS=$(secretsDetector file $EC2_AUTOSCALING_USERDATA_FILE)
|
||||
if [[ $FINDINGS -eq 0 ]]; then
|
||||
textPass "$regx: No secrets found in $autoscaling_configuration" "$regx" "$autoscaling_configuration"
|
||||
# delete file if nothing interesting is there
|
||||
rm -f $EC2_AUTOSCALING_USERDATA_FILE
|
||||
else
|
||||
textFail "$regx: Potential secret found in $autoscaling_configuration" "$regx" "$autoscaling_configuration"
|
||||
# delete file to not leave trace, user must look at the autoscaling_configuration User Data
|
||||
rm -f $EC2_AUTOSCALING_USERDATA_FILE
|
||||
fi
|
||||
else
|
||||
mv $EC2_AUTOSCALING_USERDATA_FILE $EC2_AUTOSCALING_USERDATA_FILE.gz ; gunzip $EC2_AUTOSCALING_USERDATA_FILE.gz
|
||||
FINDINGS=$(secretsDetector file $EC2_AUTOSCALING_USERDATA_FILE)
|
||||
if [[ $FINDINGS -eq 0 ]]; then
|
||||
textPass "$regx: No secrets found in $autoscaling_configuration User Data" "$regx" "$autoscaling_configuration"
|
||||
rm -f $EC2_AUTOSCALING_USERDATA_FILE
|
||||
else
|
||||
textFail "$regx: Potential secret found in $autoscaling_configuration" "$regx" "$autoscaling_configuration"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
textPass "$regx: No secrets found in $autoscaling_configuration User Data or it is empty" "$regx" "$autoscaling_configuration"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EC2 autoscaling_configurations found" "$regx"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
rm -rf $SECRETS_TEMP_FOLDER
|
||||
}
|
||||
@@ -1,60 +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.
|
||||
#
|
||||
# Remediation:
|
||||
#
|
||||
# https://docs.aws.amazon.com/cli/latest/reference/cloudformation/update-termination-protection.html
|
||||
#
|
||||
# aws cloudformation update-termination-protection \
|
||||
# --stack-name my-stack \
|
||||
# --enable-termination-protection
|
||||
|
||||
CHECK_ID_extra7154="7.154"
|
||||
CHECK_TITLE_extra7154="[extra7154] Enable termination protection for Cloudformation Stacks"
|
||||
CHECK_SCORED_extra7154="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7154="EXTRA"
|
||||
CHECK_SEVERITY_extra7154="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7154="AwsCloudFormationStack"
|
||||
CHECK_ALTERNATE_check7154="extra7154"
|
||||
CHECK_SERVICENAME_extra7154="cloudformation"
|
||||
CHECK_RISK_extra7154='Without termination protection enabled; a critical cloudformation stack can be accidently deleted.'
|
||||
CHECK_REMEDIATION_extra7154='Ensure termination protection is enabled for the cloudformation stacks'
|
||||
CHECK_DOC_extra7154='https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-protect-stacks.html'
|
||||
CHECK_CAF_EPIC_extra7154='Infrastructure Protection'
|
||||
|
||||
extra7154() {
|
||||
for regx in $REGIONS; do
|
||||
CFN_STACKS=$($AWSCLI cloudformation describe-stacks $PROFILE_OPT --region $regx --output json 2>&1)
|
||||
if [[ $(echo "$CFN_STACKS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe stacks" "$regx"
|
||||
continue
|
||||
fi
|
||||
LIST_OF_CFN_STACKS=$(echo $CFN_STACKS | jq -r '.Stacks[].StackName')
|
||||
if [[ $LIST_OF_CFN_STACKS ]];then
|
||||
for stack in $LIST_OF_CFN_STACKS; do
|
||||
CFN_STACK_DETAILS=$($AWSCLI cloudformation describe-stacks $PROFILE_OPT --region $regx --stack-name $stack --output json)
|
||||
TERMINATION_ENABLED=$(echo $CFN_STACK_DETAILS | jq -r '.Stacks[].EnableTerminationProtection')
|
||||
ROOT_ID=$(echo $CFN_STACK_DETAILS | jq -r '.Stacks[].RootId')
|
||||
if [[ $ROOT_ID != null && $TERMINATION_ENABLED == "false" ]]; then
|
||||
textInfo "$regx: $stack is a nested stack. Enable termination protection on the root stack $ROOT_ID" "$regx" "$stack" "$ROOT_ID"
|
||||
elif [[ $TERMINATION_ENABLED == "true" ]]; then
|
||||
textPass "$regx: Cloudformation stack $stack has termination protection enabled" "$regx" "$stack"
|
||||
else
|
||||
textFail "$regx: Cloudformation stack $stack has termination protection disabled" "$regx" "$stack"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No Cloudformation stacks found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,75 +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_extra742="7.42"
|
||||
CHECK_TITLE_extra742="[extra742] Find secrets in CloudFormation outputs"
|
||||
CHECK_SCORED_extra742="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra742="EXTRA"
|
||||
CHECK_SEVERITY_extra742="Critical"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra742="AwsCloudFormationStack"
|
||||
CHECK_ALTERNATE_check742="extra742"
|
||||
CHECK_SERVICENAME_extra742="cloudformation"
|
||||
CHECK_RISK_extra742='Secrets hardcoded into CloudFormation outputs can be used by malware and bad actors to gain lateral access to other services.'
|
||||
CHECK_REMEDIATION_extra742='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_extra742='https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-secretsmanager-secret-generatesecretstring.html'
|
||||
CHECK_CAF_EPIC_extra742='IAM'
|
||||
|
||||
extra742(){
|
||||
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
|
||||
CHECK_DETECT_SECRETS_INSTALLATION=$(secretsDetector)
|
||||
if [[ $? -eq 241 ]]; then
|
||||
textInfo "$regx: python library detect-secrets not found. Make sure it is installed correctly." "$regx"
|
||||
else
|
||||
CFN_STACKS=$("${AWSCLI}" cloudformation describe-stacks $PROFILE_OPT --region "${regx}" --output json 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "$CFN_STACKS" ; then
|
||||
textInfo "$regx: Access Denied trying to describe stacks" "$regx"
|
||||
continue
|
||||
fi
|
||||
LIST_OF_CFN_STACKS=$(jq -r '.Stacks[].StackName' <<< "${CFN_STACKS}")
|
||||
if [[ $LIST_OF_CFN_STACKS ]];then
|
||||
for stackName in $LIST_OF_CFN_STACKS; do
|
||||
CFN_OUTPUTS_FILE="$SECRETS_TEMP_FOLDER/extra742-${stackName}-${regx}-outputs.txt"
|
||||
# OutputKey and OutputValue are separated by a colon because secrets-detector needs a way to link both values
|
||||
jq --arg stackName "$stackName" -r '.Stacks[] | select( .StackName == $stackName ) | .Outputs[]? | "\(.OutputKey):\(.OutputValue)"' <<< "${CFN_STACKS}" > "${CFN_OUTPUTS_FILE}"
|
||||
if [ -s "${CFN_OUTPUTS_FILE}" ];then
|
||||
FINDINGS=$(secretsDetector file "${CFN_OUTPUTS_FILE}")
|
||||
if [[ $FINDINGS -eq 0 ]]; then
|
||||
textPass "$regx: No secrets found in stack ${stackName} Outputs" "$regx" "${stackName}"
|
||||
# Delete file if nothing interesting is there
|
||||
rm -f "${CFN_OUTPUTS_FILE}"
|
||||
else
|
||||
textFail "$regx: Potential secret found in stack ${stackName} Outputs" "$regx" "${stackName}"
|
||||
# Delete file to not leave trace, user must look at the CFN Stack
|
||||
rm -f "${CFN_OUTPUTS_FILE}"
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: CloudFormation stack ${stackName} has no Outputs" "$regx"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No CloudFormation stacks found" "$regx"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Cleanup temporary folder
|
||||
if [[ -d $SECRETS_TEMP_FOLDER ]]
|
||||
then
|
||||
rm -rf "${SECRETS_TEMP_FOLDER}"
|
||||
fi
|
||||
}
|
||||
@@ -1,42 +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_extra714="7.14"
|
||||
CHECK_TITLE_extra714="[extra714] Check if CloudFront distributions have logging enabled"
|
||||
CHECK_SCORED_extra714="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra714="EXTRA"
|
||||
CHECK_SEVERITY_extra714="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra714="AwsCloudFrontDistribution"
|
||||
CHECK_ALTERNATE_check714="extra714"
|
||||
CHECK_SERVICENAME_extra714="cloudfront"
|
||||
CHECK_RISK_extra714='If not enabled monitoring of service use is not possible.'
|
||||
CHECK_REMEDIATION_extra714='Real-time monitoring can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms. Enable logging for services with defined log rotation. This logs are useful for Incident Response and forensics investigation among other use cases.'
|
||||
CHECK_DOC_extra714='https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html'
|
||||
CHECK_CAF_EPIC_extra714='Logging and Monitoring'
|
||||
|
||||
extra714(){
|
||||
# "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' --output text | grep True)
|
||||
LOG_ENABLED_REALTIME=$($AWSCLI cloudfront get-distribution $PROFILE_OPT --id "$dist" --query 'Distribution.DistributionConfig.DefaultCacheBehavior.RealtimeLogConfigArn' --output text | grep -i arn)
|
||||
if [[ $LOG_ENABLED || $LOG_ENABLED_REALTIME ]]; then
|
||||
textPass "$REGION: CloudFront distribution $dist has logging enabled" "$REGION" "$dist"
|
||||
else
|
||||
textFail "$REGION: CloudFront distribution $dist has logging disabled" "$REGION" "$dist"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$REGION: No CloudFront distributions found" "$REGION" "$dist"
|
||||
fi
|
||||
}
|
||||
@@ -1,41 +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_extra732="7.32"
|
||||
CHECK_TITLE_extra732="[extra732] Check if Geo restrictions are enabled in CloudFront distributions"
|
||||
CHECK_SCORED_extra732="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra732="EXTRA"
|
||||
CHECK_SEVERITY_extra732="Low"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra732="AwsCloudFrontDistribution"
|
||||
CHECK_ALTERNATE_check732="extra732"
|
||||
CHECK_SERVICENAME_extra732="cloudfront"
|
||||
CHECK_RISK_extra732='Consider countries where service should not be accessed; by legal or compliance requirements. Additionally if not restricted the attack vector is increased.'
|
||||
CHECK_REMEDIATION_extra732='If possible; define and enable Geo restrictions for this service.'
|
||||
CHECK_DOC_extra732='https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/georestrictions.html'
|
||||
CHECK_CAF_EPIC_extra732='Infrastructure Security'
|
||||
|
||||
extra732(){
|
||||
LIST_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions $PROFILE_OPT --query 'DistributionList.Items[*].Id' --output text |grep -v ^None)
|
||||
if [[ $LIST_DISTRIBUTIONS ]]; then
|
||||
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 "$REGION: CloudFront distribution $dist has not Geo restrictions" "$REGION" "$dist"
|
||||
else
|
||||
textPass "$REGION: CloudFront distribution $dist has Geo restrictions enabled" "$REGION" "$dist"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$REGION: No CloudFront distributions found"
|
||||
fi
|
||||
}
|
||||
@@ -1,43 +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_extra738="7.38"
|
||||
CHECK_TITLE_extra738="[extra738] Check if CloudFront distributions are set to HTTPS"
|
||||
CHECK_SCORED_extra738="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra738="EXTRA"
|
||||
CHECK_SEVERITY_extra738="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra738="AwsCloudFrontDistribution"
|
||||
CHECK_ALTERNATE_check738="extra738"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra738="ens-mp.com.2.aws.front.1"
|
||||
CHECK_SERVICENAME_extra738="cloudfront"
|
||||
CHECK_RISK_extra738='If not enabled sensitive information in transit is not protected. Surveillance and other threats are risks may exists.'
|
||||
CHECK_REMEDIATION_extra738='Use HTTPS everywhere possible. It will enforce privacy and protect against account hijacking and other threats.'
|
||||
CHECK_DOC_extra738='https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https.html'
|
||||
CHECK_CAF_EPIC_extra738='Data Protection'
|
||||
|
||||
extra738(){
|
||||
LIST_OF_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions --query 'DistributionList.Items[*].Id' $PROFILE_OPT --output text|grep -v ^None)
|
||||
if [[ $LIST_OF_DISTRIBUTIONS ]];then
|
||||
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 "$REGION: CloudFront distribution $dist viewers can use HTTP or HTTPS!" "$REGION" "$dist"
|
||||
elif [[ $CHECK_HTTPS_STATUS == "redirect-to-https" ]]; then
|
||||
textPass "$REGION: CloudFront distribution $dist has redirect to HTTPS" "$REGION" "$dist"
|
||||
else
|
||||
textPass "$REGION: CloudFront distribution $dist has HTTPS only" "$REGION" "$dist"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$REGION: No CloudFront distributions found" "$REGION"
|
||||
fi
|
||||
}
|
||||
@@ -1,40 +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_extra767="7.67"
|
||||
CHECK_TITLE_extra767="[extra767] Check if CloudFront distributions have Field Level Encryption enabled "
|
||||
CHECK_SCORED_extra767="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra767="EXTRA"
|
||||
CHECK_SEVERITY_extra767="Low"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra767="AwsCloudFrontDistribution"
|
||||
CHECK_ALTERNATE_check767="extra767"
|
||||
CHECK_SERVICENAME_extra767="cloudfront"
|
||||
CHECK_RISK_extra767='Allows you protect specific data throughout system processing so that only certain applications can see it.'
|
||||
CHECK_REMEDIATION_extra767='Check if applicable to any sensitive data. This encryption ensures that only applications that need the data—and have the credentials to decrypt it - are able to do so.'
|
||||
CHECK_DOC_extra767='https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/field-level-encryption.html'
|
||||
CHECK_CAF_EPIC_extra767='Data Protection'
|
||||
|
||||
extra767(){
|
||||
LIST_OF_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions --query 'DistributionList.Items[*].Id' $PROFILE_OPT --output text|grep -v ^None)
|
||||
if [[ $LIST_OF_DISTRIBUTIONS ]];then
|
||||
for dist in $LIST_OF_DISTRIBUTIONS; do
|
||||
CHECK_FLE=$($AWSCLI cloudfront get-distribution --id $dist --query Distribution.DistributionConfig.DefaultCacheBehavior.FieldLevelEncryptionId $PROFILE_OPT --output text)
|
||||
if [[ $CHECK_FLE ]]; then
|
||||
textPass "CloudFront distribution $dist has Field Level Encryption enabled" "$regx" "$dist"
|
||||
else
|
||||
textFail "CloudFront distribution $dist has Field Level Encryption disabled!" "$regx" "$dist"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "No CloudFront distributions found" "$regx"
|
||||
fi
|
||||
}
|
||||
@@ -1,42 +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_extra773="7.73"
|
||||
CHECK_TITLE_extra773="[extra773] Check if CloudFront distributions are using WAF "
|
||||
CHECK_SCORED_extra773="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra773="EXTRA"
|
||||
CHECK_SEVERITY_extra773="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra773="AwsCloudFrontDistribution"
|
||||
CHECK_ALTERNATE_check773="extra773"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra773="ens-mp.s.2.aws.waf.1"
|
||||
CHECK_SERVICENAME_extra773="cloudfront"
|
||||
CHECK_RISK_extra773='Potential attacks and / or abuse of service; more even for even for internet reachable services.'
|
||||
CHECK_REMEDIATION_extra773='Use AWS WAF to protect your service from common web exploits. These could affect availability and performance; compromise security; or consume excessive resources.'
|
||||
CHECK_DOC_extra773='https://docs.aws.amazon.com/waf/latest/developerguide/cloudfront-features.html'
|
||||
CHECK_CAF_EPIC_extra773='Infrastructure Security'
|
||||
|
||||
extra773(){
|
||||
# "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
|
||||
WEB_ACL_ID=$($AWSCLI cloudfront get-distribution $PROFILE_OPT --id "$dist" --query 'Distribution.DistributionConfig.WebACLId' --output text)
|
||||
if [[ $WEB_ACL_ID ]]; then
|
||||
textPass "CloudFront distribution $dist is using AWS WAF web ACL $WEB_ACL_ID" "us-east-1" "$dist"
|
||||
else
|
||||
textFail "CloudFront distribution $dist is not using AWS WAF web ACL" "us-east-1" "$dist"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "No CloudFront distributions found"
|
||||
fi
|
||||
}
|
||||
@@ -1,40 +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_extra791="7.91"
|
||||
CHECK_TITLE_extra791="[extra791] Check if CloudFront distributions are using deprecated SSL protocols"
|
||||
CHECK_SCORED_extra791="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra791="EXTRA"
|
||||
CHECK_SEVERITY_extra791="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra791="AwsCloudFrontDistribution"
|
||||
CHECK_ALTERNATE_check791="extra791"
|
||||
CHECK_SERVICENAME_extra791="cloudfront"
|
||||
CHECK_RISK_extra791='Using insecure ciphers could affect privacy of in transit information.'
|
||||
CHECK_REMEDIATION_extra791='Use a Security policy with a ciphers that are stronger as possible. Drop legacy and unsecure ciphers.'
|
||||
CHECK_DOC_extra791='https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/secure-connections-supported-viewer-protocols-ciphers.html'
|
||||
CHECK_CAF_EPIC_extra791='Data Protection'
|
||||
|
||||
extra791(){
|
||||
LIST_OF_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions --query 'DistributionList.Items[*].Id' $PROFILE_OPT --output text|grep -v ^None)
|
||||
if [[ $LIST_OF_DISTRIBUTIONS ]];then
|
||||
for dist in $LIST_OF_DISTRIBUTIONS; do
|
||||
CHECK_ORIGINSSLPROTOCOL_STATUS=$($AWSCLI cloudfront get-distribution --id $dist --query Distribution.DistributionConfig.Origins.Items[].CustomOriginConfig.OriginSslProtocols.Items $PROFILE_OPT --output text)
|
||||
if [[ $CHECK_ORIGINSSLPROTOCOL_STATUS == *"SSLv2"* ]] || [[ $CHECK_ORIGINSSLPROTOCOL_STATUS == *"SSLv3"* ]]; then
|
||||
textFail "CloudFront distribution $dist is using a deprecated SSL protocol!" "$regx" "$dist"
|
||||
else
|
||||
textPass "CloudFront distribution $dist is not using a deprecated SSL protocol" "$regx" "$dist"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "No CloudFront distributions found" "$regx"
|
||||
fi
|
||||
}
|
||||
@@ -1,68 +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_check21="2.1"
|
||||
CHECK_TITLE_check21="[check21] Ensure CloudTrail is enabled in all regions"
|
||||
CHECK_SCORED_check21="SCORED"
|
||||
CHECK_CIS_LEVEL_check21="LEVEL1"
|
||||
CHECK_SEVERITY_check21="High"
|
||||
CHECK_ASFF_TYPE_check21="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check21="AwsCloudTrailTrail"
|
||||
CHECK_ALTERNATE_check201="check21"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check21="ens-op.acc.7.aws.iam.1 ens-op.mon.1.aws.trail.1"
|
||||
CHECK_SERVICENAME_check21="cloudtrail"
|
||||
CHECK_RISK_check21='AWS CloudTrail is a web service that records AWS API calls for your account and delivers log files to you. The recorded information includes the identity of the API caller; the time of the API call; the source IP address of the API caller; the request parameters; and the response elements returned by the AWS service.'
|
||||
CHECK_REMEDIATION_check21='Ensure Logging is set to ON on all regions (even if they are not being used at the moment.'
|
||||
CHECK_DOC_check21='https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrailconcepts.html#cloudtrail-concepts-management-events'
|
||||
CHECK_CAF_EPIC_check21='Logging and Monitoring'
|
||||
|
||||
check21(){
|
||||
trail_count=0
|
||||
# "Ensure CloudTrail is enabled in all regions (Scored)"
|
||||
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
|
||||
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
|
||||
continue
|
||||
fi
|
||||
if [[ $TRAILS_AND_REGIONS ]]; then
|
||||
for reg_trail in $TRAILS_AND_REGIONS; do
|
||||
TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1)
|
||||
if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region
|
||||
continue
|
||||
fi
|
||||
trail=$(echo $reg_trail | cut -d',' -f2)
|
||||
trail_count=$((trail_count + 1))
|
||||
|
||||
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 "$regx: Trail $trail is not enabled for all regions" "$regx" "$trail"
|
||||
else
|
||||
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
|
||||
fi
|
||||
done
|
||||
if [[ $trail_count == 0 ]]; then
|
||||
if [[ $FILTERREGION ]]; then
|
||||
textFail "$regx: No CloudTrail trails were found in the filtered region" "$regx" "$trail"
|
||||
else
|
||||
textFail "$regx: No CloudTrail trails were found in the account" "$regx" "$trail"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -1,60 +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_check22="2.2"
|
||||
CHECK_TITLE_check22="[check22] Ensure CloudTrail log file validation is enabled"
|
||||
CHECK_SCORED_check22="SCORED"
|
||||
CHECK_CIS_LEVEL_check22="LEVEL2"
|
||||
CHECK_SEVERITY_check22="Medium"
|
||||
CHECK_ASFF_TYPE_check22="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check22="AwsCloudTrailTrail"
|
||||
CHECK_ALTERNATE_check202="check22"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check22="ens-op.exp.10.aws.trail.1"
|
||||
CHECK_SERVICENAME_check22="cloudtrail"
|
||||
CHECK_RISK_check22='Enabling log file validation will provide additional integrity checking of CloudTrail logs. '
|
||||
CHECK_REMEDIATION_check22='Ensure LogFileValidationEnabled is set to true for each trail.'
|
||||
CHECK_DOC_check22='http://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-filevalidation-enabling.html'
|
||||
CHECK_CAF_EPIC_check22='Logging and Monitoring'
|
||||
|
||||
check22(){
|
||||
trail_count=0
|
||||
# "Ensure CloudTrail log file validation is enabled (Scored)"
|
||||
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
|
||||
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
|
||||
continue
|
||||
fi
|
||||
if [[ $TRAILS_AND_REGIONS ]]; then
|
||||
for reg_trail in $TRAILS_AND_REGIONS; do
|
||||
TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1)
|
||||
if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region
|
||||
continue
|
||||
fi
|
||||
trail=$(echo $reg_trail | cut -d',' -f2)
|
||||
trail_count=$((trail_count + 1))
|
||||
|
||||
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 "$regx: Trail $trail log file validation disabled" "$regx" "$trail"
|
||||
else
|
||||
textPass "$regx: Trail $trail log file validation enabled" "$regx" "$trail"
|
||||
fi
|
||||
|
||||
done
|
||||
fi
|
||||
done
|
||||
if [[ $trail_count == 0 ]]; then
|
||||
textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail"
|
||||
fi
|
||||
}
|
||||
@@ -1,94 +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_check23="2.3"
|
||||
CHECK_TITLE_check23="[check23] Ensure the S3 bucket CloudTrail logs to is not publicly accessible"
|
||||
CHECK_SCORED_check23="SCORED"
|
||||
CHECK_CIS_LEVEL_check23="LEVEL1"
|
||||
CHECK_SEVERITY_check23="Critical"
|
||||
CHECK_ASFF_TYPE_check23="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check23="AwsS3Bucket"
|
||||
CHECK_ALTERNATE_check203="check23"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check23="ens-op.exp.10.aws.trail.3 ens-op.exp.10.aws.trail.4"
|
||||
CHECK_SERVICENAME_check23="cloudtrail"
|
||||
CHECK_RISK_check23='Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected accounts use or configuration.'
|
||||
CHECK_REMEDIATION_check23='Analyze Bucket policy to validate appropriate permissions. Ensure the AllUsers principal is not granted privileges. Ensure the AuthenticatedUsers principal is not granted privileges.'
|
||||
CHECK_DOC_check23='https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html'
|
||||
CHECK_CAF_EPIC_check23='Logging and Monitoring'
|
||||
|
||||
check23(){
|
||||
trail_count=0
|
||||
# "Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)"
|
||||
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
|
||||
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
|
||||
continue
|
||||
fi
|
||||
if [[ $TRAILS_AND_REGIONS ]]; then
|
||||
for reg_trail in $TRAILS_AND_REGIONS; do
|
||||
TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1)
|
||||
if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region
|
||||
continue
|
||||
fi
|
||||
trail=$(echo $reg_trail | cut -d',' -f2)
|
||||
trail_count=$((trail_count + 1))
|
||||
|
||||
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"
|
||||
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"
|
||||
continue
|
||||
fi
|
||||
|
||||
#
|
||||
# LOCATION - requests referencing buckets created after March 20, 2019
|
||||
# must be made to S3 endpoints in the same region as the bucket was
|
||||
# created.
|
||||
#
|
||||
BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location $PROFILE_OPT --region $regx --bucket $CLOUDTRAILBUCKET --output text 2>&1)
|
||||
if [[ $(echo "$BUCKET_LOCATION" | grep AccessDenied) ]]; then
|
||||
textInfo "Trail $trail in $TRAIL_REGION Access Denied getting bucket location for $CLOUDTRAILBUCKET"
|
||||
continue
|
||||
fi
|
||||
if [[ $BUCKET_LOCATION == "None" ]]; then
|
||||
BUCKET_LOCATION="us-east-1"
|
||||
fi
|
||||
if [[ $BUCKET_LOCATION == "EU" ]]; then
|
||||
BUCKET_LOCATION="eu-west-1"
|
||||
fi
|
||||
|
||||
CLOUDTRAILBUCKET_HASALLPERMISIONS=$($AWSCLI s3api get-bucket-acl --bucket $CLOUDTRAILBUCKET $PROFILE_OPT --region $BUCKET_LOCATION --query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers`]' --output text 2>&1)
|
||||
if [[ $(echo "$CLOUDTRAILBUCKET_HASALLPERMISIONS" | grep AccessDenied) ]]; then
|
||||
textInfo "Trail $trail in $TRAIL_REGION Access Denied getting bucket acl for $CLOUDTRAILBUCKET"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ -z $CLOUDTRAILBUCKET_HASALLPERMISIONS ]]; then
|
||||
textPass "Trail $trail in $TRAIL_REGION S3 logging bucket $CLOUDTRAILBUCKET is not publicly accessible"
|
||||
else
|
||||
textFail "Trail $trail in $TRAIL_REGION S3 logging bucket $CLOUDTRAILBUCKET is publicly accessible"
|
||||
fi
|
||||
|
||||
done
|
||||
fi
|
||||
done
|
||||
if [[ $trail_count == 0 ]]; then
|
||||
textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail"
|
||||
fi
|
||||
}
|
||||
@@ -1,66 +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_check24="2.4"
|
||||
CHECK_TITLE_check24="[check24] Ensure CloudTrail trails are integrated with CloudWatch Logs"
|
||||
CHECK_SCORED_check24="SCORED"
|
||||
CHECK_CIS_LEVEL_check24="LEVEL1"
|
||||
CHECK_SEVERITY_check24="Low"
|
||||
CHECK_ASFF_TYPE_check24="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check24="AwsCloudTrailTrail"
|
||||
CHECK_ALTERNATE_check204="check24"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check24="ens-op.exp.8.aws.cw.1"
|
||||
CHECK_SERVICENAME_check24="cloudtrail"
|
||||
CHECK_RISK_check24='Sending CloudTrail logs to CloudWatch Logs will facilitate real-time and historic activity logging based on user; API; resource; and IP address; and provides opportunity to establish alarms and notifications for anomalous or sensitivity account activity.'
|
||||
CHECK_REMEDIATION_check24='Validate that the trails in CloudTrail has an arn set in the CloudWatchLogsLogGroupArn property.'
|
||||
CHECK_DOC_check24='https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html'
|
||||
CHECK_CAF_EPIC_check24='Logging and Monitoring'
|
||||
|
||||
check24(){
|
||||
trail_count=0
|
||||
# "Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)"
|
||||
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
|
||||
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
|
||||
continue
|
||||
fi
|
||||
if [[ $TRAILS_AND_REGIONS ]]; then
|
||||
for reg_trail in $TRAILS_AND_REGIONS; do
|
||||
TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1)
|
||||
if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region
|
||||
continue
|
||||
fi
|
||||
trail=$(echo $reg_trail | cut -d',' -f2)
|
||||
trail_count=$((trail_count + 1))
|
||||
|
||||
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_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_REGION: $trail trail is not logging in the last 24h or not configured" "$TRAIL_REGION" "$trail"
|
||||
else
|
||||
textPass "$TRAIL_REGION: $trail trail has been logging during the last 24h" "$TRAIL_REGION" "$trail"
|
||||
fi
|
||||
fi
|
||||
|
||||
done
|
||||
fi
|
||||
done
|
||||
if [[ $trail_count == 0 ]]; then
|
||||
textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail"
|
||||
fi
|
||||
}
|
||||
@@ -1,59 +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_check27="2.7"
|
||||
CHECK_TITLE_check27="[check27] Ensure CloudTrail logs are encrypted at rest using KMS CMKs"
|
||||
CHECK_SCORED_check27="SCORED"
|
||||
CHECK_CIS_LEVEL_check27="LEVEL2"
|
||||
CHECK_SEVERITY_check27="Medium"
|
||||
CHECK_ASFF_TYPE_check27="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check27="AwsCloudTrailTrail"
|
||||
CHECK_ALTERNATE_check207="check27"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check27="ens-op.exp.10.aws.trail.5"
|
||||
CHECK_SERVICENAME_check27="cloudtrail"
|
||||
CHECK_RISK_check27='By default; the log files delivered by CloudTrail to your bucket are encrypted by Amazon server-side encryption with Amazon S3-managed encryption keys (SSE-S3). To provide a security layer that is directly manageable; you can instead use server-side encryption with AWS KMS–managed keys (SSE-KMS) for your CloudTrail log files.'
|
||||
CHECK_REMEDIATION_check27='This approach has the following advantages: You can create and manage the CMK encryption keys yourself. You can use a single CMK to encrypt and decrypt log files for multiple accounts across all regions. You have control over who can use your key for encrypting and decrypting CloudTrail log files. You can assign permissions for the key to the users. You have enhanced security.'
|
||||
CHECK_DOC_check27='https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html'
|
||||
CHECK_CAF_EPIC_check27='Logging and Monitoring'
|
||||
|
||||
check27(){
|
||||
trail_count=0
|
||||
# "Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)"
|
||||
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
|
||||
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
|
||||
continue
|
||||
fi
|
||||
if [[ $TRAILS_AND_REGIONS ]]; then
|
||||
for reg_trail in $TRAILS_AND_REGIONS; do
|
||||
TRAIL_REGION=$(echo $reg_trail | cut -d',' -f1)
|
||||
if [ $TRAIL_REGION != $regx ]; then # Only report trails once in home region
|
||||
continue
|
||||
fi
|
||||
trail=$(echo $reg_trail | cut -d',' -f2)
|
||||
trail_count=$((trail_count + 1))
|
||||
|
||||
KMSKEYID=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $TRAIL_REGION --query 'trailList[*].KmsKeyId' --output text --trail-name-list $trail)
|
||||
if [[ "$KMSKEYID" ]];then
|
||||
textPass "$regx: Trail $trail has encryption enabled" "$regx" "$trail"
|
||||
else
|
||||
textFail "$regx: Trail $trail has encryption disabled" "$regx" "$trail"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
if [[ $trail_count == 0 ]]; then
|
||||
textFail "$REGION: No CloudTrail trails were found in the account" "$REGION" "$trail"
|
||||
fi
|
||||
}
|
||||
@@ -1,56 +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.
|
||||
#
|
||||
# Remediation:
|
||||
#
|
||||
# https://d1.awsstatic.com/whitepapers/compliance/AWS_CIS_Foundations_Benchmark.pdf
|
||||
#
|
||||
# aws logs put-metric-filter \
|
||||
# --region us-east-1 \
|
||||
# --log-group-name CloudTrail/MyCloudTrailLG \
|
||||
# --filter-name AWSCloudTrailChanges \
|
||||
# --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' \
|
||||
# --metric-transformations metricName=CloudTrailEventCount,metricNamespace=CloudTrailMetrics,metricValue=1
|
||||
#
|
||||
# aws cloudwatch put-metric-alarm \
|
||||
# --region us-east-1 \
|
||||
# --alarm-name "CloudTrail Changes" \
|
||||
# --alarm-description "Triggered by AWS CloudTrail configuration changes." \
|
||||
# --metric-name CloudTrailEventCount \
|
||||
# --namespace CloudTrailMetrics \
|
||||
# --statistic Sum \
|
||||
# --comparison-operator GreaterThanOrEqualToThreshold \
|
||||
# --evaluation-periods 1 \
|
||||
# --period 300 \
|
||||
# --threshold 1 \
|
||||
# --actions-enabled \
|
||||
# --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"
|
||||
CHECK_SCORED_check35="SCORED"
|
||||
CHECK_CIS_LEVEL_check35="LEVEL1"
|
||||
CHECK_SEVERITY_check35="Medium"
|
||||
CHECK_ASFF_TYPE_check35="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check35="AwsCloudTrailTrail"
|
||||
CHECK_ALTERNATE_check305="check35"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check35="ens-op.exp.8.aws.trail.1"
|
||||
CHECK_SERVICENAME_check35="cloudtrail"
|
||||
CHECK_RISK_check35='Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.'
|
||||
CHECK_REMEDIATION_check35='It is recommended that a metric filter and alarm be established for unauthorized requests.'
|
||||
CHECK_DOC_check35='https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html'
|
||||
CHECK_CAF_EPIC_check35='Logging and Monitoring'
|
||||
|
||||
check35(){
|
||||
check3x '\$\.eventName\s*=\s*CreateTrail.+\$\.eventName\s*=\s*UpdateTrail.+\$\.eventName\s*=\s*DeleteTrail.+\$\.eventName\s*=\s*StartLogging.+\$\.eventName\s*=\s*StopLogging'
|
||||
}
|
||||
@@ -1,35 +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_extra7144="7.144"
|
||||
CHECK_TITLE_extra7144="[extra7144] Check if CloudWatch has allowed cross-account sharing"
|
||||
CHECK_SCORED_extra7144="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7144="EXTRA"
|
||||
CHECK_SEVERITY_extra7144="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7144="AwsCloudWatch"
|
||||
CHECK_ALTERNATE_check7144="extra7144"
|
||||
CHECK_SERVICENAME_extra7144="cloudwatch"
|
||||
CHECK_RISK_extra7144='Cross-Account access to CloudWatch could increase the risk of compromising information between accounts'
|
||||
CHECK_REMEDIATION_extra7144='Grant usage permission on a per-resource basis to enforce least privilege and Zero Trust principles'
|
||||
CHECK_DOC_extra7144='https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Cross-Account-Cross-Region.html'
|
||||
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 "$REGION: CloudWatch has allowed cross-account sharing" "$REGION"
|
||||
else
|
||||
textPass "$REGION: CloudWatch doesn't allows cross-account sharing" "$REGION"
|
||||
fi
|
||||
}
|
||||
@@ -1,54 +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_extra7162="7.162"
|
||||
CHECK_TITLE_extra7162="[extra7162] Check if CloudWatch Log Groups have a retention policy of 365 days"
|
||||
CHECK_SCORED_extra7162="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7162="EXTRA"
|
||||
CHECK_SEVERITY_extra7162="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7162="AwsLogsLogGroup"
|
||||
CHECK_ALTERNATE_check7162="extra7162"
|
||||
CHECK_SERVICENAME_extra7162="cloudwatch"
|
||||
CHECK_RISK_extra7162='If log groups have a low retention policy of less than 365 days; crucial logs and data can be lost'
|
||||
CHECK_REMEDIATION_extra7162='Add Log Retention policy of 365 days to log groups. This will persist logs and traces for a long time.'
|
||||
CHECK_DOC_extra7162='https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Logs.html'
|
||||
CHECK_CAF_EPIC_extra7162='Data Retention'
|
||||
|
||||
extra7162() {
|
||||
# "Check if CloudWatch Log Groups have a retention policy of 365 days"
|
||||
declare -i LOG_GROUP_RETENTION_PERIOD_DAYS=365
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_365_RETENTION_LOG_GROUPS=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --query 'logGroups[?retentionInDays=="${LOG_GROUP_RETENTION_PERIOD_DAYS}"].[logGroupName]' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_365_RETENTION_LOG_GROUPS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe log groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_365_RETENTION_LOG_GROUPS ]]; then
|
||||
for log in $LIST_OF_365_RETENTION_LOG_GROUPS; do
|
||||
textPass "$regx: $log Log Group has 365 days retention period!" "$regx" "$log"
|
||||
done
|
||||
fi
|
||||
LIST_OF_NON_365_RETENTION_LOG_GROUPS=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --query 'logGroups[?retentionInDays!="${LOG_GROUP_RETENTION_PERIOD_DAYS}"].[logGroupName]' --output text)
|
||||
if [[ $LIST_OF_NON_365_RETENTION_LOG_GROUPS ]]; then
|
||||
for log in $LIST_OF_NON_365_RETENTION_LOG_GROUPS; do
|
||||
textFail "$regx: $log Log Group does not have 365 days retention period!" "$regx" "$log"
|
||||
done
|
||||
fi
|
||||
REGION_NO_LOG_GROUP=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --output text)
|
||||
if [[ $REGION_NO_LOG_GROUP ]]; then
|
||||
:
|
||||
else
|
||||
textInfo "$regx does not have a Log Group!" "$regx"
|
||||
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,61 +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.
|
||||
|
||||
# Remediation:
|
||||
#
|
||||
# https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html
|
||||
# associate-kms-key
|
||||
# --log-group-name <value>
|
||||
# --kms-key-id <value>
|
||||
# [--cli-input-json <value>]
|
||||
# [--generate-cli-skeleton <value>]
|
||||
|
||||
CHECK_ID_extra7164="7.164"
|
||||
CHECK_TITLE_extra7164="[extra7164] Check if CloudWatch log groups are protected by AWS KMS "
|
||||
CHECK_SCORED_extra7164="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7164="EXTRA"
|
||||
CHECK_SEVERITY_extra7164="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7164="Logs"
|
||||
CHECK_ALTERNATE_extra7164="extra7164"
|
||||
CHECK_SERVICENAME_extra7164="cloudwatch"
|
||||
CHECK_RISK_extra7164="Using customer managed KMS to encrypt CloudWatch log group provide additional confidentiality and control over the log data"
|
||||
CHECK_REMEDIATION_extra7164="Associate KMS Key with Cloudwatch log group."
|
||||
CHECK_DOC_extra7164="https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html"
|
||||
CHECK_CAF_EPIC_extra7164="Data Protection"
|
||||
|
||||
extra7164(){
|
||||
# "Check if Cloudwatch log groups are associated with AWS KMS"
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_LOGGROUPS=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --output json 2>&1 )
|
||||
if [[ $(echo "$LIST_OF_LOGGROUPS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe log groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_LOGGROUPS ]]; then
|
||||
LIST_OF_LOGGROUPS_WITHOUT_KMS=$(echo "${LIST_OF_LOGGROUPS}" | jq '.logGroups[]' | jq '. | select( has("kmsKeyId") == false )' | jq -r '.logGroupName')
|
||||
LIST_OF_LOGGROUPS_WITH_KMS=$(echo "${LIST_OF_LOGGROUPS}" | jq '.logGroups[]' | jq '. | select( has("kmsKeyId") == true )' | jq -r '.logGroupName')
|
||||
if [[ $LIST_OF_LOGGROUPS_WITHOUT_KMS ]]; then
|
||||
for loggroup in $LIST_OF_LOGGROUPS_WITHOUT_KMS; do
|
||||
textFail "$regx: ${loggroup} does not have AWS KMS keys associated." "$regx" "${loggroup}"
|
||||
done
|
||||
fi
|
||||
if [[ $LIST_OF_LOGGROUPS_WITH_KMS ]]; then
|
||||
for loggroup in $LIST_OF_LOGGROUPS_WITH_KMS; do
|
||||
textPass "$regx: ${loggroup} does have AWS KMS keys associated." "$regx" "${loggroup}"
|
||||
done
|
||||
fi
|
||||
else
|
||||
textPass "$regx: No Cloudwatch log groups found." "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,63 +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_extra7174="7.174"
|
||||
CHECK_TITLE_extra7174="[extra7174] CodeBuild Project last invoked greater than 90 days"
|
||||
CHECK_SCORED_extra7174="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7174="EXTRA"
|
||||
CHECK_SEVERITY_extra7174="High"
|
||||
CHECK_ASFF_TYPE_extra7174="AwsCodebuildProject"
|
||||
CHECK_ALTERNATE_check7174="extra7174"
|
||||
CHECK_SERVICENAME_extra7174="codebuild"
|
||||
CHECK_RISK_extra7174='Older CodeBuild projects can be checked to see if they are currently in use'
|
||||
CHECK_REMEDIATION_extra7174='Check if CodeBuild project are really in use and remove the stale ones'
|
||||
CHECK_DOC_extra7174='https://docs.aws.amazon.com/codebuild/latest/userguide/delete-project.html'
|
||||
CHECK_CAF_EPIC_extra7174='Infrastructure Security'
|
||||
|
||||
extra7174(){
|
||||
# "Looking for all build projects with last build invocation greater then 90 days in all regions"
|
||||
for regx in ${REGIONS}; do
|
||||
LIST_OF_PROJECTS=$("${AWSCLI}" codebuild list-projects ${PROFILE_OPT} --region "${regx}" --query 'projects[*]' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${LIST_OF_PROJECTS}"; then
|
||||
textInfo "${regx}: Access Denied trying to list Codebuild projects" "${regx}"
|
||||
continue
|
||||
fi
|
||||
if [[ "${LIST_OF_PROJECTS}" ]]; then
|
||||
for project in ${LIST_OF_PROJECTS}; do
|
||||
project_id=$("${AWSCLI}" codebuild list-builds-for-project ${PROFILE_OPT} --project-name "${project}" --query 'ids[0]' --region "${regx}" --output text | head -n 1 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${project_id}"; then
|
||||
textInfo "${regx}: Access Denied trying to fetch Id for Codebuild project" "${regx}" "${project}"
|
||||
continue
|
||||
elif grep -q -E 'None' <<< "${project_id}"; then
|
||||
textInfo "${regx}: Codebuild project ${project} has been never build" "${regx}" "${project}"
|
||||
continue
|
||||
fi
|
||||
last_invoked_time=$("${AWSCLI}" codebuild batch-get-builds ${PROFILE_OPT} --ids "${project_id}" --region "${regx}" --query 'builds[0].endTime' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${last_invoked_time}"; then
|
||||
textInfo "${regx}: Access Denied trying to get build details for Codebuild project ID" "${regx}" "${project}"
|
||||
elif grep -q -E 'None' <<< "${last_invoked_time}"; then
|
||||
textInfo "${regx}: Codebuild project ${project} has been never build" "${regx}" "${project}"
|
||||
else
|
||||
HOWOLDER=$(how_older_from_today "${last_invoked_time}")
|
||||
if [ "${HOWOLDER}" -ge 90 ]; then
|
||||
textFail "${regx}: CodeBuild project ${project} was last invoked greater then 90 days" "${regx}" "${project}"
|
||||
else
|
||||
textPass "${regx}: Codebuild project ${project} was last invoked in the past 90 days" "${regx}" "${project}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "${regx}: No CodeBuild Projects found" "${regx}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,52 +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_extra7175="7.175"
|
||||
CHECK_TITLE_extra7175="[extra7175] CodeBuild Project with an user controlled buildspec"
|
||||
CHECK_SCORED_extra7175="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7175="EXTRA"
|
||||
CHECK_SEVERITY_extra7175="High"
|
||||
CHECK_ASFF_TYPE_extra7175="AwsCodebuildProject"
|
||||
CHECK_ALTERNATE_check7175="extra7175"
|
||||
CHECK_SERVICENAME_extra7175="codebuild"
|
||||
CHECK_RISK_extra7175='The CodeBuild projects with user controlled buildspec'
|
||||
CHECK_REMEDIATION_extra7175='Use buildspec.yml from a trusted source which user cant interfere with'
|
||||
CHECK_DOC_extra7175='https://docs.aws.amazon.com/codebuild/latest/userguide/security.html'
|
||||
CHECK_CAF_EPIC_extra7175='Infrastructure Security'
|
||||
|
||||
extra7175(){
|
||||
# "Looking for all build projects with user controlled buildspec files"
|
||||
for regx in ${REGIONS}; do
|
||||
LIST_OF_PROJECTS=$("${AWSCLI}" codebuild list-projects ${PROFILE_OPT} --region "${regx}" --query 'projects[*]' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${LIST_OF_PROJECTS}"; then
|
||||
textInfo "${regx}: Access Denied trying to list Codebuild projects" "${regx}"
|
||||
continue
|
||||
fi
|
||||
if [[ "${LIST_OF_PROJECTS}" ]]; then
|
||||
for project in ${LIST_OF_PROJECTS}; do
|
||||
buildspec_file=$("${AWSCLI}" codebuild batch-get-projects ${PROFILE_OPT} --name "${project}" --query 'projects[0].source.buildspec' --region "${regx}" --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${buildspec_file}"; then
|
||||
textInfo "${regx}: Access Denied trying to fetch Id for Codebuild project" "${regx}" "${project}"
|
||||
continue
|
||||
fi
|
||||
if [[ $buildspec_file == *.yml ]];then
|
||||
textFail "${regx}: Codebuild project ${project} uses a user controlled buildspec" "${regx}" "${project}"
|
||||
else
|
||||
textPass "${regx}: Codebuild project ${project} not uses a user controlled buildspec" "${regx}" "${project}"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "${regx}: No CodeBuild Projects found" "${regx}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_check25="2.5"
|
||||
CHECK_TITLE_check25="[check25] Ensure AWS Config is enabled in all regions"
|
||||
CHECK_SCORED_check25="SCORED"
|
||||
CHECK_CIS_LEVEL_check25="LEVEL1"
|
||||
CHECK_SEVERITY_check25="Medium"
|
||||
CHECK_ASFF_TYPE_check25="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ALTERNATE_check205="check25"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check25="ens-op.exp.1.aws.cfg.1"
|
||||
CHECK_SERVICENAME_check25="config"
|
||||
CHECK_RISK_check25='The AWS configuration item history captured by AWS Config enables security analysis; resource change tracking; and compliance auditing.'
|
||||
CHECK_REMEDIATION_check25='It is recommended to enable AWS Config be enabled in all regions.'
|
||||
CHECK_DOC_check25='https://aws.amazon.com/blogs/mt/aws-config-best-practices/'
|
||||
CHECK_CAF_EPIC_check25='Logging and Monitoring'
|
||||
|
||||
check25(){
|
||||
# "Ensure AWS Config is enabled in all regions (Scored)"
|
||||
for regx in $REGIONS; do
|
||||
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
|
||||
textInfo "$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 "$regx: AWS Config recorder enabled" "$regx" "recorder"
|
||||
else
|
||||
textFail "$regx: AWS Config recorder in failure state" "$regx" "recorder"
|
||||
fi
|
||||
else
|
||||
textFail "$regx: AWS Config recorder disabled" "$regx" "recorder"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,55 +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.
|
||||
#
|
||||
# Remediation:
|
||||
#
|
||||
# https://d1.awsstatic.com/whitepapers/compliance/AWS_CIS_Foundations_Benchmark.pdf
|
||||
#
|
||||
# aws logs put-metric-filter \
|
||||
# --region us-east-1 \
|
||||
# --log-group-name CloudTrail/CloudWatchLogGroup \
|
||||
# --filter-name AWSConfigChanges \
|
||||
# --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName = StopConfigurationRecorder)||($.eventName = DeleteDeliveryChannel)||($.eventName = PutDeliveryChannel)||($.eventName = PutConfigurationRecorder)) }' \
|
||||
# --metric-transformations metricName=ConfigEventCount,metricNamespace=CloudTrailMetrics,metricValue=1
|
||||
#
|
||||
# aws cloudwatch put-metric-alarm \
|
||||
# --region us-east-1 \
|
||||
# --alarm-name AWSConfigChangesAlarm \
|
||||
# --alarm-description "Triggered by AWS Config changes." \
|
||||
# --metric-name ConfigEventCount \
|
||||
# --namespace CloudTrailMetrics \
|
||||
# --statistic Sum \
|
||||
# --comparison-operator GreaterThanOrEqualToThreshold \
|
||||
# --evaluation-periods 1 \
|
||||
# --period 300 \
|
||||
# --threshold 1 \
|
||||
# --actions-enabled \
|
||||
# --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"
|
||||
CHECK_SCORED_check39="SCORED"
|
||||
CHECK_CIS_LEVEL_check39="LEVEL2"
|
||||
CHECK_SEVERITY_check39="Medium"
|
||||
CHECK_ASFF_TYPE_check39="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check39="AwsCloudTrailTrail"
|
||||
CHECK_ALTERNATE_check309="check39"
|
||||
CHECK_SERVICENAME_check39="config"
|
||||
CHECK_RISK_check39='If not enabled important changes to accounts could go unnoticed or difficult to find.'
|
||||
CHECK_REMEDIATION_check39='Use this service as a complement to implement detective controls that cannot be prevented. (e.g. a Security Group is modified to open to internet without restrictions or route changed to avoid going thru the network firewall). Ensure AWS Config is enabled in all regions in order to detect any not intended action. On the other hand if sufficient preventive controls to make changes in critical services are in place; the rating on this finding can be lowered or discarded depending on residual risk.'
|
||||
CHECK_DOC_check39='https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html'
|
||||
CHECK_CAF_EPIC_check39='Logging and Monitoring'
|
||||
|
||||
check39(){
|
||||
check3x '\$\.eventSource\s*=\s*config.amazonaws.com.+\$\.eventName\s*=\s*StopConfigurationRecorder.+\$\.eventName\s*=\s*DeleteDeliveryChannel.+\$\.eventName\s*=\s*PutDeliveryChannel.+\$\.eventName\s*=\s*PutConfigurationRecorder'
|
||||
}
|
||||
@@ -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_extra9999="9.9999"
|
||||
CHECK_TITLE_extra9999="[check9999] Custom Defined Check"
|
||||
CHECK_SCORED_extra79999="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra9999="EXTRA"
|
||||
CHECK_SEVERITY_extra9999="Critical"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra9999="Custom"
|
||||
CHECK_ALTERNATE_extra9999="extra9999"
|
||||
CHECK_SERVICENAME_extra9999="custom"
|
||||
CHECK_RISK_cextra9999="Custom Defined Risk"
|
||||
CHECK_REMEDIATION_extra9999="Custom Remediation"
|
||||
CHECK_CAF_EPIC_extra9999="Custom EPIC"
|
||||
|
||||
extra9999(){
|
||||
|
||||
for regx in $REGIONS; do
|
||||
MY_CUSTOM_CMD=$($AWSCLI $CUSTOM_CMD $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$MY_CUSTOM_CMD" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied or error trying to execute the custom command" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $MY_CUSTOM_CMD ]]; then
|
||||
for element in $MY_CUSTOM_CMD; do
|
||||
textFail "$regx: Custom output is: $element" "$regx" "$CHECK_SGDEFAULT_ID"
|
||||
done
|
||||
else
|
||||
textPass "$regx: Custom output is empty" "$regx" "$CHECK_SGDEFAULT_ID"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,106 +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.
|
||||
|
||||
# Remediation:
|
||||
#
|
||||
# here URL to the relevand/official documentation
|
||||
#
|
||||
# here commands or steps to fix it if avalable, like:
|
||||
# aws logs put-metric-filter \
|
||||
# --region us-east-1 \
|
||||
# --log-group-name CloudTrail/MyCloudTrailLG \
|
||||
# --filter-name AWSCloudTrailChanges \
|
||||
# --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }' \
|
||||
# --metric-transformations metricName=CloudTrailEventCount,metricNamespace=CloudTrailMetrics,metricValue=1
|
||||
|
||||
# CHECK_ID_checkN="N.N"
|
||||
# CHECK_TITLE_checkN="[checkN] Description "
|
||||
# CHECK_SCORED_checkN="NOT_SCORED"
|
||||
# CHECK_CIS_LEVEL_checkN="EXTRA"
|
||||
# CHECK_SEVERITY_checkNN="Medium"
|
||||
# CHECK_ASFF_RESOURCE_TYPE_checkN="AwsAccount" # Choose appropriate value from https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format.html#asff-resources
|
||||
# CHECK_ALTERNATE_checkN="extraN"
|
||||
# CHECK_SERVICENAME_checkN="service" # get service short name from `curl -s https://api.regional-table.region-services.aws.a2z.com/index.json | jq -r '.prices[] | .id' | awk -F: '{ print $1 }' | sort -u`
|
||||
# CHECK_RISK_checkN=""
|
||||
# CHECK_REMEDIATION_checkN=""
|
||||
# CHECK_DOC_checkN=""
|
||||
# CHECK_CAF_EPIC_checkN=""
|
||||
|
||||
# General comments
|
||||
# ----------------
|
||||
# Do not add double quotes (") arround variable ${PROFILE_OPT} because this variable holds "--profile <profile-name>" and we need to read it as it is
|
||||
# Always check for AccessDenied|UnauthorizedOperation|AuthorizationError after AWS CLI command, using "2>&1" at the end
|
||||
# Avoid execute the same AWS CLI command again to check different attribute:
|
||||
# - Return all attributes on "--query"
|
||||
# - Use "read -r" to get all individual attributes
|
||||
# - Use "here-string" (<<<) when is necessary to interate through AWS CLI output with multiple attributes on the same line
|
||||
# - Here-string variable must be enclosed with double quotes, like "${LIST_OF_PUBLIC_INSTANCES}"
|
||||
# - See "Example of regional resource" below about how to do it
|
||||
# When an attribute doesn't exist, AWS CLI "--query" always return "none" if output is json or "None" if output is text
|
||||
# Use bash features to handle variable:
|
||||
# - ${var:N} : Return string from position 'N'
|
||||
# - ${var:N:len} : Return 'len' characters from position 'N'
|
||||
# - ${var^^} : Convert to upper-case all characters
|
||||
# - ${var,,} : Convert to lower-case all characters
|
||||
# - ATTENTION: macOS original bash version "GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)" doesn't support some variable expansion above.
|
||||
# Please make sure to test it.
|
||||
# - For more examples and how to use it please refer to https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
|
||||
# Check code with ShellCheck for best practices:
|
||||
# - https://www.shellcheck.net/
|
||||
# - https://github.com/koalaman/shellcheck#user-content-in-your-editor
|
||||
|
||||
# Example of regional resource
|
||||
# extraN(){
|
||||
# # "Description "
|
||||
# textInfo "Looking for instances in all regions... "
|
||||
# for regx in ${REGIONS}; do
|
||||
# LIST_OF_PUBLIC_INSTANCES=$("${AWSCLI}" ec2 describe-instances ${PROFILE_OPT} --region "${regx}" --query 'Reservations[*].Instances[?PublicIpAddress].[InstanceId,PublicIpAddress]' --output text 2>&1)
|
||||
# if [[ $(echo "${LIST_OF_PUBLIC_INSTANCES}" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
# textInfo "${regx}: Access Denied trying to list EC2 Instances" "${regx}"
|
||||
# continue
|
||||
# fi
|
||||
# if [[ "${LIST_OF_PUBLIC_INSTANCES}" != "" && "${LIST_OF_PUBLIC_INSTANCES,,}" != "none" ]]; then
|
||||
# while read -r INSTANCE_ID PUBLIC_IP; do
|
||||
# textFail "${regx}: Instance: ${INSTANCE_ID} at IP: ${PUBLIC_IP} is internet-facing!" "${regx}" "${INSTANCE_ID}"
|
||||
# done <<< "${LIST_OF_PUBLIC_INSTANCES}"
|
||||
# else
|
||||
# textPass "${regx}: no Internet Facing EC2 Instances found" "${regx}"
|
||||
# fi
|
||||
# done
|
||||
# }
|
||||
|
||||
# Example of global resource
|
||||
# extraN(){
|
||||
# # "Description "
|
||||
# LIST_DISTRIBUTIONS=$("${AWSCLI}" cloudfront list-distributions ${PROFILE_OPT} --query 'DistributionList.Items[*].Id' --output text 2>&1)
|
||||
# if [[ $(echo "${LIST_DISTRIBUTIONS}" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
# textInfo "${REGION}: Access Denied trying to list distributions" "${REGION}"
|
||||
# return
|
||||
# fi
|
||||
# if [[ "${LIST_DISTRIBUTIONS}" != "" && "${LIST_DISTRIBUTIONS,,}" != "none" ]]; then
|
||||
# for dist in ${LIST_DISTRIBUTIONS}; do
|
||||
# GEO_ENABLED=$("${AWSCLI}" cloudfront get-distribution-config $PROFILE_OPT --id "${dist}" --query 'DistributionConfig.Restrictions.GeoRestriction.RestrictionType' --output text 2>&1)
|
||||
# if [[ $(echo "${GEO_ENABLED}" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
# textInfo "${REGION}: Access Denied trying to get distribution config for ${dist}" "${REGION}"
|
||||
# continue
|
||||
# fi
|
||||
# if [[ "${GEO_ENABLED,,}" == "none" ]]; then
|
||||
# textFail "${REGION}: CloudFront distribution ${dist} has not Geo restrictions" "${REGION}" "${dist}"
|
||||
# else
|
||||
# textPass "${REGION}: CloudFront distribution ${dist} has Geo restrictions enabled" "${REGION}" "${dist}"
|
||||
# fi
|
||||
# done
|
||||
# else
|
||||
# textInfo "${REGION}: No CloudFront distributions found"
|
||||
# fi
|
||||
# }
|
||||
@@ -1,47 +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_extra7128="7.128"
|
||||
CHECK_TITLE_extra7128="[extra7128] Check if DynamoDB table has encryption at rest enabled using CMK KMS"
|
||||
CHECK_SCORED_extra7128="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7128="EXTRA"
|
||||
CHECK_SEVERITY_extra7128="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7128="AwsDynamoDBTable"
|
||||
CHECK_ALTERNATE_check7128="extra7128"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra7128="ens-mp.info.3.aws.dyndb.1"
|
||||
CHECK_SERVICENAME_extra7128="dynamodb"
|
||||
CHECK_RISK_extra7128='All user data stored in Amazon DynamoDB is fully encrypted at rest. This functionality helps reduce the operational burden and complexity involved in protecting sensitive data.'
|
||||
CHECK_REMEDIATION_extra7128='Specify an encryption key when you create a new table or switch the encryption keys on an existing table by using the AWS Management Console.'
|
||||
CHECK_DOC_extra7128='https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/EncryptionAtRest.html'
|
||||
CHECK_CAF_EPIC_extra7128='Data Protection'
|
||||
|
||||
extra7128(){
|
||||
for regx in $REGIONS; do
|
||||
DDB_TABLES_LIST=$($AWSCLI dynamodb list-tables $PROFILE_OPT --region $regx --output text --query TableNames 2>&1)
|
||||
if [[ $(echo "$DDB_TABLES_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list tables" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $DDB_TABLES_LIST ]]; then
|
||||
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" "$table"
|
||||
else
|
||||
textInfo "$regx: DynamoDB table $table does have DEFAULT encryption enabled" "$regx" "$table"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: There are no DynamoDB tables" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,48 +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_extra7151="7.151"
|
||||
CHECK_TITLE_extra7151="[extra7151] Check if DynamoDB tables point-in-time recovery (PITR) is enabled"
|
||||
CHECK_SCORED_extra7151="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7151="EXTRA"
|
||||
CHECK_SEVERITY_extra7151="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7151="AwsDynamoDbTable"
|
||||
CHECK_ALTERNATE_check7151="extra7151"
|
||||
CHECK_SERVICENAME_extra7151="dynamodb"
|
||||
CHECK_RISK_extra7151='If the DynamoDB Table does not have point-in-time recovery enabled; it is vulnerable to accidental write or delete operations.'
|
||||
CHECK_REMEDIATION_extra7151='Enable point-in-time recovery; this is not enabled by default.'
|
||||
CHECK_DOC_extra7151='https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/PointInTimeRecovery_Howitworks.html'
|
||||
CHECK_CAF_EPIC_extra7151='Data Protection'
|
||||
|
||||
extra7151(){
|
||||
# "Check if DynamoDB tables point-in-time recovery (PITR) is enabled"
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_DYNAMODB_TABLES=$($AWSCLI dynamodb list-tables $PROFILE_OPT --region $regx --query 'TableNames[*]' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_DYNAMODB_TABLES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list tables" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_DYNAMODB_TABLES ]]; then
|
||||
for dynamodb_table in $LIST_OF_DYNAMODB_TABLES; do
|
||||
POINT_IN_TIME_RECOVERY_ENABLED=$($AWSCLI dynamodb describe-continuous-backups $PROFILE_OPT --region $regx --table-name $dynamodb_table | jq '.[].PointInTimeRecoveryDescription | select(.PointInTimeRecoveryStatus=="ENABLED") | .PointInTimeRecoveryStatus')
|
||||
if [[ $POINT_IN_TIME_RECOVERY_ENABLED ]]; then
|
||||
textPass "$regx: $dynamodb_table has point-in-time recovery enabled." "$regx" "$dynamodb_table"
|
||||
else
|
||||
textFail "$regx: $dynamodb_table does not have point-in-time recovery enabled." "$regx" "$dynamodb_table"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No DynamoDB tables found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,68 +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.
|
||||
|
||||
# Remediation
|
||||
#
|
||||
# https://docs.aws.amazon.com/cli/latest/reference/dax/create-cluster.html
|
||||
#
|
||||
# create-cluster
|
||||
# --cluster-name <value>
|
||||
# --node-type <value>
|
||||
# --replication-factor <value>
|
||||
# --iam-role-arn <value>
|
||||
# --sse-specification Enabled=true
|
||||
|
||||
|
||||
CHECK_ID_extra7165="7.165"
|
||||
CHECK_TITLE_extra7165="[extra7165] Check if DynamoDB: DAX Clusters are encrypted at rest"
|
||||
CHECK_SCORED_extra7165="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7165="EXTRA"
|
||||
CHECK_SEVERITY_extra7165="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7165="AwsDaxCluster"
|
||||
CHECK_ALTERNATE_check7165="extra7165"
|
||||
CHECK_SERVICENAME_extra7165="dynamodb"
|
||||
CHECK_RISK_extra7165="Encryption at rest provides an additional layer of data protection by securing your data from unauthorized access to the underlying storage."
|
||||
CHECK_REMEDIATION_extra7165="Re-create the cluster to enable encryption at rest if it was not enabled at creation."
|
||||
CHECK_DOC_extra7165="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DAXEncryptionAtRest.html"
|
||||
CHECK_CAF_EPIC_extra7165="Data Protection"
|
||||
|
||||
extra7165(){
|
||||
# "Check if DynamoDB: DAX Clusters are encrypted at rest"
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_DAX_CLUSTERS=$($AWSCLI dax describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[*]' --output json 2>&1)
|
||||
if [[ $(echo "$LIST_OF_DAX_CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe clusters" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $(echo "$LIST_OF_DAX_CLUSTERS" | grep -E 'Could not connect') ]]; then
|
||||
textInfo "$regx: Service not available in this region" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_DAX_CLUSTERS && $LIST_OF_DAX_CLUSTERS != '[]' ]]; then
|
||||
LIST_OF_CLUSTERS_WITH_ENCRYPTION=$(echo "${LIST_OF_DAX_CLUSTERS}" | jq '.[] | select(.SSEDescription.Status=="ENABLED") | {ClusterName}' | jq -r '.ClusterName')
|
||||
LIST_OF_CLUSTERS_WITHOUT_ENCRYPTION=$(echo "${LIST_OF_DAX_CLUSTERS}" | jq '.[] | select(.SSEDescription.Status=="DISABLED") | {ClusterName}' | jq -r '.ClusterName')
|
||||
if [[ $LIST_OF_CLUSTERS_WITHOUT_ENCRYPTION ]]; then
|
||||
for cluster in $LIST_OF_CLUSTERS_WITHOUT_ENCRYPTION; do
|
||||
textFail "$regx: ${cluster} does not have encryption at rest enabled." "$regx" "${cluster}"
|
||||
done
|
||||
fi
|
||||
if [[ $LIST_OF_CLUSTERS_WITH_ENCRYPTION ]]; then
|
||||
for cluster in $LIST_OF_CLUSTERS_WITH_ENCRYPTION; do
|
||||
textPass "$regx: ${cluster} has encryption at rest enabled." "$regx" "${cluster}"
|
||||
done
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: No DynamoDB: DAX Clusters found." "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,54 +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_check119="1.19"
|
||||
CHECK_TITLE_check119="[check119] Ensure IAM instance roles are used for AWS resource access from instances"
|
||||
CHECK_SCORED_check119="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_check119="LEVEL2"
|
||||
CHECK_SEVERITY_check119="Medium"
|
||||
CHECK_ASFF_TYPE_check119="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check119="AwsEc2Instance"
|
||||
CHECK_ALTERNATE_check119="check119"
|
||||
CHECK_SERVICENAME_check119="ec2"
|
||||
CHECK_RISK_check119='AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. AWS IAM roles reduce the risks associated with sharing and rotating credentials that can be used outside of AWS itself. If credentials are compromised; they can be used from outside of the AWS account.'
|
||||
CHECK_REMEDIATION_check119='IAM roles can only be associated at the launch of an instance. To remediate an instance to add it to a role you must create or re-launch a new instance. (Check for external dependencies on its current private ip or public addresses).'
|
||||
CHECK_DOC_check119='http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html'
|
||||
CHECK_CAF_EPIC_check119='IAM'
|
||||
|
||||
check119(){
|
||||
for regx in $REGIONS; do
|
||||
EC2_DATA=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[].Instances[].[InstanceId, IamInstanceProfile.Arn, State.Name]' --output json 2>&1)
|
||||
if [[ $(echo "$EC2_DATA" | grep UnauthorizedOperation) ]]; then
|
||||
textInfo "$regx: Unauthorized Operation error trying to describe instances" "$regx"
|
||||
continue
|
||||
else
|
||||
EC2_DATA=$(echo $EC2_DATA | jq '.[]|{InstanceId: .[0], ProfileArn: .[1], StateName: .[2]}')
|
||||
INSTANCE_LIST=$(echo $EC2_DATA | jq -r '.InstanceId')
|
||||
fi
|
||||
if [[ $INSTANCE_LIST ]]; then
|
||||
for instance in $INSTANCE_LIST; do
|
||||
STATE_NAME=$(echo $EC2_DATA | jq -r --arg i "$instance" 'select(.InstanceId==$i)|.StateName')
|
||||
if [[ $STATE_NAME != "terminated" && $STATE_NAME != "shutting-down" ]]; then
|
||||
PROFILEARN=$(echo $EC2_DATA | jq -r --arg i "$instance" 'select(.InstanceId==$i)|.ProfileArn')
|
||||
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" "$instance"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EC2 instances found" "$regx" "$instance"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,55 +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.
|
||||
#
|
||||
# Remediation:
|
||||
#
|
||||
# https://d1.awsstatic.com/whitepapers/compliance/AWS_CIS_Foundations_Benchmark.pdf
|
||||
#
|
||||
# aws logs put-metric-filter \
|
||||
# --region us-east-1 \
|
||||
# --log-group-name CloudTrail/CloudWatchLogGroup \
|
||||
# --filter-name SecurityGroupConfigChanges \
|
||||
# --filter-pattern '{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }' \
|
||||
# --metric-transformations metricName=SecurityGroupEventCount,metricNamespace=CloudTrailMetrics,metricValue=1
|
||||
#
|
||||
# aws cloudwatch put-metric-alarm \
|
||||
# --region us-east-1 \
|
||||
# --alarm-name SecurityGroupConfigChangesAlarm \
|
||||
# --alarm-description "Triggered by AWS security group(s) config changes." \
|
||||
# --metric-name SecurityGroupEventCount \
|
||||
# --namespace CloudTrailMetrics \
|
||||
# --statistic Sum \
|
||||
# --comparison-operator GreaterThanOrEqualToThreshold \
|
||||
# --evaluation-periods 1 \
|
||||
# --period 300 \
|
||||
# --threshold 1 \
|
||||
# --actions-enabled \
|
||||
# --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"
|
||||
CHECK_SCORED_check310="SCORED"
|
||||
CHECK_CIS_LEVEL_check310="LEVEL2"
|
||||
CHECK_SEVERITY_check310="Medium"
|
||||
CHECK_ASFF_TYPE_check310="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check310="AwsCloudTrailTrail"
|
||||
CHECK_ALTERNATE_check310="check310"
|
||||
CHECK_SERVICENAME_check310="ec2"
|
||||
CHECK_RISK_check310='Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity.'
|
||||
CHECK_REMEDIATION_check310='It is recommended that a metric filter and alarm be established for unauthorized requests.'
|
||||
CHECK_DOC_check310='https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html'
|
||||
CHECK_CAF_EPIC_check310='Logging and Monitoring'
|
||||
|
||||
check310(){
|
||||
check3x '\$\.eventName\s*=\s*AuthorizeSecurityGroupIngress.+\$\.eventName\s*=\s*AuthorizeSecurityGroupEgress.+\$\.eventName\s*=\s*RevokeSecurityGroupIngress.+\$\.eventName\s*=\s*RevokeSecurityGroupEgress.+\$\.eventName\s*=\s*CreateSecurityGroup.+\$\.eventName\s*=\s*DeleteSecurityGroup'
|
||||
}
|
||||
@@ -1,45 +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_check41="4.1"
|
||||
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_CIS_LEVEL_check41="LEVEL2"
|
||||
CHECK_SEVERITY_check41="High"
|
||||
CHECK_ASFF_TYPE_check41="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check41="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check401="check41"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check41="ens-mp.com.4.aws.sg.4"
|
||||
CHECK_SERVICENAME_check41="ec2"
|
||||
CHECK_RISK_check41='Even having a perimeter firewall; having security groups open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.'
|
||||
CHECK_REMEDIATION_check41='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive security groups. Recommended best practices is to narrow the definition for the minimum ports required.'
|
||||
CHECK_DOC_check41='https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html'
|
||||
CHECK_CAF_EPIC_check41='Infrastructure Security'
|
||||
|
||||
check41(){
|
||||
# "Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored)"
|
||||
for regx in $REGIONS; do
|
||||
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`)) && (IpProtocol==`tcp`)]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region "${regx}" --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found with port 22 TCP open to 0.0.0.0/0" "$regx" "$SG"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,45 +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_check42="4.2"
|
||||
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_CIS_LEVEL_check42="LEVEL2"
|
||||
CHECK_SEVERITY_check42="High"
|
||||
CHECK_ASFF_TYPE_check42="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check42="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check402="check42"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check42="ens-mp.com.4.aws.sg.5"
|
||||
CHECK_SERVICENAME_check42="ec2"
|
||||
CHECK_RISK_check42='Even having a perimeter firewall; having security groups open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.'
|
||||
CHECK_REMEDIATION_check42='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive security groups. Recommended best practices is to narrow the definition for the minimum ports required.'
|
||||
CHECK_DOC_check42='https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html'
|
||||
CHECK_CAF_EPIC_check42='Infrastructure Security'
|
||||
|
||||
check42(){
|
||||
# "Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored)"
|
||||
for regx in $REGIONS; do
|
||||
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`)) && (IpProtocol==`tcp`) ]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region "${regx}" --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found with port 3389 TCP open to 0.0.0.0/0" "$regx" "$SG"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,46 +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_check43="4.3"
|
||||
CHECK_TITLE_check43="[check43] Ensure the default security group of every VPC restricts all traffic"
|
||||
CHECK_SCORED_check43="SCORED"
|
||||
CHECK_CIS_LEVEL_check43="LEVEL2"
|
||||
CHECK_SEVERITY_check43="High"
|
||||
CHECK_ASFF_TYPE_check43="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
|
||||
CHECK_ASFF_RESOURCE_TYPE_check43="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check403="check43"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_check43="ens-mp.com.4.aws.sg.1"
|
||||
CHECK_SERVICENAME_check43="ec2"
|
||||
CHECK_RISK_check43='Even having a perimeter firewall; having security groups open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.'
|
||||
CHECK_REMEDIATION_check43='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive security groups. Recommended best practices is to narrow the definition for the minimum ports required.'
|
||||
CHECK_DOC_check43='https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html'
|
||||
CHECK_CAF_EPIC_check43='Infrastructure Security'
|
||||
|
||||
check43(){
|
||||
# "Ensure the default security group of every VPC restricts all traffic (Scored)"
|
||||
for regx in $REGIONS; do
|
||||
CHECK_SGDEFAULT_IDS=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --filters Name=group-name,Values='default' --query 'SecurityGroups[*].GroupId[]' --output text 2>&1)
|
||||
if [[ $(echo "$CHECK_SGDEFAULT_IDS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
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 "$regx: Default Security Groups ($CHECK_SGDEFAULT_ID) found that allow 0.0.0.0 IN or OUT traffic" "$regx" "$CHECK_SGDEFAULT_ID"
|
||||
else
|
||||
textPass "$regx: No Default Security Groups ($CHECK_SGDEFAULT_ID) open to 0.0.0.0 found" "$regx" "$CHECK_SGDEFAULT_ID"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
@@ -1,43 +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_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_CIS_LEVEL_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="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.'
|
||||
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='https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html'
|
||||
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 2>&1)
|
||||
if [[ $(echo "$NACL_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe vpc network acls" "$regx"
|
||||
continue
|
||||
fi
|
||||
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" "$NACL"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Network ACL found with SSH port 22 open to 0.0.0.0/0" "$regx" "$NACL"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,43 +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_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_CIS_LEVEL_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="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.'
|
||||
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='https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html'
|
||||
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 2>&1)
|
||||
if [[ $(echo "$NACL_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe vpc network acls" "$regx"
|
||||
continue
|
||||
fi
|
||||
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" "$NACL"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Network ACL found with Microsoft RDP port 3389 open to 0.0.0.0/0" "$regx" "$NACL"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,45 +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_extra710="7.10"
|
||||
CHECK_TITLE_extra710="[extra710] Check for internet facing EC2 Instances"
|
||||
CHECK_SCORED_extra710="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra710="EXTRA"
|
||||
CHECK_SEVERITY_extra710="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra710="AwsEc2Instance"
|
||||
CHECK_ALTERNATE_check710="extra710"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra710="ens-mp.com.4.aws.vpc.1"
|
||||
CHECK_SERVICENAME_extra710="ec2"
|
||||
CHECK_RISK_extra710='Exposing an EC2 directly to internet increases the attack surface and therefore the risk of compromise.'
|
||||
CHECK_REMEDIATION_extra710='Use an ALB and apply WAF ACL.'
|
||||
CHECK_DOC_extra710='https://aws.amazon.com/blogs/aws/aws-web-application-firewall-waf-for-application-load-balancers/'
|
||||
CHECK_CAF_EPIC_extra710='Infrastructure Security'
|
||||
|
||||
extra710(){
|
||||
# "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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_PUBLIC_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe instances" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_PUBLIC_INSTANCES ]];then
|
||||
while read -r instance;do
|
||||
INSTANCE_ID=$(echo $instance | awk '{ print $1; }')
|
||||
PUBLIC_IP=$(echo $instance | awk '{ print $2; }')
|
||||
textFail "$regx: Instance: $INSTANCE_ID at IP: $PUBLIC_IP is internet-facing!" "$regx" "$INSTANCE_ID"
|
||||
done <<< "$LIST_OF_PUBLIC_INSTANCES"
|
||||
else
|
||||
textPass "$regx: no Internet Facing EC2 Instances found" "$regx" "$INSTANCE_ID"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,62 +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_extra7102="7.102"
|
||||
CHECK_TITLE_extra7102="[extra7102] Check if any of the Elastic or Public IP are in Shodan (requires Shodan API KEY)"
|
||||
CHECK_SCORED_extra7102="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7102="EXTRA"
|
||||
CHECK_SEVERITY_extra7102="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7102="AwsEc2Eip"
|
||||
CHECK_ALTERNATE_check7102="extra7102"
|
||||
CHECK_SERVICENAME_extra7102="ec2"
|
||||
CHECK_RISK_extra7102='Sites like Shodan index exposed systems and further expose them to wider audiences as a quick way to find exploitable systems.'
|
||||
CHECK_REMEDIATION_extra7102='Check Identified IPs; consider changing them to private ones and delete them from Shodan.'
|
||||
CHECK_DOC_extra7102='https://www.shodan.io/'
|
||||
CHECK_CAF_EPIC_extra7102='Infrastructure Security'
|
||||
|
||||
# Watch out, always use Shodan API key, if you use `curl https://www.shodan.io/host/{ip}` massively
|
||||
# your IP will be banned by Shodan
|
||||
|
||||
# This is the right way to do so
|
||||
# curl -ks https://api.shodan.io/shodan/host/{ip}?key={YOUR_API_KEY}
|
||||
|
||||
# Each finding will be saved in prowler/output folder for further review.
|
||||
|
||||
extra7102(){
|
||||
if [[ ! $SHODAN_API_KEY ]]; then
|
||||
textInfo "[extra7102] Requires a Shodan API key to work. Use -N <shodan_api_key>"
|
||||
else
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_EIP=$($AWSCLI $PROFILE_OPT --region $regx ec2 describe-network-interfaces --query 'NetworkInterfaces[*].Association.PublicIp' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_EIP" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe network interfaces" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_EIP ]]; then
|
||||
for ip in $LIST_OF_EIP;do
|
||||
SHODAN_QUERY=$(curl -ks https://api.shodan.io/shodan/host/$ip?key=$SHODAN_API_KEY)
|
||||
# Shodan has a request rate limit of 1 request/second.
|
||||
sleep 1
|
||||
if [[ $SHODAN_QUERY == *"No information available for that IP"* ]]; then
|
||||
textPass "$regx: IP $ip is not listed in Shodan" "$regx"
|
||||
else
|
||||
echo $SHODAN_QUERY > $OUTPUT_DIR/shodan-output-$ip.json
|
||||
IP_SHODAN_INFO=$(cat $OUTPUT_DIR/shodan-output-$ip.json | jq -r '. | { ports: .ports, org: .org, country: .country_name }| @text' | tr -d \"\{\}\}\]\[ | tr , '\ ' )
|
||||
textFail "$regx: IP $ip is listed in Shodan with data $IP_SHODAN_INFO. More info https://www.shodan.io/host/$ip and $OUTPUT_DIR/shodan-output-$ip.json" "$regx" "$ip"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No Public or Elastic IPs found" "$regx"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
@@ -1,41 +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_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 "
|
||||
CHECK_SCORED_extra7134="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_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 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
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" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for FTP ports" "$regx" "$SG"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,41 +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_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 "
|
||||
CHECK_SCORED_extra7135="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_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 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
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" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Kafka ports" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,41 +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_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 "
|
||||
CHECK_SCORED_extra7136="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_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 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
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" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Telnet ports" "$regx" "$SG"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,41 +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_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 "
|
||||
CHECK_SCORED_extra7137="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_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 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
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" "$SG"
|
||||
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
|
||||
}
|
||||
@@ -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_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_CIS_LEVEL_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="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.'
|
||||
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='https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html'
|
||||
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 2>&1)
|
||||
if [[ $(echo "$NACL_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe network acls" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $NACL_LIST ]];then
|
||||
for NACL in $NACL_LIST;do
|
||||
textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for any port" "$regx" "$NACL"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Network ACL found with any port open to 0.0.0.0/0" "$regx" "$NACL"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_extra7146="7.146"
|
||||
CHECK_TITLE_extra7146="[extra7146] Check if there is any unassigned Elastic IP"
|
||||
CHECK_SCORED_extra7146="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7146="EXTRA"
|
||||
CHECK_SEVERITY_extra7146="Low"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7146="AwsElasticIPs"
|
||||
CHECK_ALTERNATE_check7146="extra7146"
|
||||
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='Infrastructure Security'
|
||||
|
||||
extra7146(){
|
||||
# "Check if there is any unassigned elastic ip (Not Scored) (Not part of CIS benchmark)"
|
||||
for regx in $REGIONS; do
|
||||
ELASTIC_IP_ADDRESSES=$($AWSCLI ec2 describe-addresses $PROFILE_OPT --region $regx --query Addresses --output json 2>&1)
|
||||
if [[ $(echo "$ELASTIC_IP_ADDRESSES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe addresses" "$regx"
|
||||
continue
|
||||
fi
|
||||
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
|
||||
}
|
||||
@@ -1,44 +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_extra7173="7.173"
|
||||
CHECK_TITLE_extra7173="[check7173] Security Groups created by EC2 Launch Wizard"
|
||||
CHECK_SCORED_extra7173="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7173="EXTRA"
|
||||
CHECK_SEVERITY_extra7173="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7173="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_extra7173="extra7173"
|
||||
CHECK_SERVICENAME_extra7173="ec2"
|
||||
CHECK_RISK_cextra7173="Security Groups Created on the AWS Console using the EC2 wizard may allow port 22 from 0.0.0.0/0"
|
||||
CHECK_REMEDIATION_extra7173="Apply Zero Trust approach. Implement a process to scan and remediate security groups created by the EC2 Wizard. Recommended best practices is to use an authorized security group."
|
||||
CHECK_DOC_extra7173="CHECK_DOC_extra7173='https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html'"
|
||||
CHECK_CAF_EPIC_extra7173="Infrastructure Security"
|
||||
|
||||
extra7173(){
|
||||
# Ensure no security groups are created using Console EC2 Wizard
|
||||
for regx in $REGIONS; do
|
||||
CHECK_SGDEFAULT_IDS=$("${AWSCLI}" ec2 describe-security-groups ${PROFILE_OPT} --region "${regx}" --filters Name=group-name,Values='launch-wizard-*' --query 'SecurityGroups[*].GroupId[]' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation' <<< "${CHECK_SGDEFAULT_IDS}"; then
|
||||
textInfo "${regx}: Access Denied trying to describe security groups" "${regx}"
|
||||
continue
|
||||
fi
|
||||
if [[ ${CHECK_SGDEFAULT_IDS} ]]; then
|
||||
for CHECK_SGDEFAULT_ID in ${CHECK_SGDEFAULT_IDS}; do
|
||||
SECURITY_GROUP_NAME=$(${AWSCLI} ec2 describe-security-groups ${PROFILE_OPT} --region "${regx}" --group-ids "${CHECK_SGDEFAULT_ID}" --query 'SecurityGroups[*].GroupName[]' --output text 2>&1)
|
||||
textFail "${regx}: Security Group ${SECURITY_GROUP_NAME} (ID: ${CHECK_SGDEFAULT_ID}) was created using the EC2 Launch Wizard" "${regx}" "${CHECK_SGDEFAULT_ID}"
|
||||
done
|
||||
else
|
||||
textPass "${regx}: No Security Groups found that were created using the Wizard" "${regx}" "${CHECK_SGDEFAULT_ID}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,45 +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_extra72="7.2"
|
||||
CHECK_TITLE_extra72="[extra72] Ensure there are no EBS Snapshots set as Public"
|
||||
CHECK_SCORED_extra72="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra72="EXTRA"
|
||||
CHECK_SEVERITY_extra72="Critical"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra72="AwsEc2Snapshot"
|
||||
CHECK_ALTERNATE_extra702="extra72"
|
||||
CHECK_ALTERNATE_check72="extra72"
|
||||
CHECK_ALTERNATE_check702="extra72"
|
||||
CHECK_SERVICENAME_extra72="ec2"
|
||||
CHECK_RISK_extra72='When you share a snapshot; you are giving others access to all of the data on the snapshot. Share snapshots only with people with whom you want to share all of your snapshot data.'
|
||||
CHECK_REMEDIATION_extra72='Ensure the snapshot should be shared.'
|
||||
CHECK_DOC_extra72='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-modifying-snapshot-permissions.html'
|
||||
CHECK_CAF_EPIC_extra72='Data Protection'
|
||||
|
||||
extra72(){
|
||||
# "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 2>&1 | grep -v None )
|
||||
if [[ $(echo "$LIST_OF_EBS_SNAPSHOTS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe snapshot" "$regx"
|
||||
continue
|
||||
fi
|
||||
for snapshot in $LIST_OF_EBS_SNAPSHOTS; do
|
||||
SNAPSHOT_IS_PUBLIC=$($AWSCLI ec2 describe-snapshot-attribute $PROFILE_OPT --region $regx --output text --snapshot-id $snapshot --attribute createVolumePermission --query "CreateVolumePermissions[?Group=='all']")
|
||||
if [[ $SNAPSHOT_IS_PUBLIC ]];then
|
||||
textFail "$regx: $snapshot is currently Public!" "$regx" "$snapshot"
|
||||
else
|
||||
textPass "$regx: $snapshot is not Public" "$regx" "$snapshot"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
@@ -1,48 +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_extra729="7.29"
|
||||
CHECK_TITLE_extra729="[extra729] Ensure there are no EBS Volumes unencrypted"
|
||||
CHECK_SCORED_extra729="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra729="EXTRA"
|
||||
CHECK_SEVERITY_extra729="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra729="AwsEc2Volume"
|
||||
CHECK_ALTERNATE_check729="extra729"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra729="ens-mp.info.3.aws.ebs.1"
|
||||
CHECK_SERVICENAME_extra729="ec2"
|
||||
CHECK_RISK_extra729='Data encryption at rest prevents data visibility in the event of its unauthorized access or theft.'
|
||||
CHECK_REMEDIATION_extra729='Encrypt all EBS volumes and Enable Encryption by default You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example; Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.'
|
||||
CHECK_DOC_extra729='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html'
|
||||
CHECK_CAF_EPIC_extra729='Data Protection'
|
||||
|
||||
extra729(){
|
||||
# "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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_EBS_NON_ENC_VOLUMES" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe volumes" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_EBS_NON_ENC_VOLUMES ]];then
|
||||
for volume in $LIST_OF_EBS_NON_ENC_VOLUMES; do
|
||||
textFail "$regx: $volume is not encrypted!" "$regx" "$volume"
|
||||
done
|
||||
fi
|
||||
LIST_OF_EBS_ENC_VOLUMES=$($AWSCLI ec2 describe-volumes $PROFILE_OPT --region $regx --query 'Volumes[?Encrypted==`true`].VolumeId' --output text)
|
||||
if [[ $LIST_OF_EBS_ENC_VOLUMES ]];then
|
||||
for volume in $LIST_OF_EBS_ENC_VOLUMES; do
|
||||
textPass "$regx: $volume is encrypted" "$regx" "$volume"
|
||||
done
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_extra74="7.4"
|
||||
CHECK_TITLE_extra74="[extra74] Ensure there are no Security Groups without ingress filtering being used"
|
||||
CHECK_SCORED_extra74="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra74="EXTRA"
|
||||
CHECK_SEVERITY_extra74="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra74="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_extra704="extra74"
|
||||
CHECK_ALTERNATE_check74="extra74"
|
||||
CHECK_ALTERNATE_check704="extra74"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra74="ens-mp.com.4.aws.sg.2"
|
||||
CHECK_SERVICENAME_extra74="ec2"
|
||||
CHECK_RISK_extra74='If Security groups are not filtering traffic appropriately the attack surface is increased.'
|
||||
CHECK_REMEDIATION_extra74=' You can grant access to a specific CIDR range; or to another security group in your VPC or in a peer VPC.'
|
||||
CHECK_DOC_extra74='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra74='Infrastructure Security'
|
||||
|
||||
extra74(){
|
||||
# "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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_SECURITYGROUPS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
for SG_ID in $LIST_OF_SECURITYGROUPS; do
|
||||
SG_NO_INGRESS_FILTER=$($AWSCLI ec2 describe-network-interfaces $PROFILE_OPT --region $regx --filters "Name=group-id,Values=$SG_ID" --query "length(NetworkInterfaces)" --output text)
|
||||
if [[ $SG_NO_INGRESS_FILTER -ne 0 ]];then
|
||||
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" "$SG_ID"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
@@ -1,96 +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_extra740="7.40"
|
||||
CHECK_TITLE_extra740="[extra740] Check if EBS snapshots are encrypted"
|
||||
CHECK_SCORED_extra740="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra740="EXTRA"
|
||||
CHECK_SEVERITY_extra740="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra740="AwsEc2Snapshot"
|
||||
CHECK_ALTERNATE_check740="extra740"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra740="ens-mp.info.3.aws.ebs.3"
|
||||
CHECK_SERVICENAME_extra740="ec2"
|
||||
CHECK_RISK_extra740='Data encryption at rest prevents data visibility in the event of its unauthorized access or theft.'
|
||||
CHECK_REMEDIATION_extra740='Encrypt all EBS Snapshot and Enable Encryption by default. You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example; Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.'
|
||||
CHECK_DOC_extra740='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default'
|
||||
CHECK_CAF_EPIC_extra740='Data Protection'
|
||||
|
||||
extra740(){
|
||||
# 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.
|
||||
for regx in ${REGIONS}; do
|
||||
UNENCRYPTED_SNAPSHOTS=$(${AWSCLI} ec2 describe-snapshots ${PROFILE_OPT} \
|
||||
--region ${regx} --owner-ids ${ACCOUNT_NUM} --output text \
|
||||
--query 'Snapshots[?Encrypted==`false`]|[*].{Id:SnapshotId}' 2>&1 \
|
||||
| grep -v None )
|
||||
if [[ $(echo "$UNENCRYPTED_SNAPSHOTS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe snapshots" "$regx"
|
||||
continue
|
||||
fi
|
||||
|
||||
ENCRYPTED_SNAPSHOTS=$(${AWSCLI} ec2 describe-snapshots ${PROFILE_OPT} \
|
||||
--region ${regx} --owner-ids ${ACCOUNT_NUM} --output text \
|
||||
--query 'Snapshots[?Encrypted==`true`]|[*].{Id:SnapshotId}' 2>&1 \
|
||||
| grep -v None )
|
||||
if [[ $(echo "$ENCRYPTED_SNAPSHOTS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe snapshots" "$regx"
|
||||
continue
|
||||
fi
|
||||
typeset -i unencrypted
|
||||
typeset -i encrypted
|
||||
unencrypted=0
|
||||
encrypted=0
|
||||
|
||||
if [[ ${UNENCRYPTED_SNAPSHOTS} ]]; then
|
||||
for snapshot in ${UNENCRYPTED_SNAPSHOTS}; do
|
||||
unencrypted=${unencrypted}+1
|
||||
if [ "${unencrypted}" -le "${MAXITEMS}" ]; then
|
||||
textFail "${regx}: ${snapshot} is not encrypted!" "${regx}" "${snapshot}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ ${ENCRYPTED_SNAPSHOTS} ]]; then
|
||||
for snapshot in ${ENCRYPTED_SNAPSHOTS}; do
|
||||
encrypted=${encrypted}+1
|
||||
if [ "${encrypted}" -le "${MAXITEMS}" ]; then
|
||||
textPass "${regx}: ${snapshot} is encrypted." "${regx}" "${snapshot}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ "${encrypted}" = "0" ]] && [[ "${unencrypted}" = "0" ]] ; then
|
||||
textInfo "${regx}: No EBS volume snapshots" "${regx}"
|
||||
else
|
||||
typeset -i total
|
||||
total=${encrypted}+${unencrypted}
|
||||
if [[ "${unencrypted}" -ge "${MAXITEMS}" ]]; then
|
||||
textFail "${unencrypted} unencrypted snapshots out of ${total} snapshots found. Only the first ${MAXITEMS} unencrypted snapshots are reported!"
|
||||
fi
|
||||
if [[ "${encrypted}" -ge "${MAXITEMS}" ]]; then
|
||||
textPass "${encrypted} encrypted snapshots out of ${total} snapshots found. Only the first ${MAXITEMS} encrypted snapshots are reported."
|
||||
fi
|
||||
# Bit of 'bc' magic to print something like 10.42% or 0.85% or similar. 'bc' has a
|
||||
# bug where it will never print leading zeros. So 0.5 is output as ".5". This has a
|
||||
# little extra clause to print a 0 if 0 < x < 1.
|
||||
ratio=$(echo "scale=2; p=(100*${encrypted}/(${encrypted}+${unencrypted})); if(p<1 && p>0) print 0;print p, \"%\";" | bc 2>/dev/null)
|
||||
exit=$?
|
||||
|
||||
# maybe 'bc' doesn't exist, or it exits with an error
|
||||
if [[ "${exit}" = "0" ]]
|
||||
then
|
||||
textInfo "${regx}: ${ratio} encrypted EBS volumes (${encrypted} out of ${total})" "${regx}"
|
||||
else
|
||||
textInfo "${regx}: ${unencrypted} unencrypted EBS volume snapshots out of ${total} total snapshots" "${regx}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,75 +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_extra741="7.41"
|
||||
CHECK_TITLE_extra741="[extra741] Find secrets in EC2 User Data"
|
||||
CHECK_SCORED_extra741="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra741="EXTRA"
|
||||
CHECK_SEVERITY_extra741="Critical"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra741="AwsEc2Instance"
|
||||
CHECK_ALTERNATE_check741="extra741"
|
||||
CHECK_SERVICENAME_extra741="ec2"
|
||||
CHECK_RISK_extra741='Secrets hardcoded into instance user data can be used by malware and bad actors to gain lateral access to other services.'
|
||||
CHECK_REMEDIATION_extra741='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_extra741='https://docs.aws.amazon.com/secretsmanager/latest/userguide/tutorials_basic.html'
|
||||
CHECK_CAF_EPIC_extra741='IAM'
|
||||
|
||||
extra741(){
|
||||
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
|
||||
CHECK_DETECT_SECRETS_INSTALLATION=$(secretsDetector)
|
||||
if [[ $? -eq 241 ]]; then
|
||||
textInfo "$regx: python library detect-secrets not found. Make sure it is installed correctly." "$regx"
|
||||
else
|
||||
LIST_OF_EC2_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query Reservations[*].Instances[*].InstanceId --output text --max-items $MAXITEMS 2>&1| grep -v None)
|
||||
if [[ $(echo "$LIST_OF_EC2_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe instances" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_EC2_INSTANCES ]];then
|
||||
for instance in $LIST_OF_EC2_INSTANCES; do
|
||||
EC2_USERDATA_FILE="$SECRETS_TEMP_FOLDER/extra741-$instance-userData.decoded"
|
||||
EC2_USERDATA=$($AWSCLI ec2 describe-instance-attribute --attribute userData $PROFILE_OPT --region $regx --instance-id $instance --query UserData.Value --output text| grep -v ^None | decode_report > $EC2_USERDATA_FILE)
|
||||
if [ -s "$EC2_USERDATA_FILE" ];then
|
||||
# This finds ftp or http URLs with credentials and common keywords
|
||||
# FINDINGS=$(egrep -i '[[:alpha:]]*://[[:alnum:]]*:[[:alnum:]]*@.*/|key|secret|token|pass' $EC2_USERDATA_FILE |wc -l|tr -d '\ ')
|
||||
# New implementation using https://github.com/Yelp/detect-secrets
|
||||
# Test if user data is a valid GZIP file, if so gunzip first
|
||||
if gunzip -t "$EC2_USERDATA_FILE" > /dev/null 2>&1; then
|
||||
mv "$EC2_USERDATA_FILE" "$EC2_USERDATA_FILE.gz" ; gunzip "$EC2_USERDATA_FILE.gz"
|
||||
fi
|
||||
FINDINGS=$(secretsDetector file "$EC2_USERDATA_FILE")
|
||||
if [[ $FINDINGS -eq 0 ]]; then
|
||||
textPass "$regx: No secrets found in $instance User Data" "$regx" "$instance"
|
||||
# delete file if nothing interesting is there
|
||||
rm -f "$EC2_USERDATA_FILE"
|
||||
else
|
||||
textFail "$regx: Potential secret found in $instance User Data" "$regx" "$instance"
|
||||
# delete file to not leave trace, user must look at the instance User Data
|
||||
rm -f "$EC2_USERDATA_FILE"
|
||||
fi
|
||||
else
|
||||
textPass "$regx: No secrets found in $instance User Data or it is empty" "$regx" "$instance"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EC2 instances found" "$regx"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
rm -rf $SECRETS_TEMP_FOLDER
|
||||
}
|
||||
@@ -1,41 +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_extra748="7.48"
|
||||
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_CIS_LEVEL_extra748="EXTRA"
|
||||
CHECK_SEVERITY_extra748="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra748="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check748="extra748"
|
||||
CHECK_SERVICENAME_extra748="ec2"
|
||||
CHECK_RISK_extra748='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra748='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra748='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra748='Infrastructure Security'
|
||||
|
||||
extra748(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`0` && ToPort==`65535`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_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"
|
||||
CHECK_SCORED_extra749="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra749="EXTRA"
|
||||
CHECK_SEVERITY_extra749="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra749="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check749="extra749"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra749="ens-mp.com.4.aws.sg.6"
|
||||
CHECK_SERVICENAME_extra749="ec2"
|
||||
CHECK_RISK_extra749='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra749='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra749='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra749='Infrastructure Security'
|
||||
|
||||
extra749(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || ((FromPort<=`1521` && ToPort>=`1521`)||(FromPort<=`2483` && ToPort>=`2483`))) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Oracle ports" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found with any port open to 0.0.0.0/0 for Oracle ports" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,59 +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_extra75="7.5"
|
||||
CHECK_TITLE_extra75="[extra75] Ensure there are no Security Groups not being used"
|
||||
CHECK_SCORED_extra75="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra75="EXTRA"
|
||||
CHECK_SEVERITY_extra75="Informational"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra75="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_extra705="extra75"
|
||||
CHECK_ALTERNATE_check75="extra75"
|
||||
CHECK_ALTERNATE_check705="extra75"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra75="ens-mp.com.4.aws.sg.3"
|
||||
CHECK_SERVICENAME_extra75="ec2"
|
||||
CHECK_RISK_extra75='Having clear definition and scope for Security Groups creates a better administration environment.'
|
||||
CHECK_REMEDIATION_extra75='List all the security groups and then use the cli to check if they are attached to an instance.'
|
||||
CHECK_DOC_extra75='https://aws.amazon.com/premiumsupport/knowledge-center/ec2-find-security-group-resources/'
|
||||
CHECK_CAF_EPIC_extra75='Infrastructure Security'
|
||||
|
||||
extra75(){
|
||||
# "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 2>&1 )
|
||||
if [[ $(echo "$SECURITYGROUPS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $(echo "$SECURITYGROUPS" | jq '."SecurityGroups" | length') -eq 0 ]]; then
|
||||
textInfo "$regx: No Security Groups found in $regx" "$regx"
|
||||
continue
|
||||
fi
|
||||
SECURITYGROUP_NAMES=$(echo $SECURITYGROUPS | jq '.SecurityGroups|map({(.GroupId): (.GroupName)})|add')
|
||||
LIST_OF_SECURITYGROUPS=$(echo $SECURITYGROUP_NAMES | jq -r 'to_entries|sort_by(.key)|.[]|.key')
|
||||
for SG_ID in $LIST_OF_SECURITYGROUPS; do
|
||||
SG_NOT_USED=$($AWSCLI ec2 describe-network-interfaces $PROFILE_OPT --region $regx --filters "Name=group-id,Values=$SG_ID" --query "length(NetworkInterfaces)" --output text)
|
||||
# Default security groups can not be deleted, so draw attention to them
|
||||
if [[ $SG_NOT_USED -eq 0 ]];then
|
||||
GROUP_NAME=$(echo $SECURITYGROUP_NAMES | jq -r --arg id $SG_ID '.[$id]')
|
||||
if [[ $GROUP_NAME != "default" ]];
|
||||
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" "$SG_ID"
|
||||
fi
|
||||
else
|
||||
textPass "$regx: $SG_ID is being used" "$regx" "$SG_ID"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
@@ -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_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"
|
||||
CHECK_SCORED_extra750="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra750="EXTRA"
|
||||
CHECK_SEVERITY_extra750="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra750="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check750="extra750"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra750="ens-mp.com.4.aws.sg.7"
|
||||
CHECK_SERVICENAME_extra750="ec2"
|
||||
CHECK_RISK_extra750='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra750='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra750='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra750='Infrastructure Security'
|
||||
|
||||
extra750(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`3306` && ToPort>=`3306`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for MySQL port" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found open to 0.0.0.0/0 for MySQL port" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_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"
|
||||
CHECK_SCORED_extra751="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra751="EXTRA"
|
||||
CHECK_SEVERITY_extra751="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra751="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check751="extra751"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra751="ens-mp.com.4.aws.sg.8"
|
||||
CHECK_SERVICENAME_extra751="ec2"
|
||||
CHECK_RISK_extra751='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra751='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra751='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra751='Infrastructure Security'
|
||||
|
||||
extra751(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`5432` && ToPort>=`5432`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Postgres port" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found open to 0.0.0.0/0 for Postgres port" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_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"
|
||||
CHECK_SCORED_extra752="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra752="EXTRA"
|
||||
CHECK_SEVERITY_extra752="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra752="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check752="extra752"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra752="ens-mp.com.4.aws.sg.9"
|
||||
CHECK_SERVICENAME_extra752="ec2"
|
||||
CHECK_RISK_extra752='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra752='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra752='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra752='Infrastructure Security'
|
||||
|
||||
extra752(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`6379` && ToPort>=`6379`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Redis port" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found open to 0.0.0.0/0 for Redis port" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_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"
|
||||
CHECK_SCORED_extra753="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra753="EXTRA"
|
||||
CHECK_SEVERITY_extra753="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra753="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check753="extra753"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra753="ens-mp.com.4.aws.sg.10"
|
||||
CHECK_SERVICENAME_extra753="ec2"
|
||||
CHECK_RISK_extra753='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra753='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra753='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra753='Infrastructure Security'
|
||||
|
||||
extra753(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || ((FromPort<=`27017` && ToPort>=`27017`) || (FromPort<=`27018` && ToPort>=`27018`))) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for MongoDB ports" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found open to 0.0.0.0/0 for MongoDB ports" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_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"
|
||||
CHECK_SCORED_extra754="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra754="EXTRA"
|
||||
CHECK_SEVERITY_extra754="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra754="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check754="extra754"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra754="ens-mp.com.4.aws.sg.11"
|
||||
CHECK_SERVICENAME_extra754="ec2"
|
||||
CHECK_RISK_extra754='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra754='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra754='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra754='Infrastructure Security'
|
||||
|
||||
extra754(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || ((FromPort<=`7199` && ToPort>=`7199`) || (FromPort<=`9160` && ToPort>=`9160`)|| (FromPort<=`8888` && ToPort>=`8888`))) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Cassandra ports" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found open to 0.0.0.0/0 for Cassandra ports" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_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"
|
||||
CHECK_SCORED_extra755="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra755="EXTRA"
|
||||
CHECK_SEVERITY_extra755="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra755="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check755="extra755"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra755="ens-mp.com.4.aws.sg.12"
|
||||
CHECK_SERVICENAME_extra755="ec2"
|
||||
CHECK_RISK_extra755='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra755='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra755='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra755='Infrastructure Security'
|
||||
|
||||
extra755(){
|
||||
for regx in $REGIONS; do
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`11211` && ToPort>=`11211`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $SG_LIST ]];then
|
||||
for SG in $SG_LIST;do
|
||||
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Memcached port" "$regx" "$SG"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found open to 0.0.0.0/0 for Memcached port" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,50 +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_extra757="7.57"
|
||||
CHECK_TITLE_extra757="[extra757] Check EC2 Instances older than 6 months"
|
||||
CHECK_SCORED_extra757="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra757="EXTRA"
|
||||
CHECK_SEVERITY_extra757="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra757="AwsEc2Instance"
|
||||
CHECK_ALTERNATE_check757="extra757"
|
||||
CHECK_SERVICENAME_extra757="ec2"
|
||||
CHECK_RISK_extra757='Having old instances within your AWS account could increase the risk of having vulnerable software.'
|
||||
CHECK_REMEDIATION_extra757='Check if software running in the instance is up to date and patched accordingly. Use AWS Systems Manager to patch instances and view patching compliance information.'
|
||||
CHECK_DOC_extra757='https://docs.aws.amazon.com/systems-manager/latest/userguide/viewing-patch-compliance-results.html'
|
||||
CHECK_CAF_EPIC_extra757='Infrastructure Security'
|
||||
|
||||
extra757(){
|
||||
OLDAGE="$(get_date_previous_than_months 6)"
|
||||
for regx in $REGIONS; do
|
||||
EC2_RUNNING=$($AWSCLI ec2 describe-instances --query "Reservations[*].Instances[*].[InstanceId]" $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$EC2_RUNNING" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe instances" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $EC2_RUNNING ]]; then
|
||||
INSTACES_OLD_THAN_AGE=$($AWSCLI ec2 describe-instances --query "Reservations[].Instances[?LaunchTime<='$OLDAGE'][].{id: InstanceId, launched: LaunchTime}" $PROFILE_OPT --region $regx --output text)
|
||||
if [[ $INSTACES_OLD_THAN_AGE ]]; then
|
||||
while IFS= read -r ec2_instace
|
||||
do
|
||||
EC2_ID=$(echo "$ec2_instace" | awk '{print $1}')
|
||||
LAUNCH_DATE=$(echo "$ec2_instace" | awk '{print $2}')
|
||||
textFail "$regx: EC2 Instance $EC2_ID running before than $OLDAGE" "$regx" "$EC2_ID"
|
||||
done <<< "$INSTACES_OLD_THAN_AGE"
|
||||
else
|
||||
textPass "$regx: All Instances newer than 6 months" "$regx"
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: No EC2 Instances Found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,44 +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_extra758="7.58"
|
||||
CHECK_TITLE_extra758="[extra758] Check EC2 Instances older than 12 months "
|
||||
CHECK_SCORED_extra758="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra758="EXTRA"
|
||||
CHECK_SEVERITY_extra758="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra758="AwsEc2Instance"
|
||||
CHECK_ALTERNATE_check758="extra758"
|
||||
CHECK_SERVICENAME_extra758="ec2"
|
||||
CHECK_RISK_extra758='Having old instances within your AWS account could increase the risk of having vulnerable software.'
|
||||
CHECK_REMEDIATION_extra758='Check if software running in the instance is up to date and patched accordingly. Use AWS Systems Manager to patch instances and view patching compliance information.'
|
||||
CHECK_DOC_extra758='https://docs.aws.amazon.com/systems-manager/latest/userguide/viewing-patch-compliance-results.html'
|
||||
CHECK_CAF_EPIC_extra758='Infrastructure Security'
|
||||
|
||||
extra758(){
|
||||
# OLDAGE has the following format: YYYY-MM-DD
|
||||
OLDAGE="$(get_date_previous_than_months 12)"
|
||||
for regx in ${REGIONS}; do
|
||||
INSTACES_OLD_THAN_AGE=$("${AWSCLI}" ec2 describe-instances --query "Reservations[].Instances[?LaunchTime<='${OLDAGE}'][].[InstanceId, LaunchTime, State.Name]" ${PROFILE_OPT} --region "${regx}" --output text 2>&1)
|
||||
if [[ $(echo "${INSTACES_OLD_THAN_AGE}" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "${regx}: Access Denied trying to describe instances" "${regx}"
|
||||
continue
|
||||
fi
|
||||
if [[ "${INSTACES_OLD_THAN_AGE}" ]]; then
|
||||
while read -r EC2_ID LAUNCH_DATE STATE
|
||||
do
|
||||
textFail "${regx}: EC2 Instance ${EC2_ID} launched before than ${OLDAGE}. Launch date: ${LAUNCH_DATE} - State: ${STATE}" "${regx}" "${EC2_ID}"
|
||||
done <<< "${INSTACES_OLD_THAN_AGE}"
|
||||
else
|
||||
textPass "${regx}: No EC2 Instances found older than 12 months" "${regx}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,43 +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_extra76="7.6"
|
||||
CHECK_TITLE_extra76="[extra76] Ensure there are no EC2 AMIs set as Public"
|
||||
CHECK_SCORED_extra76="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra76="EXTRA"
|
||||
CHECK_SEVERITY_extra76="Critical"
|
||||
CHECK_ALTERNATE_extra706="extra76"
|
||||
CHECK_ALTERNATE_check76="extra76"
|
||||
CHECK_ALTERNATE_check706="extra76"
|
||||
CHECK_SERVICENAME_extra76="ec2"
|
||||
CHECK_RISK_extra76='A shared AMI is an AMI that a developer created and made available for other developers to use. If AMIs have embebed information about the environment could pose a security risk. You use a shared AMI at your own risk. Amazon can not vouch for the integrity or security of AMIs shared by Amazon EC2 users. '
|
||||
CHECK_REMEDIATION_extra76='List all shared AMIs and make sure there is a business reason for them.'
|
||||
CHECK_DOC_extra76='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/usingsharedamis-finding.html'
|
||||
CHECK_CAF_EPIC_extra76='Infrastructure Security'
|
||||
|
||||
extra76(){
|
||||
# "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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_PUBLIC_AMIS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe images" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_PUBLIC_AMIS ]];then
|
||||
for ami in $LIST_OF_PUBLIC_AMIS; do
|
||||
textFail "$regx: $ami is currently Public!" "$regx" "$ami"
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Public AMIs found" "$regx" "$ami"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,43 +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_extra761="7.61"
|
||||
CHECK_TITLE_extra761="[extra761] Check if EBS Default Encryption is activated "
|
||||
CHECK_SCORED_extra761="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra761="EXTRA"
|
||||
CHECK_SEVERITY_extra761="Medium"
|
||||
CHECK_ALTERNATE_check761="extra761"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra761="ens-mp.info.3.aws.ebs.2"
|
||||
CHECK_SERVICENAME_extra761="ec2"
|
||||
CHECK_RISK_extra761='If not enabled sensitive information at rest is not protected.'
|
||||
CHECK_REMEDIATION_extra761='Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.'
|
||||
CHECK_DOC_extra761='https://aws.amazon.com/premiumsupport/knowledge-center/ebs-automatic-encryption/'
|
||||
CHECK_CAF_EPIC_extra761='Data Protection'
|
||||
|
||||
extra761(){
|
||||
for regx in $REGIONS; do
|
||||
EBS_DEFAULT_ENCRYPTION=$($AWSCLI ec2 get-ebs-encryption-by-default $PROFILE_OPT --region $regx --query 'EbsEncryptionByDefault' --output text 2>&1)
|
||||
if [[ $(echo "$EBS_DEFAULT_ENCRYPTION" | grep "argument operation: Invalid choice") ]]; then
|
||||
textInfo "$regx: Newer aws cli needed for get-ebs-encryption-by-default" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $(echo "$EBS_DEFAULT_ENCRYPTION" | grep UnauthorizedOperation) ]]; then
|
||||
textInfo "$regx: Prowler needs ec2:GetEbsEncryptionByDefault permission for this check" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $EBS_DEFAULT_ENCRYPTION == "True" ]];then
|
||||
textPass "$regx: EBS Default Encryption is activated" "$regx"
|
||||
else
|
||||
textFail "$regx: EBS Default Encryption is not activated" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,45 +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_extra770="7.70"
|
||||
CHECK_TITLE_extra770="[extra770] Check for internet facing EC2 instances with Instance Profiles attached "
|
||||
CHECK_SCORED_extra770="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra770="EXTRA"
|
||||
CHECK_SEVERITY_extra770="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra770="AwsEc2Instance"
|
||||
CHECK_ALTERNATE_check770="extra770"
|
||||
CHECK_SERVICENAME_extra770="ec2"
|
||||
CHECK_RISK_extra770='Exposing an EC2 directly to internet increases the attack surface and therefore the risk of compromise.'
|
||||
CHECK_REMEDIATION_extra770='Use an ALB and apply WAF ACL.'
|
||||
CHECK_DOC_extra770='https://aws.amazon.com/blogs/aws/aws-web-application-firewall-waf-for-application-load-balancers/'
|
||||
CHECK_CAF_EPIC_extra770='Infrastructure Security'
|
||||
|
||||
extra770(){
|
||||
# "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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_PUBLIC_INSTANCES_WITH_INSTANCE_PROFILES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe instances" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_PUBLIC_INSTANCES_WITH_INSTANCE_PROFILES ]];then
|
||||
while read -r instance;do
|
||||
INSTANCE_ID=$(echo $instance | awk '{ print $1; }')
|
||||
PUBLIC_IP=$(echo $instance | awk '{ print $2; }')
|
||||
INSTANCE_PROFILE=$(echo $instance | awk '{ print $3; }')
|
||||
textFail "$regx: Instance: $INSTANCE_ID at IP: $PUBLIC_IP is internet-facing with Instance Profile $INSTANCE_PROFILE" "$regx" "$INSTANCE_ID"
|
||||
done <<< "$LIST_OF_PUBLIC_INSTANCES_WITH_INSTANCE_PROFILES"
|
||||
else
|
||||
textPass "$regx: no Internet Facing EC2 Instances with Instance Profiles found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_extra772="7.72"
|
||||
CHECK_TITLE_extra772="[extra772] Check if elastic IPs are unused "
|
||||
CHECK_SCORED_extra772="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra772="EXTRA"
|
||||
CHECK_SEVERITY_extra772="Low"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra772="AwsEc2Eip"
|
||||
CHECK_ALTERNATE_check772="extra772"
|
||||
CHECK_SERVICENAME_extra772="ec2"
|
||||
CHECK_RISK_extra772='You are charged by the hour for each Elastic IP address that are not attached to an EC2 instance .'
|
||||
CHECK_REMEDIATION_extra772='If you don’t need an Elastic IP address; you can stop the charges by releasing the IP address.'
|
||||
CHECK_DOC_extra772='https://aws.amazon.com/premiumsupport/knowledge-center/elastic-ip-charges/'
|
||||
CHECK_CAF_EPIC_extra772='Infrastructure Security'
|
||||
|
||||
extra772(){
|
||||
for region in $REGIONS; do
|
||||
EIP_DUMP=$($AWSCLI ec2 describe-addresses ${PROFILE_OPT} --region $region --output json 2>&1)
|
||||
if [[ $(echo "$EIP_DUMP" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe addresses" "$regx"
|
||||
continue
|
||||
fi
|
||||
EIP_LIST=$(echo $EIP_DUMP | jq -r '.Addresses[].AllocationId')
|
||||
if [[ $EIP_LIST ]]; then
|
||||
for eip in $EIP_LIST; do
|
||||
ASSOCIATION_ID=$(echo $EIP_DUMP | jq -r --arg i "$eip" '.Addresses[]|select(.AllocationId==$i)|.AssociationId')
|
||||
if [[ "$ASSOCIATION_ID" == "null" ]]; then
|
||||
textFail "$region: EIP $eip is unused" "$region" "$eip"
|
||||
else
|
||||
textPass "$region: EIP $eip is used" "$region" "$eip"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$region: No Elastic IPs found" $region
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2020) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# 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.
|
||||
|
||||
# Current VPC Limit is 120 rules (60 inbound and 60 outbound)
|
||||
# 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 more than 50 ingress or egress rules "
|
||||
CHECK_SCORED_extra777="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra777="EXTRA"
|
||||
CHECK_SEVERITY_extra777="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra777="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check777="extra777"
|
||||
CHECK_SERVICENAME_extra777="ec2"
|
||||
CHECK_RISK_extra777='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra777='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra777='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra777='Infrastructure Security'
|
||||
|
||||
extra777(){
|
||||
THRESHOLD=50
|
||||
|
||||
for regx in ${REGIONS}; do
|
||||
SECURITY_GROUP_IDS=$(${AWSCLI} ec2 describe-security-groups \
|
||||
${PROFILE_OPT} \
|
||||
--region ${regx} \
|
||||
--query 'SecurityGroups[*].GroupId' \
|
||||
--output text 2>&1| xargs )
|
||||
if [[ $(echo "$SECURITY_GROUP_IDS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
|
||||
for SECURITY_GROUP in ${SECURITY_GROUP_IDS}; do
|
||||
|
||||
INGRESS_TOTAL=$(${AWSCLI} ec2 describe-security-groups \
|
||||
${PROFILE_OPT} \
|
||||
--filter "Name=group-id,Values=${SECURITY_GROUP}" \
|
||||
--query "SecurityGroups[*].IpPermissions[*].IpRanges" \
|
||||
--region ${regx} \
|
||||
--output text | wc -l | xargs
|
||||
)
|
||||
|
||||
EGRESS_TOTAL=$(${AWSCLI} ec2 describe-security-groups \
|
||||
${PROFILE_OPT} \
|
||||
--filter "Name=group-id,Values=${SECURITY_GROUP}" \
|
||||
--query "SecurityGroups[*].IpPermissionsEgress[*].IpRanges" \
|
||||
--region ${regx} \
|
||||
--output text | wc -l | xargs
|
||||
)
|
||||
|
||||
if [[ (${INGRESS_TOTAL} -ge ${THRESHOLD}) || (${EGRESS_TOTAL} -ge ${THRESHOLD}) ]]; then
|
||||
textFail "${regx}: ${SECURITY_GROUP} has ${INGRESS_TOTAL} inbound rules and ${EGRESS_TOTAL} outbound rules" "${regx}" "${SECURITY_GROUP}"
|
||||
else
|
||||
textPass "${regx}: ${SECURITY_GROUP} has ${INGRESS_TOTAL} inbound rules and ${EGRESS_TOTAL} outbound rules" "${regx}" "${SECURITY_GROUP}"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
@@ -1,86 +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_extra778="7.78"
|
||||
CHECK_TITLE_extra778="[extra778] Find VPC security groups with wide-open public IPv4 CIDR ranges (non-RFC1918) "
|
||||
CHECK_SCORED_extra778="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra778="EXTRA"
|
||||
CHECK_SEVERITY_extra778="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra778="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check778="extra778"
|
||||
CHECK_SERVICENAME_extra778="ec2"
|
||||
CHECK_RISK_extra778='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra778='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra778='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
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\.)"
|
||||
|
||||
check_cidr() {
|
||||
local SECURITY_GROUP=$1
|
||||
local DIRECTION=$2
|
||||
local DIRECTION_FILTER=""
|
||||
local REGION=$3
|
||||
|
||||
case ${DIRECTION} in
|
||||
"inbound")
|
||||
DIRECTION_FILTER="IpPermissions"
|
||||
;;
|
||||
"outbound")
|
||||
DIRECTION_FILTER="IpPermissionsEgress"
|
||||
;;
|
||||
esac
|
||||
|
||||
CIDR_IP_LIST=$(${AWSCLI} ec2 describe-security-groups \
|
||||
${PROFILE_OPT} \
|
||||
--filter "Name=group-id,Values=${SECURITY_GROUP}" \
|
||||
--query "SecurityGroups[*].${DIRECTION_FILTER}[*].IpRanges[*].CidrIp" \
|
||||
--region ${REGION} \
|
||||
--output text 2>&1| xargs )
|
||||
if [[ $(echo "$CIDR_IP_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
|
||||
for CIDR_IP in ${CIDR_IP_LIST}; do
|
||||
if [[ ! ${CIDR_IP} =~ ${RFC1918_REGEX} ]]; then
|
||||
CIDR=$(echo ${CIDR_IP} | cut -d"/" -f2 | xargs)
|
||||
|
||||
# Edge case "0.0.0.0/0" for RDP and SSH are checked already by check41 and check42
|
||||
if [[ ${CIDR} < ${CIDR_THRESHOLD} && 0 < ${CIDR} ]]; then
|
||||
textFail "${REGION}: ${SECURITY_GROUP} has potential wide-open non-RFC1918 address ${CIDR_IP} in ${DIRECTION} rule" "${REGION}" "${SECURITY_GROUP}"
|
||||
else
|
||||
textPass "${REGION}: ${SECURITY_GROUP} has no potential wide-open non-RFC1918 address" "${REGION}" "${SECURITY_GROUP}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
for regx in ${REGIONS}; do
|
||||
SECURITY_GROUP_IDS=$(${AWSCLI} ec2 describe-security-groups \
|
||||
${PROFILE_OPT} \
|
||||
--region ${regx} \
|
||||
--query 'SecurityGroups[*].GroupId' \
|
||||
--output text 2>&1| xargs )
|
||||
if [[ $(echo "$SECURITY_GROUP_IDS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
for SECURITY_GROUP in ${SECURITY_GROUP_IDS}; do
|
||||
check_cidr "${SECURITY_GROUP}" "inbound" "${regx}"
|
||||
check_cidr "${SECURITY_GROUP}" "outbound" "${regx}"
|
||||
done
|
||||
done
|
||||
}
|
||||
@@ -1,62 +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_extra779="7.79"
|
||||
CHECK_TITLE_extra779="[extra779] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Elasticsearch/Kibana ports"
|
||||
CHECK_SCORED_extra779="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra779="EXTRA"
|
||||
CHECK_SEVERITY_extra779="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra779="AwsEc2SecurityGroup"
|
||||
CHECK_ALTERNATE_check779="extra779"
|
||||
CHECK_SERVICENAME_extra779="ec2"
|
||||
CHECK_RISK_extra779='If Security groups are not properly configured the attack surface is increased. '
|
||||
CHECK_REMEDIATION_extra779='Use a Zero Trust approach. Narrow ingress traffic as much as possible. Consider north-south as well as east-west traffic.'
|
||||
CHECK_DOC_extra779='https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html'
|
||||
CHECK_CAF_EPIC_extra779='Infrastructure Security'
|
||||
|
||||
extra779(){
|
||||
ES_API_PORT="9200"
|
||||
ES_DATA_PORT="9300"
|
||||
ES_KIBANA_PORT="5601"
|
||||
# Test connectivity and authentication is performed by check extra787
|
||||
for regx in $REGIONS; do
|
||||
# crate a list of SG open to the world with port $ES_API_PORT or $ES_DATA_PORT or $ES_KIBANA_PORT
|
||||
SG_LIST=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --output text \
|
||||
--query "SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=\`$ES_API_PORT\` && ToPort>=\`$ES_API_PORT\`) || (FromPort<=\`$ES_DATA_PORT\` && ToPort>=\`$ES_DATA_PORT\`) || (FromPort<=\`$ES_KIBANA_PORT\` && ToPort>=\`$ES_KIBANA_PORT\`)) && (contains(IpRanges[].CidrIp, \`0.0.0.0/0\`) || contains(Ipv6Ranges[].CidrIpv6, \`::/0\`))]) > \`0\`].{GroupId:GroupId}" 2>&1)
|
||||
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
# in case of open security groups goes through each one
|
||||
if [[ $SG_LIST ]];then
|
||||
for sg in $SG_LIST;do
|
||||
# temp file store the list of instances IDs and public IP address if found
|
||||
TEMP_EXTRA779_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-es-domain.EXTRA779.XXXXXXXXXX)
|
||||
# finds instances with that open security group attached and get its public ip address (if it has one)
|
||||
$AWSCLI $PROFILE_OPT --region $regx ec2 describe-instances --filters Name=instance.group-id,Values=$sg --query 'Reservations[*].Instances[*].[InstanceId,PublicIpAddress]' --output text > $TEMP_EXTRA779_FILE
|
||||
# in case of exposed instances it does access checks
|
||||
if [[ -s "$TEMP_EXTRA779_FILE" ]];then
|
||||
while read instance eip ; do
|
||||
if [[ "$eip" == "None" ]];then
|
||||
textInfo "$regx: Found instance $instance with private IP on Security Group: $sg" "$regx"
|
||||
else
|
||||
textFail "$regx: Found instance $instance with public IP $eip on Security Group: $sg open to 0.0.0.0/0 on for Elasticsearch/Kibana ports - use extra787 to test AUTH" "$regx" "$sg"
|
||||
fi
|
||||
done < <(cat $TEMP_EXTRA779_FILE)
|
||||
fi
|
||||
rm -rf $TEMP_EXTRA779_FILE
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Security Groups found open to 0.0.0.0/0 for Elasticsearch/Kibana ports" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2020) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# 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_extra786="7.86"
|
||||
CHECK_TITLE_extra786="[extra786] Check if EC2 Instance Metadata Service Version 2 (IMDSv2) is Enabled and Required "
|
||||
CHECK_SCORED_extra786="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra786="EXTRA"
|
||||
CHECK_SEVERITY_extra786="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra786="AwsEc2Instance"
|
||||
CHECK_ALTERNATE_check786="extra786"
|
||||
CHECK_SERVICENAME_extra786="ec2"
|
||||
CHECK_RISK_extra786='Using IMDSv2 will protect from misconfiguration and SSRF vulnerabilities. IMDSv1 will not.'
|
||||
CHECK_REMEDIATION_extra786='If you don’t need IMDS you can turn it off. Using aws-cli you can force the instance to use only IMDSv2.'
|
||||
CHECK_DOC_extra786='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html#configuring-instance-metadata-options'
|
||||
CHECK_CAF_EPIC_extra786='Infrastructure Security'
|
||||
|
||||
extra786(){
|
||||
for regx in $REGIONS; do
|
||||
TEMP_EXTRA786_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-es-domain.EXTRA786.XXXXXXXXXX)
|
||||
$AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx \
|
||||
--query 'Reservations[*].Instances[*].{HttpTokens:MetadataOptions.HttpTokens,HttpEndpoint:MetadataOptions.HttpEndpoint,InstanceId:InstanceId}' \
|
||||
--output text --max-items $MAXITEMS > $TEMP_EXTRA786_FILE 2>&1
|
||||
if [[ $(cat $TEMP_EXTRA786_FILE | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe instances" "$regx"
|
||||
continue
|
||||
fi
|
||||
# if the file contains data, there are instances in that region
|
||||
if [[ -s "$TEMP_EXTRA786_FILE" ]];then
|
||||
# here we read content from the file fields instanceid httptokens_status httpendpoint
|
||||
while read httpendpoint httptokens_status instanceid ; do
|
||||
#echo i:$instanceid tok:$httptokens_status end:$httpendpoint
|
||||
if [[ "$httpendpoint" == "enabled" && "$httptokens_status" == "required" ]];then
|
||||
textPass "$regx: EC2 Instance $instanceid has IMDSv2 enabled and required" "$regx" "$instanceid"
|
||||
elif [[ "$httpendpoint" == "disabled" ]];then
|
||||
textInfo "$regx: EC2 Instance $instanceid has HTTP endpoint access to metadata service disabled" "$regx"
|
||||
else
|
||||
textFail "$regx: EC2 Instance $instanceid has IMDSv2 disabled or not required" "$regx" "$instanceid"
|
||||
fi
|
||||
done < <(cat $TEMP_EXTRA786_FILE)
|
||||
else
|
||||
textInfo "$regx: no EC2 Instances found" "$regx"
|
||||
fi
|
||||
rm -fr $TEMP_EXTRA786_FILE
|
||||
done
|
||||
}
|
||||
|
||||
# Remediation:
|
||||
|
||||
# aws ec2 modify-instance-metadata-options \
|
||||
# --instance-id i-1234567898abcdef0 \
|
||||
# --http-tokens required \
|
||||
# --http-endpoint enabled
|
||||
|
||||
# More information here https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
|
||||
@@ -1,64 +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.
|
||||
|
||||
# Remediation:
|
||||
#
|
||||
# https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html
|
||||
#
|
||||
# aws ecr put-image-scanning-configuration \
|
||||
# --region <value> \
|
||||
# --repository-name <value> \
|
||||
# --image-scanning-configuration scanOnPush=true
|
||||
|
||||
CHECK_ID_extra765="7.65"
|
||||
CHECK_TITLE_extra765="[extra765] Check if ECR image scan on push is enabled "
|
||||
CHECK_SCORED_extra765="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra765="EXTRA"
|
||||
CHECK_SEVERITY_extra765="Medium"
|
||||
CHECK_ALTERNATE_check765="extra765"
|
||||
CHECK_SERVICENAME_extra765="ecr"
|
||||
CHECK_RISK_extra765='Amazon ECR image scanning helps in identifying software vulnerabilities in your container images. Amazon ECR uses the Common Vulnerabilities and Exposures (CVEs) database from the open-source Clair project and provides a list of scan findings. '
|
||||
CHECK_REMEDIATION_extra765='Enable ECR image scanning and review the scan findings for information about the security of the container images that are being deployed.'
|
||||
CHECK_DOC_extra765='https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html'
|
||||
CHECK_CAF_EPIC_extra765='Infrastructure Security'
|
||||
|
||||
extra765(){
|
||||
for region in $REGIONS; do
|
||||
LIST_ECR_REPOS=$($AWSCLI ecr describe-repositories $PROFILE_OPT --region $region --query "repositories[*].[repositoryName]" --output text 2>&1)
|
||||
if [[ $(echo "$LIST_ECR_REPOS" | grep AccessDenied) ]]; then
|
||||
textInfo "$region: Access Denied Trying to describe ECR repositories" "$region"
|
||||
continue
|
||||
fi
|
||||
if [[ ! -z "$LIST_ECR_REPOS" ]]; then
|
||||
for repo in $LIST_ECR_REPOS; do
|
||||
SCAN_ENABLED=$($AWSCLI ecr describe-repositories $PROFILE_OPT --region $region --query "repositories[?repositoryName==\`$repo\`].[imageScanningConfiguration.scanOnPush]" --output text 2>&1)
|
||||
case "$SCAN_ENABLED" in
|
||||
"True")
|
||||
textPass "$region: ECR repository $repo has scan on push enabled" "$region" "$repo"
|
||||
;;
|
||||
"False")
|
||||
textFail "$region: ECR repository $repo has scan on push disabled!" "$region" "$repo"
|
||||
;;
|
||||
"None")
|
||||
textInfo "$region: ECR repository $repo has no scanOnPush status: newer awscli needed" "$region" "$repo"
|
||||
;;
|
||||
"*")
|
||||
textInfo "$region: ECR repository $repo has unknown scanOnPush status \"$SCAN_ENABLED\"" "$region" "$repo"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
textInfo "$region: No ECR repositories found" "$region"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,68 +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_extra77="7.7"
|
||||
CHECK_TITLE_extra77="[extra77] Ensure there are no ECR repositories set as Public"
|
||||
CHECK_SCORED_extra77="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra77="EXTRA"
|
||||
CHECK_SEVERITY_extra77="Critical"
|
||||
CHECK_ALTERNATE_extra707="extra77"
|
||||
CHECK_ALTERNATE_check77="extra77"
|
||||
CHECK_ALTERNATE_check707="extra77"
|
||||
CHECK_SERVICENAME_extra77="ecr"
|
||||
CHECK_RISK_extra77='Policy may allow Anonymous users to perform actions.'
|
||||
CHECK_REMEDIATION_extra77='Ensure this repository and its contents should be publicly accessible.'
|
||||
CHECK_DOC_extra77='https://docs.aws.amazon.com/AmazonECR/latest/public/security_iam_service-with-iam.html'
|
||||
CHECK_CAF_EPIC_extra77='Data Protection'
|
||||
|
||||
extra77(){
|
||||
# "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
|
||||
textInfo "$regx: Access Denied Trying to describe ECR repositories" "$regx" "$repo"
|
||||
continue
|
||||
fi
|
||||
if [[ $(echo "$LIST_ECR_REPOS" | grep SubscriptionRequiredException) ]]; then
|
||||
textInfo "$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 $regx --repository-name $repo --query "policyText" --output text > $TEMP_POLICY_FILE 2>&1
|
||||
if [[ $(grep AccessDenied $TEMP_POLICY_FILE) ]]; then
|
||||
textInfo "$regx: Access Denied to get repository policy for repo $repo" "$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 "$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 "$regx: $repo policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
|
||||
else
|
||||
textPass "$regx: $repo is not open" "$regx" "$repo"
|
||||
fi
|
||||
rm -f $TEMP_POLICY_FILE
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No ECR repositories found" "$regx" "$repo"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,114 +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.
|
||||
|
||||
# Remediation:
|
||||
#
|
||||
# https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html
|
||||
#
|
||||
# aws ecr put-image-scanning-configuration \
|
||||
# --region <value> \
|
||||
# --repository-name <value> \
|
||||
# --image-scanning-configuration scanOnPush=true
|
||||
#
|
||||
# aws ecr describe-image-scan-findings \
|
||||
# --region <value> \
|
||||
# --repository-name <value>
|
||||
# --image-id imageTag=<value>
|
||||
|
||||
CHECK_ID_extra776="7.76"
|
||||
CHECK_TITLE_extra776="[extra776] Check if ECR image scan found vulnerabilities in the newest image version"
|
||||
CHECK_SCORED_extra776="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra776="EXTRA"
|
||||
CHECK_SEVERITY_extra776="Medium"
|
||||
CHECK_ALTERNATE_check776="extra776"
|
||||
CHECK_SERVICENAME_extra776="ecr"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra776="AwsEcrRepository"
|
||||
CHECK_RISK_extra776='Amazon ECR image scanning helps in identifying software vulnerabilities in your container images. Amazon ECR uses the Common Vulnerabilities and Exposures (CVEs) database from the open-source Clair project and provides a list of scan findings. '
|
||||
CHECK_REMEDIATION_extra776='Open the Amazon ECR console. Then look for vulnerabilities and fix them.'
|
||||
CHECK_DOC_extra776='https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html#describe-scan-findings'
|
||||
CHECK_CAF_EPIC_extra776='Logging and Monitoring'
|
||||
|
||||
extra776(){
|
||||
for region in ${REGIONS}; do
|
||||
# List ECR repositories
|
||||
LIST_ECR_REPOS=$($AWSCLI ecr describe-repositories $PROFILE_OPT --region "${region}" --query "repositories[*].[repositoryName]" --output text 2>&1)
|
||||
# Handle authorization errors
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "$LIST_ECR_REPOS"; then
|
||||
textInfo "$region: Access Denied trying to describe ECR repositories" "$region"
|
||||
continue
|
||||
fi
|
||||
if [[ -n "$LIST_ECR_REPOS" ]]; then
|
||||
for repo in $LIST_ECR_REPOS; do
|
||||
# Check if the repository has scanOnPush enabled
|
||||
SCAN_ENABLED=$($AWSCLI ecr describe-repositories $PROFILE_OPT --region "${region}" --query "repositories[?repositoryName=='${repo}'].[imageScanningConfiguration.scanOnPush]" --output text 2>&1)
|
||||
if [[ "${SCAN_ENABLED}" == "True" ]]; then
|
||||
# Recover newest image digest
|
||||
NEWEST_IMAGE_DIGEST=$($AWSCLI ecr describe-images $PROFILE_OPT --region "${region}" --repository-name "${repo}" --query "sort_by(imageDetails,& imagePushedAt)[-1].imageDigest" --output text | head -n 1 2>&1)
|
||||
if [[ "${NEWEST_IMAGE_DIGEST}" != *"None"* ]]; then
|
||||
# Recover newest image tag
|
||||
NEWEST_IMAGE_TAG=$($AWSCLI ecr describe-images $PROFILE_OPT --region "${region}" --repository-name "${repo}" --query "sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]" --output text | head -n 1 2>&1)
|
||||
if [[ -n "${LIST_ECR_REPOS}" ]]; then
|
||||
# For this newest digest, recover the last scan status
|
||||
IMAGE_SCAN_STATUS=$($AWSCLI ecr describe-image-scan-findings $PROFILE_OPT --region "${region}" --repository-name "${repo}" --image-id imageDigest="${NEWEST_IMAGE_DIGEST}" --query "imageScanStatus.status" --output text 2>&1)
|
||||
if [[ "${IMAGE_SCAN_STATUS}" == *"ScanNotFoundException"* ]]; then
|
||||
textFail "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} without a scan" "${region}" "${repo}"
|
||||
else
|
||||
if [[ "${IMAGE_SCAN_STATUS}" == *"FAILED"* ]]; then
|
||||
textFail "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} with scan status ${IMAGE_SCAN_STATUS}" "${region}" "${repo}"
|
||||
else
|
||||
# For this newest digest, recover the number of findings found
|
||||
# This search needs a JSON response to match against severity
|
||||
FINDINGS_COUNT=$($AWSCLI ecr describe-image-scan-findings $PROFILE_OPT --region "${region}" --repository-name "${repo}" --image-id imageDigest="${NEWEST_IMAGE_DIGEST}" --query "imageScanFindings.findingSeverityCounts" --output json 2>&1)
|
||||
if [[ -n "${FINDINGS_COUNT}" ]]; then
|
||||
SEVERITY_CRITICAL=$(jq -r '.CRITICAL' <<< "${FINDINGS_COUNT}")
|
||||
if [[ "${SEVERITY_CRITICAL}" != "null" ]]; then
|
||||
textFail "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} with CRITICAL ($SEVERITY_CRITICAL) findings" "${region}" "${repo}"
|
||||
fi
|
||||
SEVERITY_HIGH=$(jq -r '.HIGH' <<< "${FINDINGS_COUNT}")
|
||||
if [[ "${SEVERITY_HIGH}" != "null" ]]; then
|
||||
textFail "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} with HIGH ($SEVERITY_HIGH) findings" "${region}" "${repo}"
|
||||
fi
|
||||
SEVERITY_MEDIUM=$(jq -r '.MEDIUM' <<< "${FINDINGS_COUNT}")
|
||||
if [[ "${SEVERITY_MEDIUM}" != "null" ]]; then
|
||||
textFail "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} with MEDIUM ($SEVERITY_MEDIUM) findings" "${region}" "${repo}"
|
||||
fi
|
||||
SEVERITY_LOW=$(jq -r '.LOW' <<< "${FINDINGS_COUNT}")
|
||||
if [[ "${SEVERITY_LOW}" != "null" ]]; then
|
||||
textInfo "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} with LOW ($SEVERITY_LOW) findings" "${region}" "${repo}"
|
||||
fi
|
||||
SEVERITY_INFORMATIONAL=$(jq -r '.INFORMATIONAL' <<< "${FINDINGS_COUNT}")
|
||||
if [[ "${SEVERITY_INFORMATIONAL}" != "null" ]]; then
|
||||
textInfo "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} with INFORMATIONAL ($SEVERITY_INFORMATIONAL) findings" "${region}" "${repo}"
|
||||
fi
|
||||
SEVERITY_UNDEFINED=$(jq -r '.UNDEFINED' <<< "${FINDINGS_COUNT}")
|
||||
if [[ "${SEVERITY_UNDEFINED}" != "null" ]]; then
|
||||
textInfo "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} with UNDEFINED ($SEVERITY_UNDEFINED) findings" "${region}" "${repo}"
|
||||
fi
|
||||
else
|
||||
textPass "${region}: ECR repository ${repo} has imageTag ${NEWEST_IMAGE_TAG} without findings" "${region}" "${repo}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
textInfo "${region}: ECR repository ${repo} has no images" "${region}"
|
||||
fi
|
||||
else
|
||||
textInfo "${region}: ECR repository ${repo} has scanOnPush disabled" "${region}" "${repo}"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "${region}: No ECR repositories found" "${region}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,71 +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_extra768="7.68"
|
||||
CHECK_TITLE_extra768="[extra768] Find secrets in ECS task definitions environment variables "
|
||||
CHECK_SCORED_extra768="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra768="EXTRA"
|
||||
CHECK_SEVERITY_extra768="Critical"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra768="AwsEcsTaskDefinition"
|
||||
CHECK_ALTERNATE_check768="extra768"
|
||||
CHECK_SERVICENAME_extra768="ecs"
|
||||
CHECK_RISK_extra768='The use of a hard-coded password increases the possibility of password guessing. If hard-coded passwords are used; it is possible that malicious users gain access through the account in question.'
|
||||
CHECK_REMEDIATION_extra768='Use Secrets Manager or Parameter Store to securely provide credentials to containers without hardcoding the secrets in code or passing them through environment variables.'
|
||||
CHECK_DOC_extra768='https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html'
|
||||
CHECK_CAF_EPIC_extra768='Logging and Monitoring'
|
||||
|
||||
extra768(){
|
||||
SECRETS_TEMP_FOLDER="$PROWLER_DIR/secrets-$ACCOUNT_NUM-$PROWLER_START_TIME"
|
||||
if [[ ! -d $SECRETS_TEMP_FOLDER ]]; then
|
||||
mkdir $SECRETS_TEMP_FOLDER
|
||||
fi
|
||||
for regx in $REGIONS; do
|
||||
CHECK_DETECT_SECRETS_INSTALLATION=$(secretsDetector)
|
||||
if [[ $? -eq 241 ]]; then
|
||||
textInfo "$regx: python library detect-secrets not found. Make sure it is installed correctly." "$regx"
|
||||
else
|
||||
# Get a list of all task definition families first:
|
||||
FAMILIES=$($AWSCLI ecs list-task-definition-families $PROFILE_OPT --region $regx --status ACTIVE 2>&1 )
|
||||
if [[ $(echo "$FAMILIES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list task definition families" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $(echo $FAMILIES | jq -r .families[]) ]]; then
|
||||
for FAMILY in $(echo $FAMILIES | jq -r .families[]);do
|
||||
# Get the full task definition arn:
|
||||
TASK_DEFINITION_TEMP=$($AWSCLI ecs list-task-definitions $PROFILE_OPT --region $regx --family-prefix $FAMILY --sort DESC --max-items 1 | jq -r .taskDefinitionArns[0])
|
||||
# We only care about the task definition name:
|
||||
IFS='/' read -r -a splitArn <<< "$TASK_DEFINITION_TEMP"
|
||||
TASK_DEFINITION=${splitArn[1]}
|
||||
TASK_DEFINITION_ENV_VARIABLES_FILE="$SECRETS_TEMP_FOLDER/extra768-$TASK_DEFINITION-$regx-variables.txt"
|
||||
TASK_DEFINITION_ENV_VARIABLES=$($AWSCLI ecs $PROFILE_OPT --region $regx describe-task-definition --task-definition $TASK_DEFINITION --query 'taskDefinition.containerDefinitions[*].environment' --output text > $TASK_DEFINITION_ENV_VARIABLES_FILE)
|
||||
if [ -s $TASK_DEFINITION_ENV_VARIABLES_FILE ];then
|
||||
# Implementation using https://github.com/Yelp/detect-secrets
|
||||
FINDINGS=$(secretsDetector file $TASK_DEFINITION_ENV_VARIABLES_FILE)
|
||||
if [[ $FINDINGS -eq 0 ]]; then
|
||||
textPass "$regx: No secrets found in ECS task definition $TASK_DEFINITION variables" "$regx" "$TASK_DEFINITION"
|
||||
# delete file if nothing interesting is there
|
||||
rm -f $TASK_DEFINITION_ENV_VARIABLES_FILE
|
||||
else
|
||||
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" "$TASK_DEFINITION"
|
||||
rm -f $TASK_DEFINITION_ENV_VARIABLES_FILE
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No ECS task definitions found" "$regx"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,53 +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_extra7143="7.143"
|
||||
CHECK_TITLE_extra7143="[extra7143] Check if EFS have policies which allow access to everyone"
|
||||
CHECK_SCORED_extra7143="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7143="EXTRA"
|
||||
CHECK_SEVERITY_extra7143="Critical"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7143="AwsEFS"
|
||||
CHECK_ALTERNATE_check7143="extra7143"
|
||||
CHECK_SERVICENAME_extra7143="efs"
|
||||
CHECK_RISK_extra7143='EFS accessible to everyone could expose sensitive data to bad actors'
|
||||
CHECK_REMEDIATION_extra7143='Ensure efs has some policy but it does not have principle as *'
|
||||
CHECK_DOC_extra7143='https://docs.aws.amazon.com/efs/latest/ug/access-control-block-public-access.html'
|
||||
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 regx in $REGIONS; do
|
||||
LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query FileSystems[*].FileSystemId --output text 2>&1|xargs -n1 )
|
||||
if [[ $(echo "$LIST_OF_EFS_IDS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe file systems" "$regx"
|
||||
continue
|
||||
fi
|
||||
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 $regx --file-system-id $efsId --output json --query Policy 2>&1)
|
||||
if [[ $EFS_POLICY_STATEMENTS == *PolicyNotFound* ]]; then
|
||||
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 "$regx: EFS $efsId has policy which allows access to everyone" "$regx" "$efsId"
|
||||
else
|
||||
textPass "$regx: EFS $efsId has policy which does not allow access to everyone" "$regx" "$efsId"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
else
|
||||
textInfo "$regx: No EFS found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,51 +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_extra7148="7.148"
|
||||
CHECK_TITLE_extra7148="[extra7148] Check if EFS File systems have backup enabled"
|
||||
CHECK_SCORED_extra7148="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7148="EXTRA"
|
||||
CHECK_SEVERITY_extra7148="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7148="AwsEfsFileSystem"
|
||||
CHECK_ALTERNATE_check7148="extra7148"
|
||||
CHECK_SERVICENAME_extra7148="efs"
|
||||
CHECK_RISK_extra7148='If backup is not enabled; data is vulnerable. Human error or bad actors could erase or modify data.'
|
||||
CHECK_REMEDIATION_extra7148='Enable automated backup for production data. Define a retention period and periodically test backup restoration. A Disaster Recovery process should be in place to govern Data Protection approach.'
|
||||
CHECK_DOC_extra7148='https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html'
|
||||
CHECK_CAF_EPIC_extra7148='Data Protection'
|
||||
|
||||
extra7148() {
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_EFS_SYSTEMS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query 'FileSystems[*].FileSystemId' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_EFS_SYSTEMS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe file systems" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_EFS_SYSTEMS ]]; then
|
||||
for filesystem in $LIST_OF_EFS_SYSTEMS; do
|
||||
# if retention is 0 then is disabled
|
||||
BACKUP_POLICY=$($AWSCLI efs describe-backup-policy $PROFILE_OPT --region $regx --file-system-id $filesystem --query BackupPolicy --output text 2>&1)
|
||||
if [[ $(echo "$BACKUP_POLICY" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe backup policy" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $BACKUP_POLICY == "DISABLED" ]]; then
|
||||
textFail "$regx: File system $filesystem does not have backup enabled!" "$regx" "$filesystem"
|
||||
else
|
||||
textPass "$regx: EFS File system $filesystem has backup enabled" "$regx" "$filesystem"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EFS File systems found" "$regx" "$filesystem"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_extra7161="7.161"
|
||||
CHECK_TITLE_extra7161="[extra7161] Check if EFS protects sensitive data with encryption at rest"
|
||||
CHECK_SCORED_extra7161="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7161="EXTRA"
|
||||
CHECK_SEVERITY_extra7161="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7161="AwsEfsFileSystem"
|
||||
CHECK_ALTERNATE_check7161="extra7161"
|
||||
CHECK_SERVICENAME_extra7161="efs"
|
||||
CHECK_RISK_extra7161='EFS should be encrypted at rest to prevent exposure of sensitive data to bad actors'
|
||||
CHECK_REMEDIATION_extra7161='Ensure that encryption at rest is enabled for EFS file systems. Encryption at rest can only be enabled during the file system creation.'
|
||||
CHECK_DOC_extra7161='https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html'
|
||||
CHECK_CAF_EPIC_extra7161='Data Protection'
|
||||
|
||||
extra7161(){
|
||||
# "Check if EFS has encryption at rest enabled (Not Scored) (Proposed requirement for 1.5 CIS benchmark)"
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query 'FileSystems[*].FileSystemId' --output text 2>&1| xargs -n1 )
|
||||
if [[ $(echo "$LIST_OF_EFS_IDS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe file systems" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_EFS_IDS ]]; then
|
||||
for efsId in $LIST_OF_EFS_IDS;do
|
||||
EFS_ENCRYPTION_CHECK=$($AWSCLI efs $PROFILE_OPT describe-file-systems --region $regx --file-system-id $efsId --output json --query 'FileSystems[*].Encrypted' --output text)
|
||||
if [[ $EFS_ENCRYPTION_CHECK == "True" ]]; then
|
||||
textPass "$regx: EFS $efsId has has encryption at rest enabled" "$regx" "$efsId"
|
||||
else
|
||||
textFail "$regx: EFS: $efsId does not have encryption at rest enabled" "$regx" "$efsId"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EFS found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,52 +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_extra794="7.94"
|
||||
CHECK_TITLE_extra794="[extra794] Ensure EKS Control Plane Audit Logging is enabled for all log types"
|
||||
CHECK_SCORED_extra794="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra794="EXTRA"
|
||||
CHECK_SEVERITY_extra794="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra794="AwsEksCluster"
|
||||
CHECK_ALTERNATE_check794="extra794"
|
||||
CHECK_SERVICENAME_extra794="eks"
|
||||
CHECK_RISK_extra794='If logs are not enabled; monitoring of service use and threat analysis is not possible.'
|
||||
CHECK_REMEDIATION_extra794='Make sure you logging for EKS control plane is enabled.'
|
||||
CHECK_DOC_extra794='https://docs.aws.amazon.com/eks/latest/userguide/logging-monitoring.html'
|
||||
CHECK_CAF_EPIC_extra794='Logging and Monitoring'
|
||||
|
||||
extra794(){
|
||||
for regx in $REGIONS; do
|
||||
CLUSTERS=$($AWSCLI eks list-clusters $PROFILE_OPT --region $regx --query 'clusters[]' --output text 2>&1)
|
||||
if [[ $(echo "$CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list EKS clusters" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $CLUSTERS ]]; then
|
||||
for CLUSTER in $CLUSTERS;do
|
||||
CLUSTERDEF=$($AWSCLI eks describe-cluster $PROFILE_OPT --region $regx --name $CLUSTER --query 'cluster.logging.clusterLogging[0]')
|
||||
LOGGING_ENABLED=$(echo $CLUSTERDEF | jq -r '.enabled')
|
||||
TYPES=$(echo $CLUSTERDEF | jq -r '.types[]')
|
||||
if [[ $LOGGING_ENABLED == "true" ]]; then
|
||||
if [[ $(echo $TYPES | egrep "api.*audit.*authenticator.*controllerManager.*scheduler") ]]; then
|
||||
textPass "$regx: Control plane logging enabled and correctly configured for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
else
|
||||
textFail "$regx: Control plane logging enabled; not all log types collected for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
fi
|
||||
else
|
||||
textFail "$regx: Control plane logging is not enabled for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EKS clusters found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,49 +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_extra795="7.95"
|
||||
CHECK_TITLE_extra795="[extra795] Ensure EKS Clusters are created with Private Endpoint Enabled and Public Access Disabled"
|
||||
CHECK_SCORED_extra795="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra795="EXTRA"
|
||||
CHECK_SEVERITY_extra795="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra795="AwsEksCluster"
|
||||
CHECK_ALTERNATE_check795="extra795"
|
||||
CHECK_SERVICENAME_extra795="eks"
|
||||
CHECK_RISK_extra795='Publicly accessible services could expose sensitive data to bad actors.'
|
||||
CHECK_REMEDIATION_extra795='Enable private access to the Kubernetes API server so that all communication between your nodes and the API server stays within your VPC. Disable internet access to the API server.'
|
||||
CHECK_DOC_extra795='https://docs.aws.amazon.com/eks/latest/userguide/infrastructure-security.html'
|
||||
CHECK_CAF_EPIC_extra795='Infrastructure Security'
|
||||
|
||||
extra795(){
|
||||
for regx in $REGIONS; do
|
||||
CLUSTERS=$($AWSCLI eks list-clusters $PROFILE_OPT --region $regx --query 'clusters[]' --output text 2>&1)
|
||||
if [[ $(echo "$CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list EKS clusters" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $CLUSTERS ]]; then
|
||||
for CLUSTER in $CLUSTERS;do
|
||||
CLUSTERDEF=$($AWSCLI eks describe-cluster $PROFILE_OPT --region $regx --name $CLUSTER --query 'cluster.resourcesVpcConfig')
|
||||
PUB_ENABLED=$(echo $CLUSTERDEF | jq -r '.endpointPublicAccess')
|
||||
PRIV_ENABLED=$(echo $CLUSTERDEF | jq -r '.endpointPrivateAccess')
|
||||
|
||||
if [[ $PUB_ENABLED == "false" ]] && [[ $PRIV_ENABLED == "true" ]] ; then
|
||||
textPass "$regx: Cluster endpoint access is private for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
else
|
||||
textFail "$regx: Cluster endpoint access is public for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EKS clusters found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,54 +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_extra796="7.96"
|
||||
CHECK_TITLE_extra796="[extra796] Restrict Access to the EKS Control Plane Endpoint"
|
||||
CHECK_SCORED_extra796="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra796="EXTRA"
|
||||
CHECK_SEVERITY_extra796="High"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra796="AwsEksCluster"
|
||||
CHECK_ALTERNATE_check796="extra796"
|
||||
CHECK_SERVICENAME_extra796="eks"
|
||||
CHECK_RISK_extra796='By default; this API server endpoint is public to the internet; and access to the API server is secured using a combination of AWS Identity and Access Management (IAM) and native Kubernetes Role Based Access Control (RBAC).'
|
||||
CHECK_REMEDIATION_extra796='You should enable private access to the Kubernetes API server so that all communication between your nodes and the API server stays within your VPC. You can limit the IP addresses that can access your API server from the internet; or completely disable internet access to the API server.'
|
||||
CHECK_DOC_extra796='https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html'
|
||||
CHECK_CAF_EPIC_extra796='Infrastructure Security'
|
||||
|
||||
extra796(){
|
||||
for regx in $REGIONS; do
|
||||
CLUSTERS=$($AWSCLI eks list-clusters $PROFILE_OPT --region $regx --query 'clusters[]' --output text 2>&1)
|
||||
if [[ $(echo "$CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list EKS clusters" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $CLUSTERS ]]; then
|
||||
for CLUSTER in $CLUSTERS;do
|
||||
CLUSTERDEF=$($AWSCLI eks describe-cluster $PROFILE_OPT --region $regx --name $CLUSTER --query 'cluster.resourcesVpcConfig')
|
||||
PUB_ENABLED=$(echo $CLUSTERDEF | jq -r '.endpointPublicAccess')
|
||||
PRIV_ENABLED=$(echo $CLUSTERDEF | jq -r '.endpointPrivateAccess')
|
||||
PUB_ACCESS_CIDRS=$(echo $CLUSTERDEF | jq -r '.publicAccessCidrs')
|
||||
|
||||
if [[ $PUB_ENABLED == "false" ]] && [[ $PRIV_ENABLED == "true" ]] ; then
|
||||
textPass "$regx: Cluster endpoint access is private for EKS cluster $CLUSTER" "$regx"
|
||||
else
|
||||
if [[ $(echo $PUB_ACCESS_CIDRS | grep "0.0.0.0/0") ]] ; then
|
||||
textFail "$regx: Cluster control plane access is not restricted for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
else
|
||||
textPass "$regx: Cluster control plane access is restricted for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EKS clusters found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_extra797="7.97"
|
||||
CHECK_TITLE_extra797="[extra797] Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs)"
|
||||
CHECK_SCORED_extra797="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra797="EXTRA"
|
||||
CHECK_SEVERITY_extra797="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra797="AwsEksCluster"
|
||||
CHECK_ALTERNATE_check797="extra797"
|
||||
CHECK_SERVICENAME_extra797="eks"
|
||||
CHECK_RISK_extra797='Implementing envelope encryption is considered a security best practice for applications that store sensitive data and is part of a defense in depth security strategy.'
|
||||
CHECK_REMEDIATION_extra797=' Setup your own Customer Master Key (CMK) in KMS and link this key by providing the CMK ARN when you create an EKS cluster.'
|
||||
CHECK_DOC_extra797='https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html'
|
||||
CHECK_CAF_EPIC_extra797='Data Protection'
|
||||
|
||||
extra797(){
|
||||
for regx in $REGIONS; do
|
||||
CLUSTERS=$($AWSCLI eks list-clusters $PROFILE_OPT --region $regx --query 'clusters[]' --output text 2>&1)
|
||||
if [[ $(echo "$CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list EKS clusters" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $CLUSTERS ]]; then
|
||||
for CLUSTER in $CLUSTERS;do
|
||||
ENC_CONFIG=$($AWSCLI eks describe-cluster $PROFILE_OPT --region $regx --name $CLUSTER --query 'cluster.encryptionConfig')
|
||||
|
||||
if [[ $ENC_CONFIG == "null" ]]; then
|
||||
textFail "$regx: Encryption for Kubernetes secrets is not configured for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
else
|
||||
textPass "$regx: Encryption for Kubernetes secrets is configured for EKS cluster $CLUSTER" "$regx" "$CLUSTER"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No EKS clusters found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,81 +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_extra7129="7.129"
|
||||
CHECK_TITLE_extra7129="[extra7129] Check if Application Load Balancer has a WAF ACL attached"
|
||||
CHECK_SCORED_extra7129="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7129="EXTRA"
|
||||
CHECK_SEVERITY_extra7129="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7129="AwsElasticLoadBalancingV2LoadBalancer"
|
||||
CHECK_ALTERNATE_check7129="extra7129"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra7129="ens-mp.s.2.aws.waf.3"
|
||||
CHECK_SERVICENAME_extra7129="elb"
|
||||
CHECK_RISK_extra7129='If not WAF ACL is attached risk of web attacks increases.'
|
||||
CHECK_REMEDIATION_extra7129='Using the AWS Management Console open the AWS WAF console to attach an ACL.'
|
||||
CHECK_DOC_extra7129='https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-associating-aws-resource.html'
|
||||
CHECK_CAF_EPIC_extra7129='Infrastructure Security'
|
||||
|
||||
PARALLEL_REGIONS="50"
|
||||
|
||||
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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
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[@]} -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
|
||||
WAF_PROTECTED_ALBS+=($wafaclarn)
|
||||
fi
|
||||
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" "$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" "$alb"
|
||||
done
|
||||
fi
|
||||
else
|
||||
textFail "$regx: Application Load Balancer $alb is not protected by WAF ACL" "$regx" "$alb"
|
||||
fi
|
||||
else
|
||||
textFail "$regx: Application Load Balancer $alb is not protected no WAF ACL found" "$regx" "$alb"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No Application Load Balancers found" "$regx"
|
||||
fi
|
||||
# ) &
|
||||
done
|
||||
# wait
|
||||
}
|
||||
@@ -1,48 +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_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_CIS_LEVEL_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 sending 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'
|
||||
|
||||
|
||||
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 2>&1)
|
||||
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
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
|
||||
textFail "$regx: Application Load Balancer $alb is not dropping invalid header fields" "$regx" "$alb"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: no ALBs found"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,48 +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_extra7150="7.150"
|
||||
CHECK_TITLE_extra7150="[extra7150] Check if Elastic Load Balancers have deletion protection enabled"
|
||||
CHECK_SCORED_extra7150="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7150="EXTRA"
|
||||
CHECK_SEVERITY_extra7150="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7150="AwsElbLoadBalancer"
|
||||
CHECK_ALTERNATE_check7150="extra7150"
|
||||
CHECK_SERVICENAME_extra7150="elb"
|
||||
CHECK_RISK_extra7150='If deletion protection is not enabled; the resource is not protected against deletion.'
|
||||
CHECK_REMEDIATION_extra7150='Enable deletion protection attribute; this is not enabled by default.'
|
||||
CHECK_DOC_extra7150='https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#deletion-protection'
|
||||
CHECK_CAF_EPIC_extra7150='Data Protection'
|
||||
|
||||
extra7150(){
|
||||
# "Check if Elastic Load Balancers have delete protection enabled."
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text 2>&1|xargs -n1 )
|
||||
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ELBSV2 ]]; then
|
||||
for elb in $LIST_OF_ELBSV2; do
|
||||
CHECK_DELETION_PROTECTION_ENABLED=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $elb --query Attributes[*] --output text|grep "deletion_protection.enabled"|grep true )
|
||||
ELBV2_NAME=$(echo $elb|cut -d\/ -f3)
|
||||
if [[ $CHECK_DELETION_PROTECTION_ENABLED ]]; then
|
||||
textPass "$regx: $ELBV2_NAME has the attribute deletion protection enabled" "$regx" "$elb"
|
||||
else
|
||||
textFail "$regx: $ELBV2_NAME does not have deletion protection enabled." "$regx" "$elb"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,54 +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.
|
||||
# Remediation:
|
||||
#
|
||||
# https://docs.aws.amazon.com/cli/latest/reference/elbv2/modify-load-balancer-attributes.html
|
||||
#
|
||||
# aws elbv2 modify-load-balancer-attributes
|
||||
# --load-balancer-arn <alb arn>\
|
||||
# --attributes Key=routing.http.desync_mitigation_mode,Value=<defensive/strictest>
|
||||
|
||||
CHECK_ID_extra7155="7.155"
|
||||
CHECK_TITLE_extra7155="[extra7155] Check whether the Application Load Balancer is configured with defensive or strictest desync mitigation mode"
|
||||
CHECK_SCORED_extra7155="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7155="EXTRA"
|
||||
CHECK_SEVERITY_extra7155="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7155="AwsElasticLoadBalancingV2LoadBalancer"
|
||||
CHECK_ALTERNATE_check7155="extra7155"
|
||||
CHECK_SERVICENAME_extra7155="elb"
|
||||
CHECK_RISK_extra7155='HTTP Desync issues can lead to request smuggling and make your applications vulnerable to request queue or cache poisoning; which could lead to credential hijacking or execution of unauthorized commands.'
|
||||
CHECK_REMEDIATION_extra7155='Ensure Application Load Balancer is configured with defensive or strictest desync mitigation mode'
|
||||
CHECK_DOC_extra7155='https://aws.amazon.com/about-aws/whats-new/2020/08/application-and-classic-load-balancers-adding-defense-in-depth-with-introduction-of-desync-mitigation-mode/'
|
||||
CHECK_CAF_EPIC_extra7155='Data Protection'
|
||||
|
||||
extra7155() {
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application`].[LoadBalancerArn]' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ELBSV2 ]];then
|
||||
for alb in $LIST_OF_ELBSV2;do
|
||||
CHECK_DESYNC_MITIGATION_MODE=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $alb --query 'Attributes[8]' --output json | jq -r '.Value')
|
||||
if [[ $CHECK_DESYNC_MITIGATION_MODE == "monitor" ]]; then
|
||||
textFail "$regx: Application load balancer $alb does not have desync mitigation mode set as defensive or strictest." "$regx" "$alb"
|
||||
else
|
||||
textPass "$regx: Application load balancer $alb is configured with correct desync mitigation mode." "$regx" "$alb"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No Application Load Balancers found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,47 +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_extra7158="7.158"
|
||||
CHECK_TITLE_extra7158="[extra7158] Check if ELBV2 has listeners underneath"
|
||||
CHECK_SCORED_extra7158="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7158="EXTRA"
|
||||
CHECK_SEVERITY_extra7158="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7158="AwsElbv2LoadBalancer"
|
||||
CHECK_ALTERNATE_check7158="extra7158"
|
||||
CHECK_SERVICENAME_extra7158="elb"
|
||||
CHECK_RISK_extra7158='The rules that are defined for a listener determine how the load balancer routes requests to its registered targets.'
|
||||
CHECK_REMEDIATION_extra7158='Add listeners to Elastic Load Balancers V2.'
|
||||
CHECK_DOC_extra7158='https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html'
|
||||
CHECK_CAF_EPIC_extra7158='Data Protection'
|
||||
|
||||
extra7158(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers --query 'LoadBalancers[*].LoadBalancerArn' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ELBSV2 ]]; then
|
||||
for elb in $LIST_OF_ELBSV2; do
|
||||
LIST_OF_LISTENERS=$($AWSCLI elbv2 describe-listeners $PROFILE_OPT --region $regx --load-balancer-arn $elb --query 'Listeners[*]' --output text)
|
||||
ELBV2_NAME=$(echo $elb|cut -d\/ -f3)
|
||||
if [[ $LIST_OF_LISTENERS ]]; then
|
||||
textPass "$regx: $ELBV2_NAME has listeners underneath" "$regx" "$elb"
|
||||
else
|
||||
textFail "$regx: $ELBV2_NAME has no listeners underneath" "$regx" "$elb"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -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_extra7159="7.159"
|
||||
CHECK_TITLE_extra7159="[extra7159] Check if ELB has listeners underneath"
|
||||
CHECK_SCORED_extra7159="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7159="EXTRA"
|
||||
CHECK_SEVERITY_extra7159="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7159="AwsElbLoadBalancer"
|
||||
CHECK_ALTERNATE_check7159="extra7159"
|
||||
CHECK_SERVICENAME_extra7159="elb"
|
||||
CHECK_RISK_extra7159='The rules that are defined for a listener determine how the load balancer routes requests to its registered targets.'
|
||||
CHECK_REMEDIATION_extra7159='Add listeners to Elastic Load Balancers.'
|
||||
CHECK_DOC_extra7159='https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html'
|
||||
CHECK_CAF_EPIC_extra7159='Data Protection'
|
||||
|
||||
extra7159(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers --query 'LoadBalancerDescriptions[*].LoadBalancerName' $PROFILE_OPT --region $regx --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_ELBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ELBS ]]; then
|
||||
for elb in $LIST_OF_ELBS; do
|
||||
LIST_OF_LISTENERS=$($AWSCLI elb describe-load-balancers --load-balancer-name $elb --query 'LoadBalancerDescriptions[*].ListenerDescriptions' $PROFILE_OPT --region $regx --output text)
|
||||
if [[ $LIST_OF_LISTENERS ]]; then
|
||||
textPass "$regx: $elb has listeners underneath" "$regx" "$elb"
|
||||
else
|
||||
textFail "$regx: $elb has no listeners underneath" "$regx" "$elb"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,65 +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_extra717="7.17"
|
||||
CHECK_TITLE_extra717="[extra717] Check if Elastic Load Balancers have logging enabled"
|
||||
CHECK_SCORED_extra717="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra717="EXTRA"
|
||||
CHECK_SEVERITY_extra717="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra717="AwsElbLoadBalancer"
|
||||
CHECK_ALTERNATE_check717="extra717"
|
||||
CHECK_SERVICENAME_extra717="elb"
|
||||
CHECK_RISK_extra717='If logs are not enabled monitoring of service use and threat analysis is not possible.'
|
||||
CHECK_REMEDIATION_extra717='Enable ELB logging; create la log lifecycle and define use cases.'
|
||||
CHECK_DOC_extra717='https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html'
|
||||
CHECK_CAF_EPIC_extra717='Logging and Monitoring'
|
||||
|
||||
extra717(){
|
||||
# "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 2>&1 |xargs -n1)
|
||||
if [[ $(echo "$LIST_OF_ELBS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list load balancers v1" "$regx"
|
||||
continue
|
||||
fi
|
||||
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text 2>&1 |xargs -n1)
|
||||
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
|
||||
textInfo "$regx: Access Denied trying to list load balancers v2" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ELBS || $LIST_OF_ELBSV2 ]]; then
|
||||
if [[ $LIST_OF_ELBS ]]; then
|
||||
for elb in $LIST_OF_ELBS; do
|
||||
CHECK_ELBS_LOG_ENABLED=$($AWSCLI elb describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-name $elb --query 'LoadBalancerAttributes.AccessLog.Enabled' |grep "^true")
|
||||
if [[ $CHECK_ELBS_LOG_ENABLED ]]; then
|
||||
textPass "$regx: $elb has access logs to S3 configured" "$regx" "$elb"
|
||||
else
|
||||
textFail "$regx: $elb has not configured access logs" "$regx" "$elb"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ $LIST_OF_ELBSV2 ]]; then
|
||||
for elbarn in $LIST_OF_ELBSV2; do
|
||||
CHECK_ELBSV2_LOG_ENABLED=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query Attributes[*] --output text |grep "^access_logs.s3.enabled"|cut -f2|grep true)
|
||||
ELBV2_NAME=$(echo $elbarn|cut -d\/ -f3)
|
||||
if [[ $CHECK_ELBSV2_LOG_ENABLED ]]; then
|
||||
textPass "$regx: $ELBV2_NAME has access logs to S3 configured" "$regx" "$elb"
|
||||
else
|
||||
textFail "$regx: $ELBV2_NAME has not configured access logs" "$regx" "$elb"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: No ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,53 +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_extra79="7.9"
|
||||
CHECK_TITLE_extra79="[extra79] Check for internet facing Elastic Load Balancers"
|
||||
CHECK_SCORED_extra79="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra79="EXTRA"
|
||||
CHECK_SEVERITY_extra79="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra79="AwsElbLoadBalancer"
|
||||
CHECK_ALTERNATE_extra709="extra79"
|
||||
CHECK_ALTERNATE_check79="extra79"
|
||||
CHECK_ALTERNATE_check709="extra79"
|
||||
CHECK_SERVICENAME_extra79="elb"
|
||||
CHECK_RISK_extra79='Publicly accessible load balancers could expose sensitive data to bad actors.'
|
||||
CHECK_REMEDIATION_extra79='Ensure the load balancer should be publicly accessible. If publicly exposed ensure a WAF ACL is implemented.'
|
||||
CHECK_DOC_extra79='https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-associating-aws-resource.html'
|
||||
CHECK_CAF_EPIC_extra79='Data Protection'
|
||||
|
||||
extra79(){
|
||||
# "Check for internet facing Elastic Load Balancers "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_PUBLIC_ELBS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[?Scheme == `internet-facing`].[LoadBalancerName,DNSName]' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_PUBLIC_ELBS" | grep AccessDenied) ]]; then
|
||||
textInfo "$regx: Access Denied Trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
LIST_OF_PUBLIC_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Scheme == `internet-facing`].[LoadBalancerName,DNSName]' --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_PUBLIC_ELBSV2" | grep AccessDenied) ]]; then
|
||||
textInfo "$regx: Access Denied Trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
LIST_OF_ALL_ELBS=$( echo $LIST_OF_PUBLIC_ELBS; echo $LIST_OF_PUBLIC_ELBSV2)
|
||||
LIST_OF_ALL_ELBS_PER_LINE=$( echo $LIST_OF_ALL_ELBS| xargs -n2 )
|
||||
if [[ $LIST_OF_ALL_ELBS ]];then
|
||||
while read -r elb;do
|
||||
ELB_NAME=$(echo $elb | awk '{ print $1; }')
|
||||
ELB_DNSNAME=$(echo $elb | awk '{ print $2; }')
|
||||
textFail "$regx: ELB: $ELB_NAME at DNS: $ELB_DNSNAME is internet-facing!" "$regx" "$ELB_NAME"
|
||||
done <<< "$LIST_OF_ALL_ELBS_PER_LINE"
|
||||
else
|
||||
textPass "$regx: no Internet Facing ELBs found" "$regx" "$ELB_NAME"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,143 +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_extra792="7.92"
|
||||
CHECK_TITLE_extra792="[extra792] Check if Elastic Load Balancers have insecure SSL ciphers "
|
||||
CHECK_SCORED_extra792="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra792="EXTRA"
|
||||
CHECK_SEVERITY_extra792="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra792="AwsElbLoadBalancer"
|
||||
CHECK_ALTERNATE_check792="extra792"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra792="ens-mp.com.2.aws.elb.2"
|
||||
CHECK_SERVICENAME_extra792="elb"
|
||||
CHECK_RISK_extra792='Using insecure ciphers could affect privacy of in transit information.'
|
||||
CHECK_REMEDIATION_extra792='Use a Security policy with a ciphers that are stronger as possible. Drop legacy and unsecure ciphers.'
|
||||
CHECK_DOC_extra792='https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-ssl-security-policy.html'
|
||||
CHECK_CAF_EPIC_extra792='Data Protection'
|
||||
|
||||
extra792(){
|
||||
# "Check if Elastic Load Balancers have insecure SSL ciphers "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[*].LoadBalancerName' --output text 2>&1|xargs -n1 )
|
||||
if [[ $(echo "$LIST_OF_ELBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text 2>&1|xargs -n1 )
|
||||
if [[ $(echo "$LIST_OF_ELBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ELBS || $LIST_OF_ELBSV2 ]]; then
|
||||
if [[ $LIST_OF_ELBS ]]; then
|
||||
# https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-ssl-security-policy.html#ssl-ciphers
|
||||
# https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html
|
||||
ELBSECUREPOLICIES=("ELBSecurityPolicy-TLS-1-2-2017-01")
|
||||
ELBSECURECIPHERS=("Protocol-TLSv1.2" "ECDHE-ECDSA-AES128-GCM-SHA256" "ECDHE-RSA-AES128-GCM-SHA256" "ECDHE-ECDSA-AES128-SHA256" "ECDHE-RSA-AES128-SHA256" "ECDHE-ECDSA-AES128-SHA" "ECDHE-RSA-AES128-SHA" "ECDHE-ECDSA-AES256-GCM-SHA384" "ECDHE-RSA-AES256-GCM-SHA384" "ECDHE-ECDSA-AES256-SHA384" "ECDHE-RSA-AES256-SHA384" "ECDHE-RSA-AES256-SHA" "ECDHE-ECDSA-AES256-SHA" "AES128-GCM-SHA256" "AES128-SHA256" "AES128-SHA" "AES256-GCM-SHA384" "AES256-SHA256" "AES256-SHA" "Server-Defined-Cipher-Order")
|
||||
|
||||
for elb in $LIST_OF_ELBS; do
|
||||
ELB_LISTENERS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --load-balancer-name $elb --query "LoadBalancerDescriptions[0]" --output json)
|
||||
|
||||
ELB_PROTOCOLS=$(echo $ELB_LISTENERS | jq -r '.ListenerDescriptions[].Listener.Protocol')
|
||||
if [[ $(echo $ELB_PROTOCOLS | grep HTTPS) || $(echo $ELB_PROTOCOLS | grep SSL) ]]; then
|
||||
ELB_POLICIES=$(echo $ELB_LISTENERS | jq -r '.ListenerDescriptions[].PolicyNames | .[]')
|
||||
passed=true
|
||||
for policy in $ELB_POLICIES; do
|
||||
# Check for secure default policy
|
||||
REFPOLICY=$($AWSCLI elb describe-load-balancer-policies $PROFILE_OPT --region $regx --load-balancer-name $elb --policy-name $policy --query "PolicyDescriptions[0].PolicyAttributeDescriptions[?(AttributeName == 'Reference-Security-Policy')].AttributeValue" --output text)
|
||||
if [[ -n "$REFPOLICY" ]]; then
|
||||
if array_contains ELBSECUREPOLICIES "$REFPOLICY"; then
|
||||
continue # Passed for this listener/policy
|
||||
else
|
||||
passed=false
|
||||
fi
|
||||
else
|
||||
# A custom policy is in use. Check Ciphers
|
||||
CIPHERS=$($AWSCLI elb describe-load-balancer-policies $PROFILE_OPT --region $regx --load-balancer-name $elb --policy-name $policy --query "PolicyDescriptions[0].PolicyAttributeDescriptions[?(AttributeValue == 'true')].AttributeName" --output text)
|
||||
for cipher in $CIPHERS; do
|
||||
if array_contains ELBSECURECIPHERS "$cipher"; then
|
||||
continue
|
||||
else
|
||||
passed=false
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
if $passed; then
|
||||
textPass "$regx: $elb has no insecure SSL ciphers" "$regx" "$elb"
|
||||
else
|
||||
textFail "$regx: $elb has insecure SSL ciphers" "$regx" "$elb"
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: $elb does not have an HTTPS or SSL listener" "$regx"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ $LIST_OF_ELBSV2 ]]; then
|
||||
# NOTE - ALBs do NOT support custom security policies
|
||||
# https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html
|
||||
ELBV2SECUREPOLICIES=("ELBSecurityPolicy-TLS-1-2-2017-01" "ELBSecurityPolicy-TLS-1-2-Ext-2018-06" "ELBSecurityPolicy-FS-1-2-2019-08" "ELBSecurityPolicy-FS-1-2-Res-2019-08" "ELBSecurityPolicy-FS-1-2-Res-2020-10" "ELBSecurityPolicy-TLS13-1-2-2021-06" "ELBSecurityPolicy-TLS13-1-3-2021-06" "ELBSecurityPolicy-TLS13-1-2-Res-2021-06" "ELBSecurityPolicy-TLS13-1-2-Ext1-2021-06" "ELBSecurityPolicy-TLS13-1-2-Ext2-2021-06")
|
||||
|
||||
for elbarn in $LIST_OF_ELBSV2; do
|
||||
passed=true
|
||||
if [[ $(echo $elbarn | grep "loadbalancer/app/") ]]; then
|
||||
elbname=$(echo $elbarn | awk -F 'loadbalancer/app/' '{print $2}' | awk -F '/' '{print $1}')
|
||||
elif [[ $(echo $elbarn | grep "loadbalancer/net/") ]]; then
|
||||
elbname=$(echo $elbarn | awk -F 'loadbalancer/net/' '{print $2}' | awk -F '/' '{print $1}')
|
||||
else
|
||||
elbname=$elbarn
|
||||
fi
|
||||
|
||||
ELBV2_LISTENERS=$($AWSCLI elbv2 describe-listeners $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query "Listeners[*]" --output json)
|
||||
|
||||
ELBV2_PROTOCOLS=$(echo $ELBV2_LISTENERS | jq -r '.[].Protocol')
|
||||
|
||||
if [[ $(echo $ELBV2_PROTOCOLS | grep HTTPS) || $(echo $ELBV2_PROTOCOLS | grep TLS) ]]; then
|
||||
ELBV2_SSL_POLICIES=$($AWSCLI elbv2 describe-listeners $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query 'Listeners[*].SslPolicy' --output text)
|
||||
|
||||
for policy in $ELBV2_SSL_POLICIES; do
|
||||
if array_contains ELBV2SECUREPOLICIES "$policy"; then
|
||||
continue # Passed for this listener/policy
|
||||
else
|
||||
passed=false
|
||||
fi
|
||||
done
|
||||
|
||||
if $passed; then
|
||||
textPass "$regx: $elbname has no insecure SSL ciphers" "$regx" "$elbname"
|
||||
else
|
||||
textFail "$regx: $elbname has insecure SSL ciphers" "$regx" "$elbname"
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: $elbname does not have an HTTPS or TLS listener" "$regx"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: No ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
array_contains () {
|
||||
local array="$1[@]"
|
||||
local seeking=$2
|
||||
local in=1
|
||||
for element in "${!array}"; do
|
||||
if [[ $element == "$seeking" ]]; then
|
||||
in=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
return $in
|
||||
}
|
||||
@@ -1,124 +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_extra793="7.93"
|
||||
CHECK_TITLE_extra793="[extra793] Check if Elastic Load Balancers have SSL listeners "
|
||||
CHECK_SCORED_extra793="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra793="EXTRA"
|
||||
CHECK_SEVERITY_extra793="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra793="AwsElbLoadBalancer"
|
||||
CHECK_ALTERNATE_check793="extra793"
|
||||
CHECK_ASFF_COMPLIANCE_TYPE_extra793="ens-mp.com.2.aws.elb.1"
|
||||
CHECK_SERVICENAME_extra793="elb"
|
||||
CHECK_RISK_extra793='Clear text communication could affect privacy of information in transit.'
|
||||
CHECK_REMEDIATION_extra793='Scan for Load Balancers with HTTP or TCP listeners and understand the reason for each of them. Check if the listener can be implemented as TLS instead.'
|
||||
CHECK_DOC_extra793='https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html'
|
||||
CHECK_CAF_EPIC_extra793='Data Protection'
|
||||
|
||||
extra793(){
|
||||
# "Check if Elastic Load Balancers have encrypted listeners "
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[*].LoadBalancerName' --output text 2>&1|xargs -n1)
|
||||
if [[ $(echo "$LIST_OF_ELBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?(Type == `application`)].LoadBalancerArn' --output text 2>&1|xargs -n1)
|
||||
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
|
||||
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_ELBS || $LIST_OF_ELBSV2 ]]; then
|
||||
if [[ $LIST_OF_ELBS ]]; then
|
||||
ENCRYPTEDPROTOCOLS=("HTTPS" "SSL")
|
||||
for elb in $LIST_OF_ELBS; do
|
||||
ELB_PROTOCOLS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --load-balancer-name $elb --query "LoadBalancerDescriptions[0].ListenerDescriptions[*].Listener.Protocol" --output text)
|
||||
passed=true
|
||||
potential_redirect=false
|
||||
for protocol in $ELB_PROTOCOLS; do
|
||||
if array_contains ENCRYPTEDPROTOCOLS "$protocol"; then
|
||||
continue
|
||||
else
|
||||
# Check if both HTTP and HTTPS in use
|
||||
if [[ $(echo $ELB_PROTOCOLS | grep HTTPS) ]]; then
|
||||
potential_redirect=true
|
||||
fi
|
||||
passed=false
|
||||
fi
|
||||
done
|
||||
|
||||
if $passed; then
|
||||
textPass "$regx: $elb has encrypted listeners" "$regx"
|
||||
else
|
||||
if $potential_redirect; then
|
||||
textInfo "$regx: $elb has both encrypted and non-encrypted listeners" "$regx"
|
||||
else
|
||||
textFail "$regx: $elb has non-encrypted listeners" "$regx" "$elb"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ $LIST_OF_ELBSV2 ]]; then
|
||||
for elbarn in $LIST_OF_ELBSV2; do
|
||||
https_only=true
|
||||
redirect_rule=false
|
||||
elbname=$(echo $elbarn | awk -F 'loadbalancer/app/' '{print $2}' | awk -F '/' '{print $1}')
|
||||
|
||||
ELBV2_LISTENERS=$($AWSCLI elbv2 describe-listeners $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query "Listeners[*]")
|
||||
ELBV2_PROTOCOLS=$(echo $ELBV2_LISTENERS | jq -r '.[].Protocol')
|
||||
|
||||
if [[ $(echo $ELBV2_PROTOCOLS | grep HTTPS) ]]; then
|
||||
for line in $(echo $ELBV2_LISTENERS | jq -r '.[] | .Protocol + "," + .ListenerArn'); do
|
||||
protocol=$(echo $line | awk -F ',' '{print $1}')
|
||||
listenerArn=$(echo $line | awk -F ',' '{print $2}')
|
||||
if [[ $protocol == "HTTP" ]]; then
|
||||
https_only=false
|
||||
# Check for redirect rule
|
||||
ELBV2_RULES=$($AWSCLI elbv2 describe-rules $PROFILE_OPT --region $regx --listener-arn $listenerArn --query 'Rules[]')
|
||||
if [[ $(echo $ELBV2_RULES | jq -r '.[].Actions[].RedirectConfig.Protocol' | grep HTTPS) ]]; then
|
||||
redirect_rule=true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if $https_only; then
|
||||
textPass "$regx: $elbname has HTTPS listeners only" "$regx"
|
||||
else
|
||||
if $redirect_rule; then
|
||||
textInfo "$regx: $elbname has HTTP listener that redirects to HTTPS" "$regx"
|
||||
else
|
||||
textFail "$regx: $elbname has non-encrypted listeners" "$regx" "$elbname"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
textFail "$regx: $elbname has non-encrypted listeners" "$regx" "$elbname"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
else
|
||||
textInfo "$regx: No ELBs found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
array_contains () {
|
||||
local array="$1[@]"
|
||||
local seeking=$2
|
||||
local in=1
|
||||
for element in "${!array}"; do
|
||||
if [[ $element == "$seeking" ]]; then
|
||||
in=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
return $in
|
||||
}
|
||||
@@ -1,55 +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_extra7176="7.176"
|
||||
CHECK_TITLE_extra7176="[extra7176] EMR Cluster without Public IP"
|
||||
CHECK_SCORED_extra7176="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7176="EXTRA"
|
||||
CHECK_SEVERITY_extra7176="Medium"
|
||||
CHECK_ASFF_TYPE_extra7176="AwsEMR"
|
||||
CHECK_ALTERNATE_check7176="extra7176"
|
||||
CHECK_SERVICENAME_extra7176="emr"
|
||||
CHECK_RISK_extra7176='EMR Cluster should not have Public IP'
|
||||
CHECK_REMEDIATION_extra7176='Only make acceptable EMR clusters public'
|
||||
CHECK_DOC_extra7176='https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-block-public-access.html'
|
||||
CHECK_CAF_EPIC_extra7176='Infrastructure Security'
|
||||
|
||||
extra7176(){
|
||||
# Public EMR cluster have their DNS ending with .amazonaws.com while private ones have format of ip-xxx-xx-xx.us-east-1.compute.internal.
|
||||
for regx in ${REGIONS}; do
|
||||
# List only EMR clusters with the following states: STARTING, BOOTSTRAPPING, RUNNING, WAITING, TERMINATING
|
||||
# [NOT TERMINATED AND TERMINATED_WITH_ERRORS]
|
||||
LIST_OF_CLUSTERS=$("${AWSCLI}" emr list-clusters ${PROFILE_OPT} --region "${regx}" --query 'Clusters[?(Status.State!=`TERMINATED` && Status.State!=`TERMINATED_WITH_ERRORS`)].Id' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${LIST_OF_CLUSTERS}"; then
|
||||
textInfo "${regx}: Access Denied trying to list clusters of emr" "${regx}"
|
||||
continue
|
||||
fi
|
||||
if [[ "${LIST_OF_CLUSTERS}" ]]
|
||||
then
|
||||
for cluster_id in ${LIST_OF_CLUSTERS}; do
|
||||
master_public_dns=$("${AWSCLI}" emr describe-cluster ${PROFILE_OPT} --cluster-id "${cluster_id}" --query 'Cluster.MasterPublicDnsName' --region "${regx}" --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${master_public_dns}"; then
|
||||
textInfo "${regx}: Access Denied trying to describe emr cluster" "${regx}" "${cluster_id}"
|
||||
continue
|
||||
fi
|
||||
if [[ $master_public_dns != None && $master_public_dns != *.internal ]];then
|
||||
textFail "${regx}: EMR Cluster ${cluster_id} has a Public IP" "${regx}" "${cluster_id}"
|
||||
else
|
||||
textPass "${regx}: EMR Cluster ${cluster_id} has not a Public IP" "${regx}" "${cluster_id}"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "${regx}: No EMR Clusters found" "${regx}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1,124 +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_extra7177="7.177"
|
||||
CHECK_TITLE_extra7177="[extra7177] Publicly accessible EMR Cluster"
|
||||
CHECK_SCORED_extra7177="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7177="EXTRA"
|
||||
CHECK_SEVERITY_extra7177="High"
|
||||
CHECK_ASFF_TYPE_extra7177="AwsEMR"
|
||||
CHECK_ALTERNATE_check7177="extra7177"
|
||||
CHECK_SERVICENAME_extra7177="emr"
|
||||
CHECK_RISK_extra7177='EMR Clusters should not be publicly accessible'
|
||||
CHECK_REMEDIATION_extra7177='Only make acceptable EMR clusters public'
|
||||
CHECK_DOC_extra7177='https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-block-public-access.html'
|
||||
CHECK_CAF_EPIC_extra7177='Infrastructure Security'
|
||||
|
||||
extra7177(){
|
||||
for regx in ${REGIONS}; do
|
||||
# List only EMR clusters with the following states: STARTING, BOOTSTRAPPING, RUNNING, WAITING, TERMINATING
|
||||
# [NOT TERMINATED AND TERMINATED_WITH_ERRORS]
|
||||
LIST_OF_CLUSTERS=$("${AWSCLI}" emr list-clusters ${PROFILE_OPT} --region "${regx}" --query 'Clusters[?(Status.State!=`TERMINATED` && Status.State!=`TERMINATED_WITH_ERRORS`)].Id' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${LIST_OF_CLUSTERS}"; then
|
||||
textInfo "${regx}: Access Denied trying to list EMR clusters" "${regx}"
|
||||
continue
|
||||
fi
|
||||
if [[ "${LIST_OF_CLUSTERS}" ]]
|
||||
then
|
||||
for cluster_id in ${LIST_OF_CLUSTERS}; do
|
||||
master_public_dns=$("${AWSCLI}" emr describe-cluster ${PROFILE_OPT} --cluster-id "${cluster_id}" --query 'Cluster.MasterPublicDnsName' --region "${regx}" --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${master_public_dns}"; then
|
||||
textInfo "${regx}: Access Denied trying to describe EMR cluster" "${regx}" "${cluster_id}"
|
||||
continue
|
||||
fi
|
||||
if [[ $master_public_dns != None && $master_public_dns != *.internal ]];then
|
||||
# If EMR cluster is Public, it is required to check their Security Groups for the Master, the Slaves and the additional ones
|
||||
|
||||
# Retrive EMR Master Node Security Groups rules
|
||||
master_node_sg=$("${AWSCLI}" emr describe-cluster --cluster-id "${cluster_id}" ${PROFILE_OPT} --region "${regx}" --query 'Cluster.Ec2InstanceAttributes.EmrManagedMasterSecurityGroup' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${master_node_sg}"; then
|
||||
textInfo "${regx}: Access Denied trying to describe EMR cluster" "${regx}" "${cluster_id}"
|
||||
continue
|
||||
fi
|
||||
master_node_sg_internet_open=$("${AWSCLI}" ec2 describe-security-groups --group-ids "${master_node_sg}" --query 'SecurityGroups[?length(IpPermissions[?(contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' ${PROFILE_OPT} --region "${regx}" --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${master_node_sg_internet_open}"; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Retrive EMR Slave Node Security Groups rules
|
||||
slave_node_sg=$("${AWSCLI}" emr describe-cluster --cluster-id "${cluster_id}" ${PROFILE_OPT} --region "${regx}" --query 'Cluster.Ec2InstanceAttributes.EmrManagedSlaveSecurityGroup' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${slave_node_sg}"; then
|
||||
textInfo "${regx}: Access Denied trying to describe EMR cluster" "${regx}" "${cluster_id}"
|
||||
continue
|
||||
fi
|
||||
slave_node_sg_internet_open=$("${AWSCLI}" ec2 describe-security-groups --group-ids "${slave_node_sg}" --query 'SecurityGroups[?length(IpPermissions[?(contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' ${PROFILE_OPT} --region "${regx}" --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${slave_node_sg_internet_open}"; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Retrive EMR Additional Master node Security Groups rules
|
||||
additional_master_node_sg_list=$("${AWSCLI}" emr describe-cluster --cluster-id "${cluster_id}" ${PROFILE_OPT} --region "${regx}" --query 'Cluster.Ec2InstanceAttributes.AdditionalMasterSecurityGroups' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${slave_node_sg}"; then
|
||||
textInfo "${regx}: Access Denied trying to describe EMR cluster" "${regx}" "${cluster_id}"
|
||||
continue
|
||||
fi
|
||||
local additional_master_node_sg_internet_open_list
|
||||
if [[ "${additional_master_node_sg_list}" != "None" ]]; then
|
||||
for additional_master_node_sg in ${additional_master_node_sg_list}; do
|
||||
additional_master_node_sg_internet_open=$("${AWSCLI}" ec2 describe-security-groups --group-ids "${additional_master_node_sg}" --query 'SecurityGroups[?length(IpPermissions[?(contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' ${PROFILE_OPT} --region "${regx}" --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${slave_node_sg_internet_open}"; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
# Store additional master node security groups that allows access from the internet
|
||||
additional_master_node_sg_internet_open_list+=( "${additional_master_node_sg_internet_open}" )
|
||||
done
|
||||
fi
|
||||
|
||||
# Retrive EMR Additional Slave node Security Groups rules
|
||||
additional_slave_node_sg_list=$("${AWSCLI}" emr describe-cluster --cluster-id "${cluster_id}" ${PROFILE_OPT} --region "${regx}" --query 'Cluster.Ec2InstanceAttributes.AdditionalSlaveSecurityGroups' --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${slave_node_sg}"; then
|
||||
textInfo "${regx}: Access Denied trying to describe EMR cluster" "${regx}" "${cluster_id}"
|
||||
continue
|
||||
fi
|
||||
local additional_slave_node_sg_internet_open_list
|
||||
if [[ "${additional_slave_node_sg_list}" != "None" ]]; then
|
||||
for additional_slave_node_sg in ${additional_master_node_sg_list}; do
|
||||
additional_slave_node_sg_internet_open=$("${AWSCLI}" ec2 describe-security-groups --group-ids "${additional_slave_node_sg}" --query 'SecurityGroups[?length(IpPermissions[?(contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' ${PROFILE_OPT} --region "${regx}" --output text 2>&1)
|
||||
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${additional_slave_node_sg_internet_open}"; then
|
||||
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
|
||||
continue
|
||||
fi
|
||||
# Store additional slave node security groups that allows access from the internet
|
||||
additional_slave_node_sg_internet_open_list+=( "${additional_slave_node_sg_internet_open}" )
|
||||
done
|
||||
fi
|
||||
|
||||
# Check if EMR Cluster is publicly accessible through a Security Group
|
||||
if [[ -n "${master_node_sg_internet_open}" || -n "${slave_node_sg_internet_open}" || "${#additional_master_node_sg_internet_open_list[@]}" -ne 0 || "${#additional_slave_node_sg_internet_open_list[@]}" -ne 0 ]]; then
|
||||
textFail "${regx}: EMR Cluster ${cluster_id} is publicly accessible through the following Security Groups: Master Node ${master_node_sg_internet_open} ${additional_master_node_sg_internet_open_list[*]} -- Slaves Nodes ${slave_node_sg_internet_open} ${additional_slave_node_sg_internet_open_list[*]}" "${regx}" "${cluster_id}"
|
||||
else
|
||||
textPass "${regx}: EMR Cluster ${cluster_id} is not publicly accessible" "${regx}" "${cluster_id}"
|
||||
fi
|
||||
else
|
||||
textPass "${regx}: EMR Cluster ${cluster_id} is not publicly accessible" "${regx}" "${cluster_id}"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "${regx}: No EMR Clusters found" "${regx}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user