Skip to content

Commit

Permalink
Ran black
Browse files Browse the repository at this point in the history
  • Loading branch information
0xdabbad00 committed Nov 8, 2021
1 parent 3b2917e commit 6483c32
Show file tree
Hide file tree
Showing 23 changed files with 316 additions and 199 deletions.
14 changes: 8 additions & 6 deletions auditor/resources/alarm_forwarder/main.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import boto3
import os


def handler(event, context):
sns = boto3.client('sns')
for record in event['Records']:
sns = boto3.client("sns")
for record in event["Records"]:
sns.publish(
TopicArn=str(os.environ['ALARM_SNS']),
Message=record['Sns']['Message'],
Subject=record['Sns']['Subject'])
return True
TopicArn=str(os.environ["ALARM_SNS"]),
Message=record["Sns"]["Message"],
Subject=record["Sns"]["Subject"],
)
return True
15 changes: 7 additions & 8 deletions commands/access_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

def replace_principal_variables(reference, principal):
"""
Given a resource reference string (ie. the Resource string from an IAM policy) and a prinicipal, replace any variables in the resource string that are principal related.
Given a resource reference string (ie. the Resource string from an IAM policy) and a prinicipal, replace any variables in the resource string that are principal related.
"""
reference = reference.lower()
for tag in principal.tags:
Expand Down Expand Up @@ -189,22 +189,22 @@ class Principal:

@property
def tags(self):
""" aws:PrincipalTag """
"""aws:PrincipalTag"""
return self._tags

@property
def mytype(self):
""" aws:PrincipalType """
"""aws:PrincipalType"""
return self._type

@property
def username(self):
""" aws:username """
"""aws:username"""
return self._username

@property
def userid(self):
""" aws:userid """
"""aws:userid"""
return self._userid

def __init__(self, mytype, tags, username="", userid=""):
Expand Down Expand Up @@ -422,7 +422,7 @@ def access_check_command(accounts, config, args):

def get_managed_policy(iam, policy_arn):
"""
Given the IAM data for an account and the ARN for a policy,
Given the IAM data for an account and the ARN for a policy,
return the policy document
"""
for policy in iam["Policies"]:
Expand Down Expand Up @@ -457,8 +457,7 @@ def is_allowed(privilege_prefix, privilege_name, statements):
def get_allowed_privileges(
privilege_matches, privileged_statements, boundary_statements
):
"""
"""
""" """
allowed_privileges = []
for privilege in privilege_matches:
if boundary_statements is not None:
Expand Down
6 changes: 3 additions & 3 deletions commands/amis.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,16 @@ def amis(args, accounts, config):
)
if args.instance_filter != "":
resource_filter += "|{}".format(args.instance_filter)
if 'Reservations' not in instances:

if "Reservations" not in instances:
print(f"** skipping: {account.name} in {region_name}")
continue

instances = pyjq.all(resource_filter, instances)

account_images = query_aws(account, "ec2-describe-images", region)
resource_filter = ".Images[]"
if 'Images' not in account_images:
if "Images" not in account_images:
print(f"** skipping: {account.name} in {region_name}")
continue
account_images = pyjq.all(resource_filter, account_images)
Expand Down
4 changes: 3 additions & 1 deletion commands/api_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def api_endpoints(accounts, config):


def run(arguments):
print("*** DEPRECARTED: Not enough of data is collected for this command to run successfully ***\n\n")
print(
"*** DEPRECARTED: Not enough of data is collected for this command to run successfully ***\n\n"
)
_, accounts, config = parse_arguments(arguments)
api_endpoints(accounts, config)
6 changes: 3 additions & 3 deletions commands/audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def audit_command(accounts, config, args):

if args.json:
finding = json.loads(str(finding))
finding['finding_type_metadata']= conf
finding["finding_type_metadata"] = conf
print(json.dumps(finding, sort_keys=True))
elif args.markdown:
print(
Expand All @@ -35,7 +35,7 @@ def audit_command(accounts, config, args):
finding.region.name,
conf["description"],
finding.resource_id,
str(finding.resource_details).replace('\n', '\\n')
str(finding.resource_details).replace("\n", "\\n"),
)
)
else:
Expand Down Expand Up @@ -68,7 +68,7 @@ def run(arguments):
"--minimum_severity",
help="Only report issues that are greater than this. Default: INFO",
default="INFO",
choices=['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO', 'MUTE']
choices=["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO", "MUTE"],
)
args, accounts, config = parse_arguments(arguments, parser)

Expand Down
49 changes: 32 additions & 17 deletions commands/collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

MAX_RETRIES = 3


def snakecase(s):
return s.replace("-", "_")

Expand Down Expand Up @@ -183,7 +184,7 @@ def call_function(outputfile, handler, method_to_call, parameters, check, summar
):
print(" - Securityhub is not enabled")
elif "AWSOrganizationsNotInUseException" in str(e):
print(' - Your account is not a member of an organization.')
print(" - Your account is not a member of an organization.")
else:
print("ClientError: {}".format(e), flush=True)
call_summary["exception"] = e
Expand Down Expand Up @@ -223,12 +224,12 @@ def collect(arguments):

# Identify the default region used by global services such as IAM
default_region = os.environ.get("AWS_REGION", "us-east-1")
if 'gov-' in default_region:
default_region = 'us-gov-west-1'
elif 'cn-' in default_region:
default_region = 'cn-north-1'
if "gov-" in default_region:
default_region = "us-gov-west-1"
elif "cn-" in default_region:
default_region = "cn-north-1"
else:
default_region = 'us-east-1'
default_region = "us-east-1"

regions_filter = None
if len(arguments.regions_filter) > 0:
Expand Down Expand Up @@ -290,7 +291,9 @@ def collect(arguments):
region_list = ec2.describe_regions()

if regions_filter is not None:
filtered_regions = [r for r in region_list["Regions"] if r["RegionName"] in regions_filter]
filtered_regions = [
r for r in region_list["Regions"] if r["RegionName"] in regions_filter
]
region_list["Regions"] = filtered_regions

with open("account-data/{}/describe-regions.json".format(account_dir), "w+") as f:
Expand Down Expand Up @@ -344,8 +347,9 @@ def collect(arguments):
)
continue
handler = session.client(
runner["Service"], region_name=region["RegionName"],
config=Config(retries={'max_attempts': arguments.max_attempts})
runner["Service"],
region_name=region["RegionName"],
config=Config(retries={"max_attempts": arguments.max_attempts}),
)

filepath = "account-data/{}/{}/{}-{}".format(
Expand Down Expand Up @@ -382,7 +386,9 @@ def collect(arguments):
# For each cluster, read the `ecs list-tasks`
for clusterArn in list_clusters["clusterArns"]:
cluster_path = (
action_path + "/" + urllib.parse.quote_plus(clusterArn)
action_path
+ "/"
+ urllib.parse.quote_plus(clusterArn)
)
make_directory(cluster_path)

Expand Down Expand Up @@ -418,7 +424,10 @@ def collect(arguments):
runner.get("Check", None),
summary,
)
elif runner["Service"] == "route53" and runner["Request"] == "list-hosted-zones-by-vpc":
elif (
runner["Service"] == "route53"
and runner["Request"] == "list-hosted-zones-by-vpc"
):
action_path = filepath
make_directory(action_path)

Expand All @@ -432,15 +441,17 @@ def collect(arguments):
# For each region
for collect_region in describe_regions["Regions"]:
cluster_path = (
action_path + "/" + urllib.parse.quote_plus(collect_region["RegionName"])
action_path
+ "/"
+ urllib.parse.quote_plus(collect_region["RegionName"])
)
make_directory(cluster_path)

# Read the VPC file
describe_vpcs_file = "account-data/{}/{}/{}".format(
account_dir,
collect_region["RegionName"],
"ec2-describe-vpcs.json"
"ec2-describe-vpcs.json",
)

if os.path.isfile(describe_vpcs_file):
Expand All @@ -451,13 +462,17 @@ def collect(arguments):
outputfile = (
action_path
+ "/"
+ urllib.parse.quote_plus(collect_region["RegionName"])
+ urllib.parse.quote_plus(
collect_region["RegionName"]
)
+ "/"
+ urllib.parse.quote_plus(vpc["VpcId"])
)

call_parameters = {}
call_parameters["VPCRegion"] = collect_region["RegionName"]
call_parameters["VPCRegion"] = collect_region[
"RegionName"
]
call_parameters["VPCId"] = vpc["VpcId"]
call_function(
outputfile,
Expand Down Expand Up @@ -588,15 +603,15 @@ def run(arguments):
required=False,
type=int,
dest="max_attempts",
default=4
default=4,
)
parser.add_argument(
"--regions",
help="Filter and query AWS only for the given regions (CSV)",
required=False,
type=str,
dest="regions_filter",
default=""
default="",
)

args = parser.parse_args(arguments)
Expand Down
4 changes: 2 additions & 2 deletions commands/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ def condition(x, y):
current_account_ids = set(map(lambda entry: entry["id"], current_accounts))
for organization_account in organization_accounts:
# Don't overwrite any account already in the configuration file
if organization_account['id'] not in current_account_ids:
if organization_account["id"] not in current_account_ids:
config["accounts"].append(organization_account)

with open(arguments.config_file, "w+") as f:
f.write(json.dumps(config, indent=4, sort_keys=True))

Expand Down
10 changes: 7 additions & 3 deletions commands/iam_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def __init__(self, auth, auth_graph):
auth_graph[policy_node.key()] = policy_node

for group_name in auth.get("GroupList", []):
group_key = self.key()[0:26] + "group" + auth['Path'] + group_name
group_key = self.key()[0:26] + "group" + auth["Path"] + group_name
group_node = auth_graph[group_key]
group_node.add_parent(self)
self.add_child(group_node)
Expand Down Expand Up @@ -632,7 +632,11 @@ def iam_report(accounts, config, args):
with open("{}.json".format(REPORT_OUTPUT_FILE), "w") as f:
json.dump(t, f)

print("Report written to {}.{}".format(REPORT_OUTPUT_FILE, args.requested_output.value))
print(
"Report written to {}.{}".format(
REPORT_OUTPUT_FILE, args.requested_output.value
)
)


def run(arguments):
Expand All @@ -654,7 +658,7 @@ def run(arguments):
help="Set the output type for the report. [json | html]. Default: html",
default=OutputFormat.html,
type=OutputFormat,
dest="requested_output"
dest="requested_output",
)
parser.set_defaults(show_graph=False)
args, accounts, config = parse_arguments(arguments, parser)
Expand Down
14 changes: 9 additions & 5 deletions commands/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,11 @@ def add_node_to_subnets(region, node, nodes):

# Add a new node (potentially the same one) back to the dictionary
for vpc in region.children:
if len(node.subnets) == 0 and node._parent and vpc.local_id == node._parent.local_id:
if (
len(node.subnets) == 0
and node._parent
and vpc.local_id == node._parent.local_id
):
# VPC Gateway Endpoints (S3 and DynamoDB) reside in a VPC, not a subnet
# So set the relationship between the VPC and the node
nodes[node.arn] = node
Expand Down Expand Up @@ -658,24 +662,24 @@ def build_data_structure(account_data, config, outputfilter):


def prepare(account, config, outputfilter):
""" NO LONGER MAINTAINED
"""NO LONGER MAINTAINED
Collect the data and write it to a file
"""
log("WARNING: This functionality is no longer maintained")
cytoscape_json = build_data_structure(account, config, outputfilter)
if not outputfilter["node_data"]:
filtered_cytoscape_json=[]
filtered_cytoscape_json = []
for node in cytoscape_json:
filtered_node = node.copy()
filtered_node['data']['node_data'] = {}
filtered_node["data"]["node_data"] = {}
filtered_cytoscape_json.append(filtered_node)
cytoscape_json = filtered_cytoscape_json
with open("web/data.json", "w") as outfile:
json.dump(cytoscape_json, outfile, indent=4)


def run(arguments):
""" NO LONGER MAINTAINED """
"""NO LONGER MAINTAINED"""
log("WARNING: This functionality is no longer maintained")
# Parse arguments
parser = argparse.ArgumentParser()
Expand Down
2 changes: 1 addition & 1 deletion commands/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def public(accounts, config):
all_accounts.append(public_node)
for warning in warnings:
print("WARNING: {}".format(warning), file=sys.stderr)

print(json.dumps(all_accounts, indent=4, sort_keys=True))


Expand Down
12 changes: 10 additions & 2 deletions commands/sg_ips.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
from netaddr import IPNetwork
import pyjq

from shared.common import parse_arguments, query_aws, get_regions, is_external_cidr, is_unblockable_cidr
from shared.common import (
parse_arguments,
query_aws,
get_regions,
is_external_cidr,
is_unblockable_cidr,
)
from shared.nodes import Account, Region

# TODO: Considering removing this command. The warnings now live in the audit code.
# The creation of the map and table of locations is all this does now, which is both
# not very valuable, and is difficult to setup (requires matplotlib, basemap data, and geoip data)

__description__ = "[Deprecated] Find all IPs are that are given trusted access via Security Groups"
__description__ = (
"[Deprecated] Find all IPs are that are given trusted access via Security Groups"
)


def get_cidrs_for_account(account, cidrs):
Expand Down
Loading

0 comments on commit 6483c32

Please sign in to comment.