Skip to content

Commit

Permalink
more services and moved to separate folder
Browse files Browse the repository at this point in the history
  • Loading branch information
costasko committed May 13, 2024
1 parent c3379ba commit 4b615aa
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 17 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,23 @@ Comparison based on AWS Documentation [1](https://docs.aws.amazon.com/IAM/latest
| :--: | :--: | :--: |
| S3 Bucket| :white_check_mark: | :white_check_mark: |
| S3 Directory Buckets | :x: | :white_check_mark: |
| S3 Bucket ACLs | :white_check_mark: | :white_check_mark |
| S3 Glacier | :x: | :x: |
| S3 Access Points | :x: | :white_check_mark: |
| S3 Bucket ACLs | :white_check_mark: | :white_check_mark: |
| S3 Glacier | :white_check_mark: | :x: |
| IAM | :white_check_mark: | :white_check_mark: |
| KMS | :white_check_mark: | :white_check_mark: |
| Secrets Manager | :white_check_mark: | :white_check_mark: |
| Lambda | :x: | :white_check_mark: |
| Lambda | :white_check_mark: | :white_check_mark: |
| SNS | :x: | :white_check_mark: |
| SQS | :x: | :white_check_mark: |
| SQS | :white_check_mark: | :white_check_mark: |
| RDS Snapshots | :x: | :white_check_mark: |
| RDS Cluster Snapshots | :x: | :white_check_mark: |
| ECR | :x: | :white_check_mark: |
| EFS | :x: | :white_check_mark: |
| DynamoDB streams | :x: | :white_check_mark: |
| DynamoDB tables | :x: | :white_check_mark: |
| EBS Snapshots | :x: | :white_check_mark: |
| EventBridge | :x: | :x: |
| EventBridge | :white_check_mark: | :x: |
| EventBridge Schema | :x: | :x: |
| Mediastore | :x: | :x: |
| Glue | :x: | :x: |
Expand All @@ -66,7 +67,7 @@ Comparison based on AWS Documentation [1](https://docs.aws.amazon.com/IAM/latest
| SES v2 | :x: | :x: |
| Incident Manager | :x: | :x: |
| Incident Manager Contacts | :x: | :x: |

| VPC endpoints | :x: | :x: |

## How to run

Expand Down
18 changes: 13 additions & 5 deletions awsxenos/config.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
plugins:
- module: .s3
- module: s3
class: S3
- module: .s3
- module: s3
class: S3ACL
- module: .iam
- module: s3
class: S3Glacier
- module: iam
class: IAM
- module: .kms
- module: kms
class: KMS
- module: .secretsmanager
- module: secretsmanager
class: SecretsManager
- module: eventbridge
class: EventBus
- module: lambda
class: LambdaResource
- module: sqs
class: SQS
11 changes: 6 additions & 5 deletions awsxenos/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ def get_all_accounts(self) -> Accounts:

def load_fetch(module_path: str, class_name: str) -> Callable:
"""Dynamically load "fetch"" from a given file/module and class"""
module = importlib.import_module(module_path, package="awsxenos")
path = f".services.{module_path}"
module = importlib.import_module(path, package="awsxenos")
cls = getattr(module, class_name)
instance = cls()
fn = getattr(instance, "fetch")
Expand Down Expand Up @@ -118,6 +119,7 @@ def load_and_run(config_file, accounts) -> Findings:
results.update(future.result())
except Exception as e:
# TODO: Better handling, add logger
print(e)
results[name] = str(e) # Store the exception if the function call fails
return results

Expand All @@ -136,9 +138,8 @@ def cli():
"-c",
"--config",
dest="config",
action="store_false",
default="config.yaml",
help="Include service roles in the report",
action="store",
help="Config location",
)
parser.add_argument(
"-w",
Expand All @@ -152,12 +153,12 @@ def cli():
reporttype = args.reporttype
write_output = args.write_output

prescan = PreScan()
if not args.config:
config_path = f"{package_path.resolve().parent}/config.yaml"
else:
config_path = args.config

prescan = PreScan()
results = load_and_run(config_path, prescan.accounts)
r = Report(results, prescan.known_accounts)

Expand Down
Empty file added awsxenos/services/__init__.py
Empty file.
22 changes: 22 additions & 0 deletions awsxenos/services/eventbridge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import json
from typing import DefaultDict, Set

import boto3 # type: ignore

from awsxenos.finding import Findings, Resources, Service

"""EventBridge Bus Resource Policies"""


class EventBus(Service):

def fetch(self, accounts: DefaultDict[str, Set]) -> Findings: # type: ignore
return super().collate(accounts, self.get_eb_policies())

def get_eb_policies(self) -> Resources:
buses = Resources()
eb = boto3.client("events")
for bus in eb.list_event_buses():
if "Policy" in bus:
buses[bus["Arn"]] = json.loads(bus["Policy"])
return buses
File renamed without changes.
File renamed without changes.
40 changes: 40 additions & 0 deletions awsxenos/services/lambda.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import json
from typing import DefaultDict, Set

import boto3 # type: ignore
from botocore.exceptions import ClientError # type: ignore

from awsxenos.finding import Findings, Resources, Service

"""Lambda Resource Policies"""


class LambdaResource(Service):

def fetch(self, accounts: DefaultDict[str, Set]) -> Findings: # type: ignore
return super().collate(accounts, self.get_lambda_policies())

def get_lambda_policies(self) -> Resources:
lambdas = Resources()
lam = boto3.client("lambda")
paginator = lam.get_paginator("list_functions")
for lam_resp in paginator.paginate():
for func in lam_resp["Functions"]:
try:
lambdas[func["FunctionArn"]] = json.loads(
lam.get_policy(FunctionName=func["FunctionName"])["Policy"]
)
except ClientError as err:
lambdas[func["FunctionArn"]] = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": f"{err}",
"Effect": "Allow",
"Principal": {"AWS": ["arn:aws:iam::111122223333:root"]},
"Action": ["lambda:*"],
"Resource": f'{func["FunctionArn"]}',
}
],
}
return lambdas
21 changes: 21 additions & 0 deletions awsxenos/s3.py → awsxenos/services/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,24 @@ def get_acls(self) -> Resources:
print(e)
continue
return bucket_acls


"""S3 Glacier Vault Policies"""


class S3Glacier(Service):

def fetch(self, accounts: DefaultDict[str, Set]) -> Findings: # type: ignore
return super().collate(accounts, self.get_vault_policies())

def get_vault_policies(self) -> Resources:
vaults = Resources()
glacier = boto3.client("glacier")
paginator = glacier.get_paginator("list_vaults")
glacier_iterator = paginator.paginate()
for glacier_resp in glacier_iterator:
for vault in glacier_resp["VaultList"]:
vaults[vault["VaultARN"]] = json.loads(
glacier.get_vault_access_policy(vaultName=vault["VaultName"])["policy"]["Policy"]
)
return vaults
File renamed without changes.
33 changes: 33 additions & 0 deletions awsxenos/services/sqs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import json
from typing import DefaultDict, Optional, Set

import boto3 # type: ignore

from awsxenos.finding import Findings, Resources, Service

"""SQS Access/Resource Policy"""


class SQS(Service):

def fetch( # type: ignore
self,
accounts: DefaultDict[str, Set],
exclude_service: Optional[bool] = True,
exclude_aws: Optional[bool] = True,
) -> Findings:
return super().collate(accounts, self.get_sqs_policies(exclude_service, exclude_aws))

def get_sqs_policies(self, exclude_service: Optional[bool] = True, exclude_aws: Optional[bool] = True) -> Resources:
queues = Resources()
sqs = boto3.client("sqs")
paginator = sqs.get_paginator("list_queues")
for sqs_resp in paginator.paginate():
for queue in sqs_resp["QueueUrls"]:
queues[queue["QueueUrl"]] = json.loads(
sqs.get_queue_attributes(QueueUrl=queue["QueueUrl"], AttributeNames=["Policy"])["Attributes"][
"Policy"
]
)

return queues
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
policyuniverse==1.5.1.20231109
boto3==1.34.101
jinja2==3.0.1
jinja2==3.1.3
pyyaml==6.0.1

0 comments on commit 4b615aa

Please sign in to comment.