mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-12 06:24:14 +00:00
Merge branch '2.7' into patch-1
This commit is contained in:
21 files changed
+471
-76
No files matched your search
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is or what is not working as expected
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Command you are running
|
||||
2. Environment you have, like single account, multi-account, organizations, etc.
|
||||
3. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots or Logs**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
Add logs (anonymize them first!). Here a command that may help to share a log
|
||||
`bash -x ./prowler -options > debug.log 2>&1` then attach here `debug.log`
|
||||
|
||||
**From where are you running Prowler? (please complete the following information):**
|
||||
- Resource: [e.g. EC2 instance, Fargate task, Docker container manually, EKS, Cloud9, CodeBuild, workstation, etc.)
|
||||
- OS: [e.g. Amazon Linux 2, Mac, Alpine, Windows, etc. ]
|
||||
- AWS-CLI Version [`aws --version`]:
|
||||
- Prowler Version [`./prowler -V`]:
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -584,7 +584,7 @@ The `gdpr` group of checks uses existing and extra checks. To get a GDPR report,
|
||||
|
||||
With this group of checks, Prowler shows result of checks related to the AWS Foundational Technical Review, more information [here](https://apn-checklists.s3.amazonaws.com/foundational/partner-hosted/partner-hosted/CVLHEC5X7.html). The list of checks can be seen in the group file at:
|
||||
|
||||
[groups/group25_ftr](groups/group25_ftr)
|
||||
[groups/group25_ftr](groups/group25_FTR)
|
||||
|
||||
The `ftr` group of checks uses existing and extra checks. To get a AWS FTR report, run this command:
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ CHECK_SCORED_extra7147="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7147="EXTRA"
|
||||
CHECK_SEVERITY_extra7147="Critical"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7147="AwsGlacierVault"
|
||||
CHECK_ALTERNATE_check7147="extra7142"
|
||||
CHECK_ALTERNATE_check7147="extra7147"
|
||||
CHECK_SERVICENAME_extra7147="glacier"
|
||||
CHECK_RISK_extra7147='Vaults accessible to everyone could expose sensitive data to bad actors'
|
||||
CHECK_REMEDIATION_extra7147='Ensure vault policy does not have principle as *'
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2021) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
CHECK_ID_extra7160="7.160"
|
||||
CHECK_TITLE_extra7160="[extra7160] Check if Redshift has automatic upgrades enabled"
|
||||
CHECK_SCORED_extra7160="NOT_SCORED"
|
||||
CHECK_CIS_LEVEL_extra7160="EXTRA"
|
||||
CHECK_SEVERITY_extra7160="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7160="AwsRedshift"
|
||||
CHECK_ALTERNATE_check7160="extra7160"
|
||||
CHECK_SERVICENAME_extra7160="redshift"
|
||||
CHECK_RISK_extra7160='Without automatic version upgrade enabled; a critical Redshift Cluster version can become severly out of date.'
|
||||
CHECK_REMEDIATION_extra7160='Enabled AutomaticVersionUpgrade on Redshift Cluster'
|
||||
CHECK_DOC_extra7160='https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-operations.html'
|
||||
CHECK_CAF_EPIC_extra7160='Infrastructure Security'
|
||||
|
||||
extra7160(){
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --query 'Clusters[*].ClusterIdentifier' --region $regx --output text)
|
||||
if [[ $LIST_OF_CLUSTERS ]]; then
|
||||
for cluster in $LIST_OF_CLUSTERS; do
|
||||
AUTO_UPGRADE_ENABLED=$($AWSCLI redshift describe-clusters $PROFILE_OPT --cluster-identifier $cluster --query 'Clusters[*].AllowVersionUpgrade' --region $regx --output text)
|
||||
if [[ $AUTO_UPGRADE_ENABLED == "True" ]]; then
|
||||
textPass "$regx: $cluster has AllowVersionUpgrade enabled" "$regx" "$cluster"
|
||||
else
|
||||
textFail "$regx: $cluster has AllowVersionUpgrade disabled" "$regx" "$cluster"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textInfo "$regx: No Redshift Clusters found" "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
CHECK_ID_extra7161="7.161"
|
||||
CHECK_TITLE_extra7161="[extra7161] Check if EFS have protects sensative 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 | xargs -n1)
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
CHECK_ID_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)
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/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/secretsmanager/rotate-secret.html
|
||||
#
|
||||
# rotate-secret
|
||||
# --secret-id <value>
|
||||
# [--client-request-token <value>]
|
||||
# [--rotation-lambda-arn <value>]
|
||||
# [--rotation-rules <value>]
|
||||
# [--cli-input-json <value>]
|
||||
# [--generate-cli-skeleton <value>]
|
||||
|
||||
|
||||
CHECK_ID_extra7163="7.163"
|
||||
CHECK_TITLE_extra7163="[extra7163] Check if Secrets Manager key rotation is enabled"
|
||||
CHECK_SCORED_extra7163="NOT_SCORED"
|
||||
CHECK_TYPE_extra7163="EXTRA"
|
||||
CHECK_SEVERITY_extra7163="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7163="AwsSecretsManagerSecret"
|
||||
CHECK_ALTERNATE_extra7163="extra7163"
|
||||
CHECK_SERVICENAME_extra7163="secretsmanager"
|
||||
CHECK_RISK_extra7163="Rotating secrets minimizes exposure to attacks using stolen keys."
|
||||
CHECK_REMEDITATION_extra7163="Enable key rotation on Secrets Manager key."
|
||||
CHECK_DOC_extra7163="https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html"
|
||||
CHECK_CAF_EPIC_extra7163="Data Protection"
|
||||
|
||||
extra7163(){
|
||||
# "Check if Secrets Manager key rotation is enabled"
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_SECRETS=$($AWSCLI secretsmanager list-secrets $PROFILE_OPT --region $regx --query 'SecretList[*].Name' --output text)
|
||||
if [[ $LIST_OF_SECRETS ]]; then
|
||||
for secret in $LIST_OF_SECRETS; do
|
||||
KEY_ROTATION_ENABLED=$($AWSCLI secretsmanager describe-secret $PROFILE_OPT --region $regx --secret-id $secret --output json | jq '.RotationEnabled')
|
||||
if [[ $KEY_ROTATION_ENABLED == true ]]; then
|
||||
textPass "$regx: $secret has key rotation enabled." "$regx" "$secret"
|
||||
else
|
||||
textFail "$regx: $secret does not have key rotation enabled." "$regx" "$secret"
|
||||
fi
|
||||
done
|
||||
else
|
||||
textPass "$regx: No Secrets Manager secrets found." "$regx"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/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_TYPE_extra7164="EXTRA"
|
||||
CHECK_SEVERITY_extra7164="Medium"
|
||||
CHECK_ASFF_RESOURCE_TYPE_extra7164="Logs"
|
||||
CHECK_ALTERNATE_extra7164="extra7164"
|
||||
CHECK_SERVICENAME_extra7164="logs"
|
||||
CHECK_RISK_extra7164="Using customer managed KMS to encrypt CloudWatch log group provide additional confidentiality and control over the log data"
|
||||
CHECK_REMEDITATION_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 | jq '.logGroups[]')
|
||||
if [[ $LIST_OF_LOGGROUPS ]]; then
|
||||
LIST_OF_LOGGROUPS_WITHOUT_KMS=$(echo "${LIST_OF_LOGGROUPS}" | jq '. | select( has("kmsKeyId") == false )' | jq -r '.logGroupName')
|
||||
LIST_OF_LOGGROUPS_WITH_KMS=$(echo "${LIST_OF_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
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/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_TYPE_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 "Could not connect\|Access Denied" )" ]]; then
|
||||
textInfo "$regx: DynamoDB: DAX Clusters do not exist in this region." "$regx"
|
||||
elif [[ $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
|
||||
}
|
||||
@@ -31,7 +31,11 @@ extra760(){
|
||||
fi
|
||||
|
||||
for regx in $REGIONS; do
|
||||
LIST_OF_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text)
|
||||
LIST_OF_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text 2>&1)
|
||||
if [[ $(echo "$LIST_OF_FUNCTIONS" | grep AccessDenied) ]]; then
|
||||
textFail "$regx: Access Denied trying to list Lambda functions" "$regx" "$lambdafunction"
|
||||
continue
|
||||
fi
|
||||
if [[ $LIST_OF_FUNCTIONS ]]; then
|
||||
for lambdafunction in $LIST_OF_FUNCTIONS;do
|
||||
LAMBDA_FUNCTION_FOLDER="$SECRETS_TEMP_FOLDER/extra760-$lambdafunction-$regx"
|
||||
|
||||
@@ -34,9 +34,9 @@ extra763(){
|
||||
continue
|
||||
fi
|
||||
if [[ $(echo "$BUCKET_VERSIONING_ENABLED" | grep "^Enabled$") ]]; then
|
||||
textPass "Bucket $bucket has versioning enabled" "us-east-1" "$bucket"
|
||||
textPass "Bucket $bucket has versioning enabled" "$REGION" "$bucket"
|
||||
else
|
||||
textFail "Bucket $bucket has versioning disabled!" "us-east-1" "$bucket"
|
||||
textFail "Bucket $bucket has versioning disabled!" "$REGION" "$bucket"
|
||||
fi
|
||||
done
|
||||
else
|
||||
|
||||
@@ -37,7 +37,7 @@ extra792(){
|
||||
ELBSECURECIPHERS=("Protocol-TLSv1.2" "Protocol-TLSv1.1" "Protocol-TLSv1" "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]")
|
||||
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
|
||||
@@ -90,7 +90,7 @@ extra792(){
|
||||
elbname=$elbarn
|
||||
fi
|
||||
|
||||
ELBV2_LISTENERS=$($AWSCLI elbv2 describe-listeners $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query "Listeners[*]")
|
||||
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')
|
||||
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@
|
||||
GROUP_ID[25]='ftr'
|
||||
GROUP_NUMBER[25]='25.0'
|
||||
GROUP_TITLE[25]='Amazon FTR related security checks - [ftr] ******************'
|
||||
GROUP_RUN_BY_DEFAULT[9]='N' # run it when execute_all is called
|
||||
GROUP_CHECKS[9]='check11,check12,check13,check14,check15,check16,check17,check18,check19,check110,check111,check111,check112,check113,check117,check118,check122,check21,check22,extra759,extra760,extra768,extra775,extra797,extra7141,extra73'
|
||||
GROUP_RUN_BY_DEFAULT[25]='N' # run it when execute_all is called
|
||||
GROUP_CHECKS[25]='check11,check12,check13,check14,check15,check16,check17,check18,check19,check110,check111,check111,check112,check113,check117,check118,check122,check21,check22,extra759,extra760,extra768,extra775,extra797,extra7141,extra73'
|
||||
|
||||
# Checks from AWS FTR https://apn-checklists.s3.amazonaws.com/foundational/partner-hosted/partner-hosted/CVLHEC5X7.html
|
||||
# 1.1 [check11] Avoid the use of the root account - iam [High]
|
||||
|
||||
@@ -15,9 +15,9 @@ GROUP_ID[7]='extras'
|
||||
GROUP_NUMBER[7]='7.0'
|
||||
GROUP_TITLE[7]='Extras - all non CIS specific checks - [extras] ****************'
|
||||
GROUP_RUN_BY_DEFAULT[7]='Y' # run it when execute_all is called
|
||||
GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142,extra7143,extra7144,extra7145,extra7146,extra7147,extra7148,extra7149,extra7150,extra7151,extra7152,extra7153,extra7154,extra7155,extra7156,extra7157,extra7158,extra7159'
|
||||
GROUP_CHECKS[7]='extra71,extra72,extra73,extra74,extra75,extra76,extra77,extra78,extra79,extra710,extra711,extra712,extra713,extra714,extra715,extra716,extra717,extra718,extra719,extra720,extra721,extra722,extra723,extra724,extra725,extra726,extra727,extra728,extra729,extra730,extra731,extra732,extra733,extra734,extra735,extra736,extra738,extra739,extra740,extra741,extra742,extra743,extra744,extra745,extra746,extra747,extra748,extra749,extra750,extra751,extra752,extra753,extra754,extra755,extra757,extra758,extra761,extra762,extra763,extra764,extra765,extra767,extra768,extra769,extra770,extra771,extra772,extra773,extra774,extra775,extra776,extra777,extra778,extra779,extra780,extra781,extra782,extra783,extra784,extra785,extra786,extra787,extra788,extra791,extra792,extra793,extra794,extra795,extra796,extra797,extra798,extra799,extra7100,extra7101,extra7102,extra7103,extra7104,extra7105,extra7106,extra7107,extra7108,extra7109,extra7110,extra7111,extra7112,extra7113,extra7114,extra7115,extra7116,extra7117,extra7118,extra7119,extra7120,extra7121,extra7122,extra7123,extra7124,extra7125,extra7126,extra7127,extra7128,extra7129,extra7130,extra7131,extra7132,extra7133,extra7134,extra7135,extra7136,extra7137,extra7138,extra7139,extra7140,extra7141,extra7142,extra7143,extra7144,extra7145,extra7146,extra7147,extra7148,extra7149,extra7150,extra7151,extra7152,extra7153,extra7154,extra7155,extra7156,extra7157,extra7158,extra7159,extra7160,extra7161,extra7162,extra7163,extra7164,extra7165'
|
||||
|
||||
# Extras 759 and 760 (lambda variables and code secrets finder are not included)
|
||||
# Extras 759 and 760 (lambda variables and code secrets finder are not included)
|
||||
# to run detect-secrets use `./prowler -g secrets`
|
||||
|
||||
# Extras 789 and 790 VPC trust boundaries are not included by default in Extras
|
||||
|
||||
+39
-45
@@ -11,9 +11,10 @@
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
# both variables are mandatory to be set together
|
||||
assume_role(){
|
||||
if [[ -z $ROLE_TO_ASSUME ]]; then
|
||||
PROFILE_OPT=$PROFILE_OPT_BAK
|
||||
# Both variables are mandatory to be set together
|
||||
if [[ -z $ROLE_TO_ASSUME || -z $ACCOUNT_TO_ASSUME ]]; then
|
||||
echo "$OPTRED ERROR!$OPTNORMAL - Both Account ID (-A) and IAM Role to assume (-R) must be set"
|
||||
exit 1
|
||||
fi
|
||||
@@ -28,6 +29,7 @@ assume_role(){
|
||||
|
||||
# temporary file where to store credentials
|
||||
TEMP_STS_ASSUMED_FILE=$(mktemp -t prowler.sts_assumed-XXXXXX)
|
||||
TEMP_STS_ASSUMED_ERROR=$(mktemp -t prowler.sts_assumed-XXXXXX)
|
||||
|
||||
# check if role arn or role name
|
||||
if [[ $ROLE_TO_ASSUME == arn:* ]]; then
|
||||
@@ -36,57 +38,49 @@ assume_role(){
|
||||
PROWLER_ROLE=arn:${AWS_PARTITION}:iam::$ACCOUNT_TO_ASSUME:role/$ROLE_TO_ASSUME
|
||||
fi
|
||||
|
||||
#Check if external ID has bee provided if so execute with external ID if not ignore
|
||||
if [[ -z $ROLE_EXTERNAL_ID ]]; then
|
||||
# assume role command
|
||||
$AWSCLI $PROFILE_OPT sts assume-role --role-arn $PROWLER_ROLE \
|
||||
--role-session-name ProwlerAssessmentSession \
|
||||
--region $REGION_FOR_STS \
|
||||
--duration-seconds $SESSION_DURATION_TO_ASSUME > $TEMP_STS_ASSUMED_FILE 2>&1
|
||||
else
|
||||
$AWSCLI $PROFILE_OPT sts assume-role --role-arn $PROWLER_ROLE \
|
||||
--role-session-name ProwlerAssessmentSession \
|
||||
--duration-seconds $SESSION_DURATION_TO_ASSUME \
|
||||
--region $REGION_FOR_STS \
|
||||
--external-id $ROLE_EXTERNAL_ID > $TEMP_STS_ASSUMED_FILE 2>&1
|
||||
fi
|
||||
if [[ $(grep AccessDenied $TEMP_STS_ASSUMED_FILE) ]]; then
|
||||
textFail "Access Denied assuming role $PROWLER_ROLE"
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
elif [[ "$(grep MaxSessionDuration $TEMP_STS_ASSUMED_FILE)" ]]; then
|
||||
textFail "The requested DurationSeconds exceeds the MaxSessionDuration set for the role ${PROWLER_ROLE}"
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
# Check if external ID has bee provided if so execute with external ID if not ignore
|
||||
ROLE_EXTERNAL_ID_OPTION=""
|
||||
if [[ -n "${ROLE_EXTERNAL_ID}" ]]; then
|
||||
ROLE_EXTERNAL_ID_OPTION="--external-id ${ROLE_EXTERNAL_ID}"
|
||||
fi
|
||||
|
||||
# assume role command
|
||||
#$AWSCLI $PROFILE_OPT sts assume-role --role-arn arn:${AWS_PARTITION}:iam::$ACCOUNT_TO_ASSUME:role/$ROLE_TO_ASSUME \
|
||||
# --role-session-name ProwlerAssessmentSession \
|
||||
# --duration-seconds $SESSION_DURATION_TO_ASSUME > $TEMP_STS_ASSUMED_FILE
|
||||
|
||||
# if previous command fails exit with the given error from aws-cli
|
||||
# this is likely to be due to session duration limit of 1h in case
|
||||
# of assume role chaining:
|
||||
# "The requested DurationSeconds exceeds the 1 hour session limit
|
||||
# for roles assumed by role chaining."
|
||||
# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html
|
||||
if [[ $? != 0 ]];then
|
||||
exit 1
|
||||
# Assume role
|
||||
if ! $AWSCLI $PROFILE_OPT sts assume-role --role-arn $PROWLER_ROLE \
|
||||
--role-session-name ProwlerAssessmentSession \
|
||||
--duration-seconds $SESSION_DURATION_TO_ASSUME \
|
||||
--region $REGION_FOR_STS \
|
||||
"${ROLE_EXTERNAL_ID_OPTION}" > $TEMP_STS_ASSUMED_FILE 2>"${TEMP_STS_ASSUMED_ERROR}"
|
||||
then
|
||||
STS_ERROR="$(cat ${TEMP_STS_ASSUMED_ERROR} | tr '\n' ' ')"
|
||||
textFail "${STS_ERROR}"
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
fi
|
||||
|
||||
|
||||
echo FILE WITH TEMP CREDS: $TEMP_STS_ASSUMED_FILE
|
||||
|
||||
# The profile shouldn't be used for CLI
|
||||
PROFILE=""
|
||||
PROFILE_OPT=""
|
||||
PROFILE_OPT=""
|
||||
|
||||
# Set AWS environment variables with assumed role credentials
|
||||
AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' "${TEMP_STS_ASSUMED_FILE}")
|
||||
export AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' "${TEMP_STS_ASSUMED_FILE}")
|
||||
export AWS_SECRET_ACCESS_KEY
|
||||
AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' "${TEMP_STS_ASSUMED_FILE}")
|
||||
export AWS_SESSION_TOKEN
|
||||
AWS_SESSION_EXPIRATION=$(jq -r '.Credentials.Expiration | sub("\\+00:00";"Z") | fromdateiso8601' "${TEMP_STS_ASSUMED_FILE}")
|
||||
export AWS_SESSION_EXPIRATION
|
||||
echo TEMP AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
|
||||
echo TEMP AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
|
||||
echo TEMP AWS_SESSION_TOKEN: $AWS_SESSION_TOKEN
|
||||
echo EXPIRATION EPOCH TIME: $AWS_SESSION_EXPIRATION
|
||||
|
||||
# set env variables with assumed role credentials
|
||||
export AWS_ACCESS_KEY_ID=$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.AccessKeyId')
|
||||
export AWS_SECRET_ACCESS_KEY=$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.SecretAccessKey')
|
||||
export AWS_SESSION_TOKEN=$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.SessionToken')
|
||||
export AWS_SESSION_EXPIRATION=$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.Expiration | sub("\\+00:00";"Z") | fromdateiso8601')
|
||||
cleanSTSAssumeFile
|
||||
}
|
||||
|
||||
cleanSTSAssumeFile() {
|
||||
rm -fr "${TEMP_STS_ASSUMED_FILE}"
|
||||
}
|
||||
rm -fr "${TEMP_STS_ASSUMED_ERROR}"
|
||||
}
|
||||
@@ -45,7 +45,8 @@ else
|
||||
PROFILE="default"
|
||||
PROFILE_OPT="--profile $PROFILE"
|
||||
fi
|
||||
|
||||
# Backing up $PROFILE_OPT needed to renew assume_role
|
||||
PROFILE_OPT_BAK=$PROFILE_OPT
|
||||
# Set default region by aws config, fall back to us-east-1
|
||||
REGION_CONFIG=$(aws configure get region)
|
||||
if [[ $REGION_OPT ]]; then
|
||||
|
||||
@@ -42,29 +42,48 @@ checkSecurityHubCompatibility(){
|
||||
|
||||
resolveSecurityHubPreviousFails(){
|
||||
# Move previous check findings RecordState to ARCHIVED (as prowler didn't re-detect them)
|
||||
SH_TEMP_FOLDER="$PROWLER_DIR/SH-$ACCOUNT_NUM"
|
||||
if [[ ! -d $SH_TEMP_FOLDER ]]; then
|
||||
# this folder is deleted once the security hub update is completed
|
||||
mkdir "$SH_TEMP_FOLDER"
|
||||
fi
|
||||
for regx in $REGIONS; do
|
||||
|
||||
REGION_FOLDER="$SH_TEMP_FOLDER/$regx"
|
||||
if [[ ! -d $REGION_FOLDER ]]; then
|
||||
mkdir "$REGION_FOLDER"
|
||||
fi
|
||||
local check="$1"
|
||||
NEW_TIMESTAMP=$(get_iso8601_timestamp)
|
||||
|
||||
FILTER="{\"GeneratorId\":[{\"Value\": \"prowler-$check\",\"Comparison\":\"EQUALS\"}],\"RecordState\":[{\"Value\": \"ACTIVE\",\"Comparison\":\"EQUALS\"}],\"AwsAccountId\":[{\"Value\": \"$ACCOUNT_NUM\",\"Comparison\":\"EQUALS\"}]}"
|
||||
|
||||
NEW_FINDING_IDS=$(echo -n "${SECURITYHUB_NEW_FINDINGS_IDS[@]}" | jq -cRs 'split(" ")')
|
||||
SECURITY_HUB_PREVIOUS_FINDINGS=$($AWSCLI securityhub --region "$regx" $PROFILE_OPT get-findings --filters "${FILTER}" | jq -c --argjson ids "$NEW_FINDING_IDS" --arg updated_at $NEW_TIMESTAMP '[ .Findings[] | select( .Id| first(select($ids[] == .)) // false | not) | .RecordState = "ARCHIVED" | .UpdatedAt = $updated_at ]')
|
||||
NEW_FINDING_FILE="$REGION_FOLDER/findings.json"
|
||||
NEW_FINDING_IDS=$(echo -n "${SECURITYHUB_NEW_FINDINGS_IDS[@]}" | jq -cRs 'split(" ")' > $NEW_FINDING_FILE)
|
||||
EXISTING_FILE="$REGION_FOLDER/existing.json"
|
||||
EXISTING_FINDINGS=$($AWSCLI securityhub --region "$regx" $PROFILE_OPT get-findings --filters "${FILTER}" > $EXISTING_FILE)
|
||||
|
||||
SECURITY_HUB_PREVIOUS_FINDINGS=$(for id in $(comm -23 <(jq '[.Findings[].Id] | sort | .[]' $EXISTING_FILE) <(jq '[.[]] | sort | .[]' $NEW_FINDING_FILE));
|
||||
do
|
||||
jq --arg updated_at $NEW_TIMESTAMP '.Findings[] | select(.Id == '"$id"') | .RecordState = "ARCHIVED" | .UpdatedAt = $updated_at ' < $EXISTING_FILE
|
||||
done | jq -s '.')
|
||||
|
||||
|
||||
if [[ $SECURITY_HUB_PREVIOUS_FINDINGS != "[]" ]]; then
|
||||
FINDINGS_COUNT=$(echo $SECURITY_HUB_PREVIOUS_FINDINGS | jq '. | length')
|
||||
for i in `seq 0 100 $FINDINGS_COUNT`;
|
||||
for i in $(seq 0 50 $FINDINGS_COUNT);
|
||||
do
|
||||
BATCH_FINDINGS=$(echo $SECURITY_HUB_PREVIOUS_FINDINGS | jq -c '.['"$i:$i+100"']')
|
||||
BATCH_IMPORT_RESULT=$($AWSCLI securityhub --region "$regx" $PROFILE_OPT batch-import-findings --findings "${BATCH_FINDINGS}")
|
||||
if [[ -z "${BATCH_IMPORT_RESULT}" ]] || jq -e '.FailedCount >= 1' <<< "${BATCH_IMPORT_RESULT}" > /dev/null 2>&1; then
|
||||
echo -e "\n$RED ERROR!$NORMAL Failed to send check output to AWS Security Hub\n"
|
||||
BATCH_FINDINGS=$(echo $SECURITY_HUB_PREVIOUS_FINDINGS | jq -c '.['"$i:$i+50"']')
|
||||
BATCH_FINDINGS_COUNT=$(echo $BATCH_FINDINGS | jq '. | length')
|
||||
if [ "$BATCH_FINDINGS_COUNT" -gt 0 ]; then
|
||||
BATCH_IMPORT_RESULT=$($AWSCLI securityhub --region "$regx" $PROFILE_OPT batch-import-findings --findings "${BATCH_FINDINGS}")
|
||||
if [[ -z "${BATCH_IMPORT_RESULT}" ]] || jq -e '.FailedCount >= 1' <<< "${BATCH_IMPORT_RESULT}" > /dev/null 2>&1; then
|
||||
echo -e "\n$RED ERROR!$NORMAL Failed to send check output to AWS Security Hub\n"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
rm -rf "$SH_TEMP_FOLDER"
|
||||
}
|
||||
|
||||
sendToSecurityHub(){
|
||||
|
||||
@@ -32,7 +32,7 @@ OPTRED="[1;31m"
|
||||
OPTNORMAL="[0;39m"
|
||||
|
||||
# Set the defaults variables
|
||||
PROWLER_VERSION=2.6.1-15November2021
|
||||
PROWLER_VERSION=2.7.0-1December2021
|
||||
PROWLER_DIR=$(dirname "$0")
|
||||
|
||||
REGION=""
|
||||
@@ -97,7 +97,7 @@ USAGE:
|
||||
(i.e.: 123456789012)
|
||||
-R role name or role arn to assume in the account, requires -A and -T
|
||||
(i.e.: ProwlerRole)
|
||||
-T session duration given to that role credentials in seconds, default 1h (3600) recommended 12h, requires -R and -T
|
||||
-T session duration given to that role credentials in seconds, default 1h (3600) recommended 12h, optional with -R and -A
|
||||
(i.e.: 43200)
|
||||
-I External ID to be used when assuming roles (not mandatory), requires -A and -R
|
||||
-w whitelist file. See whitelist_sample.txt for reference and format
|
||||
@@ -135,6 +135,7 @@ while getopts ":hlLkqp:r:c:C:g:f:m:M:E:x:enbVsSI:A:R:T:w:N:o:B:F:zZ:" OPTION; do
|
||||
;;
|
||||
p )
|
||||
PROFILE=$OPTARG
|
||||
AWS_PROFILE=$OPTARG
|
||||
;;
|
||||
r )
|
||||
REGION_OPT=$OPTARG
|
||||
@@ -338,6 +339,7 @@ TOTAL_CHECKS=($(echo "${TOTAL_CHECKS[*]}" | tr ' ' '\n' | awk '!seen[$0]++' | so
|
||||
get_regions() {
|
||||
# Get list of regions based on include/whoami
|
||||
REGIONS=$($AWSCLI ec2 describe-regions --query 'Regions[].RegionName' --output text $PROFILE_OPT --region $REGION_FOR_STS --region-names $FILTERREGION 2>&1)
|
||||
echo $REGIONS
|
||||
ret=$?
|
||||
if [[ $ret -ne 0 ]]; then
|
||||
echo "$OPTRED Access Denied trying to describe regions! Review permissions as described here: https://github.com/toniblyx/prowler/#requirements-and-installation $OPTNORMAL"
|
||||
@@ -392,13 +394,15 @@ show_group_title() {
|
||||
# Function to execute the check
|
||||
execute_check() {
|
||||
|
||||
if [[ $ACCOUNT_TO_ASSUME ]]; then
|
||||
if [[ -n "${ACCOUNT_TO_ASSUME}" || -n "${ROLE_TO_ASSUME}" ]]; then
|
||||
# Following logic looks for time remaining in the session and review it
|
||||
# if it is less than 600 seconds, 10 minutes.
|
||||
CURRENT_TIMESTAMP=$(date -u "+%s")
|
||||
SESSION_TIME_REMAINING=$(expr $AWS_SESSION_EXPIRATION - $CURRENT_TIMESTAMP)
|
||||
MINIMUM_REMAINING_TIME_ALLOWED="600"
|
||||
if [[ $MINIMUM_REMAINING_TIME_ALLOWED > $SESSION_TIME_REMAINING ]]; then
|
||||
echo SESSION TIME REMAINING IN SECONDS: $SESSION_TIME_REMAINING
|
||||
MINIMUM_REMAINING_TIME_ALLOWED=600
|
||||
if (( $MINIMUM_REMAINING_TIME_ALLOWED > $SESSION_TIME_REMAINING )); then
|
||||
echo LESS THAN 10 MIN LEFT: RE-ASSUMING...
|
||||
unset AWS_ACCESS_KEY_ID
|
||||
unset AWS_SECRET_ACCESS_KEY
|
||||
unset AWS_SESSION_TOKEN
|
||||
@@ -497,7 +501,7 @@ execute_check() {
|
||||
fi
|
||||
|
||||
else
|
||||
textFail "ERROR! Use a valid check name (i.e. check41 or extra71)";
|
||||
textFail "Check ${CHECK_ID} does not exist. Use a valid check name (i.e. check41 or extra71)";
|
||||
exit $EXITCODE
|
||||
fi
|
||||
fi
|
||||
@@ -565,7 +569,7 @@ show_all_titles() {
|
||||
fi
|
||||
done
|
||||
else
|
||||
textFail "Use a valid check group ID i.e.: group1, extras, forensics-ready, etc."
|
||||
textFail "Group ${GROUP_ID_READ} does not exist. Use a valid check group ID i.e.: group1, extras, forensics-ready, etc."
|
||||
show_all_group_titles
|
||||
exit $EXITCODE
|
||||
fi
|
||||
@@ -639,12 +643,14 @@ fi
|
||||
|
||||
# Gather account data / test aws cli connectivity
|
||||
getWhoami
|
||||
if [[ $ACCOUNT_TO_ASSUME ]]; then
|
||||
if [[ -n "${ACCOUNT_TO_ASSUME}" || -n "${ROLE_TO_ASSUME}" ]]; then
|
||||
assume_role
|
||||
fi
|
||||
|
||||
# List regions
|
||||
echo REGIONS_init
|
||||
get_regions
|
||||
echo REGIONS_end
|
||||
|
||||
# Execute group of checks if called with -g
|
||||
if [[ $GROUP_ID_READ ]];then
|
||||
@@ -659,7 +665,7 @@ if [[ $GROUP_ID_READ ]];then
|
||||
copyToS3
|
||||
exit $EXITCODE
|
||||
else
|
||||
textFail "Use a valid check group ID i.e.: group1, extras, forensics-ready, etc."
|
||||
textFail "Group ${GROUP_ID_READ} does not exist. Use a valid check group ID i.e.: group1, extras, forensics-ready, etc."
|
||||
show_all_group_titles
|
||||
exit $EXITCODE
|
||||
fi
|
||||
|
||||
@@ -123,8 +123,12 @@ Resources:
|
||||
runtime-versions:
|
||||
python: 3.8
|
||||
commands:
|
||||
- echo "Updating yum..."
|
||||
- echo "Updating yum ..."
|
||||
- yum -y update
|
||||
- echo "Updating pip ..."
|
||||
- python -m pip install --upgrade pip
|
||||
- echo "Installing requirements ..."
|
||||
- pip install "git+https://github.com/ibm/detect-secrets.git@master#egg=detect-secrets"
|
||||
build:
|
||||
commands:
|
||||
- echo "Running Prowler with script"
|
||||
|
||||
@@ -83,6 +83,7 @@ Resources:
|
||||
- dax:ListTables
|
||||
- ds:ListAuthorizedApplications
|
||||
- ds:DescribeRoles
|
||||
- ec2:GetEbsEncryptionByDefault
|
||||
- ecr:Describe*
|
||||
- lambda:GetAccountSettings
|
||||
- lambda:GetFunctionConfiguration
|
||||
|
||||
Reference in new issue
Block a user