Merge remote-tracking branch 'official/master' into whitelistSupport

This commit is contained in:
Urjit Singh Bhatia
2020-05-04 13:56:14 -07:00
160 changed files with 2419 additions and 765 deletions

11
.gitignore vendored
View File

@@ -18,4 +18,13 @@ tags
[._]*.un~
# MacOs DS_Store
*.DS_Store
*.DS_Store
# Prowler output
prowler-output-*
# JUnit Reports
junit-reports/
# VSCode files
.vscode/

View File

@@ -1,4 +0,0 @@
```
./prowler -l # to see all available checks and groups.
./prowler -L # to see all available groups only.
```

247
README.md
View File

@@ -7,6 +7,7 @@
- [Requirements and Installation](#requirements-and-installation)
- [Usage](#usage)
- [Advanced Usage](#advanced-usage)
- [Security Hub integration](#security-hub-integration)
- [Fix](#fix)
- [Screenshots](#screenshots)
- [Troubleshooting](#troubleshooting)
@@ -14,6 +15,7 @@
- [Forensics Ready Checks](#forensics-ready-checks)
- [GDPR Checks](#gdpr-checks)
- [HIPAA Checks](#hipaa-checks)
- [Trust Boundaries Checks](#trust-boundaries-checks)
- [Add Custom Checks](#add-custom-checks)
- [Third Party Integrations](#third-party-integrations)
- [Full list of checks and groups](/LIST_OF_CHECKS_AND_GROUPS.md)
@@ -29,10 +31,10 @@ Read more about [CIS Amazon Web Services Foundations Benchmark v1.2.0 - 05-23-20
## Features
It covers hardening and security best practices for all AWS regions related to the next groups:
~140 checks controls covering security best practices across all AWS regions and most of AWS services and related to the next groups:
- Identity and Access Management (22 checks) [group1]
- Logging (9 checks) [group2]
- Identity and Access Management [group1]
- Logging [group2]
- Monitoring (14 checks) [group3]
- Networking (4 checks) [group4]
- CIS Level 1 [cislevel1]
@@ -41,16 +43,16 @@ It covers hardening and security best practices for all AWS regions related to t
- Forensics related group of checks [forensics-ready]
- GDPR [gdpr] Read more [here](#gdpr-checks)
- HIPAA [hipaa] Read more [here](#hipaa-checks)
For a comprehensive list and resolution look at the guide on the link above.
- Trust Boundaries [trustboundaries] Read more [here](#trustboundaries-checks)
With Prowler you can:
- get a colorful or monochrome report
- a CSV format report for diff
- run specific checks without having to run the entire report
- check multiple AWS accounts in parallel
- a CSV, JSON or JSON ASFF format report
- send findings directly to Security Hub
- run specific checks
- check multiple AWS accounts in parallel or sequentially
- and more! Read examples below
## Requirements and Installation
@@ -62,9 +64,10 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
pip install awscli ansi2html detect-secrets
```
AWS-CLI can be also installed it using "brew", "apt", "yum" or manually from <https://aws.amazon.com/cli/>, but `ansi2html` and `detect-secrets` has to be installed using `pip`. You will need to install `jq` to get more accuracy in some checks.
AWS-CLI can be also installed it using "brew", "apt", "yum" or manually from <https://aws.amazon.com/cli/>, but `ansi2html` and `detect-secrets` has to be installed using `pip`. You will need to install `jq` to get more accuracy in some checks.
- Make sure jq is installed (example below with "apt" but use a valid package manager for your OS):
```sh
sudo apt install jq
```
@@ -81,20 +84,23 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
```sh
aws configure
```
or
or
```sh
export AWS_ACCESS_KEY_ID="ASXXXXXXX"
export AWS_SECRET_ACCESS_KEY="XXXXXXXXX"
export AWS_SESSION_TOKEN="XXXXXXXXX"
```
- Those credentials must be associated to a user or role with proper permissions to do all checks. To make sure add SecurityAuditor default policy to your user. Policy ARN is
- Those credentials must be associated to a user or role with proper permissions to do all checks. To make sure, add the AWS managed policies, SecurityAudit and ViewOnlyAccess, to the user or role being used. Policy ARNs are:
```sh
arn:aws:iam::aws:policy/SecurityAudit
arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
```
> Additional permissions needed: to make sure Prowler can scan all services included in the group *Extras*, make sure you attach also the custom policy [prowler-additions-policy.json](https://github.com/toniblyx/prowler/blob/master/iam/prowler-additions-policy.json) to the role you are using.
> Additional permissions needed: to make sure Prowler can scan all services included in the group *Extras*, make sure you attach also the custom policy [prowler-additions-policy.json](https://github.com/toniblyx/prowler/blob/master/iam/prowler-additions-policy.json) to the role you are using. If you want Prowler to send findings to [AWS Security Hub](https://aws.amazon.com/security-hub), make sure you also attach the custom policy [prowler-security-hub.json](https://github.com/toniblyx/prowler/blob/master/iam/prowler-security-hub.json).
## Usage
@@ -104,10 +110,10 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
./prowler
```
Use `-l` to list all available checks and group of checks (sections)
Use `-l` to list all available checks and the groups (sections) that reference them
If you want to avoid installing dependencies run it using Docker:
If you want to avoid installing dependences run it using Docker:
```sh
docker run -ti --rm --name prowler --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN toniblyx/prowler:latest
```
@@ -123,16 +129,21 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
```sh
./prowler -c check310
```
With Docker:
```sh
docker run -ti --rm --name prowler --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN toniblyx/prowler:latest "-c check310"
```
or multiple checks separated by comma:
```sh
./prowler -c check310,check722
```
or all checks but some of them:
```sh
./prowler -E check42,check43
```
@@ -148,14 +159,38 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
```sh
./prowler -g group1 # for iam related checks
```
or exclude some checks in the group:
```sh
./prowler -g group4 -E check42,check43
```
Valid check numbers are based on the AWS CIS Benchmark guide, so 1.1 is check11 and 3.10 is check310
1. If you want to save your report for later analysis:
### Save your reports
1. If you want to save your report for later analysis thare are different ways, natively (supported text, mono, csv, json, json-asff and junit-xml see note below for more info):
```sh
./prowler -M csv
```
or with multiple formats at the same time:
```sh
./prowler -M csv,json,json-asff
```
or just a group of checks in multiple formats:
```sh
./prowler -g gdpr -M csv,json,json-asff
```
Now `-M` creates a file inside the prowler root directory named `prowler-output-AWSACCOUNTID-YYYYMMDDHHMMSS.format`. You don't have to specify anything else, no pipes, no redirects.
or just saving the output to a file like below:
```sh
./prowler -M mono > prowler-report.txt
@@ -168,18 +203,15 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
./prowler | ansi2html -la > report.html
```
or if you want a pipe-delimited report file, do:
To generate JUnit report files, include the junit-xml format. This can be combined with any other format. Files are written inside a prowler root directory named `junit-reports`:
```sh
./prowler -M csv > output.psv
```
or json formatted output using jq, do:
```sh
./prowler -M json > prowler-output.json
./prowler -M text,junit-xml
```
or save your report in a S3 bucket:
>Note about output formats to use with `-M`: "text" is the default one with colors, "mono" is like default one but monochrome, "csv" is comma separated values, "json" plain basic json (without comma between lines) and "json-asff" is also json with Amazon Security Finding Format that you can ship to Security Hub using `-S`.
or save your report in a S3 bucket (this only works for text or mono, for csv, json or json-asff it has to be copied afterwards):
```sh
./prowler -M mono | aws s3 cp - s3://bucket-name/prowler-report.txt
@@ -200,7 +232,7 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
1. For help use:
```
```sh
./prowler -h
USAGE:
@@ -217,17 +249,19 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
-f <filterregion> specify an AWS region to run checks against
(i.e.: us-west-1)
-m <maxitems> specify the maximum number of items to return for long-running requests (default: 100)
-M <mode> output mode: text (default), mono, json, csv (separator is ,; data is on stdout; progress on stderr)
-M <mode> output mode: text (default), mono, json, json-asff, junit-xml, csv. They can be used combined comma separated.
(separator is ","; data is on stdout; progress on stderr).
-k keep the credential report
-n show check numbers to sort easier
(i.e.: 1.01 instead of 1.1)
-l list all available checks only (does not perform any check)
-l list all available checks only (does not perform any check). Add -g <group_id> to only list checks within the specified group
-L list all groups (does not perform any check)
-e exclude group extras
-E execute all tests except a list of specified checks separated by comma (i.e. check21,check31)
-b do not print Prowler banner
-V show version number & exit
-s show scoring report
-S send check output to AWS Security Hub - only valid when the output mode is json-asff (i.e. "-M json-asff -S")
-x specify external directory with custom checks (i.e. /my/own/checks, files must start by check)
-q suppress info messages and passing test output
-A account id for the account where to assume a role, requires -R and -T
@@ -236,29 +270,51 @@ This script has been written in bash using AWS-CLI and it works in Linux and OSX
(i.e.: ProwlerRole)
-T session durantion given to that role credentials in seconds, default 1h (3600) recommended 12h, requires -R and -T
(i.e.: 43200)
-I External ID to be used when assuming roles (no mandatory)
-h this help
```
## Advanced Usage
### Assume Role:
### Assume Role:
Prowler uses the AWS CLI underneath so it uses the same authentication methods. However, there are few ways to run Prowler against multiple accounts using IAM Assume Role feature depending on eachg use case. You can just set up your custom profile inside `~/.aws/config` with all needed information about the role to assume then call it with `./prowler -p your-custom-profile`. Additionally you can use `-A 123456789012` and `-R RemoteRoleToAssume` and Prowler will get those temporary credentials using `aws sts assume-role`, set them up as environment variables and run against that given account.
```sh
./prowler -A 123456789012 -R ProwlerRole
```
./prowler -A 123456789012 -R ProwlerRole
```sh
./prowler -A 123456789012 -R ProwlerRole -I 123456
```
> *NOTE 1 about Session Duration*: By default it gets credentials valid for 1 hour (3600 seconds). Depending on the mount of checks you run and the size of your infrastructure, Prowler may require more than 1 hour to finish. Use option `-T <seconds>` to allow up to 12h (43200 seconds). To allow more than 1h you need to modify *"Maximum CLI/API session duration"* for that particular role, read more [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session).
> *NOTE 2 about Session Duration*: Bear in mind that if you are using roles assumed by role chaining there is a hard limit of 1 hour so consider not using role chaining if possible, read more about that, in foot note 1 below the table [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html).
> *NOTE 2 about Session Duration*: Bear in mind that if you are using roles assumed by role chaining there is a hard limit of 1 hour so consider not using role chaining if possible, read more about that, in foot note 1 below the table [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html).
For example, if you want to get only the fails in CSV format from all checks regarding RDS without banner from the AWS Account 123456789012 assuming the role RemoteRoleToAssume and set a fixed session duration of 1h:
```
```sh
./prowler -A 123456789012 -R RemoteRoleToAssume -T 3600 -b -M cvs -q -g rds
```
```sh
./prowler -A 123456789012 -R RemoteRoleToAssume -T 3600 -I 123456 -b -M cvs -q -g rds
```
### Assume Role and across all accounts in AWS Organizations:
If you want to run Prowler or just a check or a group across all accounts of AWS Organizations you can do this:
First get a list of accounts:
```
ACCOUNTS_IN_ORGS=$(aws organizations list-accounts --query Accounts[*].Id --output text)
```
Then run Prowler to assume a role (same in all members) per each account, in this example it is just running one particular check:
```
for accountId in $ACCOUNTS_IN_ORGS; do ./prowler -A $accountId -R RemoteRoleToAssume -c extra79; done
```
### Custom folder for custom checks
Flag `-x /my/own/checks` will include any check in that particular directory. To see how to write checks see [Add Custom Checks](#add-custom-checks) section.
@@ -267,10 +323,25 @@ Flag `-x /my/own/checks` will include any check in that particular directory. To
In order to remove noise and get only FAIL findings there is a `-q` flag that makes Prowler to show and log only FAILs. It can be combined with any other option.
```
```sh
./prowler -q -M csv -b
```
## Security Hub integration
Since version v2.3, Prowler supports natively sending findings to [AWS Security Hub](https://aws.amazon.com/security-hub). This integration allows Prowler to import its findings to AWS Security Hub. With Security Hub, you now have a single place that aggregates, organizes, and prioritizes your security alerts, or findings, from multiple AWS services, such as Amazon GuardDuty, Amazon Inspector, Amazon Macie, AWS Identity and Access Management (IAM) Access Analyzer, and AWS Firewall Manager, as well as from AWS Partner solutions and now from Prowler. It is as simple as running the command below:
```sh
./prowler -M json-asff -S
```
There are two requirements:
1. Security Hub must be enabled for the active region from where you are calling Prowler (if no region is used with `-r` then `us-east-1` is used). It can be enabled by calling `aws securityhub enable-security-hub`
2. As mentioned in section "Custom IAM Policy", to allow Prowler to import its findings to AWS Security Hub you need to add the policy below to the role or user running Prowler:
- [iam/prowler-security-hub.json](iam/prowler-security-hub.json)
>Note: to have updated findings in Security Hub you have to run Prowler periodically. Once a day or every certain amount of hours.
## How to fix every FAIL
@@ -292,7 +363,7 @@ Check your report and fix the issues following all specific guidelines per check
If you are using an STS token for AWS-CLI and your session is expired you probably get this error:
```
```sh
A client error (ExpiredToken) occurred when calling the GenerateCredentialReport operation: The security token included in the request is expired
```
@@ -302,41 +373,61 @@ To fix it, please renew your token by authenticating again to the AWS API, see n
To run Prowler using a profile that requires MFA you just need to get the session token before hand. Just make sure you use this command:
```
```sh
aws --profile <YOUR_AWS_PROFILE> sts get-session-token --duration 129600 --serial-number <ARN_OF_MFA> --token-code <MFA_TOKEN_CODE> --output text
```
Once you get your token you can export it as environment variable:
```
Once you get your token you can export it as environment variable:
```sh
export AWS_PROFILE=YOUR_AWS_PROFILE
export AWS_SESSION_TOKEN=YOUR_NEW_TOKEN
AWS_SECRET_ACCESS_KEY=YOUR_SECRET
export AWS_ACCESS_KEY_ID=YOUR_KEY
```
or set manually up your `~/.aws/credentials` file properly.
There are some helpfull tools to save time in this process like [aws-mfa-script](https://github.com/asagage/aws-mfa-script) or [aws-cli-mfa](https://github.com/sweharris/aws-cli-mfa).
### AWS Managed IAM Policies
[ViewOnlyAccess](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_view-only-user)
- Use case: This user can view a list of AWS resources and basic metadata in the account across all services. The user cannot read resource content or metadata that goes beyond the quota and list information for resources.
- Policy description: This policy grants List*, Describe*, Get*, View*, and Lookup* access to resources for most AWS services. To see what actions this policy includes for each service, see [ViewOnlyAccess Permissions](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/job-function/ViewOnlyAccess)
[SecurityAudit](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_security-auditor)
- Use case: This user monitors accounts for compliance with security requirements. This user can access logs and events to investigate potential security breaches or potential malicious activity.
- Policy description: This policy grants permissions to view configuration data for many AWS services and to review their logs. To see what actions this policy includes for each service, see [SecurityAudit Permissions](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/SecurityAudit)
### Custom IAM Policy
Some new and specific checks require Prowler to inherit more permissions than SecurityAudit to work properly. In addition to the AWS managed policy "SecurityAudit" for the role you use for checks you may need to create a custom policy with a few more permissions (get and list and additional services mostly). Here you go a good example for a "ProwlerReadOnlyPolicy" (see below bootstrap script for set it up):
[Prowler-Additions-Policy](iam/prowler-additions-policy.json)
[iam/prowler-additions-policy.json](iam/prowler-additions-policy.json)
Some new and specific checks require Prowler to inherit more permissions than SecurityAudit and ViewOnlyAccess to work properly. In addition to the AWS managed policies, "SecurityAudit" and "ViewOnlyAccess", the user/role you use for checks may need to be granted a custom policy with a few more read-only permissions (to support additional services mostly). Here is an example policy with the additional rights, "Prowler-Additions-Policy" (see below bootstrap script for set it up):
> Note: Action `ec2:get*` is included in "ProwlerReadOnlyPolicy" policy above, that includes `get-password-data`, type `aws ec2 get-password-data help` to better understand its implications.
- [iam/prowler-additions-policy.json](iam/prowler-additions-policy.json)
[Prowler-Security-Hub Policy](iam/prowler-security-hub.json)
Allows Prowler to import its findings to [AWS Security Hub](https://aws.amazon.com/security-hub). More information in [Security Hub integration](#security-hub-integration):
- [iam/prowler-security-hub.json](iam/prowler-security-hub.json)
### Bootstrap Script
Quick bash script to set up a "prowler" IAM user with "SecurityAudit" group with the required permissions (including "ProwlerReadOnlyPolicy"). To run the script below, you need user with administrative permissions; set the `AWS_DEFAULT_PROFILE` to use that account:
Quick bash script to set up a "prowler" IAM user with "SecurityAudit" and "ViewOnlyAccess" group with the required permissions (including "Prowler-Additions-Policy"). To run the script below, you need user with administrative permissions; set the `AWS_DEFAULT_PROFILE` to use that account:
```sh
export AWS_DEFAULT_PROFILE=default
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' | tr -d '"')
aws iam create-group --group-name SecurityAudit
aws iam create-policy --policy-name ProwlerReadOnlyPolicy --policy-document file://$(pwd)/iam/prowler-additions-policy.json
aws iam attach-group-policy --group-name SecurityAudit --policy-arn arn:aws:iam::aws:policy/SecurityAudit
aws iam attach-group-policy --group-name SecurityAudit --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/ProwlerReadOnlyPolicy
aws iam create-group --group-name Prowler
aws iam create-policy --policy-name Prowler-Additions-Policy --policy-document file://$(pwd)/iam/prowler-additions-policy.json
aws iam attach-group-policy --group-name Prowler --policy-arn arn:aws:iam::aws:policy/SecurityAudit
aws iam attach-group-policy --group-name Prowler --policy-arn arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
aws iam attach-group-policy --group-name Prowler --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/Prowler-Additions-Policy
aws iam create-user --user-name prowler
aws iam add-user-to-group --user-name prowler --group-name SecurityAudit
aws iam add-user-to-group --user-name prowler --group-name Prowler
aws iam create-access-key --user-name prowler
unset ACCOUNT_ID AWS_DEFAULT_PROFILE
```
@@ -351,7 +442,7 @@ Some of these checks look for publicly facing resources may not actually be full
To list all existing checks please run the command below:
```
```sh
./prowler -l
```
@@ -369,6 +460,13 @@ or to run just one of the checks:
./prowler -c extraNUMBER
```
or to run multiple extras in one go:
```sh
./prowler -c extraNumber,extraNumber
```
## Forensics Ready Checks
With this group of checks, Prowler looks if each service with logging or audit capabilities has them enabled to ensure all needed evidences are recorded and collected for an eventual digital forensic investigation in case of incident. List of checks part of this group (you can also see all groups with `./prowler -L`). The list of checks can be seen in the group file at:
@@ -400,6 +498,7 @@ With this group of checks, Prowler shows results of controls related to the "Sec
More information on the original PR is [here](https://github.com/toniblyx/prowler/issues/227).
### Note on Business Associate Addendum's (BAA)
Under the HIPAA regulations, cloud service providers (CSPs) such as AWS are considered business associates. The Business Associate Addendum (BAA) is an AWS contract that is required under HIPAA rules to ensure that AWS appropriately safeguards protected health information (PHI). The BAA also serves to clarify and limit, as appropriate, the permissible uses and disclosures of PHI by AWS, based on the relationship between AWS and our customers, and the activities or services being performed by AWS. Customers may use any AWS service in an account designated as a HIPAA account, but they should only process, store, and transmit protected health information (PHI) in the HIPAA-eligible services defined in the Business Associate Addendum (BAA). For the latest list of HIPAA-eligible AWS services, see [HIPAA Eligible Services Reference](https://aws.amazon.com/compliance/hipaa-eligible-services-reference/).
More information on AWS & HIPAA can be found [here](https://aws.amazon.com/compliance/hipaa-compliance/)
@@ -414,6 +513,55 @@ The `hipaa` group of checks uses existing and extra checks. To get a HIPAA repor
./prowler -g hipaa
```
## Trust Boundaries Checks
### Definition and Terms
The term "trust boundary" is originating from the threat modelling process and the most popular contributor Adam Shostack and author of "Threat Modeling: Designing for Security" defines it as following ([reference](https://adam.shostack.org/uncover.html)):
> Trust boundaries are perhaps the most subjective of all: these represent the border between trusted and untrusted elements. Trust is complex. You might trust your mechanic with your car, your dentist with your teeth, and your banker with your money, but you probably don't trust your dentist to change your spark plugs.
AWS is made to be flexible for service links within and between different AWS accounts, we all know that.
This group of checks helps to analyse a particular AWS account (subject) on existing links to other AWS accounts across various AWS services, in order to identify untrusted links.
### Run
To give it a quick shot just call:
```sh
./prowler -g trustboundaries
```
### Scenarios
Currently this check group supports two different scenarios:
1. Single account environment: no action required, the configuration is happening automatically for you.
2. Multi account environment: in case you environment has multiple trusted and known AWS accounts you maybe want to append them manually to [groups/group16_trustboundaries](groups/group16_trustboundaries) as a space separated list into `GROUP_TRUSTBOUNDARIES_TRUSTED_ACCOUNT_IDS` variable, then just run prowler.
### Coverage
Current coverage of Amazon Web Service (AWS) taken from [here](https://docs.aws.amazon.com/whitepapers/latest/aws-overview/introduction.html):
| Topic | Service | Trust Boundary |
|---------------------------------|------------|---------------------------------------------------------------------------|
| Networking and Content Delivery | Amazon VPC | VPC endpoints connections ([extra786](checks/check_extra786)) |
| | | VPC endpoints whitelisted principals ([extra787](checks/check_extra787)) |
All ideas or recommendations to extend this group are very welcome [here](https://github.com/toniblyx/prowler/issues/new/choose).
### Detailed Explanation of the Concept
The diagrams depict two common scenarios, single account and multi account environments.
Every circle represents one AWS account.
The dashed line represents the trust boundary, that separates trust and untrusted AWS accounts.
The arrow simply describes the direction of the trust, however the data can potentially flow in both directions.
Single Account environment assumes that only the AWS account subject to this analysis is trusted. However there is a chance that two VPCs are existing within that one AWS account which are still trusted as a self reference.
![single-account-environment](/docs/images/prowler-single-account-environment.png)
Multi Account environments assumes a minimum of two trusted or known accounts. For this particular example all trusted and known accounts will be tested. Therefore `GROUP_TRUSTBOUNDARIES_TRUSTED_ACCOUNT_IDS` variable in [groups/group16_trustboundaries](groups/group16_trustboundaries) should include all trusted accounts Account #A, Account #B, Account #C, and Account #D in order to finally raise Account #E and Account #F for being untrusted or unknown.
![multi-account-environment](/docs/images/prowler-multi-account-environment.png)
## Add Custom Checks
In order to add any new check feel free to create a new extra check in the extras group or other group. To do so, you will need to follow these steps:
@@ -434,7 +582,7 @@ In order to add any new check feel free to create a new extra check in the extra
## Third Party Integrations
### AWS Security Hub
### AWS Security Hub
There is a blog post about that integration in the AWS Security blog here <https://aws.amazon.com/blogs/security/use-aws-fargate-prowler-send-security-configuration-findings-about-aws-services-security-hub/>
@@ -459,3 +607,4 @@ NOTE: If you are interested in using Prowler for commercial purposes remember th
**I'm not related anyhow with CIS organization, I just write and maintain Prowler to help companies over the world to make their cloud infrastructure more secure.**
If you want to contact me visit <https://blyx.com/contact>

View File

@@ -8,10 +8,11 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check11="1.1,1.01"
CHECK_ID_check11="1.1"
CHECK_TITLE_check11="[check11] Avoid the use of the root account (Scored)"
CHECK_SCORED_check11="SCORED"
CHECK_TYPE_check11="LEVEL1"
CHECK_ASFF_TYPE_check11="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check101="check11"
check11(){

View File

@@ -12,6 +12,7 @@ CHECK_ID_check110="1.10"
CHECK_TITLE_check110="[check110] Ensure IAM password policy prevents password reuse: 24 or greater (Scored)"
CHECK_SCORED_check110="SCORED"
CHECK_TYPE_check110="LEVEL1"
CHECK_ASFF_TYPE_check110="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check110="check110"
check110(){

View File

@@ -12,6 +12,7 @@ CHECK_ID_check111="1.11"
CHECK_TITLE_check111="[check111] Ensure IAM password policy expires passwords within 90 days or less (Scored)"
CHECK_SCORED_check111="SCORED"
CHECK_TYPE_check111="LEVEL1"
CHECK_ASFF_TYPE_check111="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check111="check111"
check111(){

View File

@@ -12,6 +12,7 @@ CHECK_ID_check112="1.12"
CHECK_TITLE_check112="[check112] Ensure no root account access key exists (Scored)"
CHECK_SCORED_check112="SCORED"
CHECK_TYPE_check112="LEVEL1"
CHECK_ASFF_TYPE_check112="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check112="check112"
check112(){
@@ -22,11 +23,11 @@ check112(){
if [ "$ROOTKEY1" == "false" ];then
textPass "No access key 1 found for root"
else
textFail "Found access key 1 for root "
textFail "Found access key 1 for root"
fi
if [ "$ROOTKEY2" == "false" ];then
textPass "No access key 2 found for root"
else
textFail "Found access key 2 for root "
textFail "Found access key 2 for root"
fi
}

View File

@@ -12,6 +12,7 @@ CHECK_ID_check113="1.13"
CHECK_TITLE_check113="[check113] Ensure MFA is enabled for the root account (Scored)"
CHECK_SCORED_check113="SCORED"
CHECK_TYPE_check113="LEVEL1"
CHECK_ASFF_TYPE_check113="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check113="check113"
check113(){
@@ -20,6 +21,6 @@ check113(){
if [ "$COMMAND113" == "1" ]; then
textPass "Virtual MFA is enabled for root"
else
textFail "MFA is not ENABLED for root account "
textFail "MFA is not ENABLED for root account"
fi
}

View File

@@ -12,19 +12,20 @@ CHECK_ID_check114="1.14"
CHECK_TITLE_check114="[check114] Ensure hardware MFA is enabled for the root account (Scored)"
CHECK_SCORED_check114="SCORED"
CHECK_TYPE_check114="LEVEL2"
CHECK_ASFF_TYPE_check114="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check114="check114"
check114(){
# "Ensure hardware MFA is enabled for the root account (Scored)"
COMMAND113=$($AWSCLI iam get-account-summary $PROFILE_OPT --region $REGION --output json --query 'SummaryMap.AccountMFAEnabled')
if [ "$COMMAND113" == "1" ]; then
COMMAND114=$($AWSCLI iam list-virtual-mfa-devices $PROFILE_OPT --region $REGION --output text --assignment-status Assigned --query 'VirtualMFADevices[*].[SerialNumber]' | grep '^arn:aws:iam::[0-9]\{12\}:mfa/root-account-mfa-device$')
COMMAND114=$($AWSCLI iam list-virtual-mfa-devices $PROFILE_OPT --region $REGION --output text --assignment-status Assigned --query 'VirtualMFADevices[*].[SerialNumber]' | grep '^arn:${AWS_PARTITION}:iam::[0-9]\{12\}:mfa/root-account-mfa-device$')
if [[ "$COMMAND114" ]]; then
textFail "Only Virtual MFA is enabled for root"
else
textPass "Hardware MFA is enabled for root "
textPass "Hardware MFA is enabled for root"
fi
else
textFail "MFA is not ENABLED for root account "
textFail "MFA is not ENABLED for root account"
fi
}

View File

@@ -12,6 +12,7 @@ CHECK_ID_check115="1.15"
CHECK_TITLE_check115="[check115] Ensure security questions are registered in the AWS account (Not Scored)"
CHECK_SCORED_check115="NOT_SCORED"
CHECK_TYPE_check115="LEVEL1"
CHECK_ASFF_TYPE_check115="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check115="check115"
check115(){

View File

@@ -12,6 +12,8 @@ CHECK_ID_check116="1.16"
CHECK_TITLE_check116="[check116] Ensure IAM policies are attached only to groups or roles (Scored)"
CHECK_SCORED_check116="SCORED"
CHECK_TYPE_check116="LEVEL1"
CHECK_ASFF_TYPE_check116="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check116="AwsIamUser"
CHECK_ALTERNATE_check116="check116"
check116(){
@@ -21,16 +23,16 @@ check116(){
for user in $LIST_USERS;do
USER_POLICY=$($AWSCLI iam list-attached-user-policies --output text $PROFILE_OPT --region $REGION --user-name $user)
if [[ $USER_POLICY ]]; then
textFail "$user has managed policy directly attached "
textFail "$user has managed policy directly attached"
C116_NUM_USERS=$(expr $C116_NUM_USERS + 1)
fi
USER_POLICY=$($AWSCLI iam list-user-policies --output text $PROFILE_OPT --region $REGION --user-name $user)
if [[ $USER_POLICY ]]; then
textFail "$user has inline policy directly attached "
textFail "$user has inline policy directly attached"
C116_NUM_USERS=$(expr $C116_NUM_USERS + 1)
fi
done
if [[ $C116_NUM_USERS -eq 0 ]]; then
textPass "No policies attached to users."
textPass "No policies attached to users"
fi
}

View File

@@ -12,6 +12,7 @@ CHECK_ID_check117="1.17"
CHECK_TITLE_check117="[check117] Maintain current contact details (Not Scored)"
CHECK_SCORED_check117="NOT_SCORED"
CHECK_TYPE_check117="LEVEL1"
CHECK_ASFF_TYPE_check117="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check117="check117"
check117(){

View File

@@ -12,6 +12,7 @@ CHECK_ID_check118="1.18"
CHECK_TITLE_check118="[check118] Ensure security contact information is registered (Not Scored)"
CHECK_SCORED_check118="NOT_SCORED"
CHECK_TYPE_check118="LEVEL1"
CHECK_ASFF_TYPE_check118="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check118="check118"
check118(){

View File

@@ -12,6 +12,8 @@ CHECK_ID_check119="1.19"
CHECK_TITLE_check119="[check119] Ensure IAM instance roles are used for AWS resource access from instances (Not Scored)"
CHECK_SCORED_check119="NOT_SCORED"
CHECK_TYPE_check119="LEVEL2"
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"
check119(){
@@ -25,9 +27,9 @@ check119(){
if [[ $STATE_NAME != "terminated" ]]; 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
textFail "$regx: Instance $instance not associated with an instance role" $regx
else
textPass "$regx: Instance $instance associated with role ${PROFILEARN##*/}." $regx
textPass "$regx: Instance $instance associated with role ${PROFILEARN##*/}" $regx
fi
fi
done

View File

@@ -8,16 +8,18 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check12="1.2,1.02"
CHECK_ID_check12="1.2"
CHECK_TITLE_check12="[check12] Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)"
CHECK_SCORED_check12="SCORED"
CHECK_TYPE_check12="LEVEL1"
CHECK_ASFF_TYPE_check12="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check12="AwsIamUser"
CHECK_ALTERNATE_check102="check12"
check12(){
# "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)"
# List users with password enabled
COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$4 }' |grep true | awk '{ print $1 }')
COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$4 }' |grep -F ' true$' | awk '{ print $1 }')
COMMAND12=$(
for i in $COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED; do
cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$8 }' |grep "^$i " |grep false | awk '{ print $1 }'

View File

@@ -12,6 +12,8 @@ CHECK_ID_check120="1.20"
CHECK_TITLE_check120="[check120] Ensure a support role has been created to manage incidents with AWS Support (Scored)"
CHECK_SCORED_check120="SCORED"
CHECK_TYPE_check120="LEVEL1"
CHECK_ASFF_TYPE_check120="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check120="AwsIamRole"
CHECK_ALTERNATE_check120="check120"
check120(){
@@ -28,7 +30,7 @@ check120(){
# textInfo "User $user has support access via $policyarn"
# done
else
textFail "Support Policy not applied to any Role "
textFail "Support Policy not applied to any Role"
fi
done
else

View File

@@ -12,6 +12,8 @@ CHECK_ID_check121="1.21"
CHECK_TITLE_check121="[check121] Do not setup access keys during initial user setup for all IAM users that have a console password (Not Scored)"
CHECK_SCORED_check121="NOT_SCORED"
CHECK_TYPE_check121="LEVEL1"
CHECK_ASFF_TYPE_check121="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check121="AwsIamUser"
CHECK_ALTERNATE_check121="check121"
check121(){
@@ -19,22 +21,24 @@ check121(){
LIST_USERS=$($AWSCLI iam list-users --query 'Users[*].UserName' --output text $PROFILE_OPT --region $REGION)
# List of USERS with KEY1 last_used_date as N/A
LIST_USERS_KEY1_NA=$(for user in $LIST_USERS; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$11 }'|grep N/A |awk '{ print $1 }'; done)
LIST_USERS_KEY1_ACTIVE=$(for user in $LIST_USERS_KEY1_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$9 }'|grep "true$"|awk '{ print $1 }'|sed 's/[[:blank:]]+/,/g' ; done)
# List of USERS with KEY1 active, last_used_date as N/A and have a console password
LIST_USERS_KEY1_ACTIVE=$(for user in $LIST_USERS_KEY1_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$4,$9 }'|grep "true true$"|awk '{ print $1 }'|sed 's/[[:blank:]]+/,/g' ; done)
if [[ $LIST_USERS_KEY1_ACTIVE ]]; then
for user in $LIST_USERS_KEY1_ACTIVE; do
textFail "$user has never used Access Key 1"
textFail "User $user has never used access key 1"
done
else
textPass "No users found with Access Key 1 never used"
textPass "No users found with access key 1 never used"
fi
# List of USERS with KEY2 last_used_date as N/A
LIST_USERS_KEY2_NA=$(for user in $LIST_USERS; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$16 }'|grep N/A |awk '{ print $1 }' ; done)
LIST_USERS_KEY2_ACTIVE=$(for user in $LIST_USERS_KEY2_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$14 }'|grep "true$" |awk '{ print $1 }' ; done)
# List of USERS with KEY2 active, last_used_date as N/A and have a console password
LIST_USERS_KEY2_ACTIVE=$(for user in $LIST_USERS_KEY2_NA; do grep "^${user}," $TEMP_REPORT_FILE|awk -F, '{ print $1,$4,$14 }'|grep "true true$" |awk '{ print $1 }' ; done)
if [[ $LIST_USERS_KEY2_ACTIVE ]]; then
for user in $LIST_USERS_KEY2_ACTIVE; do
textFail "$user has never used Access Key 2"
textFail "User $user has never used access key 2"
done
else
textPass "No users found with Access Key 2 never used"
textPass "No users found with access key 2 never used"
fi
}

View File

@@ -12,6 +12,8 @@ CHECK_ID_check122="1.22"
CHECK_TITLE_check122="[check122] Ensure IAM policies that allow full \"*:*\" administrative privileges are not created (Scored)"
CHECK_SCORED_check122="SCORED"
CHECK_TYPE_check122="LEVEL1"
CHECK_ASFF_TYPE_check122="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check122="AwsIamPolicy"
CHECK_ALTERNATE_check122="check122"
check122(){

View File

@@ -8,32 +8,14 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check13="1.3,1.03"
CHECK_ID_check13="1.3"
CHECK_TITLE_check13="[check13] Ensure credentials unused for 90 days or greater are disabled (Scored)"
CHECK_SCORED_check13="SCORED"
CHECK_TYPE_check13="LEVEL1"
CHECK_ASFF_TYPE_check13="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check13="AwsIamUser"
CHECK_ALTERNATE_check103="check13"
check13(){
# "Ensure credentials unused for 90 days or greater are disabled (Scored)"
COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$4 }' |grep true | awk '{ print $1 }')
# Only check Password last used for users with password enabled
if [[ $COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED ]]; then
for i in $COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED; do
DATEUSED=$($AWSCLI iam list-users --query "Users[?UserName=='$i'].PasswordLastUsed" --output text $PROFILE_OPT --region $REGION | cut -d'T' -f1)
if [ "$DATEUSED" == "" ]
then
textFail "User \"$i\" has not logged in during the last 90 days "
else
HOWOLDER=$(how_older_from_today $DATEUSED)
if [ $HOWOLDER -gt "90" ];then
textFail "User \"$i\" has not logged in during the last 90 days "
else
textPass "User \"$i\" found with credentials used in the last 90 days"
fi
fi
done
else
textPass "No users found with password enabled"
fi
check_creds_used_in_last_days 90
}

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check14="1.4,1.04"
CHECK_ID_check14="1.4"
CHECK_TITLE_check14="[check14] Ensure access keys are rotated every 90 days or less (Scored)"
CHECK_SCORED_check14="SCORED"
CHECK_TYPE_check14="LEVEL1"
CHECK_ASFF_TYPE_check14="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check14="AwsIamUser"
CHECK_ALTERNATE_check104="check14"
check14(){
@@ -28,15 +30,15 @@ check14(){
HOWOLDER=$(how_older_from_today $DATEROTATED1)
if [ $HOWOLDER -gt "90" ];then
textFail " $user has not rotated access key1 in over 90 days."
textFail "$user has not rotated access key 1 in over 90 days"
C14_NUM_USERS1=$(expr $C14_NUM_USERS1 + 1)
fi
done
if [[ $C14_NUM_USERS1 -eq 0 ]]; then
textPass "No users with access key 1 older than 90 days."
textPass "No users with access key 1 older than 90 days"
fi
else
textPass "No users with access key 1."
textPass "No users with access key 1"
fi
if [[ $LIST_OF_USERS_WITH_ACCESS_KEY2 ]]; then
@@ -46,14 +48,14 @@ check14(){
DATEROTATED2=$(cat $TEMP_REPORT_FILE | grep -v user_creation_time | grep "^${user},"| awk -F, '{ print $15 }' | grep -v "N/A" | awk -F"T" '{ print $1 }')
HOWOLDER=$(how_older_from_today $DATEROTATED2)
if [ $HOWOLDER -gt "90" ];then
textFail " $user has not rotated access key2 in over 90 days. "
textFail "$user has not rotated access key 2 in over 90 days"
C14_NUM_USERS2=$(expr $C14_NUM_USERS2 + 1)
fi
done
if [[ $C14_NUM_USERS2 -eq 0 ]]; then
textPass "No users with access key 2 older than 90 days."
textPass "No users with access key 2 older than 90 days"
fi
else
textPass "No users with access key 2."
textPass "No users with access key 2"
fi
}

View File

@@ -8,10 +8,11 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check15="1.5,1.05"
CHECK_ID_check15="1.5"
CHECK_TITLE_check15="[check15] Ensure IAM password policy requires at least one uppercase letter (Scored)"
CHECK_SCORED_check15="SCORED"
CHECK_TYPE_check15="LEVEL1"
CHECK_ASFF_TYPE_check15="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check105="check15"
check15(){

View File

@@ -8,10 +8,11 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check16="1.6,1.06"
CHECK_ID_check16="1.6"
CHECK_TITLE_check16="[check16] Ensure IAM password policy require at least one lowercase letter (Scored)"
CHECK_SCORED_check16="SCORED"
CHECK_TYPE_check16="LEVEL1"
CHECK_ASFF_TYPE_check16="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check106="check16"
check16(){

View File

@@ -8,10 +8,11 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check17="1.7,1.07"
CHECK_ID_check17="1.7"
CHECK_TITLE_check17="[check17] Ensure IAM password policy require at least one symbol (Scored)"
CHECK_SCORED_check17="SCORED"
CHECK_TYPE_check17="LEVEL1"
CHECK_ASFF_TYPE_check17="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check107="check17"
check17(){

View File

@@ -8,10 +8,11 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check18="1.8,1.08"
CHECK_ID_check18="1.8"
CHECK_TITLE_check18="[check18] Ensure IAM password policy require at least one number (Scored)"
CHECK_SCORED_check18="SCORED"
CHECK_TYPE_check18="LEVEL1"
CHECK_ASFF_TYPE_check18="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check108="check18"
check18(){

View File

@@ -8,10 +8,11 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check19="1.9,1.09"
CHECK_ID_check19="1.9"
CHECK_TITLE_check19="[check19] Ensure IAM password policy requires minimum length of 14 or greater (Scored)"
CHECK_SCORED_check19="SCORED"
CHECK_TYPE_check19="LEVEL1"
CHECK_ASFF_TYPE_check19="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check109="check19"
check19(){

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check21="2.1,2.01"
CHECK_ID_check21="2.1"
CHECK_TITLE_check21="[check21] Ensure CloudTrail is enabled in all regions (Scored)"
CHECK_SCORED_check21="SCORED"
CHECK_TYPE_check21="LEVEL1"
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"
check21(){
@@ -20,20 +22,24 @@ check21(){
for regx in $REGIONS; do
LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].Name' --output text --no-include-shadow-trails)
if [[ $LIST_OF_TRAILS ]];then
for trail in $LIST_OF_TRAILS;do
trail_count=$((trail_count + 1))
MULTIREGION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].IsMultiRegionTrail' --output text --trail-name-list $trail)
if [[ "$MULTIREGION_TRAIL_STATUS" == 'False' ]];then
textFail "$trail trail in $regx is not enabled in multi region mode"
else
textPass "$trail trail in $regx is enabled for all regions"
fi
done
for trail in $LIST_OF_TRAILS;do
trail_count=$((trail_count + 1))
MULTIREGION_TRAIL_STATUS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].IsMultiRegionTrail' --output text --trail-name-list $trail)
if [[ "$MULTIREGION_TRAIL_STATUS" == 'False' ]];then
textFail "$trail trail in $regx is not enabled in multi region mode"
else
textPass "$trail trail in $regx is enabled for all regions"
fi
done
fi
done
if [[ $trail_count == 0 ]]; then
textFail "No CloudTrail trails were found in the account"
ORG_TRAIL=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region us-east-1 | jq '.trailList[] | select(.IsMultiRegionTrail and .IsOrganizationTrail) | .Name' | sed 's/"//g')
if [[ $ORG_TRAIL != "" ]]; then
textPass "$ORG_TRAIL trail in $regx is enabled for all regions"
else
textFail "No CloudTrail trails were found in the account"
fi
fi
}
}

View File

@@ -8,15 +8,17 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check22="2.2,2.02"
CHECK_ID_check22="2.2"
CHECK_TITLE_check22="[check22] Ensure CloudTrail log file validation is enabled (Scored)"
CHECK_SCORED_check22="SCORED"
CHECK_TYPE_check22="LEVEL2"
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"
check22(){
# "Ensure CloudTrail log file validation is enabled (Scored)"
for regx in $REGIONS; do
LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].Name' --output text --no-include-shadow-trails)
if [[ $LIST_OF_TRAILS ]];then

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check23="2.3,2.03"
CHECK_ID_check23="2.3"
CHECK_TITLE_check23="[check23] Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)"
CHECK_SCORED_check23="SCORED"
CHECK_TYPE_check23="LEVEL1"
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"
check23(){
@@ -21,7 +23,7 @@ check23(){
for bucket in $CLOUDTRAILBUCKET;do
CLOUDTRAILBUCKET_HASALLPERMISIONS=$($AWSCLI s3api get-bucket-acl --bucket $bucket --query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers`]' $PROFILE_OPT --region $REGION --output text 2>&1)
if [[ $(echo "$CLOUDTRAILBUCKET_HASALLPERMISIONS" | grep AccessDenied) ]]; then
textFail "Access Denied Trying to Get Bucket Acl for $bucket"
textInfo "Access Denied Trying to Get Bucket Acl for $bucket"
continue
fi
if [[ $CLOUDTRAILBUCKET_HASALLPERMISIONS ]]; then

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check24="2.4,2.04"
CHECK_ID_check24="2.4"
CHECK_TITLE_check24="[check24] Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)"
CHECK_SCORED_check24="SCORED"
CHECK_TYPE_check24="LEVEL1"
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"
check24(){

View File

@@ -8,10 +8,11 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check25="2.5,2.05"
CHECK_ID_check25="2.5"
CHECK_TITLE_check25="[check25] Ensure AWS Config is enabled in all regions (Scored)"
CHECK_SCORED_check25="SCORED"
CHECK_TYPE_check25="LEVEL1"
CHECK_ASFF_TYPE_check25="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ALTERNATE_check205="check25"
check25(){

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check26="2.6,2.06"
CHECK_ID_check26="2.6"
CHECK_TITLE_check26="[check26] Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Scored)"
CHECK_SCORED_check26="SCORED"
CHECK_TYPE_check26="LEVEL1"
CHECK_ASFF_TYPE_check26="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check26="AwsS3Bucket"
CHECK_ALTERNATE_check206="check26"
check26(){
@@ -27,9 +29,9 @@ check26(){
if [[ $CLOUDTRAILBUCKET ]]; then
bucket=$CLOUDTRAILBUCKET
if [ "$CLOUDTRAIL_ACCOUNT_ID" == "$ACCOUNT_NUM" ]; then
CLOUDTRAILBUCKET_LOGENABLED=$($AWSCLI s3api get-bucket-logging --bucket $bucket $PROFILE_OPT --region $REGION --query 'LoggingEnabled.TargetBucket' --output text 2>&1)
CLOUDTRAILBUCKET_LOGENABLED=$($AWSCLI s3api get-bucket-logging --bucket $bucket $PROFILE_OPT --region $REGION --query 'LoggingEnabled.TargetBucket' 2>&1)
if [[ $(echo "$CLOUDTRAILBUCKET_LOGENABLED" | grep AccessDenied) ]]; then
textFail "Access Denied Trying to Get Bucket Logging for $bucket"
textInfo "Access Denied Trying to Get Bucket Logging for $bucket"
continue
fi
if [[ $CLOUDTRAILBUCKET_LOGENABLED != "null" ]]; then

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check27="2.7,2.07"
CHECK_ID_check27="2.7"
CHECK_TITLE_check27="[check27] Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)"
CHECK_SCORED_check27="SCORED"
CHECK_TYPE_check27="LEVEL2"
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"
check27(){

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check28="2.8,2.08"
CHECK_ID_check28="2.8"
CHECK_TITLE_check28="[check28] Ensure rotation for customer created CMKs is enabled (Scored)"
CHECK_SCORED_check28="SCORED"
CHECK_TYPE_check28="LEVEL2"
CHECK_ASFF_TYPE_check28="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check28="AwsKmsKey"
CHECK_ALTERNATE_check208="check28"
check28(){
@@ -27,7 +29,7 @@ check28(){
for key in $CHECK_KMS_KEYLIST_NO_DEFAULT; do
CHECK_KMS_KEY_TYPE=$($AWSCLI kms describe-key --key-id $key $PROFILE_OPT --region $regx --query 'KeyMetadata.Origin' | sed 's/["]//g')
if [[ "$CHECK_KMS_KEY_TYPE" == "EXTERNAL" ]];then
textPass "$regx: Key $key in Region $regx Customer Uploaded Key Material." "$regx"
textPass "$regx: Key $key in Region $regx Customer Uploaded Key Material" "$regx"
else
CHECK_KMS_KEY_ROTATION=$($AWSCLI kms get-key-rotation-status --key-id $key $PROFILE_OPT --region $regx --output text)
if [[ "$CHECK_KMS_KEY_ROTATION" == "True" ]];then

View File

@@ -8,14 +8,16 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check29="2.9,2.09"
CHECK_ID_check29="2.9"
CHECK_TITLE_check29="[check29] Ensure VPC Flow Logging is Enabled in all VPCs (Scored)"
CHECK_SCORED_check29="SCORED"
CHECK_TYPE_check29="LEVEL2"
CHECK_ASFF_TYPE_check29="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check29="AwsEc2Vpc"
CHECK_ALTERNATE_check209="check29"
check29(){
# "Ensure VPC Flow Logging is Enabled in all VPCs (Scored)"
# "Ensure VPC Flow Logging is Enabled in all VPCs (Scored)"
for regx in $REGIONS; do
AVAILABLE_VPC=$($AWSCLI ec2 describe-vpcs $PROFILE_OPT --region $regx --query 'Vpcs[?State==`available`].VpcId' --output text)
for vpcx in $AVAILABLE_VPC; do
@@ -26,7 +28,7 @@ check29(){
done
else
textFail "VPC $vpcx: No VPCFlowLog has been found in Region $regx" "$regx"
fi
fi
done
done
}

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check31="3.1,3.01"
CHECK_ID_check31="3.1"
CHECK_TITLE_check31="[check31] Ensure a log metric filter and alarm exist for unauthorized API calls (Scored)"
CHECK_SCORED_check31="SCORED"
CHECK_TYPE_check31="LEVEL1"
CHECK_ASFF_TYPE_check31="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check31="AwsCloudTrailTrail"
CHECK_ALTERNATE_check301="check31"
check31(){

View File

@@ -37,6 +37,8 @@ CHECK_ID_check310="3.10"
CHECK_TITLE_check310="[check310] Ensure a log metric filter and alarm exist for security group changes (Scored)"
CHECK_SCORED_check310="SCORED"
CHECK_TYPE_check310="LEVEL2"
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"
check310(){

View File

@@ -37,6 +37,8 @@ CHECK_ID_check311="3.11"
CHECK_TITLE_check311="[check311] Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) (Scored)"
CHECK_SCORED_check311="SCORED"
CHECK_TYPE_check311="LEVEL2"
CHECK_ASFF_TYPE_check311="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check311="AwsCloudTrailTrail"
CHECK_ALTERNATE_check311="check311"
check311(){

View File

@@ -37,6 +37,8 @@ CHECK_ID_check312="3.12"
CHECK_TITLE_check312="[check312] Ensure a log metric filter and alarm exist for changes to network gateways (Scored)"
CHECK_SCORED_check312="SCORED"
CHECK_TYPE_check312="LEVEL1"
CHECK_ASFF_TYPE_check312="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check312="AwsCloudTrailTrail"
CHECK_ALTERNATE_check312="check312"
check312(){

View File

@@ -37,6 +37,8 @@ CHECK_ID_check313="3.13"
CHECK_TITLE_check313="[check313] Ensure a log metric filter and alarm exist for route table changes (Scored)"
CHECK_SCORED_check313="SCORED"
CHECK_TYPE_check313="LEVEL1"
CHECK_ASFF_TYPE_check313="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check313="AwsCloudTrailTrail"
CHECK_ALTERNATE_check313="check313"
check313(){

View File

@@ -37,6 +37,8 @@ CHECK_ID_check314="3.14"
CHECK_TITLE_check314="[check314] Ensure a log metric filter and alarm exist for VPC changes (Scored)"
CHECK_SCORED_check314="SCORED"
CHECK_TYPE_check314="LEVEL1"
CHECK_ASFF_TYPE_check314="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check314="AwsCloudTrailTrail"
CHECK_ALTERNATE_check314="check314"
check314(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check32="3.2,3.02"
CHECK_ID_check32="3.2"
CHECK_TITLE_check32="[check32] Ensure a log metric filter and alarm exist for Management Console sign-in without MFA (Scored)"
CHECK_SCORED_check32="SCORED"
CHECK_TYPE_check32="LEVEL1"
CHECK_ASFF_TYPE_check32="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check32="AwsCloudTrailTrail"
CHECK_ALTERNATE_check302="check32"
check32(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check33="3.3,3.03"
CHECK_ID_check33="3.3"
CHECK_TITLE_check33="[check33] Ensure a log metric filter and alarm exist for usage of root account (Scored)"
CHECK_SCORED_check33="SCORED"
CHECK_TYPE_check33="LEVEL1"
CHECK_ASFF_TYPE_check33="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check33="AwsCloudTrailTrail"
CHECK_ALTERNATE_check303="check33"
check33(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check34="3.4,3.04"
CHECK_ID_check34="3.4"
CHECK_TITLE_check34="[check34] Ensure a log metric filter and alarm exist for IAM policy changes (Scored)"
CHECK_SCORED_check34="SCORED"
CHECK_TYPE_check34="LEVEL1"
CHECK_ASFF_TYPE_check34="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check34="AwsCloudTrailTrail"
CHECK_ALTERNATE_check304="check34"
check34(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check35="3.5,3.05"
CHECK_ID_check35="3.5"
CHECK_TITLE_check35="[check35] Ensure a log metric filter and alarm exist for CloudTrail configuration changes (Scored)"
CHECK_SCORED_check35="SCORED"
CHECK_TYPE_check35="LEVEL1"
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"
check35(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check36="3.6,3.06"
CHECK_ID_check36="3.6"
CHECK_TITLE_check36="[check36] Ensure a log metric filter and alarm exist for AWS Management Console authentication failures (Scored)"
CHECK_SCORED_check36="SCORED"
CHECK_TYPE_check36="LEVEL2"
CHECK_ASFF_TYPE_check36="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check36="AwsCloudTrailTrail"
CHECK_ALTERNATE_check306="check36"
check36(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check37="3.7,3.07"
CHECK_ID_check37="3.7"
CHECK_TITLE_check37="[check37] Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs (Scored)"
CHECK_SCORED_check37="SCORED"
CHECK_TYPE_check37="LEVEL2"
CHECK_ASFF_TYPE_check37="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check37="AwsCloudTrailTrail"
CHECK_ALTERNATE_check307="check37"
check37(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check38="3.8,3.08"
CHECK_ID_check38="3.8"
CHECK_TITLE_check38="[check38] Ensure a log metric filter and alarm exist for S3 bucket policy changes (Scored)"
CHECK_SCORED_check38="SCORED"
CHECK_TYPE_check38="LEVEL1"
CHECK_ASFF_TYPE_check38="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check38="AwsCloudTrailTrail"
CHECK_ALTERNATE_check308="check38"
check38(){

View File

@@ -33,10 +33,12 @@
# --actions-enabled \
# --alarm-actions arn:aws:sns:us-east-1:123456789012:CloudWatchAlarmTopic
CHECK_ID_check39="3.9,3.09"
CHECK_ID_check39="3.9"
CHECK_TITLE_check39="[check39] Ensure a log metric filter and alarm exist for AWS Config configuration changes (Scored)"
CHECK_SCORED_check39="SCORED"
CHECK_TYPE_check39="LEVEL2"
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"
check39(){

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check41="4.1,4.01"
CHECK_ID_check41="4.1"
CHECK_TITLE_check41="[check41] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored)"
CHECK_SCORED_check41="SCORED"
CHECK_TYPE_check41="LEVEL2"
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"
check41(){

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check42="4.2,4.02"
CHECK_ID_check42="4.2"
CHECK_TITLE_check42="[check42] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored)"
CHECK_SCORED_check42="SCORED"
CHECK_TYPE_check42="LEVEL2"
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"
check42(){

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check43="4.3,4.03"
CHECK_ID_check43="4.3"
CHECK_TITLE_check43="[check43] Ensure the default security group of every VPC restricts all traffic (Scored)"
CHECK_SCORED_check43="SCORED"
CHECK_TYPE_check43="LEVEL2"
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"
check43(){

View File

@@ -8,10 +8,12 @@
# You should have received a copy of the license along with this
# work. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.
CHECK_ID_check44="4.4,4.04"
CHECK_ID_check44="4.4"
CHECK_TITLE_check44="[check44] Ensure routing tables for VPC peering are \"least access\" (Not Scored)"
CHECK_SCORED_check44="NOT_SCORED"
CHECK_TYPE_check44="LEVEL2"
CHECK_ASFF_TYPE_check44="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_check44="AwsEc2Vpc"
CHECK_ALTERNATE_check404="check44"
check44(){

View File

@@ -10,10 +10,11 @@
# 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_extra71="7.1,7.01"
CHECK_ID_extra71="7.1"
CHECK_TITLE_extra71="[extra71] Ensure users of groups with AdministratorAccess policy have MFA tokens enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra71="NOT_SCORED"
CHECK_TYPE_extra71="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra71="AwsIamUser"
CHECK_ALTERNATE_extra701="extra71"
CHECK_ALTERNATE_check71="extra71"
CHECK_ALTERNATE_check701="extra71"
@@ -21,15 +22,15 @@ CHECK_ALTERNATE_check701="extra71"
extra71(){
# "Ensure users of groups with AdministratorAccess policy have MFA tokens enabled (Not Scored) (Not part of CIS benchmark)"
ADMIN_GROUPS=''
AWS_GROUPS=$($AWSCLI $PROFILE_OPT iam list-groups --output text --query 'Groups[].GroupName')
AWS_GROUPS=$($AWSCLI $PROFILE_OPT iam list-groups --output text --region $REGION --query 'Groups[].GroupName')
for grp in $AWS_GROUPS; do
# aws --profile onlinetraining iam list-attached-group-policies --group-name Administrators --query 'AttachedPolicies[].PolicyArn' | grep 'arn:aws:iam::aws:policy/AdministratorAccess'
# list-attached-group-policies
CHECK_ADMIN_GROUP=$($AWSCLI $PROFILE_OPT iam list-attached-group-policies --group-name $grp --output json --query 'AttachedPolicies[].PolicyArn' | grep 'arn:aws:iam::aws:policy/AdministratorAccess')
CHECK_ADMIN_GROUP=$($AWSCLI $PROFILE_OPT --region $REGION iam list-attached-group-policies --group-name $grp --output json --query 'AttachedPolicies[].PolicyArn' | grep 'arn:${AWS_PARTITION}:iam::aws:policy/AdministratorAccess')
if [[ $CHECK_ADMIN_GROUP ]]; then
ADMIN_GROUPS="$ADMIN_GROUPS $grp"
textInfo "$grp group provides administrative access"
ADMIN_USERS=$($AWSCLI $PROFILE_OPT iam get-group --group-name $grp --output json --query 'Users[].UserName' | grep '"' | cut -d'"' -f2 )
ADMIN_USERS=$($AWSCLI $PROFILE_OPT iam get-group --region $REGION --group-name $grp --output json --query 'Users[].UserName' | grep '"' | cut -d'"' -f2 )
for auser in $ADMIN_USERS; do
# users in group are Administrators
# users

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra710="7.10"
CHECK_TITLE_extra710="[extra710] Check for internet facing EC2 Instances (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra710="NOT_SCORED"
CHECK_TYPE_extra710="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra710="AwsEc2Instance"
CHECK_ALTERNATE_check710="extra710"
extra710(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra711="7.11"
CHECK_TITLE_extra711="[extra711] Check for Publicly Accessible Redshift Clusters (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra711="NOT_SCORED"
CHECK_TYPE_extra711="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra711="AwsRedshiftCluster"
CHECK_ALTERNATE_check711="extra711"
extra711(){

View File

@@ -16,14 +16,13 @@ CHECK_SCORED_extra712="NOT_SCORED"
CHECK_TYPE_extra712="EXTRA"
CHECK_ALTERNATE_check712="extra712"
extra712(){
# "Check if Amazon Macie is enabled (Not Scored) (Not part of CIS benchmark)"
textInfo "No API commands available to check if Macie is enabled,"
textInfo "just looking if IAM Macie related permissions exist. "
MACIE_IAM_ROLES_CREATED=$($AWSCLI iam list-roles $PROFILE_OPT --query 'Roles[*].Arn'|grep AWSMacieServiceCustomer|wc -l)
if [[ $MACIE_IAM_ROLES_CREATED -eq 2 ]];then
textPass "Macie related IAM roles exist so it might be enabled. Check it out manually."
else
textFail "No Macie related IAM roles found. It is most likely not to be enabled"
fi
extra712(){
textInfo "No API commands available to check if Macie is enabled,"
textInfo "just looking if IAM Macie related permissions exist. "
MACIE_IAM_ROLES_CREATED=$($AWSCLI iam list-roles $PROFILE_OPT --query 'Roles[*].Arn'|grep AWSMacieServiceCustomer|wc -l)
if [[ $MACIE_IAM_ROLES_CREATED -eq 2 ]];then
textPass "Macie related IAM roles exist so it might be enabled. Check it out manually"
else
textFail "No Macie related IAM roles found. It is most likely not to be enabled"
fi
}

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra714="7.14"
CHECK_TITLE_extra714="[extra714] Check if CloudFront distributions have logging enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra714="NOT_SCORED"
CHECK_TYPE_extra714="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra714="AwsCloudFrontDistribution"
CHECK_ALTERNATE_check714="extra714"
extra714(){

View File

@@ -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.
CHECK_ID_extra715="7.15"
CHECK_TITLE_extra715="[extra715] Check if Elasticsearch Service domains have logging enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_TITLE_extra715="[extra715] Check if Amazon Elasticsearch Service (ES) domains have logging enabled"
CHECK_SCORED_extra715="NOT_SCORED"
CHECK_TYPE_extra715="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra715="AwsElasticsearchDomain"
CHECK_ALTERNATE_check715="extra715"
extra715(){
@@ -23,19 +24,19 @@ extra715(){
for domain in $LIST_OF_DOMAINS;do
SEARCH_SLOWLOG_ENABLED=$($AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.LogPublishingOptions.Options.SEARCH_SLOW_LOGS.Enabled --output text |grep -v ^None|grep -v ^False)
if [[ $SEARCH_SLOWLOG_ENABLED ]];then
textPass "$regx: ElasticSearch Service domain $domain SEARCH_SLOW_LOGS enabled" "$regx"
textPass "$regx: Amazon ES domain $domain SEARCH_SLOW_LOGS enabled" "$regx"
else
textFail "$regx: ElasticSearch Service domain $domain SEARCH_SLOW_LOGS disabled!" "$regx"
textFail "$regx: Amazon ES domain $domain SEARCH_SLOW_LOGS disabled!" "$regx"
fi
INDEX_SLOWLOG_ENABLED=$($AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.LogPublishingOptions.Options.INDEX_SLOW_LOGS.Enabled --output text |grep -v ^None|grep -v ^False)
if [[ $INDEX_SLOWLOG_ENABLED ]];then
textPass "$regx: ElasticSearch Service domain $domain INDEX_SLOW_LOGS enabled" "$regx"
textPass "$regx: Amazon ES domain $domain INDEX_SLOW_LOGS enabled" "$regx"
else
textFail "$regx: ElasticSearch Service domain $domain INDEX_SLOW_LOGS disabled!" "$regx"
textFail "$regx: Amazon ES domain $domain INDEX_SLOW_LOGS disabled!" "$regx"
fi
done
else
textInfo "$regx: No Elasticsearch Service domain found" "$regx"
textInfo "$regx: No Amazon ES domain found" "$regx"
fi
done
}

View File

@@ -11,35 +11,79 @@
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra716="7.16"
CHECK_TITLE_extra716="[extra716] Check if Elasticsearch Service domains allow open access (Not Scored) (Not part of CIS benchmark)"
CHECK_TITLE_extra716="[extra716] Check if Amazon Elasticsearch Service (ES) domains are set as Public or if it has open policy access"
CHECK_SCORED_extra716="NOT_SCORED"
CHECK_TYPE_extra716="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra716="AwsElasticsearchDomain"
CHECK_ALTERNATE_check716="extra716"
extra716(){
# "Check if Elasticsearch Service domains allow open access (Not Scored) (Not part of CIS benchmark)"
for regx in $REGIONS; do
LIST_OF_DOMAINS=$($AWSCLI es list-domain-names $PROFILE_OPT --region $regx --query DomainNames --output text)
if [[ $LIST_OF_DOMAINS ]]; then
for domain in $LIST_OF_DOMAINS;do
CHECK_IF_MEMBER_OF_VPC=$($AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.VPCOptions.Options.VPCId --output text|grep -v ^None)
if [[ ! $CHECK_IF_MEMBER_OF_VPC ]];then
TEMP_POLICY_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-es-domain.policy.XXXXXXXXXX)
$AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.AccessPolicies.Options --output text > $TEMP_POLICY_FILE 2> /dev/null
# check if the policy has Principal as *
CHECK_ES_DOMAIN_ALLUSERS_POLICY=$(cat $TEMP_POLICY_FILE | jq -r '. | .Statement[] | select(.Effect == "Allow" and (((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and .Condition == null)')
if [[ $CHECK_ES_DOMAIN_ALLUSERS_POLICY ]];then
textFail "$regx: $domain policy \"may\" allow Anonymous users to perform actions (Principal: \"*\")" "$regx"
else
textPass "$regx: $domain is not open" "$regx"
fi
TEMP_POLICY_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-es-domain.policy.XXXXXXXXXX)
# get endpoint or vpc endpoints
ES_DOMAIN_ENDPOINT=$($AWSCLI es describe-elasticsearch-domain --domain-name $domain $PROFILE_OPT --region $regx --query 'DomainStatus.[Endpoint || Endpoints]' --output text)
# If the endpoint starts with "vpc-" it is in a VPC then it is fine.
if [[ "$ES_DOMAIN_ENDPOINT" =~ ^vpc-* ]];then
ES_DOMAIN_VPC=$($AWSCLI es describe-elasticsearch-domain --domain-name $domain $PROFILE_OPT --region $regx --query 'DomainStatus.VPCOptions.VPCId' --output text)
textInfo "$regx: Amazon ES domain $domain is in VPC $ES_DOMAIN_VPC run extra779 to make sure it is not exposed using custom proxy" "$regx"
else
textPass "$regx: $domain is in a VPC" "$regx"
$AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.AccessPolicies.Options --output text > $TEMP_POLICY_FILE 2> /dev/null
# check if the policy has a principal set up
CHECK_ES_POLICY_PRINCIPAL=$(cat $TEMP_POLICY_FILE | jq -r '. | .Statement[] | select(.Effect == "Allow" and (((.Principal|type == "object") and .Principal.AWS != "*") or ((.Principal|type == "string") and .Principal != "*")) and select(has("Condition") | not))')
if [[ $CHECK_ES_POLICY_PRINCIPAL ]]; then
textPass "$regx: Amazon ES domain $domain does have a Principal set up" "$regx"
fi
CHECK_ES_DOMAIN_POLICY_OPEN=$(cat $TEMP_POLICY_FILE | jq -r '. | .Statement[] | select(.Effect == "Allow" and (((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and select(has("Condition") | not))')
CHECK_ES_DOMAIN_POLICY_HAS_CONDITION=$(cat $TEMP_POLICY_FILE | jq -r '. | .Statement[] | select(.Effect == "Allow" and (((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and select(has("Condition")))' )
if [[ $CHECK_ES_DOMAIN_POLICY_HAS_CONDITION ]]; then
# get content of IpAddress."aws:SourceIp" and get a clean list
LIST_CONDITION_IPS=$(cat $TEMP_POLICY_FILE | jq '.Statement[0] .Condition.IpAddress."aws:SourceIp"'| awk -F'"' '{print $2}' | tr -d '",^$' | sed '/^$/d')
unset CONDITION_HAS_PUBLIC_IP_ARRAY
for condition_ip in "${LIST_CONDITION_IPS}";do
CONDITION_HAS_PRIVATE_IP=$(echo "${condition_ip}" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')
if [[ $CONDITION_HAS_PRIVATE_IP ]];then
CONDITION_HAS_PRIVATE_IP_ARRAY+=($condition_ip)
fi
CONDITION_HAS_PUBLIC_IP=$(echo "${condition_ip}" | grep -vE '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|0\.0\.0\.0|\*)')
if [[ $CONDITION_HAS_PUBLIC_IP ]];then
CONDITION_HAS_PUBLIC_IP_ARRAY+=($condition_ip)
fi
CONDITION_HAS_ZERO_NET=$(echo "${condition_ip}" | grep -E '^(0\.0\.0\.0)')
CONDITION_HAS_STAR=$(echo "${condition_ip}" | grep -E '^\*')
done
CHECK_ES_DOMAIN_POLICY_CONDITION_PRIVATE_IP=${CONDITION_HAS_PRIVATE_IP_ARRAY[@]}
CHECK_ES_DOMAIN_POLICY_CONDITION_PUBLIC_IP=${CONDITION_HAS_PUBLIC_IP_ARRAY[@]}
CHECK_ES_DOMAIN_POLICY_CONDITION_ZERO=$CONDITION_HAS_ZERO_NET
CHECK_ES_DOMAIN_POLICY_CONDITION_STAR=$CONDITION_HAS_STAR
fi
if [[ $CHECK_ES_DOMAIN_POLICY_OPEN || $CHECK_ES_DOMAIN_POLICY_CONDITION_ZERO || $CHECK_ES_DOMAIN_POLICY_CONDITION_STAR || ${CHECK_ES_DOMAIN_POLICY_CONDITION_PUBLIC_IP[@]} ]];then
if [[ $CHECK_ES_DOMAIN_POLICY_OPEN ]];then
textFail "$regx: Amazon ES domain $domain policy allows access (Principal: \"*\") - use extra788 to test AUTH" "$regx"
fi
if [[ $CHECK_ES_DOMAIN_POLICY_HAS_CONDITION && $CHECK_ES_DOMAIN_POLICY_CONDITION_ZERO ]];then
textFail "$regx: Amazon ES domain $domain policy allows access (Principal: \"*\" and network 0.0.0.0) - use extra788 to test AUTH" "$regx"
fi
if [[ $CHECK_ES_DOMAIN_POLICY_HAS_CONDITION && $CHECK_ES_DOMAIN_POLICY_CONDITION_STAR ]];then
textFail "$regx: Amazon ES domain $domain policy allows access (Principal: \"*\" and network \"*\") - use extra788 to test AUTH" "$regx"
fi
if [[ $CHECK_ES_DOMAIN_POLICY_HAS_CONDITION && ${CHECK_ES_DOMAIN_POLICY_CONDITION_PUBLIC_IP[@]} ]];then
textInfo "$regx: Amazon ES domain $domain policy allows access (Principal: \"*\" and Public IP or Network $(echo ${CONDITION_HAS_PUBLIC_IP_ARRAY[@]})) - use extra788 to test AUTH" "$regx"
fi
else
if [[ $CHECK_ES_DOMAIN_POLICY_HAS_CONDITION && ${CHECK_ES_DOMAIN_POLICY_CONDITION_PRIVATE_IP[@]} ]];then
textInfo "$regx: Amazon ES domain $domain policy allows access from a Private IP or CIDR RFC1918 $(echo ${CONDITION_HAS_PRIVATE_IP_ARRAY[@]})" "$regx"
else
textPass "$regx: Amazon ES domain $domain does not allow anonymous access" "$regx"
fi
fi
rm -f $TEMP_POLICY_FILE
fi
rm -f $TEMP_POLICY_FILE
done
else
textInfo "$regx: No Elasticsearch Service domain found" "$regx"
textInfo "$regx: No Amazon ES domain found" "$regx"
fi
done
}

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra717="7.17"
CHECK_TITLE_extra717="[extra717] Check if Elastic Load Balancers have logging enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra717="NOT_SCORED"
CHECK_TYPE_extra717="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra717="AwsElbLoadBalancer"
CHECK_ALTERNATE_check717="extra717"
extra717(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra718="7.18"
CHECK_TITLE_extra718="[extra718] Check if S3 buckets have server access logging enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra718="NOT_SCORED"
CHECK_TYPE_extra718="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra718="AwsS3Bucket"
CHECK_ALTERNATE_check718="extra718"
extra718(){

View File

@@ -10,10 +10,11 @@
# 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,7.02"
CHECK_ID_extra72="7.2"
CHECK_TITLE_extra72="[extra72] Ensure there are no EBS Snapshots set as Public (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra72="NOT_SCORED"
CHECK_TYPE_extra72="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra72="AwsEc2Snapshot"
CHECK_ALTERNATE_extra702="extra72"
CHECK_ALTERNATE_check72="extra72"
CHECK_ALTERNATE_check702="extra72"

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra720="7.20"
CHECK_TITLE_extra720="[extra720] Check if Lambda functions invoke API operations are being recorded by CloudTrail (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra720="NOT_SCORED"
CHECK_TYPE_extra720="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra720="AwsLambdaFunction"
CHECK_ALTERNATE_check720="extra720"
extra720(){
@@ -22,10 +23,10 @@ extra720(){
LIST_OF_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text)
if [[ $LIST_OF_FUNCTIONS ]]; then
for lambdafunction in $LIST_OF_FUNCTIONS;do
LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query trailList[?HomeRegion==\`$regx\`].Name --output text)
LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query trailList[].TrailARN --output text)
if [[ $LIST_OF_TRAILS ]]; then
for trail in $LIST_OF_TRAILS; do
FUNCTION_ENABLED_IN_TRAIL=$($AWSCLI cloudtrail get-event-selectors $PROFILE_OPT --trail-name $trail --region $regx --query "EventSelectors[*].DataResources[?Type == \`AWS::Lambda::Function\`].Values" --output text |xargs -n1| grep -E "^arn:aws:lambda.*function:$lambdafunction$|^arn:aws:lambda$")
FUNCTION_ENABLED_IN_TRAIL=$($AWSCLI cloudtrail get-event-selectors $PROFILE_OPT --trail-name $trail --region $regx --query "EventSelectors[*].DataResources[?Type == \`AWS::Lambda::Function\`].Values" --output text |xargs -n1| grep -E "^arn:${AWS_PARTITION}:lambda.*function:$lambdafunction$|^arn:${AWS_PARTITION}:lambda$")
if [[ $FUNCTION_ENABLED_IN_TRAIL ]]; then
textPass "$regx: Lambda function $lambdafunction enabled in trail $trail" "$regx"
else

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra721="7.21"
CHECK_TITLE_extra721="[extra721] Check if Redshift cluster has audit logging enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra721="NOT_SCORED"
CHECK_TYPE_extra721="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra721="AwsRedshiftCluster"
CHECK_ALTERNATE_check721="extra721"
extra721(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra722="7.22"
CHECK_TITLE_extra722="[extra722] Check if API Gateway has logging enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra722="NOT_SCORED"
CHECK_TYPE_extra722="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra722="AwsApiGatewayRestApi"
CHECK_ALTERNATE_check722="extra722"
extra722(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra723="7.23"
CHECK_TITLE_extra723="[extra723] Check if RDS Snapshots and Cluster Snapshots are public (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra723="NOT_SCORED"
CHECK_TYPE_extra723="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra723="AwsRdsDbSnapshot"
CHECK_ALTERNATE_check723="extra723"
extra723(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra724="7.24"
CHECK_TITLE_extra724="[extra724] Check if ACM certificates have Certificate Transparency logging enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra724="NOT_SCORED"
CHECK_TYPE_extra724="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra724="AwsCertificateManagerCertificate"
CHECK_ALTERNATE_check724="extra724"
extra724(){
@@ -24,10 +25,16 @@ extra724(){
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)
if [[ $CT_ENABLED == "ENABLED" ]];then
textPass "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging enabled!" "$regx"
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"
else
textFail "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging disabled!" "$regx"
if [[ $CT_ENABLED == "ENABLED" ]];then
textPass "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging enabled!" "$regx"
else
textFail "$regx: ACM Certificate $CERT_DOMAIN_NAME has Certificate Transparency logging disabled!" "$regx"
fi
fi
done
else

View File

@@ -15,6 +15,7 @@ CHECK_ID_extra725="7.25"
CHECK_TITLE_extra725="[extra725] Check if S3 buckets have Object-level logging enabled in CloudTrail (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra725="NOT_SCORED"
CHECK_TYPE_extra725="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra725="AwsS3Bucket"
CHECK_ALTERNATE_check725="extra725"
# per Object-level logging is not configured at Bucket level but at CloudTrail trail level
@@ -22,42 +23,35 @@ extra725(){
# "Check if S3 buckets have Object-level logging enabled in CloudTrail (Not Scored) (Not part of CIS benchmark)"
textInfo "Looking for S3 Buckets Object-level logging information in all trails... "
# create a file with a list of all buckets
TEMP_BUCKET_LIST_FILE=$(mktemp -t prowler.bucket-list-XXXXXX)
$AWSCLI s3api list-buckets --query 'Buckets[*].{Name:Name}' $PROFILE_OPT --region $REGION --output text > $TEMP_BUCKET_LIST_FILE
if [ ! -s $TEMP_BUCKET_LIST_FILE ]; then
LIST_OF_BUCKETS=$($AWSCLI s3api list-buckets $PROFILE_OPT --region $REGION --query 'Buckets[*].{Name:Name}' --output text)
LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $REGION --query 'trailList[].TrailARN' --output text)
if [[ $LIST_OF_BUCKETS ]]; then
for bucketName in $LIST_OF_BUCKETS;do
if [[ $LIST_OF_TRAILS ]]; then
BUCKET_ENABLED_TRAILS=()
for trail in $LIST_OF_TRAILS; do
BUCKET_ENABLED_IN_TRAIL=$($AWSCLI cloudtrail get-event-selectors --region $REGION $PROFILE_OPT --trail-name $trail --query "EventSelectors[*].DataResources[?Type == \`AWS::S3::Object\`].Values" --output text |xargs -n1| grep -E "^arn:${AWS_PARTITION}:s3:::$bucketName/\S*$|^arn:${AWS_PARTITION}:s3$|^arn:${AWS_PARTITION}:s3:::$")
if [[ $BUCKET_ENABLED_IN_TRAIL ]]; then
BUCKET_ENABLED_TRAILS+=($trail)
# textPass "$regx: S3 bucket $bucketName has Object-level logging enabled in trail $trail" "$regx"
#else
# textFail "$regx: S3 bucket $bucketName has Object-level logging disabled" "$regx"
fi
done
if [[ ${#BUCKET_ENABLED_TRAILS[@]} -gt 0 ]]; then
for trail in "${BUCKET_ENABLED_TRAILS[@]}"; do
textPass "$regx: S3 bucket $bucketName has Object-level logging enabled in trail $trail" "$regx"
done
else
textFail "$regx: S3 bucket $bucketName has Object-level logging disabled" "$regx"
fi
else
textFail "$regx: S3 bucket $bucketName is not being recorded no CloudTrail found!" "$regx"
fi
done
else
textInfo "$regx: No S3 buckets found" "$regx"
exit
fi
# now create a list with all trails available and their region
TEMP_TRAILS_LIST_FILE=$(mktemp -t prowler.trails-list-XXXXXX)
for regx in $REGIONS; do
$AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query trailList[?HomeRegion==\`$regx\`].[Name,HomeRegion] --output text >> $TEMP_TRAILS_LIST_FILE
done
# look for buckets being logged per trail and create a list with them
TEMP_BUCKETS_LOGGING_LIST_FILE=$(mktemp -t prowler.buckets-logging-list-XXXXXX)
while IFS='' read -r LINE || [[ -n "${LINE}" ]]; do
TRAIL_REGION=$(echo "${LINE}" | awk '{ print $2 }')
TRAIL_NAME=$(echo "${LINE}" | awk '{ print $1 }')
BUCKETS_OBJECT_LOGGING_ENABLED=$($AWSCLI cloudtrail get-event-selectors --trail-name "${TRAIL_NAME}" $PROFILE_OPT --region $TRAIL_REGION --query "EventSelectors[*].DataResources[?Type == \`AWS::S3::Object\`].Values" --output text |xargs -n1 |cut -d: -f 6|sed 's/\///g')
echo $BUCKETS_OBJECT_LOGGING_ENABLED |tr " " "\n"|sort >> $TEMP_BUCKETS_LOGGING_LIST_FILE
if [[ $BUCKETS_OBJECT_LOGGING_ENABLED ]]; then
for bucket in $BUCKETS_OBJECT_LOGGING_ENABLED; do
textPass "$regx: S3 bucket $bucket has Object-level logging enabled in trail $trail" "$regx"
done
fi
done < $TEMP_TRAILS_LIST_FILE
# diff to get the ones that are not in any trail then they are not logging
BUCKETS_NOT_LOGGING=$(diff $TEMP_BUCKETS_LOGGING_LIST_FILE $TEMP_BUCKET_LIST_FILE | sed -n 's/^> //p')
if [[ $BUCKETS_NOT_LOGGING ]]; then
for bucket in $BUCKETS_NOT_LOGGING; do
textFail "$regx: S3 bucket $bucket has Object-level logging disabled" "$regx"
done
fi
# delete all temp files
rm -fr $TEMP_BUCKET_LIST_FILE $TEMP_TRAILS_LIST_FILE $TEMP_BUCKETS_LOGGING_LIST_FILE
}

View File

@@ -15,6 +15,7 @@ CHECK_ID_extra727="7.27"
CHECK_TITLE_extra727="[extra727] Check if SQS queues have policy set as Public (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra727="NOT_SCORED"
CHECK_TYPE_extra727="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra727="AwsSqsQueue"
CHECK_ALTERNATE_check727="extra727"
extra727(){

View File

@@ -15,6 +15,7 @@ CHECK_ID_extra728="7.28"
CHECK_TITLE_extra728="[extra728] Check if SQS queues have Server Side Encryption enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra728="NOT_SCORED"
CHECK_TYPE_extra728="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra728="AwsSqsQueue"
CHECK_ALTERNATE_check728="extra728"
extra728(){

View File

@@ -15,6 +15,7 @@ CHECK_ID_extra729="7.29"
CHECK_TITLE_extra729="[extra729] Ensure there are no EBS Volumes unencrypted (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra729="NOT_SCORED"
CHECK_TYPE_extra729="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra729="AwsEc2Volume"
CHECK_ALTERNATE_check729="extra729"
extra729(){

View File

@@ -11,10 +11,11 @@
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra73="7.3,7.03"
CHECK_ID_extra73="7.3"
CHECK_TITLE_extra73="[extra73] Ensure there are no S3 buckets open to the Everyone or Any AWS user (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra73="NOT_SCORED"
CHECK_TYPE_extra73="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra73="AwsS3Bucket"
CHECK_ALTERNATE_extra703="extra73"
CHECK_ALTERNATE_check73="extra73"
CHECK_ALTERNATE_check703="extra73"

View File

@@ -17,6 +17,7 @@ CHECK_ID_extra730="7.30"
CHECK_TITLE_extra730="[extra730] Check if ACM Certificates are about to expire in $DAYS_TO_EXPIRE_THRESHOLD days or less (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra730="NOT_SCORED"
CHECK_TYPE_extra730="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra730="AwsCertificateManagerCertificate"
CHECK_ALTERNATE_check730="extra730"
extra730(){

View File

@@ -15,6 +15,7 @@ CHECK_ID_extra731="7.31"
CHECK_TITLE_extra731="[extra731] Check if SNS topics have policy set as Public (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra731="NOT_SCORED"
CHECK_TYPE_extra731="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra731="AwsSnsTopic"
CHECK_ALTERNATE_check731="extra731"
extra731(){

View File

@@ -15,6 +15,7 @@ CHECK_ID_extra732="7.32"
CHECK_TITLE_extra732="[extra732] Check if Geo restrictions are enabled in CloudFront distributions (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra732="NOT_SCORED"
CHECK_TYPE_extra732="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra732="AwsCloudFrontDistribution"
CHECK_ALTERNATE_check732="extra732"
extra732(){

View File

@@ -14,10 +14,11 @@ CHECK_ID_extra734="7.34"
CHECK_TITLE_extra734="[extra734] Check if S3 buckets have default encryption (SSE) enabled or use a bucket policy to enforce it (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra734="NOT_SCORED"
CHECK_TYPE_extra734="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra734="AwsS3Bucket"
CHECK_ALTERNATE_check734="extra734"
extra734(){
LIST_OF_BUCKETS=$($AWSCLI s3api list-buckets $PROFILE_OPT --query Buckets[*].Name --output text|xargs -n1)
LIST_OF_BUCKETS=$($AWSCLI s3api list-buckets $PROFILE_OPT --region $REGION --query Buckets[*].Name --output text|xargs -n1)
if [[ $LIST_OF_BUCKETS ]]; then
for bucket in $LIST_OF_BUCKETS;do
@@ -27,7 +28,7 @@ extra734(){
# - Have bucket policy denying s3:PutObject when s3:x-amz-server-side-encryption is absent
# query to get if has encryption enabled or not
RESULT=$($AWSCLI s3api get-bucket-encryption $PROFILE_OPT --bucket $bucket --query ServerSideEncryptionConfiguration.Rules[].ApplyServerSideEncryptionByDefault[].SSEAlgorithm --output text 2>&1)
RESULT=$($AWSCLI s3api get-bucket-encryption $PROFILE_OPT --region $REGION --bucket $bucket --query ServerSideEncryptionConfiguration.Rules[].ApplyServerSideEncryptionByDefault[].SSEAlgorithm --output text 2>&1)
if [[ $(echo "$RESULT" | grep AccessDenied) ]]; then
textFail "Access Denied Trying to Get Encryption for $bucket"
continue
@@ -42,7 +43,7 @@ extra734(){
TEMP_SSE_POLICY_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-${bucket}.policy.XXXXXXXXXX)
# get bucket policy
$AWSCLI s3api get-bucket-policy $PROFILE_OPT --bucket $bucket --output text --query Policy > $TEMP_SSE_POLICY_FILE 2>&1
$AWSCLI s3api get-bucket-policy $PROFILE_OPT --bucket $bucket --region $REGION --output text --query Policy > $TEMP_SSE_POLICY_FILE 2>&1
if [[ $(grep AccessDenied $TEMP_SSE_POLICY_FILE) ]]; then
textFail "Access Denied Trying to Get Bucket Policy for $bucket"
rm -f $TEMP_SSE_POLICY_FILE
@@ -55,7 +56,7 @@ extra734(){
fi
# check if the S3 policy forces SSE s3:x-amz-server-side-encryption:true
CHECK_BUCKET_SSE_POLICY_PRESENT=$(cat $TEMP_SSE_POLICY_FILE | jq --arg arn "arn:aws:s3:::${bucket}/*" '.Statement[]|select(.Effect=="Deny" and ((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*") and .Action=="s3:PutObject" and .Resource==$arn and .Condition.StringEquals."s3:x-amz-server-side-encryption" != null)')
CHECK_BUCKET_SSE_POLICY_PRESENT=$(cat $TEMP_SSE_POLICY_FILE | jq --arg arn "arn:${AWS_PARTITION}:s3:::${bucket}/*" '.Statement[]|select(.Effect=="Deny" and ((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*") and .Action=="s3:PutObject" and .Resource==$arn and .Condition.StringEquals."s3:x-amz-server-side-encryption" != null)')
if [[ $CHECK_BUCKET_SSE_POLICY_PRESENT == "" ]]; then
textFail "Bucket $bucket does not enforce encryption!"
rm -f $TEMP_SSE_POLICY_FILE

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra735="7.35"
CHECK_TITLE_extra735="[extra735] Check if RDS instances storage is encrypted (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra735="NOT_SCORED"
CHECK_TYPE_extra735="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra735="AwsRdsDbInstance"
CHECK_ALTERNATE_check735="extra735"
extra735(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra736="7.36"
CHECK_TITLE_extra736="[extra736] Check exposed KMS keys (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra736="NOT_SCORED"
CHECK_TYPE_extra736="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra736="AwsKmsKey"
CHECK_ALTERNATE_check736="extra736"
extra736(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra737="7.37"
CHECK_TITLE_extra737="[extra737] Check KMS keys with key rotation disabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra737="NOT_SCORED"
CHECK_TYPE_extra737="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra737="AwsKmsKey"
CHECK_ALTERNATE_check737="extra737"
extra737(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra738="7.38"
CHECK_TITLE_extra738="[extra738] Check if CloudFront distributions are set to HTTPS (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra738="NOT_SCORED"
CHECK_TYPE_extra738="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra738="AwsCloudFrontDistribution"
CHECK_ALTERNATE_check738="extra738"
extra738(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra739="7.39"
CHECK_TITLE_extra739="[extra739] Check if RDS instances have backup enabled (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra739="NOT_SCORED"
CHECK_TYPE_extra739="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra739="AwsRdsDbInstance"
CHECK_ALTERNATE_check739="extra739"
extra739(){
@@ -21,12 +22,12 @@ extra739(){
LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].DBInstanceIdentifier' --output text)
if [[ $LIST_OF_RDS_INSTANCES ]];then
for rdsinstance in $LIST_OF_RDS_INSTANCES; do
# if retention is 0 then is disabled
# if retention is 0 then is disabled
BACKUP_RETENTION=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].BackupRetentionPeriod' --output text)
if [[ $BACKUP_RETENTION == "0" ]]; then
textFail "$regx: RDS instance $rdsinstance has not backup enabled!" "$regx"
else
textPass "$regx: RDS instance $rdsinstance has backup enabled with retention period $BACKUP_RETENTION days " "$regx"
textPass "$regx: RDS instance $rdsinstance has backup enabled with retention period $BACKUP_RETENTION days" "$regx"
fi
done
else

View File

@@ -10,10 +10,11 @@
# 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,7.04"
CHECK_ID_extra74="7.4"
CHECK_TITLE_extra74="[extra74] Ensure there are no Security Groups without ingress filtering being used (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra74="NOT_SCORED"
CHECK_TYPE_extra74="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra74="AwsEc2SecurityGroup"
CHECK_ALTERNATE_extra704="extra74"
CHECK_ALTERNATE_check74="extra74"
CHECK_ALTERNATE_check704="extra74"

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra740="7.40"
CHECK_TITLE_extra740="[extra740] Check if EBS snapshots are encrypted (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra740="NOT_SCORED"
CHECK_TYPE_extra740="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra740="AwsEc2Snapshot"
CHECK_ALTERNATE_check740="extra740"
extra740(){
@@ -30,7 +31,7 @@ extra740(){
fi
done
else
textInfo "$regx: No EBS Snapshots found" "$regx"
textInfo "$regx: No EBS Snapshots found" "$regx"
fi
done
}

View File

@@ -14,14 +14,15 @@ CHECK_ID_extra741="7.41"
CHECK_TITLE_extra741="[extra741] Find secrets in EC2 User Data (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra741="NOT_SCORED"
CHECK_TYPE_extra741="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra741="AwsEc2Instance"
CHECK_ALTERNATE_check741="extra741"
extra741(){
SECRETS_TEMP_FOLDER="$PROWLER_DIR/secrets-$ACCOUNT_NUM"
if [[ ! -d $SECRETS_TEMP_FOLDER ]]; then
if [[ ! -d $SECRETS_TEMP_FOLDER ]]; then
# this folder is deleted once this check is finished
mkdir $SECRETS_TEMP_FOLDER
fi
fi
textInfo "Looking for secrets in EC2 User Data in instances across all regions... (max 100 instances per region use -m to increase it) "
for regx in $REGIONS; do
@@ -30,33 +31,25 @@ extra741(){
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
FILE_FORMAT_ASCII=$(file -b $EC2_USERDATA_FILE|grep ASCII)
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
if [[ $FILE_FORMAT_ASCII ]]; then
FINDINGS=$(secretsDetector file $EC2_USERDATA_FILE)
if [[ $FINDINGS -eq 0 ]]; then
textPass "$regx: No secrets found in $instance" "$regx"
# delete file if nothing interesting is there
rm -f $EC2_USERDATA_FILE
else
textFail "$regx: Potential secret found in $instance" "$regx"
# delete file to not leave trace, user must look at the instance User Data
rm -f $EC2_USERDATA_FILE
fi
else
mv $EC2_USERDATA_FILE $EC2_USERDATA_FILE.gz ; gunzip $EC2_USERDATA_FILE.gz
FINDINGS=$(secretsDetector file $EC2_USERDATA_FILE)
if [[ $FINDINGS -eq 0 ]]; then
textPass "$regx: No secrets found in $instance User Data" "$regx"
rm -f $EC2_USERDATA_FILE
else
textFail "$regx: Potential secret found in $instance" "$regx"
fi
# 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
else
FINDINGS=$(secretsDetector file "$EC2_USERDATA_FILE")
if [[ $FINDINGS -eq 0 ]]; then
textPass "$regx: No secrets found in $instance User Data" "$regx"
# delete file if nothing interesting is there
rm -f "$EC2_USERDATA_FILE"
else
textFail "$regx: Potential secret found in $instance User Data" "$regx"
# 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"
fi
done

View File

@@ -14,11 +14,12 @@ CHECK_ID_extra742="7.42"
CHECK_TITLE_extra742="[extra742] Find secrets in CloudFormation outputs (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra742="NOT_SCORED"
CHECK_TYPE_extra742="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra742="AwsCloudFormationStack"
CHECK_ALTERNATE_check742="extra742"
extra742(){
SECRETS_TEMP_FOLDER="$PROWLER_DIR/secrets-$ACCOUNT_NUM"
if [[ ! -d $SECRETS_TEMP_FOLDER ]]; then
if [[ ! -d $SECRETS_TEMP_FOLDER ]]; then
# this folder is deleted once this check is finished
mkdir $SECRETS_TEMP_FOLDER
fi

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra743="7.43"
CHECK_TITLE_extra743="[extra743] Check if API Gateway has client certificate enabled to access your backend endpoint (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra743="NOT_SCORED"
CHECK_TYPE_extra743="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra743="AwsApiGatewayRestApi"
CHECK_ALTERNATE_check743="extra743"
extra743(){
@@ -23,15 +24,15 @@ extra743(){
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
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"
else
else
textFail "$regx: API Gateway $API_GW_NAME ID $api in $stage has not client certificate enabled" "$regx"
fi
done
fi
done
fi
done
else

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra744="7.44"
CHECK_TITLE_extra744="[extra744] Check if API Gateway has a WAF ACL attached (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra744="NOT_SCORED"
CHECK_TYPE_extra744="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra744="AwsApiGatewayRestApi"
CHECK_ALTERNATE_check744="extra744"
extra744(){
@@ -23,15 +24,15 @@ extra744(){
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
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"
else
else
textFail "$regx: API Gateway $API_GW_NAME ID $api in $stage has not WAF ACL attached" "$regx"
fi
done
fi
done
fi
done
else

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra745="7.45"
CHECK_TITLE_extra745="[extra745] Check if API Gateway endpoint is public or private (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra745="NOT_SCORED"
CHECK_TYPE_extra745="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra745="AwsApiGatewayRestApi"
CHECK_ALTERNATE_check745="extra745"
extra745(){
@@ -23,7 +24,7 @@ extra745(){
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
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"

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra746="7.46"
CHECK_TITLE_extra746="[extra746] Check if API Gateway has configured authorizers (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra746="NOT_SCORED"
CHECK_TYPE_extra746="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra746="AwsApiGatewayRestApi"
CHECK_ALTERNATE_check746="extra746"
extra746(){
@@ -23,7 +24,7 @@ extra746(){
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
if [[ $AUTHORIZER_CONFIGURED ]]; then
textPass "$regx: API Gateway $API_GW_NAME ID $api has authorizer configured" "$regx"
else
textFail "$regx: API Gateway $API_GW_NAME ID $api has not authorizer configured" "$regx"

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra747="7.47"
CHECK_TITLE_extra747="[extra747] Check if RDS instances is integrated with CloudWatch Logs (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra747="NOT_SCORED"
CHECK_TYPE_extra747="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra747="AwsRdsDbInstance"
CHECK_ALTERNATE_check747="extra747"
extra747(){
@@ -21,7 +22,7 @@ extra747(){
LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].DBInstanceIdentifier' --output text)
if [[ $LIST_OF_RDS_INSTANCES ]];then
for rdsinstance in $LIST_OF_RDS_INSTANCES; do
# if retention is 0 then is disabled
# if retention is 0 then is disabled
ENABLED_CLOUDWATCHLOGS_EXPORTS=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].EnabledCloudwatchLogsExports' --output text)
if [[ $ENABLED_CLOUDWATCHLOGS_EXPORTS ]]; then
textPass "$regx: RDS instance $rdsinstance is shipping $ENABLED_CLOUDWATCHLOGS_EXPORTS to CloudWatch Logs" "$regx"

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra748="7.48"
CHECK_TITLE_extra748="[extra748] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to any port (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra748="NOT_SCORED"
CHECK_TYPE_extra748="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra748="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check748="extra748"
extra748(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra749="7.49"
CHECK_TITLE_extra749="[extra749] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Oracle ports 1521 or 2483 (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra749="NOT_SCORED"
CHECK_TYPE_extra749="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra749="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check749="extra749"
extra749(){

View File

@@ -10,10 +10,11 @@
# 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,7.05"
CHECK_ID_extra75="7.5"
CHECK_TITLE_extra75="[extra75] Ensure there are no Security Groups not being used (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra75="NOT_SCORED"
CHECK_TYPE_extra75="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra75="AwsEc2SecurityGroup"
CHECK_ALTERNATE_extra705="extra75"
CHECK_ALTERNATE_check75="extra75"
CHECK_ALTERNATE_check705="extra75"

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra750="7.50"
CHECK_TITLE_extra750="[extra750] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to MySQL port 3306 (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra750="NOT_SCORED"
CHECK_TYPE_extra750="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra750="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check750="extra750"
extra750(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra751="7.51"
CHECK_TITLE_extra751="[extra751] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Postgres port 5432 (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra751="NOT_SCORED"
CHECK_TYPE_extra751="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra751="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check751="extra751"
extra751(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra752="7.52"
CHECK_TITLE_extra752="[extra752] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Redis port 6379 (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra752="NOT_SCORED"
CHECK_TYPE_extra752="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra752="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check752="extra752"
extra752(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra753="7.53"
CHECK_TITLE_extra753="[extra753] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to MongoDB ports 27017 and 27018 (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra753="NOT_SCORED"
CHECK_TYPE_extra753="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra753="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check753="extra753"
extra753(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra754="7.54"
CHECK_TITLE_extra754="[extra754] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Cassandra ports 7199 or 9160 or 8888 (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra754="NOT_SCORED"
CHECK_TYPE_extra754="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra754="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check754="extra754"
extra754(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra755="7.55"
CHECK_TITLE_extra755="[extra755] Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to Memcached port 11211 (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra755="NOT_SCORED"
CHECK_TYPE_extra755="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra755="AwsEc2SecurityGroup"
CHECK_ALTERNATE_check755="extra755"
extra755(){

View File

@@ -14,6 +14,7 @@ CHECK_ID_extra756="7.56"
CHECK_TITLE_extra756="[extra756] Check if Redshift cluster is Public Accessible (Not Scored) (Not part of CIS benchmark)"
CHECK_SCORED_extra756="NOT_SCORED"
CHECK_TYPE_extra756="EXTRA"
CHECK_ASFF_RESOURCE_TYPE_extra756="AwsRedshiftCluster"
CHECK_ALTERNATE_check756="extra756"
extra756(){
@@ -22,10 +23,10 @@ extra756(){
if [[ $LIST_OF_RS_CLUSTERS ]];then
for cluster in $LIST_OF_RS_CLUSTERS; do
IS_PUBLICLY_ACCESSIBLE=$($AWSCLI $PROFILE_OPT redshift describe-clusters --region $regx --cluster-identifier $cluster --query Clusters[*].PubliclyAccessible --output text|grep True)
if [[ $IS_PUBLICLY_ACCESSIBLE ]]; then
textFail "$regx: Redshift cluster $cluster is publicly accessible" "$regx"
if [[ $IS_PUBLICLY_ACCESSIBLE ]]; then
textFail "$regx: Redshift cluster $cluster is publicly accessible" "$regx"
else
textPass "$regx: Redshift cluster $cluster is not publicly accessible" "$regx"
textPass "$regx: Redshift cluster $cluster is not publicly accessible" "$regx"
fi
done
else

Some files were not shown because too many files have changed in this diff Show More