AWS Tower give the ability to discover and monitor AWS account to find vulnerabilities or misconfigurations. Give also a brief overview for non-AWS expert.
Not related at all of the AWS Trusted Advisor.
AWS Services monitored:
- API Gateway
- CloudFront
- EC2
- EKS
- ALB/ELB
- IAM
- MQ
- RDS
- S3
- VPC
$ pip install -r requirements.txt
$ cp config/rules.yaml.sample config/rules.yaml # if you want to use "audit"
$ cp config/subnet_allow_list.txt.sample config/subnet_allow_list.txt # if you want to use a subnet allow list
$ cp config/trusted_accounts_list.txt.sample config/trusted_accounts_list.txt # if you want to use an aws account allow list
$ alias aws-tower='<path>/aws_tower_cli.py'
$ aws-tower --help
usage: aws_tower_cli.py [-h] [--version] [--no-color] [--no-cache] [--clean-cache] [-l] [-p] {audit,discover,draw,iam} ...
positional arguments:
{audit,discover,draw,iam}
commands
audit Audit AWS account to find security issues
discover Discover assets in an AWS account
draw Draw a threat model of your AWS account
iam Display IAM info for an AWS account
options:
-h, --help show this help message and exit
--version show program's version number and exit
--no-color Disable colors
--no-cache Disable cache
--clean-cache Erase current cache by a new one
-l, --layer [BETA] Generate a layer for the ATT&CK navigator
-p, --list-profiles List available profiles
$ aws-tower audit --help
usage: aws_tower_cli.py audit [-h] [-t {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}] [-m {info,low,medium,high,critical}] [-M {info,low,medium,high,critical}] [-f FILTER] [-v] [-b]
[-s] [-o OUTPUT]
profile
positional arguments:
profile A valid profile name configured in the ~/.aws/config file
options:
-h, --help show this help message and exit
-t {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}, --type {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}
Types to display (default: display everything)
-m {info,low,medium,high,critical}, --min-severity {info,low,medium,high,critical}
min severity level to report when security is enabled (default: medium)
-M {info,low,medium,high,critical}, --max-severity {info,low,medium,high,critical}
max severity level to report when security is enabled (default: high)
-f FILTER, --filter FILTER
Filter by asset value (Ex: "something", "port:xxx", "engine:xxx", "version:xxx", "os:xxx"
-v, --verbose Verbose output of the account assets
-b, --brief Brief output of the account assets
-s, --summary Summary of the account assets
-o OUTPUT, --output OUTPUT
Save the JSON output inside the specified file
$ aws-tower discover --help
usage: aws_tower_cli.py discover [-h] [-t {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}] [-p] [-f FILTER] [-v] [-b] [-s] [-o OUTPUT] profile
positional arguments:
profile A valid profile name configured in the ~/.aws/config file
options:
-h, --help show this help message and exit
-t {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}, --type {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}
Types to display (default: display everything)
-p, --public-only Display public assets only
-f FILTER, --filter FILTER
Filter by asset value (Ex: "something", "port:xxx", "engine:xxx", "version:xxx", "os:xxx"
-v, --verbose Verbose output of the account assets
-b, --brief Brief output of the account assets
-s, --summary Summary of the account assets
-o OUTPUT, --output OUTPUT
Save the JSON output inside the specified file
$ aws-tower draw --help
usage: aws_tower_cli.py draw [-h] [-t {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}] [--limit] [--all] [--vpc-peering-dot VPC_PEERING_DOT] profile
positional arguments:
profile A valid profile name configured in the ~/.aws/config file
options:
-h, --help show this help message and exit
-t {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}, --type {APIGW,CLOUDFRONT,EC2,EKS,ELB,IAM,MQ,RDS,S3,VPC}
Types to display (default: display everything)
--limit Restrict to only interesting assets among vulnerable
--all All assets, without lonely nodes
--vpc-peering-dot VPC_PEERING_DOT
Save VPC peering dot file
$ aws-tower iam --help
usage: aws_tower_cli.py iam [-h] [-s SOURCE] [-a ACTION] [--min-rights {admin,poweruser,reader}] [--service SERVICE] [-d] [--only-dangerous-actions] [-v] profile
positional arguments:
profile A valid profile name configured in the ~/.aws/config file
options:
-h, --help show this help message and exit
-s SOURCE, --source SOURCE
Source arn
-a ACTION, --action ACTION
Action to match
--min-rights {admin,poweruser,reader}
Minimum actions rights
--service SERVICE Action Category to match
-d, --display Display informations about the source ARN
--only-dangerous-actions
Display IAM dangerous actions only
-v, --verbose Verbose output of the account assets
$ pip install -r requirements.lambda.txt --target ./package
$ cp config/lambda.config.sample config/lambda.config
$ export PATROWL_APITOKEN=xxxxxxxxxxxxxxx
$ export PATROWL_PRO_ASSETGROUP=1
$ export PATROWL_PRE_ASSETGROUP=2
$ export PATROWL_DEV_ASSETGROUP=3
$ export PATROWL_PRIVATE_ENDPOINT=http://localhost/
$ export PATROWL_PUBLIC_ENDPOINT=http://localhost/
$ python -c 'from monitoring.aws_lambda import aws_tower_child; aws_tower_child.main({ "my-account-profile": "arn:aws:iam::xxxxxxxxxxxxx:role/readonly", "env": "pro|pre|dev", "region_name": "eu-west-1", "meta_types": ["S3"] })'
$ aws-tower --layer > /tmp/aws-tower-layer.json
Then, go to Attack Navigator
Click on "Open Existing Layer" -> "Upload from local"
Upload your generated file, /tmp/aws-tower-layer.json
You will have a warning, Click No to refuse the upgrade on Att&ck v12, stay in v11.
# Display demo-account with only medium, high and critical findings
$ aws-tower draw demo-account
# Display demo-account, with all assets
$ aws-tower draw demo-account --all
# Display VPC peering connexion in demo-account
$ aws-tower draw demo-account --vpc-peering-dot /tmp/_vpc_demo_account.dot
$ dot -Tjpg /tmp/_vpc_demo_account.dot -o /tmp/_vpc_demo_account.jpg
# Display VPC peering connexion in all accounts
$ for account in $(aws-tower -p); do aws-tower draw $account --vpc-peering-dot "/tmp/_${account}.dot"; done
$ (echo 'graph {'; grep -h -- ';' /tmp/_*.dot | sort -u; echo '}')> /tmp/complete.dot
$ dot -Tjpg /tmp/complete.dot -o /tmp/graph.jpg
Some rules already exists in config/rules.yaml.sample
, but you can add your own too.
You need to add your findings in config/rules.yaml
with the following format:
- message:
text: '{arg1}: Your text ({arg2}, {arg3}), your text'
args:
arg1:
type: dict
key: key_in_dict
variable: dict
arg2:
type: variable
variable: my_variable
arg3:
type: variable
variable: my_other_variable
rules:
- type: in # not_in, is_cidr, is_private_cidr, ...
description: Check if 'all' is 'IN' 'ports'
conditions:
- type: constant
name: data_element
value: all
data_sources:
- type: variable
name: data_list
value: ports
severity: medium # info, medium, high, critical
Types already presents:
- in: check if
data_element
is indata_list
- not_in: check if
data_element
is not indata_list
- has_attribute: check if
data_sources['asset']
has the attributeconditions['attribute']
- has_not_attribute: check if
data_sources['asset']
hasn't the attributeconditions['attribute']
- has_attribute_equal: check if
data_sources['attribute_value']
has the attribute equal toconditions['attribute_value']
- has_attribute_equal: check if
data_sources['attribute_value']
has the attribute not equal toconditions['attribute_value']
- is_cidr: check if
source
is a CIDR (example:0.0.0.0/0
is a valid cidr). - is_private_cidr: check if
source
is a private CIDR (rfc 1918) - is_in_networks: check if
source
is one the networks innetworks
- is_ports: check if source is a port or range ports (example: 9000-90001 is valid)
- engine_deprecated_version: check if
engine
version is higher thanversions
To add a new type, you must define it in libs/patterns.py
with the following format:
- The method name must be:
_check_rule_{type}
where type is the name you want (likeis_cidr
,type_regex
, ...) - Use 2 arguments for your method (will be changed in next update)
To generate the documentation:
$ cd docs && make html
To update the documentation:
$ sphinx-apidoc -o docs/source .
Licensed under the Apache License, Version 2.0 (the "License").
Copyright 2020-2023 Leboncoin