Compare commits

...

109 Commits

Author SHA1 Message Date
Leonardo Azize Martins
c120a31904 Fix: Credential chaining from environment variables @lazize #996f
If profile is not defined, restore original credentials from environment variables,
if they exists, before assume-role
2022-01-21 19:21:40 +01:00
Leonardo Azize Martins
ed558c857a Add additional action permissions for Glue and Shield Advanced checks @lazize
* Add extra shield action permission

Allows the shield:GetSubscriptionState action

* Add permission actions

Make sure all files where permission actions are necessary will have the same actions
2022-01-20 16:45:34 +01:00
Toni de la Fuente
d7b360629d Fix: issue #986 2022-01-14 13:10:17 +01:00
Toni de la Fuente
0be3be129c Fix issues #971 set all as INFO instead of FAIL when no access to resource 2022-01-14 12:56:08 +01:00
Toni de la Fuente
e54bd14527 Fix: issue #741 CloudFront and real-time logs 2022-01-14 12:50:06 +01:00
Toni de la Fuente
2e9cd246ad Fix: issue #758 and #984 2022-01-13 15:16:17 +01:00
Toni de la Fuente
2cbb55feb5 Updated .dockerignore with .github/ 2022-01-06 13:45:26 +01:00
Toni de la Fuente
8cee401512 Label version 2.7.0-6January2022 2022-01-06 13:44:46 +01:00
Toni de la Fuente
7b848c04c4 Added FAIL as error handling when SCP prevents queries to regions 2022-01-06 13:43:48 +01:00
Toni de la Fuente
f0e8c79928 Added passed security groups and updated title to check 777 2022-01-06 13:40:19 +01:00
Toni de la Fuente
7a0e180cee Added passed security groups in output to check 778 2022-01-06 13:35:24 +01:00
Toni de la Fuente
9e90bde554 Changed Route53 checks 7152 and 7153 title to clarify 2022-01-06 13:12:24 +01:00
Toni de la Fuente
d65eabcd9e Changed Route53 checks7152 and 7153 to INFO when no domains found 2022-01-06 13:08:11 +01:00
Toni de la Fuente
d3e50169d9 Merge branch '2.7' of https://github.com/toniblyx/prowler into 2.7 2022-01-05 09:46:43 +01:00
Toni de la Fuente
b60aa38d77 Removed echoes after role chaining fix 2022-01-05 09:46:34 +01:00
Pepe Fagoaga
57e3c5a2b2 docs(templates): Improve bug template with more info (#982) 2022-01-04 11:00:09 +01:00
Toni de la Fuente
99538a8a9c Added Shield actions GetSubscriptionState and DescribeProtection 2021-12-29 12:51:13 +01:00
Toni de la Fuente
4cd025538f Added Shield actions GetSubscriptionState and DescribeProtection 2021-12-29 12:29:39 +01:00
Toni de la Fuente
d1eca877dd Add AWS Advance Shield protection checks corrections 2021-12-29 11:35:17 +01:00
Toni de la Fuente
70e5335406 Add AWS Advance Shield protection checks @michael-dickinson-sainsburys
Add AWS Advance Shield protection checks @michael-dickinson-sainsburys
2021-12-29 11:03:12 +01:00
Michael Dickinson
d707f5d994 Include example for global resources 2021-12-23 22:36:53 +00:00
Michael Dickinson
586d1f308c New check 7171 Classic load balancers are protected by AWS Shield Advanced 2021-12-23 22:30:01 +00:00
Michael Dickinson
ab9e40c4dd New check 7170 Application load balancers are protected by AWS Shield Advanced 2021-12-23 22:30:01 +00:00
Michael Dickinson
472afa5a1f New check 7169 Global accelerators are protected by AWS Shield Advanced 2021-12-23 22:30:01 +00:00
Michael Dickinson
122e1c0cf8 New check 7168 Route53 hosted zones are protected by AWS Shield Advanced 2021-12-23 22:30:01 +00:00
Michael Dickinson
4aa4c95d22 New check 7167 Cloudfront distributions are protected by AWS Shield Advanced 2021-12-23 22:30:01 +00:00
Michael Dickinson
7690cb5f98 New check 7166 Elastic IP addresses with associations are protected by AWS Shield Advanced 2021-12-23 22:21:51 +00:00
Toni de la Fuente
751bf805f9 restoreInitialAWSCredentials, unset the credentials if never set
restoreInitialAWSCredentials, unset the credentials if never set
2021-12-22 16:22:48 +01:00
Andrea Di Fabio
0f2e351716 When performing a restoreInitialAWSCredentials, unset the credentials ENV variables if they were never set 2021-12-22 10:13:06 -05:00
Toni de la Fuente
39171b7387 Fixed CIS LEVEL on 7163 through 7165 2021-12-22 15:54:50 +01:00
Toni de la Fuente
8acd861ef9 Improved help usage options -h 2021-12-22 15:31:29 +01:00
Toni de la Fuente
050718c423 Fix checks with comma in fields that break csv @j2clerck
Fix checks with comma in fields that break csv @j2clerck
2021-12-22 15:08:02 +01:00
Toni de la Fuente
62eeafec37 Removed unneeded package "file" from Dockerfile @sectoramen
Removed unneeded package "file" from Dockerfile @sectoramen
2021-12-22 14:48:42 +01:00
Andrea Di Fabio
693a5dfd09 removed file as it is not needed 2021-12-22 08:40:59 -05:00
Joseph de CLERCK
c5416fdeec remove commas 2021-12-21 17:55:10 -05:00
Toni de la Fuente
180c2f27c5 Added $PROFILE_OPT to CopyToS3 commands @sectoramen
Added $PROFILE_OPT to CopyToS3 commands @sectoramen
2021-12-21 19:09:37 +01:00
Andrea Di Fabio
5771c78206 Added $PROFILE_OPT to CopyToS3 commands 2021-12-21 12:51:22 -05:00
Toni de la Fuente
8b415ec063 Added -D option to copy to S3 with the initial AWS credentials instead of the assumed as with -B option @sectoramen
Added -D option to copy to S3 with the initial AWS credentials instead of the assumed as with -B option @sectoramen
2021-12-21 17:22:01 +01:00
Andrea Di Fabio
aa945f3b46 Cosmetic variable name change 2021-12-21 11:16:46 -05:00
Andrea Di Fabio
949c2056ab Added -D option to copy to S3 with the initial AWS credentials 2021-12-21 11:11:53 -05:00
Joseph de CLERCK
050a565440 fix checks with comma issues 2021-12-20 14:38:24 -05:00
Toni de la Fuente
833ad79c3a Improved documentation for install process 2021-12-20 09:45:55 +01:00
Andrea Di Fabio
6cb3d23ed2 fixed bracket 2021-12-19 11:48:32 -05:00
Andrea Di Fabio
947c78cd76 exporting the ENV variables 2021-12-19 11:47:34 -05:00
Andrea Di Fabio
cc9d015fc8 Backup AWS Credentials before AssumeRole and Restore them before CopyToS3 2021-12-19 09:53:20 -05:00
Toni de la Fuente
a6249c54e0 Added cache purge to Dockerfile 2021-12-16 20:34:00 +01:00
Toni de la Fuente
9a9b933f88 Added upgrade to the RUN 2021-12-16 16:27:09 +01:00
Toni de la Fuente
67adaf522e Updated Dockerfile with AWS cli v2 2021-12-16 15:58:02 +01:00
Toni de la Fuente
dc6718b9d1 Updated Dockerfile to use amazonlinux container @Kirizan
Updated Dockerfile to use amazonlinux container @Kirizan
2021-12-16 15:22:02 +01:00
nikirby
bbfd47da2e Updated Dockerfile to use amazonlinux container 2021-12-16 09:16:29 -05:00
Toni de la Fuente
0c7adae3cd Add docker volume example to README.md 2021-12-13 15:20:37 +01:00
Toni de la Fuente
1045fc8330 Fix broken link in README.md @rtcms
Fix broken link in README.md @rtcms
2021-12-13 14:36:52 +01:00
Toni de la Fuente
13db49ba64 Merge branch '2.7' into patch-1 2021-12-13 14:36:10 +01:00
RT
70669eb5b5 Fix Broken Link 2021-12-13 14:56:53 +05:30
Toni de la Fuente
142f42d406 Added invalid check or group id to the error message #962 2021-12-09 15:54:43 +01:00
Toni de la Fuente
d48e9f34a5 Added new checks 7164 and 7165 to group extras 2021-12-09 12:23:22 +01:00
Toni de la Fuente
49ea3d8589 Fix #940 handling error when can not list functions 2021-12-09 12:19:45 +01:00
Toni de la Fuente
78faa8f365 Fix #962 check 7147 ALTERNATE NAME 2021-12-09 11:48:20 +01:00
Toni de la Fuente
c241f0008a Fix #957 check 763 had us-east-1 region hardcoded 2021-12-09 10:01:34 +01:00
Toni de la Fuente
f98f1f8a1d Merge branch '2.7' of https://github.com/toniblyx/prowler into 2.7 2021-12-09 09:54:14 +01:00
Toni de la Fuente
65c95a8354 Fix #963 check 792 to force json in ELB queries 2021-12-09 09:54:05 +01:00
Toni de la Fuente
bfdc88123c New check 7165 DynamoDB: DAX encrypted at rest @Daniel-Peladeau @7thseraph @maisenhe
New check 7165 DynamoDB: DAX encrypted at rest @Daniel-Peladeau @7thseraph @maisenhe
2021-12-07 15:55:10 +01:00
Daniel Peladeau
ad902746f4 Fix ASFF Resource Type 2021-12-07 08:48:41 -05:00
Daniel Peladeau
15c5409b0b New check 7165 DynamoDB: DAX encrypted at rest @Daniel-Peladeau 2021-12-07 08:42:31 -05:00
Daniel Peladeau
f9d792d677 New check 7165 DynamoDB: DAX encrypted at rest @Daniel-Peladeau 2021-12-03 17:05:04 -05:00
Toni de la Fuente
022a4487f3 Merge branch '2.7' of https://github.com/toniblyx/prowler into 2.7 2021-12-03 16:09:36 +01:00
Toni de la Fuente
0ac1b00044 Added issue templates 2021-12-03 15:40:26 +01:00
Toni de la Fuente
2c6895f31e Added checks extra7160,extra7161,extra7162,extra7163 to group Extras 2021-12-03 15:19:01 +01:00
Toni de la Fuente
fdcc4fb54a Added checks extra7160,extra7161,extra7162,extra7163 to group Extras 2021-12-03 15:15:58 +01:00
Toni de la Fuente
3c3a3f7c54 Fix issue with Security Hub integration when resolving closed findings are either a lot of new findings, or a lot of resolved findings @Kirizan
Fix issue with Security Hub integration when resolving closed findings are either a lot of new findings, or a lot of resolved findings @Kirizan
2021-12-03 14:53:53 +01:00
Toni de la Fuente
334a8c2b13 New check 7164 Cloudwatch log groups are protected by KMS @maisenhe
New check 7164 Cloudwatch log groups are protected by KMS @maisenhe
2021-12-02 18:36:25 +01:00
Joel Maisenhelder
6ff94b2b60 updated CHECK_RISK 2021-12-02 09:01:54 -06:00
Joel Maisenhelder
e1e57db93e New check 7164 Check if Cloudwatch log groups are protected by AWS KMS@maisenhe 2021-12-01 19:44:34 -06:00
nikirby
4ea4debedd Added line to delete the temp folder after everything is done. 2021-12-01 15:06:09 -05:00
nikirby
43b3ad6447 Adjusted the batch to only do 50 at a time. 100 caused capacity issues. Also added a check for an edge case where if the updated findings was a multiple of the batch size, it would throw an error for attempting to import 0 findings. 2021-12-01 13:29:12 -05:00
nikirby
5ecf1e2a85 Fixed error that appeared if the number of findings was very high. 2021-12-01 13:25:48 -05:00
Toni de la Fuente
2bed303474 Label 2.7.0-1December2021 for tests 2021-12-01 14:14:36 +01:00
Toni de la Fuente
fa46709860 Fix and clean assume-role to better handle AWS STS CLI errors @jfagoagas
Fix and clean assume-role to better handle AWS STS CLI errors @jfagoagas
2021-12-01 13:35:05 +01:00
Pepe Fagoaga
61bab1d85e Merge branch '2.7' into fix-aws-sts-handle-errors 2021-12-01 13:29:59 +01:00
Toni de la Fuente
84a6843dda Fix issue #938 assume_role multiple times @halfluke
Fix issue #938 assume_role multiple times @halfluke
2021-12-01 12:52:16 +01:00
Toni de la Fuente
0b92aeca4c Merge branch '2.7' into fix_#938_assume_role 2021-12-01 12:47:08 +01:00
root
e5eb066c61 #938 issue assume_role multiple times should be fixed 2021-11-30 15:29:10 -05:00
Toni de la Fuente
593c3b88e8 Docs Readme: fix link for group25 FTR @lopmoris
Docs Readme: fix link for group25 FTR @lopmoris
2021-11-29 19:27:01 +01:00
Israel
f8ea974142 Update README.md
broken link for capital letters in group file (group25_FTR)
2021-11-29 19:11:10 +01:00
Toni de la Fuente
3c32c995bf Fix group25 FTR @lopmoris
Fix group25 FTR @lopmoris
2021-11-29 18:00:05 +01:00
Israel
dd4c3a3b3d Update group25_FTR
When trying to run the group 25 (Amazon FTR related security checks) nothing happens, after looking at the code there is a misconfiguration in 2 params: GROUP_RUN_BY_DEFAULT[9] and GROUP_CHECKS[9]. Updating values to 25 fixed the issue.
2021-11-29 17:56:04 +01:00
Pepe Fagoaga
0b9526da1d Merge branch '2.7' into fix-aws-sts-handle-errors 2021-11-29 12:19:48 +01:00
Toni de la Fuente
315b4cc7c9 Fix assume-role: check if -T and -A options are set together @jfagoagas
Fix assume-role: check if `-T` and `-A` options are set together @jfagoagas
2021-11-29 10:56:27 +01:00
Toni de la Fuente
37de1a1330 Docs Readme: -T option is not mandatory @jfagoagas
Docs Readme: `-T` option is not mandatory @jfagoagas
2021-11-29 10:54:57 +01:00
Pepe Fagoaga
63eb184f39 fix(assume-role): Handle AWS STS CLI errors 2021-11-28 18:44:28 +01:00
Pepe Fagoaga
e74658557e fix(assume-role): Handle AWS STS CLI errors 2021-11-28 14:01:26 +01:00
Pepe Fagoaga
43af01e805 docs(Readme): -T option is not mandatory 2021-11-28 13:31:07 +01:00
Pepe Fagoaga
af4b5539e6 fix(assumed-role): Check if -T and -A options are set 2021-11-28 13:14:10 +01:00
Toni de la Fuente
1f27f08489 New check 7163 Secrets Manager key rotation enabled @Daniel-Peladeau
New check 7163 Secrets Manager key rotation enabled @Daniel-Peladeau
2021-11-25 15:22:35 +01:00
Daniel Peladeau
a101352219 Updating check_extra7163 with requested changes 2021-11-23 22:29:12 -05:00
Toni de la Fuente
34f67f71e4 Smaller fixes in README and multiaccount serverless deployment templates @dlorch
Smaller fixes in README and multiaccount serverless deployment templates @dlorch
2021-11-23 20:59:44 +01:00
Daniel Lorch
bbf6a0f5d9 Install detect-secrets (e.g. for check_extra742) 2021-11-23 20:08:07 +01:00
Daniel Lorch
10f2234e3d Fix link to quicksight dashboard 2021-11-23 17:26:26 +01:00
Daniel Lorch
cebd5cce3e Update ProwlerRole.yaml to have same permissions as util/org-multi-account/ProwlerRole.yaml 2021-11-23 17:26:14 +01:00
Toni de la Fuente
d45cab2b0a New check 7162 CloudWatch log groups have 365 days retention @Obiakara
New check 7162 CloudWatch log groups have 365 days retention @Obiakara
2021-11-23 11:12:43 +01:00
Toni de la Fuente
8e793c9060 New check 7161 EFS encryption at rest enabled @rustic
New check 7161 EFS encryption at rest enabled @rustic
2021-11-23 11:03:23 +01:00
Toni de la Fuente
5ae04717fa New check 7160 Redshift cluster AutomaticVersionUpgrade enabled @jonloza
New check 7160 Redshift cluster AutomaticVersionUpgrade enabled @jonloza
2021-11-23 11:02:40 +01:00
Jonathan Lozano
49f1060922 New check7160 Enabled AutomaticVersionUpgrade on RedShift Cluster 2021-11-22 16:06:10 -05:00
Daniel Peladeau
65cf527d5a New check_extra7163 Secrets Manager key rotation enabled 2021-11-21 16:36:49 -05:00
Lee Myers
e7a5d7266c Extra7161 EFS encryption at rest check 2021-11-19 17:28:12 -05:00
Chinedu Obiakara
2af565ead1 changed check title, resource type and service name as well as making the code more dynamic 2021-11-19 13:31:14 -06:00
Chinedu Obiakara
1fd2e36049 fixed code to handle all regions and formatted output 2021-11-19 12:00:15 -06:00
Chinedu Obiakara
68b26700c1 Added check_extra7162 which checks if Log groups have 365 days retention 2021-11-19 09:28:16 -06:00
Lee Myers
c6858f1d0e Extra7161 EFS encryption at rest check 2021-11-18 20:25:25 -05:00
186 changed files with 1746 additions and 394 deletions

View File

@@ -1,4 +1,5 @@
.git/
.github/
# Ignore output directories
output/

50
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,50 @@
---
name: Bug report
about: Create a report to help us improve
title: "[Bug]: "
labels: ["bug", "triage"]
assignees: ''
---
<!--
Please use this template to create your bug report. By providing as much info as possible you help us understand the issue, reproduce it and resolve it for you quicker. Therefore, take a couple of extra minutes to make sure you have provided all info needed.
PROTIP: record your screen and attach it as a gif to showcase the issue.
- How to record and attach gif: https://bit.ly/2Mi8T6K
-->
**What happened?**
A clear and concise description of what the bug is or what is not working as expected
**How to reproduce it**
Steps to reproduce the behavior:
1. What command are you running?
2. Environment you have, like single account, multi-account, organizations, etc.
3. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots or Logs**
If applicable, add screenshots to help explain your problem.
Also, you can add logs (anonymize them first!). Here a command that may help to share a log
`bash -x ./prowler -options > debug.log 2>&1` then attach here `debug.log`
**From where are you running Prowler?**
Please, complete the following information:
- Resource: [e.g. EC2 instance, Fargate task, Docker container manually, EKS, Cloud9, CodeBuild, workstation, etc.)
- OS: [e.g. Amazon Linux 2, Mac, Alpine, Windows, etc. ]
- AWS-CLI Version [`aws --version`]:
- Prowler Version [`./prowler -V`]:
- Shell and version:
- Others:
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -66,7 +66,7 @@ Read more about [CIS Amazon Web Services Foundations Benchmark v1.2.0 - 05-23-20
With Prowler you can:
- Get a direct colorful or monochrome report
- A HTML, CSV, JUNIT, JSON or JSON ASFF format report
- A HTML, CSV, JUNIT, JSON or JSON ASFF (Security Hub) format report
- Send findings directly to Security Hub
- Run specific checks and groups or create your own
- Check multiple AWS accounts in parallel or sequentially
@@ -79,39 +79,47 @@ You can run Prowler from your workstation, an EC2 instance, Fargate or any other
![Prowler high level architecture](https://user-images.githubusercontent.com/3985464/109143232-1488af80-7760-11eb-8d83-726790fda592.jpg)
## Requirements and Installation
Prowler has been written in bash using AWS-CLI and it works in Linux and OSX.
Prowler has been written in bash using AWS-CLI underneath and it works in Linux, Mac OS or Windows with cygwin or virtualization. Also requires `jq` and `detect-secrets` to work properly.
- Make sure the latest version of AWS-CLI is installed on your workstation (it works with either v1 or v2), and other components needed, with Python pip already installed:
- Make sure the latest version of AWS-CLI is installed. It works with either v1 or v2, however _latest v2 is recommended if using new regions since they require STS v2 token_, and other components needed, with Python pip already installed.
```sh
pip install awscli
- For Amazon Linux (`yum` based Linux distributions and AWS CLI v2):
```
sudo yum update -y
sudo yum remove -y awscli
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
sudo yum install -y python3 jq git
sudo pip3 install detect-secrets==1.0.3
git clone https://github.com/toniblyx/prowler
```
- For Ubuntu Linux (`apt` based Linux distributions and AWS CLI v2):
```
sudo apt update
sudo apt install python3 python3-pip jq git zip
pip install detect-secrets==1.0.3
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
git clone https://github.com/toniblyx/prowler
```
> NOTE: detect-secrets Yelp version is no longer supported the one from IBM is mantained now. Use the one mentioned below or the specific Yelp version 1.0.3 to make sure it works as expected (`pip install detect-secrets==1.0.3`):
> NOTE: detect-secrets Yelp version is no longer supported, the one from IBM is mantained now. Use the one mentioned below or the specific Yelp version 1.0.3 to make sure it works as expected (`pip install detect-secrets==1.0.3`):
```sh
pip install "git+https://github.com/ibm/detect-secrets.git@master#egg=detect-secrets"
```
AWS-CLI can be also installed it using "brew", "apt", "yum" or manually from <https://aws.amazon.com/cli/>, but `detect-secrets` has to be installed using `pip` or `pip3`. You will need to install `jq` to get the most from Prowler.
AWS-CLI can be also installed it using other methods, refer to official documentation for more details: <https://aws.amazon.com/cli/>, but `detect-secrets` has to be installed using `pip` or `pip3`.
- Make sure jq is installed: examples below with "apt" for Debian alike and "yum" for RedHat alike distros (like Amazon Linux):
- Once Prowler repository is cloned, get into the folder and you can run it:
```sh
sudo apt install jq
```
```sh
sudo yum install jq
```
- Previous steps, from your workstation:
```sh
git clone https://github.com/toniblyx/prowler
cd prowler
./prowler
```
- Since Prowler users AWS CLI under the hood, you can follow any authentication method as described [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-precedence). Make sure you have properly configured your AWS-CLI with a valid Access Key and Region or declare AWS variables properly (or intance profile):
- Since Prowler users AWS CLI under the hood, you can follow any authentication method as described [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-precedence). Make sure you have properly configured your AWS-CLI with a valid Access Key and Region or declare AWS variables properly (or instance profile/role):
```sh
aws configure
@@ -150,6 +158,11 @@ Prowler has been written in bash using AWS-CLI and it works in Linux and OSX.
docker run -ti --rm --name prowler --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN toniblyx/prowler:latest
```
In case you want to get reports created by Prowler use docker volume option like in the example below:
```sh
docker run -ti --rm -v /your/local/output:/prowler/output --name prowler --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN toniblyx/prowler:latest -g hipaa -M csv,json,html
```
1. For custom AWS-CLI profile and region, use the following: (it will use your custom profile and run checks over all regions when needed):
```sh
@@ -216,7 +229,7 @@ Prowler has two parameters related to regions: `-r` that is used query AWS servi
<img width="900" alt="Prowler html" src="https://user-images.githubusercontent.com/3985464/141443976-41d32cc2-533d-405a-92cb-affc3995d6ec.png">
- Sample screenshot of the Quicksight dashboard, see [https://quicksight-security-dashboard.workshop.aws](quicksight-security-dashboard.workshop.aws/):
- Sample screenshot of the Quicksight dashboard, see [quicksight-security-dashboard.workshop.aws](https://quicksight-security-dashboard.workshop.aws/):
<img width="900" alt="Prowler with Quicksight" src="https://user-images.githubusercontent.com/3985464/128932819-0156e838-286d-483c-b953-fda68a325a3d.png">
@@ -584,7 +597,7 @@ The `gdpr` group of checks uses existing and extra checks. To get a GDPR report,
With this group of checks, Prowler shows result of checks related to the AWS Foundational Technical Review, more information [here](https://apn-checklists.s3.amazonaws.com/foundational/partner-hosted/partner-hosted/CVLHEC5X7.html). The list of checks can be seen in the group file at:
[groups/group25_ftr](groups/group25_ftr)
[groups/group25_ftr](groups/group25_FTR)
The `ftr` group of checks uses existing and extra checks. To get a AWS FTR report, run this command:

View File

@@ -27,9 +27,14 @@ CHECK_CAF_EPIC_check119='IAM'
check119(){
for regx in $REGIONS; do
EC2_DATA=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[].Instances[].[InstanceId, IamInstanceProfile.Arn, State.Name]' --output json)
EC2_DATA=$(echo $EC2_DATA | jq '.[]|{InstanceId: .[0], ProfileArn: .[1], StateName: .[2]}')
INSTANCE_LIST=$(echo $EC2_DATA | jq -r '.InstanceId')
EC2_DATA=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[].Instances[].[InstanceId, IamInstanceProfile.Arn, State.Name]' --output json 2>&1)
if [[ $(echo "$EC2_DATA" | grep UnauthorizedOperation) ]]; then
textInfo "$regx: Unauthorized Operation error trying to describe instances" "$regx"
continue
else
EC2_DATA=$(echo $EC2_DATA | jq '.[]|{InstanceId: .[0], ProfileArn: .[1], StateName: .[2]}')
INSTANCE_LIST=$(echo $EC2_DATA | jq -r '.InstanceId')
fi
if [[ $INSTANCE_LIST ]]; then
for instance in $INSTANCE_LIST; do
STATE_NAME=$(echo $EC2_DATA | jq -r --arg i "$instance" 'select(.InstanceId==$i)|.StateName')

View File

@@ -42,9 +42,9 @@ check122(){
textFail "$REGION: Policy $policy allows \"*:*\"" "$REGION" "$policy"
done
else
textPass "$REGION: No custom policy found that allow full \"*:*\" administrative privileges" "$REGION" "$policy"
textPass "$REGION: No custom policy found that allow full \"*:*\" administrative privileges" "$REGION"
fi
else
textPass "$REGION: No custom policies found" "$REGION" "$policy"
textPass "$REGION: No custom policies found" "$REGION"
fi
}

View File

@@ -32,7 +32,7 @@ check21(){
for regx in $REGIONS; do
TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',')
if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail"
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
continue
fi
if [[ $TRAILS_AND_REGIONS ]]; then

View File

@@ -32,7 +32,7 @@ check22(){
for regx in $REGIONS; do
TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',')
if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail"
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
continue
fi
if [[ $TRAILS_AND_REGIONS ]]; then

View File

@@ -32,7 +32,7 @@ check23(){
for regx in $REGIONS; do
TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',')
if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail"
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
continue
fi
if [[ $TRAILS_AND_REGIONS ]]; then
@@ -63,7 +63,7 @@ check23(){
#
BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location $PROFILE_OPT --region $regx --bucket $CLOUDTRAILBUCKET --output text 2>&1)
if [[ $(echo "$BUCKET_LOCATION" | grep AccessDenied) ]]; then
textFail "Trail $trail in $TRAIL_REGION Access Denied getting bucket location for $CLOUDTRAILBUCKET"
textInfo "Trail $trail in $TRAIL_REGION Access Denied getting bucket location for $CLOUDTRAILBUCKET"
continue
fi
if [[ $BUCKET_LOCATION == "None" ]]; then

View File

@@ -32,7 +32,7 @@ check24(){
for regx in $REGIONS; do
TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',')
if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail"
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
continue
fi
if [[ $TRAILS_AND_REGIONS ]]; then

View File

@@ -31,7 +31,7 @@ check25(){
CHECK_AWSCONFIG_RECORDING=$($AWSCLI configservice describe-configuration-recorder-status $PROFILE_OPT --region $regx --query 'ConfigurationRecordersStatus[*].recording' --output text 2>&1)
CHECK_AWSCONFIG_STATUS=$($AWSCLI configservice describe-configuration-recorder-status $PROFILE_OPT --region $regx --query 'ConfigurationRecordersStatus[*].lastStatus' --output text 2>&1)
if [[ $(echo "$CHECK_AWSCONFIG_STATUS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe configuration recorder status" "$regx" "recorder"
textInfo "$regx: Access Denied trying to describe configuration recorder status" "$regx" "recorder"
continue
fi
if [[ $CHECK_AWSCONFIG_RECORDING == "True" ]]; then

View File

@@ -31,7 +31,7 @@ check26(){
for regx in $REGIONS; do
TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',')
if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail"
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
continue
fi
if [[ $TRAILS_AND_REGIONS ]]; then
@@ -62,7 +62,7 @@ check26(){
#
BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location $PROFILE_OPT --region $regx --bucket $CLOUDTRAILBUCKET --output text 2>&1)
if [[ $(echo "$BUCKET_LOCATION" | grep AccessDenied) ]]; then
textFail "$regx: Trail $trail Access Denied getting bucket location for $CLOUDTRAILBUCKET" "$TRAIL_REGION" "$trail"
textInfo "$regx: Trail $trail Access Denied getting bucket location for $CLOUDTRAILBUCKET" "$TRAIL_REGION" "$trail"
continue
fi
if [[ $BUCKET_LOCATION == "None" ]]; then

View File

@@ -32,7 +32,7 @@ check27(){
for regx in $REGIONS; do
TRAILS_AND_REGIONS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].{Name:TrailARN, HomeRegion:HomeRegion}' --output text 2>&1 | tr " " ',')
if [[ $(echo "$TRAILS_AND_REGIONS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe trails" "$regx" "$trail"
textInfo "$regx: Access Denied trying to describe trails" "$regx" "$trail"
continue
fi
if [[ $TRAILS_AND_REGIONS ]]; then

View File

@@ -30,7 +30,7 @@ check28(){
for regx in $REGIONS; do
CHECK_KMS_KEYLIST=$($AWSCLI kms list-keys $PROFILE_OPT --region $regx --output text --query 'Keys[*].KeyId' --output text 2>&1)
if [[ $(echo "$CHECK_KMS_KEYLIST" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to list keys" "$regx" "$key"
textInfo "$regx: Access Denied trying to list keys" "$regx" "$key"
continue
fi
if [[ $CHECK_KMS_KEYLIST ]]; then
@@ -38,7 +38,7 @@ check28(){
for key in $CHECK_KMS_KEYLIST; do
KMSDETAILS=$($AWSCLI kms describe-key --key-id $key $PROFILE_OPT --region $regx --query 'KeyMetadata.{key:KeyId,man:KeyManager,origin:Origin,spec:CustomerMasterKeySpec,state:KeyState}' --output text 2>&1 | grep SYMMETRIC)
if [[ $(echo "$KMSDETAILS" | grep AccessDenied) ]]; then
textFail "$regx: Key $key Access Denied describing key" "$regx" "$key"
textInfo "$regx: Access Denied describing key $key" "$regx" "$key"
continue
fi
@@ -60,7 +60,7 @@ check28(){
else
CHECK_KMS_KEY_ROTATION=$($AWSCLI kms get-key-rotation-status --key-id $key $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$CHECK_KMS_KEY_ROTATION" | grep AccessDenied) ]]; then
textFail "$regx: Key $key Access Denied getting key rotation status" "$regx" "$key"
textInfo "$regx: Access Denied getting key rotation status for $key " "$regx" "$key"
continue
fi
if [[ "$CHECK_KMS_KEY_ROTATION" == "True" ]];then

View File

@@ -30,14 +30,14 @@ check29(){
# "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 2>&1)
if [[ $(echo "$AVAILABLE_VPC" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe VPCs" "$regx" "$vpcx"
if [[ $(echo "$AVAILABLE_VPC" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe VPCs" "$regx" "$vpcx"
continue
fi
for vpcx in $AVAILABLE_VPC; do
CHECK_FL=$($AWSCLI ec2 describe-flow-logs $PROFILE_OPT --region $regx --filter Name="resource-id",Values="${vpcx}" --query 'FlowLogs[?FlowLogStatus==`ACTIVE`].FlowLogId' --output text 2>&1)
if [[ $(echo "$CHECK_FL" | grep AccessDenied) ]]; then
textFail "$regx: VPC $vpcx Access Denied trying to describe flow logs" "$regx" "$vpcx"
if [[ $(echo "$CHECK_FL" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe flow logs in VPC $vpcx" "$regx" "$vpcx"
continue
fi
if [[ $CHECK_FL ]]; then

View File

@@ -29,7 +29,11 @@ CHECK_CAF_EPIC_check41='Infrastructure Security'
check41(){
# "Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 22 (Scored)"
for regx in $REGIONS; do
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`22` && ToPort>=`22`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`22` && ToPort>=`22`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
continue
fi
if [[ $SG_LIST ]];then
for SG in $SG_LIST;do
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" "$SG"

View File

@@ -29,7 +29,11 @@ CHECK_CAF_EPIC_check42='Infrastructure Security'
check42(){
# "Ensure no security groups allow ingress from 0.0.0.0/0 or ::/0 to port 3389 (Scored)"
for regx in $REGIONS; do
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`3389` && ToPort>=`3389`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort<=`3389` && ToPort>=`3389`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
continue
fi
if [[ $SG_LIST ]];then
for SG in $SG_LIST;do
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0" "$regx" "$SG"

View File

@@ -29,7 +29,11 @@ CHECK_CAF_EPIC_check43='Infrastructure Security'
check43(){
# "Ensure the default security group of every VPC restricts all traffic (Scored)"
for regx in $REGIONS; do
CHECK_SGDEFAULT_IDS=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --filters Name=group-name,Values='default' --query 'SecurityGroups[*].GroupId[]' --output text)
CHECK_SGDEFAULT_IDS=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --filters Name=group-name,Values='default' --query 'SecurityGroups[*].GroupId[]' --output text 2>&1)
if [[ $(echo "$CHECK_SGDEFAULT_IDS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
continue
fi
for CHECK_SGDEFAULT_ID in $CHECK_SGDEFAULT_IDS; do
CHECK_SGDEFAULT_ID_OPEN=$($AWSCLI ec2 describe-security-groups $PROFILE_OPT --region $regx --group-ids $CHECK_SGDEFAULT_ID --query 'SecurityGroups[*].{IpPermissions:IpPermissions,IpPermissionsEgress:IpPermissionsEgress,GroupId:GroupId}' --output text |egrep '\s0.0.0.0|\:\:\/0')
if [[ $CHECK_SGDEFAULT_ID_OPEN ]];then

View File

@@ -28,7 +28,11 @@ CHECK_CAF_EPIC_check44='Infrastructure Security'
check44(){
# "Ensure routing tables for VPC peering are \"least access\" (Not Scored)"
for regx in $REGIONS; do
LIST_OF_VPCS_PEERING_CONNECTIONS=$($AWSCLI ec2 describe-vpc-peering-connections --output text $PROFILE_OPT --region $regx --query 'VpcPeeringConnections[*].VpcPeeringConnectionId'| sort | paste -s -d" " -)
LIST_OF_VPCS_PEERING_CONNECTIONS=$($AWSCLI ec2 describe-vpc-peering-connections --output text $PROFILE_OPT --region $regx --query 'VpcPeeringConnections[*].VpcPeeringConnectionId' 2>&1| sort | paste -s -d" " - )
if [[ $(echo "$LIST_OF_VPCS_PEERING_CONNECTIONS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe vpc peering connections" "$regx"
continue
fi
if [[ $LIST_OF_VPCS_PEERING_CONNECTIONS ]];then
textInfo "$regx: $LIST_OF_VPCS_PEERING_CONNECTIONS - review routing tables" "$regx" "$LIST_OF_VPCS_PEERING_CONNECTIONS"
#LIST_OF_VPCS=$($AWSCLI ec2 describe-vpcs $PROFILE_OPT --region $regx --query 'Vpcs[*].VpcId' --output text)

View File

@@ -27,7 +27,11 @@ CHECK_CAF_EPIC_check45='Infrastructure Security'
check45(){
for regx in $REGIONS; do
NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`22` && PortRange.To>=`22`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text)
NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`22` && PortRange.To>=`22`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$NACL_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe vpc network acls" "$regx"
continue
fi
if [[ $NACL_LIST ]];then
for NACL in $NACL_LIST;do
textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for SSH port 22" "$regx" "$NACL"

View File

@@ -27,7 +27,11 @@ CHECK_CAF_EPIC_check46='Infrastructure Security'
check46(){
for regx in $REGIONS; do
NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`3389` && PortRange.To>=`3389`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text)
NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?(((!PortRange) || (PortRange.From<=`3389` && PortRange.To>=`3389`)) && ((CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`)))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$NACL_LIST" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe vpc network acls" "$regx"
continue
fi
if [[ $NACL_LIST ]];then
for NACL in $NACL_LIST;do
textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for Microsoft RDP port 3389" "$regx" "$NACL"

View File

@@ -27,7 +27,11 @@ CHECK_CAF_EPIC_extra710='Infrastructure Security'
extra710(){
# "Check for internet facing EC2 Instances "
for regx in $REGIONS; do
LIST_OF_PUBLIC_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[*].Instances[?PublicIpAddress].[InstanceId,PublicIpAddress]' --output text)
LIST_OF_PUBLIC_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[*].Instances[?PublicIpAddress].[InstanceId,PublicIpAddress]' --output text 2>&1)
if [[ $(echo "$LIST_OF_PUBLIC_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe instances" "$regx"
continue
fi
if [[ $LIST_OF_PUBLIC_INSTANCES ]];then
while read -r instance;do
INSTANCE_ID=$(echo $instance | awk '{ print $1; }')

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7101='Logging and Monitoring'
extra7101(){
for regx in $REGIONS; do
LIST_OF_DOMAINS=$($AWSCLI es list-domain-names $PROFILE_OPT --region $regx --query DomainNames --output text)
LIST_OF_DOMAINS=$($AWSCLI es list-domain-names $PROFILE_OPT --region $regx --query DomainNames --output text 2>&1)
if [[ $(echo "$LIST_OF_DOMAINS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list domain names" "$regx"
continue
fi
if [[ $LIST_OF_DOMAINS ]]; then
for domain in $LIST_OF_DOMAINS;do
AUDIT_LOGS_ENABLED=$($AWSCLI es describe-elasticsearch-domain-config --domain-name $domain $PROFILE_OPT --region $regx --query DomainConfig.LogPublishingOptions.Options.AUDIT_LOGS.Enabled --output text |grep -v ^None|grep -v ^False)

View File

@@ -36,7 +36,11 @@ extra7102(){
textInfo "[extra7102] Requires a Shodan API key to work. Use -N <shodan_api_key>"
else
for regx in $REGIONS; do
LIST_OF_EIP=$($AWSCLI $PROFILE_OPT --region $regx ec2 describe-network-interfaces --query 'NetworkInterfaces[*].Association.PublicIp' --output text)
LIST_OF_EIP=$($AWSCLI $PROFILE_OPT --region $regx ec2 describe-network-interfaces --query 'NetworkInterfaces[*].Association.PublicIp' --output text 2>&1)
if [[ $(echo "$LIST_OF_EIP" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe network interfaces" "$regx"
continue
fi
if [[ $LIST_OF_EIP ]]; then
for ip in $LIST_OF_EIP;do
SHODAN_QUERY=$(curl -ks https://api.shodan.io/shodan/host/$ip?key=$SHODAN_API_KEY)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7103='IAM'
extra7103(){
for regx in ${REGIONS}; do
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text)
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list notebook instances" "$regx"
continue
fi
if [[ $LIST_SM_NB_INSTANCES ]];then
for nb_instance in $LIST_SM_NB_INSTANCES; do
SM_NB_ROOTACCESS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-notebook-instance --notebook-instance-name $nb_instance --query 'RootAccess' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7104='Infrastructure Security'
extra7104(){
for regx in ${REGIONS}; do
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text)
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list notebook instances" "$regx"
continue
fi
if [[ $LIST_SM_NB_INSTANCES ]];then
for nb_instance in $LIST_SM_NB_INSTANCES; do
SM_NB_SUBNETID=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-notebook-instance --notebook-instance-name $nb_instance --query 'SubnetId' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7105='Infrastructure Security'
extra7105(){
for regx in ${REGIONS}; do
LIST_SM_NB_MODELS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-models --query 'Models[*].ModelName' --output text)
LIST_SM_NB_MODELS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-models --query 'Models[*].ModelName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_MODELS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list models" "$regx"
continue
fi
if [[ $LIST_SM_NB_MODELS ]];then
for nb_model_name in $LIST_SM_NB_MODELS; do
SM_NB_NETWORKISOLATION=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-model --model-name $nb_model_name --query 'EnableNetworkIsolation' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7106='Infrastructure Security'
extra7106(){
for regx in ${REGIONS}; do
LIST_SM_NB_MODELS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-models --query 'Models[*].ModelName' --output text)
LIST_SM_NB_MODELS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-models --query 'Models[*].ModelName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_MODELS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list models" "$regx"
continue
fi
if [[ $LIST_SM_NB_MODELS ]];then
for nb_model_name in $LIST_SM_NB_MODELS; do
SM_NB_VPCCONFIG=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-model --model-name $nb_model_name --query 'VpcConfig.Subnets' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7107='Data Protection'
extra7107(){
for regx in ${REGIONS}; do
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text)
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_JOBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list training jobs" "$regx"
continue
fi
if [[ $LIST_SM_NB_JOBS ]];then
for nb_job_name in $LIST_SM_NB_JOBS; do
SM_NB_INTERCONTAINERENCRYPTION=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-training-job --training-job-name $nb_job_name --query 'EnableInterContainerTrafficEncryption' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7108='Data Protection'
extra7108(){
for regx in ${REGIONS}; do
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text)
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_JOBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list training jobs" "$regx"
continue
fi
if [[ $LIST_SM_NB_JOBS ]];then
for nb_job_name in $LIST_SM_NB_JOBS; do
SM_JOB_KMSENCRYPTION=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-training-job --training-job-name $nb_job_name --query 'ResourceConfig.VolumeKmsKeyId' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7109='Infrastructure Security'
extra7109(){
for regx in ${REGIONS}; do
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text)
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_JOBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list training jobs" "$regx"
continue
fi
if [[ $LIST_SM_NB_JOBS ]];then
for nb_job_name in $LIST_SM_NB_JOBS; do
SM_NB_NETWORKISOLATION=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-training-job --training-job-name $nb_job_name --query 'EnableNetworkIsolation' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra711='Data Protection'
extra711(){
# "Check for Publicly Accessible Redshift Clusters "
for regx in $REGIONS; do
LIST_OF_PUBLIC_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[?PubliclyAccessible == `true`].[ClusterIdentifier,Endpoint.Address]' --output text)
LIST_OF_PUBLIC_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[?PubliclyAccessible == `true`].[ClusterIdentifier,Endpoint.Address]' --output text 2>&1)
if [[ $(echo "$LIST_OF_PUBLIC_REDSHIFT_CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe clusters" "$regx"
continue
fi
if [[ $LIST_OF_PUBLIC_REDSHIFT_CLUSTERS ]];then
while read -r cluster;do
CLUSTER_ID=$(echo $cluster | awk '{ print $1; }')

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7110='Infrastructure Security'
extra7110(){
for regx in ${REGIONS}; do
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text)
LIST_SM_NB_JOBS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-training-jobs --query 'TrainingJobSummaries[*].TrainingJobName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_JOBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list training jobs" "$regx"
continue
fi
if [[ $LIST_SM_NB_JOBS ]];then
for nb_job_name in $LIST_SM_NB_JOBS; do
SM_NB_SUBNETS=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-training-job --training-job-name $nb_job_name --query 'VpcConfig.Subnets' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7111='Infrastructure Security'
extra7111(){
for regx in ${REGIONS}; do
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text)
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list notebook instances" "$regx"
continue
fi
if [[ $LIST_SM_NB_INSTANCES ]];then
for nb_instance in $LIST_SM_NB_INSTANCES; do
SM_NB_DIRECTINET=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-notebook-instance --notebook-instance-name $nb_instance --query 'DirectInternetAccess' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7112='Data Protection'
extra7112(){
for regx in ${REGIONS}; do
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text)
LIST_SM_NB_INSTANCES=$($AWSCLI $PROFILE_OPT --region $regx sagemaker list-notebook-instances --query 'NotebookInstances[*].NotebookInstanceName' --output text 2>&1)
if [[ $(echo "$LIST_SM_NB_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list notebook instances" "$regx"
continue
fi
if [[ $LIST_SM_NB_INSTANCES ]];then
for nb_instance in $LIST_SM_NB_INSTANCES; do
SM_NB_KMSKEY=$($AWSCLI $PROFILE_OPT --region $regx sagemaker describe-notebook-instance --notebook-instance-name $nb_instance --query 'KmsKeyId' --output text)

View File

@@ -37,7 +37,11 @@ CHECK_CAF_EPIC_extra7113='Data Protection'
extra7113(){
for regx in $REGIONS; do
LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text)
LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text 2>&1)
if [[ $(echo "$LIST_OF_RDS_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe DB instances" "$regx"
continue
fi
if [[ $LIST_OF_RDS_INSTANCES ]];then
for rdsinstance in $LIST_OF_RDS_INSTANCES; do
IS_DELETIONPROTECTION=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --db-instance-identifier $rdsinstance --query 'DBInstances[*].DeletionProtection' --output text)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7114='Data Protection'
extra7114(){
for regx in $REGIONS; do
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json)
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json 2>&1)
if [[ $(echo "$LIST_EP_SC" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get dev endpoints" "$regx"
continue
fi
if [[ $LIST_EP_SC != '[]' ]]; then
for ep in $(echo "${LIST_EP_SC}"| jq -r '.[] | @base64');do
ENDPOINT_NAME=$(echo $ep | base64 --decode | jq -r '.Name')

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7115='Data Protection'
extra7115(){
for regx in $REGIONS; do
CONNECTION_LIST=$($AWSCLI glue get-connections $PROFILE_OPT --region $regx --output json --query 'ConnectionList[*].{Name:Name,SSL:ConnectionProperties.JDBC_ENFORCE_SSL}')
CONNECTION_LIST=$($AWSCLI glue get-connections $PROFILE_OPT --region $regx --output json --query 'ConnectionList[*].{Name:Name,SSL:ConnectionProperties.JDBC_ENFORCE_SSL}' 2>&1)
if [[ $(echo "$CONNECTION_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get connections" "$regx"
continue
fi
if [[ $CONNECTION_LIST != '[]' ]]; then
for connection in $(echo "${CONNECTION_LIST}" | jq -r '.[] | @base64'); do
CONNECTION_NAME=$(echo $connection | base64 --decode | jq -r '.Name' )

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7116='Data Protection'
extra7116(){
for regx in $REGIONS; do
TABLE_LIST=$($AWSCLI glue search-tables --max-results 1 $PROFILE_OPT --region $regx --output text --query 'TableList[*]' )
TABLE_LIST=$($AWSCLI glue search-tables --max-results 1 $PROFILE_OPT --region $regx --output text --query 'TableList[*]' 2>&1)
if [[ $(echo "$TABLE_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to search tables" "$regx"
continue
fi
if [[ ! -z $TABLE_LIST ]]; then
METADATA_ENCRYPTED=$($AWSCLI glue get-data-catalog-encryption-settings $PROFILE_OPT --region $regx --output text --query "DataCatalogEncryptionSettings.EncryptionAtRest.CatalogEncryptionMode")
if [[ "$METADATA_ENCRYPTED" == "DISABLED" ]]; then

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7117='Data Protection'
extra7117(){
for regx in $REGIONS; do
CONNECTION_LIST=$($AWSCLI glue get-connections $PROFILE_OPT --region $regx --output text --query 'ConnectionList[*]')
CONNECTION_LIST=$($AWSCLI glue get-connections $PROFILE_OPT --region $regx --output text --query 'ConnectionList[*]' 2>&1)
if [[ $(echo "$CONNECTION_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get connections" "$regx"
continue
fi
if [[ ! -z $CONNECTION_LIST ]]; then
METADATA_ENCRYPTED=$($AWSCLI glue get-data-catalog-encryption-settings $PROFILE_OPT --region $regx --output text --query "DataCatalogEncryptionSettings.ConnectionPasswordEncryption.ReturnConnectionPasswordEncrypted")
if [[ "$METADATA_ENCRYPTED" == "False" ]]; then

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7118='Data Protection'
extra7118(){
for regx in $REGIONS; do
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration,JobEncryption:DefaultArguments."--encryption-type"}')
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration,JobEncryption:DefaultArguments."--encryption-type"}' 2>&1)
if [[ $(echo "$JOB_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get jobs" "$regx"
continue
fi
if [[ $JOB_LIST != '[]' ]]; then
for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do
JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name')

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7119='Logging and Monitoring'
extra7119(){
for regx in $REGIONS; do
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json)
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json 2>&1)
if [[ $(echo "$LIST_EP_SC" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get dev endpoints" "$regx"
continue
fi
if [[ $LIST_EP_SC != '[]' ]]; then
for ep in $(echo "${LIST_EP_SC}"| jq -r '.[] | @base64');do
ENDPOINT_NAME=$(echo $ep | base64 --decode | jq -r '.Name')

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7120='Logging and Monitoring'
extra7120(){
for regx in $REGIONS; do
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}')
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}' 2>&1)
if [[ $(echo "$JOB_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get jobs" "$regx"
continue
fi
if [[ $JOB_LIST != '[]' ]]; then
for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do
JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name')

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7121='Data Protection'
extra7121(){
for regx in $REGIONS; do
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json)
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json 2>&1)
if [[ $(echo "$LIST_EP_SC" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get dev endpoints" "$regx"
continue
fi
if [[ $LIST_EP_SC != '[]' ]]; then
for ep in $(echo "${LIST_EP_SC}"| jq -r '.[] | @base64');do
ENDPOINT_NAME=$(echo $ep | base64 --decode | jq -r '.Name')

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7122='Data Protection'
extra7122(){
for regx in $REGIONS; do
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}')
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}' 2>&1)
if [[ $(echo "$JOB_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get jobs" "$regx"
continue
fi
if [[ $JOB_LIST != '[]' ]]; then
for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do
JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name')

View File

@@ -27,7 +27,11 @@ CHECK_CAF_EPIC_extra7124='Infrastructure Security'
extra7124(){
for regx in $REGIONS; do
# Filters running instances only
LIST_EC2_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --query 'Reservations[*].Instances[*].[InstanceId]' --filters Name=instance-state-name,Values=running --region $regx --output text)
LIST_EC2_INSTANCES=$($AWSCLI ec2 describe-instances $PROFILE_OPT --query 'Reservations[*].Instances[*].[InstanceId]' --filters Name=instance-state-name,Values=running --region $regx --output text 2>&1)
if [[ $(echo "$LIST_EC2_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe instances" "$regx"
continue
fi
if [[ $LIST_EC2_INSTANCES ]]; then
LIST_SSM_MANAGED_INSTANCES=$($AWSCLI ssm describe-instance-information $PROFILE_OPT --query "InstanceInformationList[].InstanceId" --region $regx | jq -r '.[]')
LIST_EC2_UNMANAGED=$(echo ${LIST_SSM_MANAGED_INSTANCES[@]} ${LIST_EC2_INSTANCES[@]} | tr ' ' '\n' | sort | uniq -u)

View File

@@ -27,7 +27,11 @@ CHECK_CAF_EPIC_extra7127='Infrastructure Security'
extra7127(){
for regx in $REGIONS; do
NON_COMPLIANT_SSM_MANAGED_INSTANCES=$($AWSCLI ssm list-resource-compliance-summaries $PROFILE_OPT --region $regx --filters Key=Status,Values=NON_COMPLIANT --query ResourceComplianceSummaryItems[].ResourceId --output text)
NON_COMPLIANT_SSM_MANAGED_INSTANCES=$($AWSCLI ssm list-resource-compliance-summaries $PROFILE_OPT --region $regx --filters Key=Status,Values=NON_COMPLIANT --query ResourceComplianceSummaryItems[].ResourceId --output text 2>&1)
if [[ $(echo "$NON_COMPLIANT_SSM_MANAGED_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list resource compliance summaries" "$regx"
continue
fi
COMPLIANT_SSM_MANAGED_INSTANCES=$($AWSCLI ssm list-resource-compliance-summaries $PROFILE_OPT --region $regx --filters Key=Status,Values=COMPLIANT --query ResourceComplianceSummaryItems[].ResourceId --output text)
if [[ $NON_COMPLIANT_SSM_MANAGED_INSTANCES || $COMPLIANT_SSM_MANAGED_INSTANCES ]]; then
if [[ $NON_COMPLIANT_SSM_MANAGED_INSTANCES ]]; then

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7128='Data Protection'
extra7128(){
for regx in $REGIONS; do
DDB_TABLES_LIST=$($AWSCLI dynamodb list-tables $PROFILE_OPT --region $regx --output text --query TableNames)
DDB_TABLES_LIST=$($AWSCLI dynamodb list-tables $PROFILE_OPT --region $regx --output text --query TableNames 2>&1)
if [[ $(echo "$DDB_TABLES_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list tables" "$regx"
continue
fi
if [[ $DDB_TABLES_LIST ]]; then
for table in $DDB_TABLES_LIST; do
DDB_TABLE_WITH_KMS=$($AWSCLI dynamodb describe-table --table-name $table $PROFILE_OPT --region $regx --query Table.SSEDescription.SSEType --output text)

View File

@@ -29,7 +29,11 @@ PARALLEL_REGIONS="50"
extra7129(){
for regx in $REGIONS; do
# (
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Scheme == `internet-facing` && Type == `application`].[LoadBalancerName]' --output text)
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Scheme == `internet-facing` && Type == `application`].[LoadBalancerName]' --output text 2>&1)
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
continue
fi
LIST_OF_WAFV2_WEBACL_ARN=$($AWSCLI wafv2 list-web-acls $PROFILE_OPT --region=$regx --scope=REGIONAL --query WebACLs[*].ARN --output text)
LIST_OF_WAFV1_WEBACL_WEBACLID=$($AWSCLI waf-regional list-web-acls $PROFILE_OPT --region $regx --query WebACLs[*].[WebACLId] --output text)

View File

@@ -44,7 +44,7 @@ extra713(){
fi
else
# if list-detectors return any error
textInfo "$regx: GuardDuty not checked" "$regx"
textInfo "$regx: GuardDuty not checked or Access Denied trying to get detector" "$regx"
fi
done
}

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7130='Data Protection'
extra7130(){
for regx in $REGIONS; do
LIST_SNS=$($AWSCLI sns list-topics $PROFILE_OPT --region $regx --query 'Topics[*].TopicArn' --output text)
LIST_SNS=$($AWSCLI sns list-topics $PROFILE_OPT --region $regx --query 'Topics[*].TopicArn' --output text 2>&1)
if [[ $(echo "$LIST_SNS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list topics" "$regx"
continue
fi
if [[ $LIST_SNS ]];then
for topic in $LIST_SNS; do
SHORT_TOPIC=$(echo $topic | awk -F ":" '{print $NF}')

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7131='Infrastructure Security'
extra7131(){
for regx in $REGIONS; do
# LIST_OF_RDS_PUBLIC_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[?PubliclyAccessible==`true` && DBInstanceStatus==`"available"`].[DBInstanceIdentifier,Endpoint.Address]' --output text)
LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].[DBInstanceIdentifier,AutoMinorVersionUpgrade]' --output text)
LIST_OF_RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[*].[DBInstanceIdentifier,AutoMinorVersionUpgrade]' --output text 2>&1)
if [[ $(echo "$LIST_OF_RDS_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe DB instances" "$regx"
continue
fi
if [[ $LIST_OF_RDS_INSTANCES ]];then
while read -r rds_instance;do
RDS_NAME=$(echo $rds_instance | awk '{ print $1; }')

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7132='Logging and Monitoring'
extra7132(){
for regx in $REGIONS; do
RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text)
RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text 2>&1)
if [[ $(echo "$RDS_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe DB instances" "$regx"
continue
fi
if [[ $RDS_INSTANCES ]];then
for rdsinstance in ${RDS_INSTANCES}; do
RDS_NAME="$rdsinstance"

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7133='Data Protection'
extra7133(){
for regx in $REGIONS; do
RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text)
RDS_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query "DBInstances[?Engine != 'docdb'].DBInstanceIdentifier" --output text 2>&1)
if [[ $(echo "$RDS_INSTANCES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe DB instances" "$regx"
continue
fi
if [[ $RDS_INSTANCES ]];then
for rdsinstance in ${RDS_INSTANCES}; do
RDS_NAME="$rdsinstance"

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7134='Infrastructure Security'
extra7134(){
for regx in $REGIONS; do
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`20` && ToPort==`21`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`20` && ToPort==`21`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
continue
fi
if [[ $SG_LIST ]];then
for SG in $SG_LIST;do
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for FTP ports" "$regx" "$SG"

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7135='Infrastructure Security'
extra7135(){
for regx in $REGIONS; do
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`9092` && ToPort==`9092`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`9092` && ToPort==`9092`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
continue
fi
if [[ $SG_LIST ]];then
for SG in $SG_LIST;do
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Kafka ports" "$regx" "$SG"

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7136='Infrastructure Security'
extra7136(){
for regx in $REGIONS; do
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`23` && ToPort==`23`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`23` && ToPort==`23`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
continue
fi
if [[ $SG_LIST ]];then
for SG in $SG_LIST;do
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Telnet ports" "$regx" "$SG"

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7137='Infrastructure Security'
extra7137(){
for regx in $REGIONS; do
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`1433` && ToPort==`1434`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text)
SG_LIST=$($AWSCLI ec2 describe-security-groups --query 'SecurityGroups[?length(IpPermissions[?((FromPort==null && ToPort==null) || (FromPort==`1433` && ToPort==`1434`)) && (contains(IpRanges[].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[].CidrIpv6, `::/0`))]) > `0`].{GroupId:GroupId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$SG_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe security groups" "$regx"
continue
fi
if [[ $SG_LIST ]];then
for SG in $SG_LIST;do
textFail "$regx: Found Security Group: $SG open to 0.0.0.0/0 for Microsoft SQL Server ports" "$regx" "$SG"

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7138='Infrastructure Security'
extra7138(){
for regx in $REGIONS; do
NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?((!PortRange) && (CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text)
NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?((!PortRange) && (CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$NACL_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe network acls" "$regx"
continue
fi
if [[ $NACL_LIST ]];then
for NACL in $NACL_LIST;do
textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for any port" "$regx" "$NACL"

View File

@@ -25,7 +25,11 @@ extra7139(){
for regx in $REGIONS; do
DETECTORS_LIST=""
DETECTORS_LIST=$($AWSCLI guardduty list-detectors --query DetectorIds $PROFILE_OPT --region $regx --output text)
DETECTORS_LIST=$($AWSCLI guardduty list-detectors --query DetectorIds $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$DETECTORS_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list detectors" "$regx"
continue
fi
if [[ $DETECTORS_LIST ]];then
for DETECTOR in $DETECTORS_LIST;do
FINDINGS_COUNT=""

View File

@@ -28,8 +28,9 @@ extra714(){
LIST_OF_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions $PROFILE_OPT --query 'DistributionList.Items[].Id' --output text | grep -v "^None")
if [[ $LIST_OF_DISTRIBUTIONS ]]; then
for dist in $LIST_OF_DISTRIBUTIONS; do
LOG_ENABLED=$($AWSCLI cloudfront get-distribution $PROFILE_OPT --id "$dist" --query 'Distribution.DistributionConfig.Logging.Enabled' | grep true)
if [[ $LOG_ENABLED ]]; then
LOG_ENABLED=$($AWSCLI cloudfront get-distribution $PROFILE_OPT --id "$dist" --query 'Distribution.DistributionConfig.Logging.Enabled' --output text | grep True)
LOG_ENABLED_REALTIME=$($AWSCLI cloudfront get-distribution $PROFILE_OPT --id "$dist" --query 'Distribution.DistributionConfig.DefaultCacheBehavior.RealtimeLogConfigArn' --output text | grep -i arn)
if [[ $LOG_ENABLED || $LOG_ENABLED_REALTIME ]]; then
textPass "$REGION: CloudFront distribution $dist has logging enabled" "$REGION" "$dist"
else
textFail "$REGION: CloudFront distribution $dist has logging disabled" "$REGION" "$dist"

View File

@@ -24,7 +24,11 @@ CHECK_CAF_EPIC_extra7140='Data Protection'
extra7140(){
for regx in $REGIONS; do
SSM_DOCS=$($AWSCLI $PROFILE_OPT --region $regx ssm list-documents --filters Key=Owner,Values=Self --query DocumentIdentifiers[].Name --output text)
SSM_DOCS=$($AWSCLI $PROFILE_OPT --region $regx ssm list-documents --filters Key=Owner,Values=Self --query DocumentIdentifiers[].Name --output text 2>&1)
if [[ $(echo "$SSM_DOCS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list documents" "$regx"
continue
fi
if [[ $SSM_DOCS ]];then
for ssmdoc in $SSM_DOCS; do
SSM_DOC_SHARED_ALL=$($AWSCLI $PROFILE_OPT --region $regx ssm describe-document-permission --name "$ssmdoc" --permission-type "Share" --query AccountIds[] --output text | grep all)

View File

@@ -31,7 +31,11 @@ extra7141(){
fi
for regx in $REGIONS; do
SSM_DOCS=$($AWSCLI $PROFILE_OPT --region $regx ssm list-documents --filters Key=Owner,Values=Self --query DocumentIdentifiers[].Name --output text)
SSM_DOCS=$($AWSCLI $PROFILE_OPT --region $regx ssm list-documents --filters Key=Owner,Values=Self --query DocumentIdentifiers[].Name --output text 2>&1)
if [[ $(echo "$SSM_DOCS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list documents" "$regx"
continue
fi
if [[ $SSM_DOCS ]];then
for ssmdoc in $SSM_DOCS; do
SSM_DOC_FILE="$SECRETS_TEMP_FOLDER/extra7141-$ssmdoc-$regx-content.txt"

View File

@@ -27,7 +27,11 @@ CHECK_CAF_EPIC_extra7142='Data Protection'
extra7142(){
for regx in $REGIONS; do
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application`].[LoadBalancerArn]' --output text)
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application`].[LoadBalancerArn]' --output text 2>&1)
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
continue
fi
if [[ $LIST_OF_ELBSV2 ]];then
for alb in $LIST_OF_ELBSV2;do
CHECK_IF_DROP_INVALID_HEADER_FIELDS=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $alb --query 'Attributes[6]' --output text|grep -i true)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7143='Data Protection'
extra7143(){
# "Check if EFS have policies which allow access to everyone (Not Scored) (Not part of CIS benchmark)"
for regx in $REGIONS; do
LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query FileSystems[*].FileSystemId --output text|xargs -n1)
LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query FileSystems[*].FileSystemId --output text 2>&1|xargs -n1 )
if [[ $(echo "$LIST_OF_EFS_IDS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe file systems" "$regx"
continue
fi
if [[ $LIST_OF_EFS_IDS ]]; then
for efsId in $LIST_OF_EFS_IDS;do
EFS_POLICY_STATEMENTS=$($AWSCLI efs $PROFILE_OPT describe-file-system-policy --region $regx --file-system-id $efsId --output json --query Policy 2>&1)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7145='IAM'
extra7145(){
# "Check if lambda functions have policies which allow access to every aws account (Not Scored) (Not part of CIS benchmark)"
for regx in $REGIONS; do
LIST_OF_LAMBDA_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text)
LIST_OF_LAMBDA_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query Functions[*].FunctionName --output text 2>&1)
if [[ $(echo "$LIST_OF_LAMBDA_FUNCTIONS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list functions" "$regx"
continue
fi
if [[ $LIST_OF_LAMBDA_FUNCTIONS ]]; then
for lambdaFunction in $LIST_OF_LAMBDA_FUNCTIONS;do
FUNCTION_POLICY_STATEMENTS=$($AWSCLI lambda $PROFILE_OPT get-policy --region $regx --function-name $lambdaFunction --output json --query Policy 2>&1)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7146='Infrastructure Security'
extra7146(){
# "Check if there is any unassigned elastic ip (Not Scored) (Not part of CIS benchmark)"
for regx in $REGIONS; do
ELASTIC_IP_ADDRESSES=$($AWSCLI ec2 describe-addresses $PROFILE_OPT --region $regx --query Addresses --output json)
ELASTIC_IP_ADDRESSES=$($AWSCLI ec2 describe-addresses $PROFILE_OPT --region $regx --query Addresses --output json 2>&1)
if [[ $(echo "$ELASTIC_IP_ADDRESSES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe addresses" "$regx"
continue
fi
if [[ $ELASTIC_IP_ADDRESSES != [] ]]; then
LIST_OF_ASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId!=null) | .PublicIp')
LIST_OF_UNASSOCIATED_IPS=$(echo $ELASTIC_IP_ADDRESSES | jq -r '.[] | select(.AssociationId==null) | .PublicIp')

View File

@@ -16,7 +16,7 @@ CHECK_SCORED_extra7147="NOT_SCORED"
CHECK_CIS_LEVEL_extra7147="EXTRA"
CHECK_SEVERITY_extra7147="Critical"
CHECK_ASFF_RESOURCE_TYPE_extra7147="AwsGlacierVault"
CHECK_ALTERNATE_check7147="extra7142"
CHECK_ALTERNATE_check7147="extra7147"
CHECK_SERVICENAME_extra7147="glacier"
CHECK_RISK_extra7147='Vaults accessible to everyone could expose sensitive data to bad actors'
CHECK_REMEDIATION_extra7147='Ensure vault policy does not have principle as *'
@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7147='Data Protection'
extra7147(){
for regx in $REGIONS; do
LIST_OF_VAULTS=$($AWSCLI glacier list-vaults $PROFILE_OPT --region $regx --account-id $ACCOUNT_NUM --query VaultList[*].VaultName --output text|xargs -n1)
LIST_OF_VAULTS=$($AWSCLI glacier list-vaults $PROFILE_OPT --region $regx --account-id $ACCOUNT_NUM --query VaultList[*].VaultName --output text 2>&1|xargs -n1)
if [[ $(echo "$LIST_OF_VAULTS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list vaults" "$regx"
continue
fi
if [[ $LIST_OF_VAULTS ]]; then
for vault in $LIST_OF_VAULTS;do
VAULT_POLICY_STATEMENTS=$($AWSCLI glacier $PROFILE_OPT get-vault-access-policy --region $regx --account-id $ACCOUNT_NUM --vault-name $vault --output json --query policy.Policy 2>&1)

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7148='Data Protection'
extra7148() {
for regx in $REGIONS; do
LIST_OF_EFS_SYSTEMS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query 'FileSystems[*].FileSystemId' --output text)
LIST_OF_EFS_SYSTEMS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query 'FileSystems[*].FileSystemId' --output text 2>&1)
if [[ $(echo "$LIST_OF_EFS_SYSTEMS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe file systems" "$regx"
continue
fi
if [[ $LIST_OF_EFS_SYSTEMS ]]; then
for filesystem in $LIST_OF_EFS_SYSTEMS; do
# if retention is 0 then is disabled

View File

@@ -26,12 +26,16 @@ CHECK_CAF_EPIC_extra7149='Data Protection'
extra7149() {
# "Check if Redshift cluster has audit logging enabled "
for regx in $REGIONS; do
LIST_OF_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[*].ClusterIdentifier' --output text)
LIST_OF_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[*].ClusterIdentifier' --output text 2>&1)
if [[ $(echo "$LIST_OF_REDSHIFT_CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe clusters" "$regx"
continue
fi
if [[ $LIST_OF_REDSHIFT_CLUSTERS ]]; then
for redshiftcluster in $LIST_OF_REDSHIFT_CLUSTERS; do
REDSHIFT_SNAPSHOT_ENABLED=$($AWSCLI redshift describe-cluster-snapshots $PROFILE_OPT --region $regx --cluster-identifier $redshiftcluster --snapshot-type automated)
if [[ $REDSHIFT_SNAPSHOT_ENABLED ]]; then
textPass "$regx: Redshift cluster $redshiftcluster has automated snapshots $REDSHIFT_SNAPSHOT_ENABLED" "$regx" "$redshiftcluster"
textPass "$regx: Redshift cluster $redshiftcluster has automated snapshots." "$regx" "$redshiftcluster"
else
textFail "$regx: Redshift cluster $redshiftcluster has automated snapshots disabled!" "$regx" "$redshiftcluster"
fi

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra715='Logging and Monitoring'
extra715(){
for regx in $REGIONS; do
LIST_OF_DOMAINS=$($AWSCLI es list-domain-names $PROFILE_OPT --region $regx --query DomainNames --output text)
LIST_OF_DOMAINS=$($AWSCLI es list-domain-names $PROFILE_OPT --region $regx --query DomainNames --output text 2>&1)
if [[ $(echo "$LIST_OF_DOMAINS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to list domain names" "$regx"
continue
fi
if [[ $LIST_OF_DOMAINS ]]; then
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)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra7150='Data Protection'
extra7150(){
# "Check if Elastic Load Balancers have delete protection enabled."
for regx in $REGIONS; do
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text|xargs -n1)
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text 2>&1|xargs -n1 )
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
continue
fi
if [[ $LIST_OF_ELBSV2 ]]; then
for elb in $LIST_OF_ELBSV2; do
CHECK_DELETION_PROTECTION_ENABLED=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $elb --query Attributes[*] --output text|grep "deletion_protection.enabled"|grep true )

View File

@@ -27,7 +27,11 @@ CHECK_CAF_EPIC_extra7151='Data Protection'
extra7151(){
# "Check if DynamoDB tables point-in-time recovery (PITR) is enabled"
for regx in $REGIONS; do
LIST_OF_DYNAMODB_TABLES=$($AWSCLI dynamodb list-tables $PROFILE_OPT --region $regx --query 'TableNames[*]' --output text)
LIST_OF_DYNAMODB_TABLES=$($AWSCLI dynamodb list-tables $PROFILE_OPT --region $regx --query 'TableNames[*]' --output text 2>&1)
if [[ $(echo "$LIST_OF_DYNAMODB_TABLES" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list tables" "$regx"
continue
fi
if [[ $LIST_OF_DYNAMODB_TABLES ]]; then
for dynamodb_table in $LIST_OF_DYNAMODB_TABLES; do
POINT_IN_TIME_RECOVERY_ENABLED=$($AWSCLI dynamodb describe-continuous-backups $PROFILE_OPT --region $regx --table-name $dynamodb_table | jq '.[].PointInTimeRecoveryDescription | select(.PointInTimeRecoveryStatus=="ENABLED") | .PointInTimeRecoveryStatus')

View File

@@ -23,31 +23,32 @@
# --tech-privacy
CHECK_ID_extra7152="7.152"
CHECK_TITLE_extra7152="[extra7152] Enable Privacy Protection for for a Route53 Domain"
CHECK_TITLE_extra7152="[extra7152] Enable Privacy Protection for for a Route53 Domain (us-east-1 only)"
CHECK_SCORED_extra7152="NOT_SCORED"
CHECK_CIS_LEVEL_extra7152="EXTRA"
CHECK_SEVERITY_extra7152="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7152="AwsRoute53Domain"
CHECK_ALTERNATE_check7152="extra7152"
CHECK_SERVICENAME_extra7152="route53"
CHECK_RISK_extra7152='Without privacy protection enabled, ones personal information is published to the public WHOIS database'
CHECK_RISK_extra7152='Without privacy protection enabled; ones personal information is published to the public WHOIS database'
CHECK_REMEDIATION_extra7152='Ensure default Privacy is enabled'
CHECK_DOC_extra7152='https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-privacy-protection.html'
CHECK_CAF_EPIC_extra7152='Data Protection'
extra7152(){
echo "Route53 is a global service, looking for domains in US-EAST-1"
# Route53 is a global service, looking for domains in US-EAST-1
# this is also valid for GovCloud https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/setting-up-route53.html
DOMAIN_NAMES=$($AWSCLI route53domains list-domains $PROFILE_OPT --region us-east-1 --query 'Domains[*].DomainName' --output text )
if [[ $DOMAIN_NAMES ]];then
for domain_name in $DOMAIN_NAMES;do
DOMAIN_DETAIL=$($AWSCLI route53domains get-domain-detail $PROFILE_OPT --region us-east-1 --query 'AdminPrivacy' --domain-name $domain_name)
if [[ $DOMAIN_DETAIL == false ]]; then
textFail "$regx: Contact information public for: $domain_name" "$regx" "$domain_name"
textFail "us-east-1: Contact information public for: $domain_name" "us-east-1" "$domain_name"
else
textPass "$regx: All contact information is private for: $domain_name" "$regx" "$domain_name"
textPass "us-east-1: All contact information is private for: $domain_name" "us-east-1" "$domain_name"
fi
done
else
textPass "$regx: No Domain Names found" "$regx"
textInfo "us-east-1: No Domain Names found" "us-east-1"
fi
}

View File

@@ -20,32 +20,33 @@
CHECK_ID_extra7153="7.153"
CHECK_TITLE_extra7153="[extra7153] Enable Transfer Lock for a Route53 Domain"
CHECK_TITLE_extra7153="[extra7153] Enable Transfer Lock for a Route53 Domain (us-east-1 only)"
CHECK_SCORED_extra7153="NOT_SCORED"
CHECK_CIS_LEVEL_extra7153="EXTRA"
CHECK_SEVERITY_extra7153="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7153="AwsRoute53Domain"
CHECK_ALTERNATE_check7153="extra7153"
CHECK_SERVICENAME_extra7153="route53"
CHECK_RISK_extra7153='Without transfer lock enabled, a domain name could be incorrectly moved to a new registrar'
CHECK_RISK_extra7153='Without transfer lock enabled; a domain name could be incorrectly moved to a new registrar'
CHECK_REMEDIATION_extra7153='Ensure transfer lock is enabled'
CHECK_DOC_extra7153='https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-lock.html'
CHECK_CAF_EPIC_extra7153='Data Protection'
extra7153(){
# Route53 is a global service, looking for domains in US-EAST-1
# this is also valid for GovCloud https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/setting-up-route53.html
DOMAIN_NAMES=$($AWSCLI route53domains list-domains $PROFILE_OPT --region us-east-1 --query 'Domains[*].DomainName' --output text )
if [[ $DOMAIN_NAMES ]];then
for domain_name in $DOMAIN_NAMES;do
DOMAIN_DETAIL=$($AWSCLI route53domains get-domain-detail $PROFILE_OPT --region us-east-1 --query 'StatusList' --domain-name $domain_name)
HAS_TRANSFER_LOCK=$( grep -o 'clientTransferProhibited' <<< $DOMAIN_DETAIL)
if [[ $HAS_TRANSFER_LOCK ]]; then
textPass "$regx: clientTransferProhibited found for: $domain_name" "$regx" "$domain_name"
textPass "us-east-1: clientTransferProhibited found for: $domain_name" "us-east-1" "$domain_name"
else
textFail "$regx: clientTransferProhibited not found for: $domain_name" "$regx" "$domain_name"
textFail "us-east-1: clientTransferProhibited not found for: $domain_name" "us-east-1" "$domain_name"
fi
done
else
textPass "$regx: No Domain Names found" "$regx"
textInfo "us-east-1: No Domain Names found" "us-east-1"
fi
}

View File

@@ -34,7 +34,11 @@ CHECK_CAF_EPIC_extra7154='Infrastructure Protection'
extra7154() {
for regx in $REGIONS; do
CFN_STACKS=$($AWSCLI cloudformation describe-stacks $PROFILE_OPT --region $regx --output json)
CFN_STACKS=$($AWSCLI cloudformation describe-stacks $PROFILE_OPT --region $regx --output json 2>&1)
if [[ $(echo "$CFN_STACKS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe stacks" "$regx"
continue
fi
LIST_OF_CFN_STACKS=$(echo $CFN_STACKS | jq -r '.Stacks[].StackName')
if [[ $LIST_OF_CFN_STACKS ]];then
for stack in $LIST_OF_CFN_STACKS; do

View File

@@ -33,7 +33,11 @@ CHECK_CAF_EPIC_extra7155='Data Protection'
extra7155() {
for regx in $REGIONS; do
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application`].[LoadBalancerArn]' --output text)
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application`].[LoadBalancerArn]' --output text 2>&1)
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
continue
fi
if [[ $LIST_OF_ELBSV2 ]];then
for alb in $LIST_OF_ELBSV2;do
CHECK_DESYNC_MITIGATION_MODE=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $alb --query 'Attributes[8]' --output json | jq -r '.Value')

View File

@@ -28,7 +28,11 @@ extra7156(){
# "Check if API Gateway V2 has Access Logging enabled "
for regx in $REGIONS; do
LIST_OF_API_GW=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query Items[*].ApiId --output text)
LIST_OF_API_GW=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query Items[*].ApiId --output text 2>&1)
if [[ $(echo "$LIST_OF_API_GW" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get APIs" "$regx"
continue
fi
if [[ $LIST_OF_API_GW ]];then
for apigwid in $LIST_OF_API_GW;do
API_GW_NAME=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query "Items[?ApiId==\`$apigwid\`].Name" --output text)
@@ -37,9 +41,9 @@ extra7156(){
for stagename in $CHECK_STAGES_NAME;do
CHECK_STAGE_METHOD_LOGGING=$($AWSCLI apigatewayv2 get-stages $PROFILE_OPT --region $regx --api-id $apigwid --query "Items[?StageName == \`$stagename\` ].AccessLogSettings.DestinationArn" --output text)
if [[ $CHECK_STAGE_METHOD_LOGGING ]];then
textPass "$regx: API Gateway V2 $API_GW_NAME ID: $apigwid, stage: $stagename, has access logging enabled to $CHECK_STAGE_METHOD_LOGGING" "$regx" "$API_GW_NAME"
textPass "$regx: API Gateway V2 $API_GW_NAME ID: $apigwid with stage: $stagename has access logging enabled to $CHECK_STAGE_METHOD_LOGGING" "$regx" "$API_GW_NAME"
else
textFail "$regx: API Gateway V2 $API_GW_NAME ID: $apigwid, stage: $stagename, has access logging disabled" "$regx" "$API_GW_NAME"
textFail "$regx: API Gateway V2 $API_GW_NAME ID: $apigwid with stage: $stagename has access logging disabled" "$regx" "$API_GW_NAME"
fi
done
else

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7157='IAM'
extra7157(){
for regx in $REGIONS; do
LIST_OF_API_GW=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query "Items[*].ApiId" --output text)
LIST_OF_API_GW=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query "Items[*].ApiId" --output text 2>&1)
if [[ $(echo "$LIST_OF_API_GW" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get APIs" "$regx"
continue
fi
if [[ $LIST_OF_API_GW ]];then
for api in $LIST_OF_API_GW; do
API_GW_NAME=$($AWSCLI apigatewayv2 get-apis $PROFILE_OPT --region $regx --query "Items[?ApiId==\`$api\`].Name" --output text)

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7158='Data Protection'
extra7158(){
for regx in $REGIONS; do
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers --query 'LoadBalancers[*].LoadBalancerArn' $PROFILE_OPT --region $regx --output text)
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers --query 'LoadBalancers[*].LoadBalancerArn' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
continue
fi
if [[ $LIST_OF_ELBSV2 ]]; then
for elb in $LIST_OF_ELBSV2; do
LIST_OF_LISTENERS=$($AWSCLI elbv2 describe-listeners $PROFILE_OPT --region $regx --load-balancer-arn $elb --query 'Listeners[*]' --output text)

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra7159='Data Protection'
extra7159(){
for regx in $REGIONS; do
LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers --query 'LoadBalancerDescriptions[*].LoadBalancerName' $PROFILE_OPT --region $regx --output text)
LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers --query 'LoadBalancerDescriptions[*].LoadBalancerName' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$LIST_OF_ELBS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe load balancers" "$regx"
continue
fi
if [[ $LIST_OF_ELBS ]]; then
for elb in $LIST_OF_ELBS; do
LIST_OF_LISTENERS=$($AWSCLI elb describe-load-balancers --load-balancer-name $elb --query 'LoadBalancerDescriptions[*].ListenerDescriptions' $PROFILE_OPT --region $regx --output text)

View File

@@ -25,7 +25,11 @@ CHECK_CAF_EPIC_extra716='Infrastructure Security'
extra716(){
for regx in $REGIONS; do
LIST_OF_DOMAINS=$($AWSCLI es list-domain-names $PROFILE_OPT --region $regx --query DomainNames --output text)
LIST_OF_DOMAINS=$($AWSCLI es list-domain-names $PROFILE_OPT --region $regx --query DomainNames --output text 2>&1)
if [[ $(echo "$LIST_OF_DOMAINS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to list domain names" "$regx"
continue
fi
if [[ $LIST_OF_DOMAINS ]]; then
for domain in $LIST_OF_DOMAINS;do
TEMP_POLICY_FILE=$(mktemp -t prowler-${ACCOUNT_NUM}-es-domain.policy.XXXXXXXXXX)

46
checks/check_extra7160 Normal file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2021) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7160="7.160"
CHECK_TITLE_extra7160="[extra7160] Check if Redshift has automatic upgrades enabled"
CHECK_SCORED_extra7160="NOT_SCORED"
CHECK_CIS_LEVEL_extra7160="EXTRA"
CHECK_SEVERITY_extra7160="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7160="AwsRedshift"
CHECK_ALTERNATE_check7160="extra7160"
CHECK_SERVICENAME_extra7160="redshift"
CHECK_RISK_extra7160='Without automatic version upgrade enabled; a critical Redshift Cluster version can become severly out of date.'
CHECK_REMEDIATION_extra7160='Enabled AutomaticVersionUpgrade on Redshift Cluster'
CHECK_DOC_extra7160='https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-operations.html'
CHECK_CAF_EPIC_extra7160='Infrastructure Security'
extra7160(){
for regx in $REGIONS; do
LIST_OF_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --query 'Clusters[*].ClusterIdentifier' --region $regx --output text 2>&1)
if [[ $(echo "$LIST_OF_CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe clusters" "$regx"
continue
fi
if [[ $LIST_OF_CLUSTERS ]]; then
for cluster in $LIST_OF_CLUSTERS; do
AUTO_UPGRADE_ENABLED=$($AWSCLI redshift describe-clusters $PROFILE_OPT --cluster-identifier $cluster --query 'Clusters[*].AllowVersionUpgrade' --region $regx --output text)
if [[ $AUTO_UPGRADE_ENABLED == "True" ]]; then
textPass "$regx: $cluster has AllowVersionUpgrade enabled" "$regx" "$cluster"
else
textFail "$regx: $cluster has AllowVersionUpgrade disabled" "$regx" "$cluster"
fi
done
else
textInfo "$regx: No Redshift Clusters found" "$regx"
fi
done
}

47
checks/check_extra7161 Normal file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7161="7.161"
CHECK_TITLE_extra7161="[extra7161] Check if EFS have protects sensative data with encryption at rest"
CHECK_SCORED_extra7161="NOT_SCORED"
CHECK_CIS_LEVEL_extra7161="EXTRA"
CHECK_SEVERITY_extra7161="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7161="AwsEfsFileSystem"
CHECK_ALTERNATE_check7161="extra7161"
CHECK_SERVICENAME_extra7161="efs"
CHECK_RISK_extra7161='EFS should be encrypted at rest to prevent exposure of sensitive data to bad actors'
CHECK_REMEDIATION_extra7161='Ensure that encryption at rest is enabled for EFS file systems. Encryption at rest can only be enabled during the file system creation.'
CHECK_DOC_extra7161='https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html'
CHECK_CAF_EPIC_extra7161='Data Protection'
extra7161(){
# "Check if EFS has encryption at rest enabled (Not Scored) (Proposed requirement for 1.5 CIS benchmark)"
for regx in $REGIONS; do
LIST_OF_EFS_IDS=$($AWSCLI efs describe-file-systems $PROFILE_OPT --region $regx --query 'FileSystems[*].FileSystemId' --output text 2>&1| xargs -n1 )
if [[ $(echo "$LIST_OF_EFS_IDS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe file systems" "$regx"
continue
fi
if [[ $LIST_OF_EFS_IDS ]]; then
for efsId in $LIST_OF_EFS_IDS;do
EFS_ENCRYPTION_CHECK=$($AWSCLI efs $PROFILE_OPT describe-file-systems --region $regx --file-system-id $efsId --output json --query 'FileSystems[*].Encrypted' --output text)
if [[ $EFS_ENCRYPTION_CHECK == "True" ]]; then
textPass "$regx: EFS $efsId has has encryption at rest enabled" "$regx" "$efsId"
else
textFail "$regx: EFS: $efsId does not have encryption at rest enabled" "$regx" "$efsId"
fi
done
else
textInfo "$regx: No EFS found" "$regx"
fi
done
}

54
checks/check_extra7162 Normal file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7162="7.162"
CHECK_TITLE_extra7162="[extra7162] Check if CloudWatch Log Groups have a retention policy of 365 days"
CHECK_SCORED_extra7162="NOT_SCORED"
CHECK_CIS_LEVEL_extra7162="EXTRA"
CHECK_SEVERITY_extra7162="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7162="AwsLogsLogGroup"
CHECK_ALTERNATE_check7162="extra7162"
CHECK_SERVICENAME_extra7162="cloudwatch"
CHECK_RISK_extra7162='If log groups have a low retention policy of less than 365 days; crucial logs and data can be lost'
CHECK_REMEDIATION_extra7162='Add Log Retention policy of 365 days to log groups. This will persist logs and traces for a long time.'
CHECK_DOC_extra7162='https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Logs.html'
CHECK_CAF_EPIC_extra7162='Data Retention'
extra7162() {
# "Check if CloudWatch Log Groups have a retention policy of 365 days"
declare -i LOG_GROUP_RETENTION_PERIOD_DAYS=365
for regx in $REGIONS; do
LIST_OF_365_RETENTION_LOG_GROUPS=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --query 'logGroups[?retentionInDays=="${LOG_GROUP_RETENTION_PERIOD_DAYS}"].[logGroupName]' --output text 2>&1)
if [[ $(echo "$LIST_OF_365_RETENTION_LOG_GROUPS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe log groups" "$regx"
continue
fi
if [[ $LIST_OF_365_RETENTION_LOG_GROUPS ]]; then
for log in $LIST_OF_365_RETENTION_LOG_GROUPS; do
textPass "$regx: $log Log Group has 365 days retention period!" "$regx" "$log"
done
fi
LIST_OF_NON_365_RETENTION_LOG_GROUPS=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --query 'logGroups[?retentionInDays!="${LOG_GROUP_RETENTION_PERIOD_DAYS}"].[logGroupName]' --output text)
if [[ $LIST_OF_NON_365_RETENTION_LOG_GROUPS ]]; then
for log in $LIST_OF_NON_365_RETENTION_LOG_GROUPS; do
textFail "$regx: $log Log Group does not have 365 days retention period!" "$regx" "$log"
done
fi
REGION_NO_LOG_GROUP=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --output text)
if [[ $REGION_NO_LOG_GROUP ]]; then
:
else
textInfo "$regx does not have a Log Group!" "$regx"
fi
done
}

61
checks/check_extra7163 Normal file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# Remediation:
#
# https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/rotate-secret.html
#
# rotate-secret
# --secret-id <value>
# [--client-request-token <value>]
# [--rotation-lambda-arn <value>]
# [--rotation-rules <value>]
# [--cli-input-json <value>]
# [--generate-cli-skeleton <value>]
CHECK_ID_extra7163="7.163"
CHECK_TITLE_extra7163="[extra7163] Check if Secrets Manager key rotation is enabled"
CHECK_SCORED_extra7163="NOT_SCORED"
CHECK_CIS_LEVEL_extra7163="EXTRA"
CHECK_SEVERITY_extra7163="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7163="AwsSecretsManagerSecret"
CHECK_ALTERNATE_extra7163="extra7163"
CHECK_SERVICENAME_extra7163="secretsmanager"
CHECK_RISK_extra7163="Rotating secrets minimizes exposure to attacks using stolen keys."
CHECK_REMEDITATION_extra7163="Enable key rotation on Secrets Manager key."
CHECK_DOC_extra7163="https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html"
CHECK_CAF_EPIC_extra7163="Data Protection"
extra7163(){
# "Check if Secrets Manager key rotation is enabled"
for regx in $REGIONS; do
LIST_OF_SECRETS=$($AWSCLI secretsmanager list-secrets $PROFILE_OPT --region $regx --query 'SecretList[*].Name' --output text 2>&1)
if [[ $(echo "$LIST_OF_SECRETS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to list secrets" "$regx"
continue
fi
if [[ $LIST_OF_SECRETS ]]; then
for secret in $LIST_OF_SECRETS; do
KEY_ROTATION_ENABLED=$($AWSCLI secretsmanager describe-secret $PROFILE_OPT --region $regx --secret-id $secret --output json | jq '.RotationEnabled')
if [[ $KEY_ROTATION_ENABLED == true ]]; then
textPass "$regx: $secret has key rotation enabled." "$regx" "$secret"
else
textFail "$regx: $secret does not have key rotation enabled." "$regx" "$secret"
fi
done
else
textPass "$regx: No Secrets Manager secrets found." "$regx"
fi
done
}

61
checks/check_extra7164 Normal file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# Remediation:
#
# https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html
# associate-kms-key
# --log-group-name <value>
# --kms-key-id <value>
# [--cli-input-json <value>]
# [--generate-cli-skeleton <value>]
CHECK_ID_extra7164="7.164"
CHECK_TITLE_extra7164="[extra7164] Check if CloudWatch log groups are protected by AWS KMS "
CHECK_SCORED_extra7164="NOT_SCORED"
CHECK_CIS_LEVEL_extra7164="EXTRA"
CHECK_SEVERITY_extra7164="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7164="Logs"
CHECK_ALTERNATE_extra7164="extra7164"
CHECK_SERVICENAME_extra7164="logs"
CHECK_RISK_extra7164="Using customer managed KMS to encrypt CloudWatch log group provide additional confidentiality and control over the log data"
CHECK_REMEDITATION_extra7164="Associate KMS Key with Cloudwatch log group."
CHECK_DOC_extra7164="https://docs.aws.amazon.com/cli/latest/reference/logs/associate-kms-key.html"
CHECK_CAF_EPIC_extra7164="Data Protection"
extra7164(){
# "Check if Cloudwatch log groups are associated with AWS KMS"
for regx in $REGIONS; do
LIST_OF_LOGGROUPS=$($AWSCLI logs describe-log-groups $PROFILE_OPT --region $regx --output json 2>&1 )
if [[ $(echo "$LIST_OF_LOGGROUPS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe log groups" "$regx"
continue
fi
if [[ $LIST_OF_LOGGROUPS ]]; then
LIST_OF_LOGGROUPS_WITHOUT_KMS=$(echo "${LIST_OF_LOGGROUPS}" | jq '.logGroups[]' | jq '. | select( has("kmsKeyId") == false )' | jq -r '.logGroupName')
LIST_OF_LOGGROUPS_WITH_KMS=$(echo "${LIST_OF_LOGGROUPS}" | jq '.logGroups[]' | jq '. | select( has("kmsKeyId") == true )' | jq -r '.logGroupName')
if [[ $LIST_OF_LOGGROUPS_WITHOUT_KMS ]]; then
for loggroup in $LIST_OF_LOGGROUPS_WITHOUT_KMS; do
textFail "$regx: ${loggroup} does not have AWS KMS keys associated." "$regx" "${loggroup}"
done
fi
if [[ $LIST_OF_LOGGROUPS_WITH_KMS ]]; then
for loggroup in $LIST_OF_LOGGROUPS_WITH_KMS; do
textPass "$regx: ${loggroup} does have AWS KMS keys associated." "$regx" "${loggroup}"
done
fi
else
textPass "$regx: No Cloudwatch log groups found." "$regx"
fi
done
}

68
checks/check_extra7165 Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# Remediation
#
# https://docs.aws.amazon.com/cli/latest/reference/dax/create-cluster.html
#
# create-cluster
# --cluster-name <value>
# --node-type <value>
# --replication-factor <value>
# --iam-role-arn <value>
# --sse-specification Enabled=true
CHECK_ID_extra7165="7.165"
CHECK_TITLE_extra7165="[extra7165] Check if DynamoDB: DAX Clusters are encrypted at rest"
CHECK_SCORED_extra7165="NOT_SCORED"
CHECK_CIS_LEVEL_extra7165="EXTRA"
CHECK_SEVERITY_extra7165="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7165="AwsDaxCluster"
CHECK_ALTERNATE_check7165="extra7165"
CHECK_SERVICENAME_extra7165="dynamodb"
CHECK_RISK_extra7165="Encryption at rest provides an additional layer of data protection by securing your data from unauthorized access to the underlying storage."
CHECK_REMEDIATION_extra7165="Re-create the cluster to enable encryption at rest if it was not enabled at creation."
CHECK_DOC_extra7165="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DAXEncryptionAtRest.html"
CHECK_CAF_EPIC_extra7165="Data Protection"
extra7165(){
# "Check if DynamoDB: DAX Clusters are encrypted at rest"
for regx in $REGIONS; do
LIST_OF_DAX_CLUSTERS=$($AWSCLI dax describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[*]' --output json 2>&1)
if [[ $(echo "$LIST_OF_DAX_CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe clusters" "$regx"
continue
fi
if [[ $(echo "$LIST_OF_DAX_CLUSTERS" | grep -E 'Could not connect') ]]; then
textInfo "$regx: Service not available in this region" "$regx"
continue
fi
if [[ $LIST_OF_DAX_CLUSTERS && $LIST_OF_DAX_CLUSTERS != '[]' ]]; then
LIST_OF_CLUSTERS_WITH_ENCRYPTION=$(echo "${LIST_OF_DAX_CLUSTERS}" | jq '.[] | select(.SSEDescription.Status=="ENABLED") | {ClusterName}' | jq -r '.ClusterName')
LIST_OF_CLUSTERS_WITHOUT_ENCRYPTION=$(echo "${LIST_OF_DAX_CLUSTERS}" | jq '.[] | select(.SSEDescription.Status=="DISABLED") | {ClusterName}' | jq -r '.ClusterName')
if [[ $LIST_OF_CLUSTERS_WITHOUT_ENCRYPTION ]]; then
for cluster in $LIST_OF_CLUSTERS_WITHOUT_ENCRYPTION; do
textFail "$regx: ${cluster} does not have encryption at rest enabled." "$regx" "${cluster}"
done
fi
if [[ $LIST_OF_CLUSTERS_WITH_ENCRYPTION ]]; then
for cluster in $LIST_OF_CLUSTERS_WITH_ENCRYPTION; do
textPass "$regx: ${cluster} has encryption at rest enabled." "$regx" "${cluster}"
done
fi
else
textInfo "$regx: No DynamoDB: DAX Clusters found." "$regx"
fi
done
}

50
checks/check_extra7166 Normal file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7166="7.166"
CHECK_TITLE_extra7166="[extra7166] Check if Elastic IP addresses with associations are protected by AWS Shield Advanced"
CHECK_SCORED_extra7166="NOT_SCORED"
CHECK_CIS_LEVEL_extra7166="EXTRA"
CHECK_SEVERITY_extra7166="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7166="AwsEc2Eip"
CHECK_ALTERNATE_check7166="extra7166"
CHECK_SERVICENAME_extra7166="shield"
CHECK_RISK_extra7166='AWS Shield Advanced provides expanded DDoS attack protection for your resources'
CHECK_REMEDIATION_extra7166='Add as a protected resource in AWS Shield Advanced.'
CHECK_DOC_extra7166='https://docs.aws.amazon.com/waf/latest/developerguide/configure-new-protection.html'
CHECK_CAF_EPIC_extra7166='Infrastructure security'
extra7166() {
if [[ "$($AWSCLI $PROFILE_OPT shield get-subscription-state --output text)" == "ACTIVE" ]]; then
CALLER_IDENTITY=$($AWSCLI sts get-caller-identity $PROFILE_OPT --query Arn)
PARTITION=$(echo $CALLER_IDENTITY | cut -d: -f2)
ACCOUNT_ID=$(echo $CALLER_IDENTITY | cut -d: -f5)
for regx in $REGIONS; do
LIST_OF_ELASTIC_IPS_WITH_ASSOCIATIONS=$($AWSCLI ec2 describe-addresses $PROFILE_OPT --region $regx --query 'Addresses[?AssociationId].AllocationId' --output text)
if [[ $LIST_OF_ELASTIC_IPS_WITH_ASSOCIATIONS ]]; then
for elastic_ip in $LIST_OF_ELASTIC_IPS_WITH_ASSOCIATIONS; do
EIP_ARN="arn:${PARTITION}:ec2:${regx}:${ACCOUNT_ID}:eip-allocation/${elastic_ip}"
if $AWSCLI $PROFILE_OPT shield describe-protection --resource-arn $EIP_ARN >/dev/null 2>&1; then
textPass "$regx: EIP $elastic_ip is protected by AWS Shield Advanced" "$regx" "$elastic_ip"
else
textFail "$regx: EIP $elastic_ip is not protected by AWS Shield Advanced" "$regx" "$elastic_ip"
fi
done
else
textInfo "$regx: no elastic IP addresses with assocations found" "$regx"
fi
done
else
textInfo "No AWS Shield Advanced subscription found. Skipping check."
fi
}

46
checks/check_extra7167 Normal file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7167="7.167"
CHECK_TITLE_extra7167="[extra7167] Check if Cloudfront distributions are protected by AWS Shield Advanced"
CHECK_SCORED_extra7167="NOT_SCORED"
CHECK_CIS_LEVEL_extra7167="EXTRA"
CHECK_SEVERITY_extra7167="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7167="AwsCloudFrontDistribution"
CHECK_ALTERNATE_check7167="extra7167"
CHECK_SERVICENAME_extra7167="shield"
CHECK_RISK_extra7167='AWS Shield Advanced provides expanded DDoS attack protection for your resources'
CHECK_REMEDIATION_extra7167='Add as a protected resource in AWS Shield Advanced.'
CHECK_DOC_extra7167='https://docs.aws.amazon.com/waf/latest/developerguide/configure-new-protection.html'
CHECK_CAF_EPIC_extra7167='Infrastructure security'
extra7167() {
if [[ "$($AWSCLI $PROFILE_OPT shield get-subscription-state --output text)" == "ACTIVE" ]]; then
LIST_OF_CLOUDFRONT_DISTRIBUTIONS=$($AWSCLI cloudfront list-distributions $PROFILE_OPT --query 'DistributionList.Items[*].[Id,ARN]' --output text)
if [[ $LIST_OF_CLOUDFRONT_DISTRIBUTIONS ]]; then
while read -r distribution; do
DISTRIBUTION_ID=$(echo $distribution | awk '{ print $1; }')
DISTRIBUTION_ARN=$(echo $distribution | awk '{ print $2; }')
if $AWSCLI $PROFILE_OPT shield describe-protection --resource-arn $DISTRIBUTION_ARN >/dev/null 2>&1; then
textPass "$REGION: Cloudfront distribution $DISTRIBUTION_ID is protected by AWS Shield Advanced" "$REGION" "$DISTRIBUTION_ID"
else
textFail "$REGION: Cloudfront distribution $DISTRIBUTION_ID is not protected by AWS Shield Advanced" "$REGION" "$DISTRIBUTION_ID"
fi
done <<<"$LIST_OF_CLOUDFRONT_DISTRIBUTIONS"
else
textInfo "$REGION: no Cloudfront distributions found" "$REGION"
fi
else
textInfo "No AWS Shield Advanced subscription found. Skipping check."
fi
}

49
checks/check_extra7168 Normal file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7168="7.168"
CHECK_TITLE_extra7168="[extra7168] Check if Route53 hosted zones are protected by AWS Shield Advanced"
CHECK_SCORED_extra7168="NOT_SCORED"
CHECK_CIS_LEVEL_extra7168="EXTRA"
CHECK_SEVERITY_extra7168="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7168="AwsRoute53Domain"
CHECK_ALTERNATE_check7168="extra7168"
CHECK_SERVICENAME_extra7168="shield"
CHECK_RISK_extra7168='AWS Shield Advanced provides expanded DDoS attack protection for your resources'
CHECK_REMEDIATION_extra7168='Add as a protected resource in AWS Shield Advanced.'
CHECK_DOC_extra7168='https://docs.aws.amazon.com/waf/latest/developerguide/configure-new-protection.html'
CHECK_CAF_EPIC_extra7168='Infrastructure security'
extra7168() {
if [[ "$($AWSCLI $PROFILE_OPT shield get-subscription-state --output text)" == "ACTIVE" ]]; then
CALLER_IDENTITY=$($AWSCLI sts get-caller-identity $PROFILE_OPT --query Arn)
PARTITION=$(echo $CALLER_IDENTITY | cut -d: -f2)
LIST_OF_ROUTE53_HOSTED_ZONES=$($AWSCLI route53 list-hosted-zones $PROFILE_OPT --query 'HostedZones[*].[Id,Name]' --output text)
if [[ $LIST_OF_ROUTE53_HOSTED_ZONES ]]; then
while read -r hosted_zone; do
HOSTED_ZONE_ID=$(echo $hosted_zone | awk '{ print $1; }')
HOSTED_ZONE_NAME=$(echo $hosted_zone | awk '{ print $2; }')
HOSTED_ZONE_ARN="arn:${PARTITION}:route53:::${HOSTED_ZONE_ID:1}"
if $AWSCLI $PROFILE_OPT shield describe-protection --resource-arn $HOSTED_ZONE_ARN >/dev/null 2>&1; then
textPass "$REGION: Route53 Hosted Zone $HOSTED_ZONE_NAME is protected by AWS Shield Advanced" "$REGION" "$HOSTED_ZONE_NAME"
else
textFail "$REGION: Route53 Hosted Zone $HOSTED_ZONE_NAME is not protected by AWS Shield Advanced" "$REGION" "$HOSTED_ZONE_NAME"
fi
done <<<"$LIST_OF_ROUTE53_HOSTED_ZONES"
else
textInfo "$REGION: no Route53 hosted zones found" "$REGION"
fi
else
textInfo "No AWS Shield Advanced subscription found. Skipping check."
fi
}

46
checks/check_extra7169 Normal file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7169="7.169"
CHECK_TITLE_extra7169="[extra7169] Check if global accelerators are protected by AWS Shield Advanced"
CHECK_SCORED_extra7169="NOT_SCORED"
CHECK_CIS_LEVEL_extra7169="EXTRA"
CHECK_SEVERITY_extra7169="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7169="AwsGlobalAccelerator"
CHECK_ALTERNATE_check7169="extra7169"
CHECK_SERVICENAME_extra7169="shield"
CHECK_RISK_extra7169='AWS Shield Advanced provides expanded DDoS attack protection for your resources'
CHECK_REMEDIATION_extra7169='Add as a protected resource in AWS Shield Advanced.'
CHECK_DOC_extra7169='https://docs.aws.amazon.com/waf/latest/developerguide/configure-new-protection.html'
CHECK_CAF_EPIC_extra7169='Infrastructure security'
extra7169() {
if [[ "$($AWSCLI $PROFILE_OPT shield get-subscription-state --output text)" == "ACTIVE" ]]; then
LIST_OF_GLOBAL_ACCELERATORS=$($AWSCLI globalaccelerator list-accelerators --region us-west-2 $PROFILE_OPT --query 'Accelerators[?Enabled].[Name,AcceleratorArn]' --output text)
if [[ $LIST_OF_GLOBAL_ACCELERATORS ]]; then
while read -r accelerator; do
ACCELERATOR_NAME=$(echo $accelerator | awk '{ print $1; }')
ACCELERATOR_ARN=$(echo $accelerator | awk '{ print $2; }')
if $AWSCLI $PROFILE_OPT shield describe-protection --resource-arn $ACCELERATOR_ARN >/dev/null 2>&1; then
textPass "$REGION: Global Accelerator $ACCELERATOR_NAME is protected by AWS Shield Advanced" "$REGION" "$ACCELERATOR_NAME"
else
textFail "$REGION: Global Accelerator $ACCELERATOR_NAME is not protected by AWS Shield Advanced" "$REGION" "$ACCELERATOR_NAME"
fi
done <<<"$LIST_OF_GLOBAL_ACCELERATORS"
else
textInfo "$REGION: no global accelerators found" "$REGION"
fi
else
textInfo "No AWS Shield Advanced subscription found. Skipping check."
fi
}

View File

@@ -26,12 +26,20 @@ CHECK_CAF_EPIC_extra717='Logging and Monitoring'
extra717(){
# "Check if Elastic Load Balancers have logging enabled "
for regx in $REGIONS; do
LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[*].LoadBalancerName' --output text|xargs -n1)
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text|xargs -n1)
LIST_OF_ELBS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[*].LoadBalancerName' --output text 2>&1 |xargs -n1)
if [[ $(echo "$LIST_OF_ELBS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to list load balancers v1" "$regx"
continue
fi
LIST_OF_ELBSV2=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[*].LoadBalancerArn' --output text 2>&1 |xargs -n1)
if [[ $(echo "$LIST_OF_ELBSV2" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to list load balancers v2" "$regx"
continue
fi
if [[ $LIST_OF_ELBS || $LIST_OF_ELBSV2 ]]; then
if [[ $LIST_OF_ELBS ]]; then
for elb in $LIST_OF_ELBS; do
CHECK_ELBS_LOG_ENABLED=$($AWSCLI elb describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-name $elb --query 'LoadBalancerAttributes.AccessLog.Enabled'|grep "^true")
CHECK_ELBS_LOG_ENABLED=$($AWSCLI elb describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-name $elb --query 'LoadBalancerAttributes.AccessLog.Enabled' |grep "^true")
if [[ $CHECK_ELBS_LOG_ENABLED ]]; then
textPass "$regx: $elb has access logs to S3 configured" "$regx" "$elb"
else
@@ -41,7 +49,7 @@ extra717(){
fi
if [[ $LIST_OF_ELBSV2 ]]; then
for elbarn in $LIST_OF_ELBSV2; do
CHECK_ELBSV2_LOG_ENABLED=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query Attributes[*] --output text|grep "^access_logs.s3.enabled"|cut -f2|grep true)
CHECK_ELBSV2_LOG_ENABLED=$($AWSCLI elbv2 describe-load-balancer-attributes $PROFILE_OPT --region $regx --load-balancer-arn $elbarn --query Attributes[*] --output text |grep "^access_logs.s3.enabled"|cut -f2|grep true)
ELBV2_NAME=$(echo $elbarn|cut -d\/ -f3)
if [[ $CHECK_ELBSV2_LOG_ENABLED ]]; then
textPass "$regx: $ELBV2_NAME has access logs to S3 configured" "$regx" "$elb"

48
checks/check_extra7170 Normal file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7170="7.170"
CHECK_TITLE_extra7170="[extra7170] Check if internet-facing application load balancers are protected by AWS Shield Advanced"
CHECK_SCORED_extra7170="NOT_SCORED"
CHECK_CIS_LEVEL_extra7170="EXTRA"
CHECK_SEVERITY_extra7170="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7170="AwsElasticLoadBalancingV2LoadBalancer"
CHECK_ALTERNATE_check7170="extra7170"
CHECK_SERVICENAME_extra7170="shield"
CHECK_RISK_extra7170='AWS Shield Advanced provides expanded DDoS attack protection for your resources'
CHECK_REMEDIATION_extra7170='Add as a protected resource in AWS Shield Advanced.'
CHECK_DOC_extra7170='https://docs.aws.amazon.com/waf/latest/developerguide/configure-new-protection.html'
CHECK_CAF_EPIC_extra7170='Infrastructure security'
extra7170() {
if [[ "$($AWSCLI $PROFILE_OPT shield get-subscription-state --output text)" == "ACTIVE" ]]; then
for regx in $REGIONS; do
LIST_OF_APPLICATION_LOAD_BALANCERS=$($AWSCLI elbv2 describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancers[?Type == `application` && Scheme == `internet-facing`].[LoadBalancerName,LoadBalancerArn]' --output text)
if [[ $LIST_OF_APPLICATION_LOAD_BALANCERS ]]; then
while read -r alb; do
ALB_NAME=$(echo $alb | awk '{ print $1; }')
ALB_ARN=$(echo $alb | awk '{ print $2; }')
if $AWSCLI $PROFILE_OPT shield describe-protection --resource-arn $ALB_ARN >/dev/null 2>&1; then
textPass "$regx: ALB $ALB_NAME is protected by AWS Shield Advanced" "$regx" "$ALB_NAME"
else
textFail "$regx: ALB $ALB_NAME is not protected by AWS Shield Advanced" "$regx" "$ALB_NAME"
fi
done <<<"$LIST_OF_APPLICATION_LOAD_BALANCERS"
else
textInfo "$regx: no application load balancers found" "$regx"
fi
done
else
textInfo "No AWS Shield Advanced subscription found. Skipping check."
fi
}

50
checks/check_extra7171 Normal file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7171="7.171"
CHECK_TITLE_extra7171="[extra7171] Check if classic load balancers are protected by AWS Shield Advanced"
CHECK_SCORED_extra7171="NOT_SCORED"
CHECK_CIS_LEVEL_extra7171="EXTRA"
CHECK_SEVERITY_extra7171="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7171="AwsElasticLoadBalancingLoadBalancer"
CHECK_ALTERNATE_check7171="extra7171"
CHECK_SERVICENAME_extra7171="shield"
CHECK_RISK_extra7171='AWS Shield Advanced provides expanded DDoS attack protection for your resources'
CHECK_REMEDIATION_extra7171='Add as a protected resource in AWS Shield Advanced.'
CHECK_DOC_extra7171='https://docs.aws.amazon.com/waf/latest/developerguide/configure-new-protection.html'
CHECK_CAF_EPIC_extra7171='Infrastructure security'
extra7171() {
if [[ "$($AWSCLI $PROFILE_OPT shield get-subscription-state --output text)" == "ACTIVE" ]]; then
CALLER_IDENTITY=$($AWSCLI sts get-caller-identity $PROFILE_OPT --query Arn)
PARTITION=$(echo $CALLER_IDENTITY | cut -d: -f2)
ACCOUNT_ID=$(echo $CALLER_IDENTITY | cut -d: -f5)
for regx in $REGIONS; do
LIST_OF_CLASSIC_LOAD_BALANCERS=$($AWSCLI elb describe-load-balancers $PROFILE_OPT --region $regx --query 'LoadBalancerDescriptions[?Scheme == `internet-facing`].[LoadBalancerName]' --output text |grep -v '^None$')
if [[ $LIST_OF_CLASSIC_LOAD_BALANCERS ]]; then
for elb in $LIST_OF_CLASSIC_LOAD_BALANCERS; do
ELB_ARN="arn:${PARTITION}:elasticloadbalancing:${regx}:${ACCOUNT_ID}:loadbalancer/${elb}"
if $AWSCLI $PROFILE_OPT shield describe-protection --resource-arn $ELB_ARN >/dev/null 2>&1; then
textPass "$regx: ELB $elb is protected by AWS Shield Advanced" "$regx" "$elb"
else
textFail "$regx: ELB $elb is not protected by AWS Shield Advanced" "$regx" "$elb"
fi
done
else
textInfo "$regx: no classic load balancers found" "$regx"
fi
done
else
textInfo "No AWS Shield Advanced subscription found. Skipping check."
fi
}

View File

@@ -30,7 +30,7 @@ extra718(){
for bucket in $LIST_OF_BUCKETS;do
BUCKET_SERVER_LOG_ENABLED=$($AWSCLI s3api get-bucket-logging --bucket $bucket $PROFILE_OPT --query [LoggingEnabled] --output text 2>&1)
if [[ $(echo "$BUCKET_SERVER_LOG_ENABLED" | grep AccessDenied) ]]; then
textFail "$REGION: Access Denied Trying to Get Bucket Logging for $bucket" "$REGION" "$bucket"
textInfo "$REGION: Access Denied Trying to Get Bucket Logging for $bucket" "$REGION" "$bucket"
continue
fi
if [[ $(echo "$BUCKET_SERVER_LOG_ENABLED" | grep "^None$") ]]; then

View File

@@ -28,7 +28,11 @@ CHECK_CAF_EPIC_extra72='Data Protection'
extra72(){
# "Ensure there are no EBS Snapshots set as Public "
for regx in $REGIONS; do
LIST_OF_EBS_SNAPSHOTS=$($AWSCLI ec2 describe-snapshots $PROFILE_OPT --region $regx --owner-ids $ACCOUNT_NUM --output text --query 'Snapshots[*].{ID:SnapshotId}' --max-items $MAXITEMS | grep -v None 2> /dev/null)
LIST_OF_EBS_SNAPSHOTS=$($AWSCLI ec2 describe-snapshots $PROFILE_OPT --region $regx --owner-ids $ACCOUNT_NUM --output text --query 'Snapshots[*].{ID:SnapshotId}' --max-items $MAXITEMS 2>&1 | grep -v None )
if [[ $(echo "$LIST_OF_EBS_SNAPSHOTS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe snapshot" "$regx"
continue
fi
for snapshot in $LIST_OF_EBS_SNAPSHOTS; do
SNAPSHOT_IS_PUBLIC=$($AWSCLI ec2 describe-snapshot-attribute $PROFILE_OPT --region $regx --output text --snapshot-id $snapshot --attribute createVolumePermission --query "CreateVolumePermissions[?Group=='all']")
if [[ $SNAPSHOT_IS_PUBLIC ]];then

View File

@@ -28,13 +28,13 @@ extra720(){
for regx in $REGIONS; do
LIST_OF_FUNCTIONS=$($AWSCLI lambda list-functions $PROFILE_OPT --region $regx --query 'Functions[*].FunctionName' --output text 2>&1)
if [[ $(echo "$LIST_OF_FUNCTIONS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to list functions" "$regx"
textInfo "$regx: Access Denied trying to list functions" "$regx"
continue
fi
if [[ $LIST_OF_FUNCTIONS ]]; then
LIST_OF_TRAILS=$($AWSCLI cloudtrail describe-trails $PROFILE_OPT --region $regx --query 'trailList[*].TrailARN' --output text 2>&1)
if [[ $(echo "$LIST_OF_TRAILS" | grep AccessDenied) ]]; then
textFail "$regx: Access Denied trying to describe trails" "$regx"
textInfo "$regx: Access Denied trying to describe trails" "$regx"
continue
fi
for lambdafunction in $LIST_OF_FUNCTIONS; do

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra721='Logging and Monitoring'
extra721(){
# "Check if Redshift cluster has audit logging enabled "
for regx in $REGIONS; do
LIST_OF_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[*].ClusterIdentifier' --output text)
LIST_OF_REDSHIFT_CLUSTERS=$($AWSCLI redshift describe-clusters $PROFILE_OPT --region $regx --query 'Clusters[*].ClusterIdentifier' --output text 2>&1)
if [[ $(echo "$LIST_OF_REDSHIFT_CLUSTERS" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe clusters" "$regx"
continue
fi
if [[ $LIST_OF_REDSHIFT_CLUSTERS ]]; then
for redshiftcluster in $LIST_OF_REDSHIFT_CLUSTERS;do
REDSHIFT_LOG_ENABLED=$($AWSCLI redshift describe-logging-status $PROFILE_OPT --region $regx --cluster-identifier $redshiftcluster --query LoggingEnabled --output text | grep True)

View File

@@ -26,7 +26,11 @@ CHECK_CAF_EPIC_extra722='Logging and Monitoring'
extra722(){
# "Check if API Gateway has logging enabled "
for regx in $REGIONS; do
LIST_OF_API_GW=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query items[*].id --output text)
LIST_OF_API_GW=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query items[*].id --output text 2>&1)
if [[ $(echo "$LIST_OF_API_GW" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to get rest APIs" "$regx"
continue
fi
if [[ $LIST_OF_API_GW ]];then
for apigwid in $LIST_OF_API_GW;do
API_GW_NAME=$($AWSCLI apigateway get-rest-apis $PROFILE_OPT --region $regx --query "items[?id==\`$apigwid\`].name" --output text)

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