def test_access_check(self): # This test calls the access_check command across the demo data, # thereby excersising much of its code # TODO This parsing code should not be here parser = argparse.ArgumentParser() parser.add_argument( "--resource_arn", help="The resource to be looked at, such as arn:aws:s3:::mybucket", required=True, ) parser.add_argument( "--privilege", help="The privilege in question (ex. s3:GetObject)") args, accounts, config = parse_arguments( [ "--accounts", "demo", "--config", "config.json.demo", "--resource_arn", "arn:aws:sns:*:*:prod-*", ], parser, ) access_check_command(accounts, config, args)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--privs", help="The privileges to look for. Defaults to iam privileges that allow direct admin or escalation.", default=None, ) parser.add_argument( "--json", help="Print the json of the issues", default=False, action="store_true", ) parser.add_argument( "--include_restricted", help="Include references to these privs that may be restricted by resources or conditions", default=False, action="store_true", ) args, accounts, config = parse_arguments(arguments, parser) admins = find_admins(accounts, args, findings=set()) for admin in admins: if args.json: print(json.dumps(admin, sort_keys=True)) else: print("{}\t{}\t{}".format(admin["account"], admin["type"], admin["name"]))
def run(arguments): parser = argparse.ArgumentParser() # TODO: Have flags for each connection type parser.add_argument( "--network_only", help="Show networking connections only", default=False, action="store_true", ) parser.add_argument( "--admin_only", help="Show admin connections only", default=False, action="store_true", ) parser.add_argument( "--show_aws_owned_accounts", help="Show accounts owned by AWS (defaults to hiding)", default=False, action="store_true", ) args, accounts, config = parse_arguments(arguments, parser) if args.network_only and args.admin_only: print( "ERROR: You cannot use network_only and admin_only at the same time" ) exit(-1) cytoscape_json = weboftrust(args, accounts, config) with open("web/data.json", "w") as outfile: json.dump(cytoscape_json, outfile, indent=4)
def test_get_public_nodes(self): args, accounts, config = parse_arguments( ['--accounts', 'demo', '--config', 'config.json.demo'], None) public_nodes = get_public_nodes(accounts[0], config) # public_nodes contains a list of nodes from the network diagram as the first item, # and then things like API Gateway and CloudFront as the second item assert_equal(len(public_nodes), 2) # Check sizes of other items assert_equal(len(public_nodes[1]), 0) assert_equal(len(public_nodes[0]), 3) public_nodes[0] ecs_nodes = [] elb_nodes = [] elbv2_nodes = [] print(public_nodes[0]) for node in public_nodes[0]: if node['type'] == 'ecs': ecs_nodes.append(node) if node['type'] == 'elb': elb_nodes.append(node) if node['type'] == 'elbv2': elbv2_nodes.append(node) assert_equal(len(ecs_nodes), 1) assert_equal(ecs_nodes[0]['ports'], '443') assert_equal(len(elb_nodes), 1) assert_equal(len(elbv2_nodes), 1)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--output_image", help="Name of output image", default="resource_stats.png", type=str, ) parser.add_argument( "--no_output_image", help="Don't create output image", default=False, action="store_true", ) parser.add_argument( "--stats_all_resources", help="Show stats for all resource types", action="store_true", default=False, dest="stats_all_resources", ) args, accounts, config = parse_arguments(arguments, parser) stats(accounts, config, args)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--max-age", help="Number of days a user or role hasn't been used before it's marked dead. Default: 90", default=90, type=int, ) parser.add_argument( "--graph", help="Display a graph. Default: False", dest="show_graph", action="store_true", ) parser.add_argument( "--output", help="Set the output type for the report. [json | html]. Default: html", default=OutputFormat.html, type=OutputFormat, dest="requested_output", ) parser.set_defaults(show_graph=False) args, accounts, config = parse_arguments(arguments, parser) iam_report(accounts, config, args)
def test_audit(self): args, accounts, config = parse_arguments( ["--accounts", "demo", "--config", "config.json.demo"], None) findings = audit(accounts) issue_ids = set() for finding in findings: print(finding) issue_ids.add(finding.issue_id) assert_equal( issue_ids, set([ # The trail includes "IsMultiRegionTrail": false "CLOUDTRAIL_NOT_MULTIREGION", # No password policy exists, so no file for it exists "PASSWORD_POLICY_NOT_SET", "ROOT_USER_HAS_ACCESS_KEYS", "USER_HAS_NOT_USED_ACCESS_KEY_FOR_MAX_DAYS", "USER_HAS_UNUSED_ACCESS_KEY", "USER_HAS_TWO_ACCESS_KEYS", "USER_HAS_NOT_LOGGED_IN_FOR_OVER_MAX_DAYS", "USER_WITH_PASSWORD_LOGIN_BUT_NO_MFA", "S3_ACCESS_BLOCK_OFF", "S3_PUBLIC_POLICY_GETOBJECT_ONLY", "GUARDDUTY_OFF", "REDSHIFT_PUBLIC_IP", "ECR_PUBLIC", "SQS_PUBLIC", "SNS_PUBLIC", "BAD_MFA_POLICY", "IAM_CUSTOM_POLICY_ALLOWS_ADMIN", "IAM_KNOWN_BAD_POLICY" ]), )
def run(arguments): _, accounts, config = parse_arguments(arguments) admins = find_admins(accounts, config) for admin in admins: print("{}\t{}\t{}".format(admin['account'], admin['type'], admin['name']))
def run(arguments): _, accounts, _ = parse_arguments(arguments) admins = find_admins(accounts, findings=set()) for admin in admins: print("{}\t{}\t{}".format(admin["account"], admin["type"], admin["name"]))
def test_get_public_nodes(self): args, accounts, config = parse_arguments( ["--accounts", "demo", "--config", "config.json.demo"], None) public_nodes = get_public_nodes(accounts[0], config) # public_nodes contains a list of nodes from the network diagram as the first item, # and then things like API Gateway and CloudFront as the second item assert_equal(len(public_nodes), 2) # Check sizes of other items assert_equal(len(public_nodes[1]), 0) assert_equal(len(public_nodes[0]), 3) public_nodes[0] ecs_nodes = [] elb_nodes = [] elbv2_nodes = [] print(public_nodes[0]) for node in public_nodes[0]: if node["type"] == "ecs": ecs_nodes.append(node) if node["type"] == "elb": elb_nodes.append(node) if node["type"] == "elbv2": elbv2_nodes.append(node) assert_equal(len(ecs_nodes), 1) assert_equal(ecs_nodes[0]["ports"], "443") assert_equal(len(elb_nodes), 1) assert_equal(len(elbv2_nodes), 1)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--max-age", help="Number of days a user or role hasn't been used before it's marked inactive", default=90, type=int, ) parser.add_argument( "--stats_all_resources", help="Show stats for all resource types", action="store_true", default=False, dest="stats_all_resources", ) parser.add_argument( "--minimum_severity", help="Only report issues that are greater than this. Default: INFO", default="INFO", choices=['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO', 'MUTE'] ) parser.add_argument( "--skip_public_resource_audit", help="Skip auditing public resources, which can be slow for large accounts", action="store_true", dest="skip_public_resource_audit", ) args, accounts, config = parse_arguments(arguments, parser) report(accounts, config, args)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--max-age", help= "Number of days a user or role hasn't been used before it's marked inactive", default=90, type=int, ) parser.add_argument( "--output-file", help="Path to write report output to", default=REPORT_OUTPUT_FILE, ) parser.add_argument( "--stats_all_resources", help="Show stats for all resource types", action="store_true", default=False, dest="stats_all_resources", ) parser.add_argument( "--minimum_severity", help="Only report issues that are greater than this. Default: INFO", default="INFO", choices=["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO", "MUTE"], ) args, accounts, config = parse_arguments(arguments, parser) try: report(accounts, config, args) except InvalidAccountData as e: print("Invalid account data: {}".format(e))
def test_audit(self): args, accounts, config = parse_arguments( ['--accounts', 'demo', '--config', 'config.json.demo'], None) findings = audit(accounts) issue_ids = set() for finding in findings: print(finding) issue_ids.add(finding.issue_id) assert_equal( issue_ids, set([ # The trail includes "IsMultiRegionTrail": false 'CLOUDTRAIL_NOT_MULTIREGION', # No password policy exists, so no file for it exists 'PASSWORD_POLICY_NOT_SET', 'ROOT_USER_HAS_ACCESS_KEYS', 'USER_HAS_NOT_USED_ACCESS_KEY_FOR_MAX_DAYS', 'USER_HAS_UNUSED_ACCESS_KEY', 'USER_HAS_TWO_ACCESS_KEYS', 'USER_HAS_NOT_LOGGED_IN_FOR_OVER_MAX_DAYS', 'USER_WITH_PASSWORD_LOGIN_BUT_NO_MFA', 'S3_ACCESS_BLOCK_OFF', 'S3_PUBLIC_POLICY_GETOBJECT_ONLY', 'GUARDDUTY_OFF', 'REDSHIFT_PUBLIC_IP', 'ECR_PUBLIC', 'SQS_PUBLIC', 'SNS_PUBLIC', 'BAD_MFA_POLICY', 'IAM_CUSTOM_POLICY_ALLOWS_ADMIN' ]))
def test_get_public_nodes(self): args, accounts, config = parse_arguments( ["--accounts", "demo", "--config", "config.json.demo"], None) public_nodes, warnings = get_public_nodes(accounts[0], config) assert_equal(len(public_nodes), 3) # Check sizes of other items assert_equal(len(public_nodes[0]), 6) public_nodes[0] ecs_nodes = [] elb_nodes = [] elbv2_nodes = [] print(public_nodes) for node in public_nodes: if node["type"] == "ecs": ecs_nodes.append(node) if node["type"] == "elb": elb_nodes.append(node) if node["type"] == "elbv2": elbv2_nodes.append(node) assert_equal(len(ecs_nodes), 1) assert_equal(ecs_nodes[0]["ports"], "443") assert_equal(len(elb_nodes), 1) assert_equal(len(elbv2_nodes), 1)
def test_find_admins(self): args, accounts, config = parse_arguments( ["--accounts", "demo", "--config", "config.json.demo"], None ) findings = set() admins = find_admins(accounts, findings) assert_equal(admins, [{"account": "demo", "name": "bad_role", "type": "role"}])
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--instance_filter", help= "Filter on the EC2 info, for example `select(.Platform == \"windows\")` or `select(.Architecture!=\"x86_64\")`", default='') args, accounts, config = parse_arguments(arguments, parser) amis(args, accounts, config)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument("--json", help="Print the json of the issues", default=False, action='store_true') args, accounts, config = parse_arguments(arguments, parser) audit_command(accounts, config, args)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--max-age", help="Number of days a user or role hasn't been used before it's marked inactive", default=90, type=int) args, accounts, config = parse_arguments(arguments, parser) report(accounts, config, args)
def test_parse_arguments(self): parser = argparse.ArgumentParser() parser.add_argument('--json', help='Print the json of the issues', default=False, action='store_true') args, accounts, config = parse_arguments( ['--json', '--accounts', 'demo', '--config', 'config.json.demo'], parser) assert_equal(args.json, True)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument('--output_image', help='Name of output image', default='resource_stats.png', type=str) parser.add_argument("--no_output_image", help="Don't create output image", default=False, action='store_true') args, accounts, config = parse_arguments(arguments, parser) stats(accounts, config, args)
def test_find_admins(self): args, accounts, config = parse_arguments( ['--accounts', 'demo', '--config', 'config.json.demo'], None) findings = set() admins = find_admins(accounts, findings) assert_equal(admins, [{ 'account': 'demo', 'name': 'bad_role', 'type': 'role' }])
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--resource_arn", help="The resource to be looked at, such as arn:aws:s3:::mybucket", required=True, ) parser.add_argument("--privilege", help="The privilege in question (ex. s3:GetObject)") args, accounts, config = parse_arguments(arguments, parser) access_check_command(accounts, config, args)
def test_parse_arguments(self): parser = argparse.ArgumentParser() parser.add_argument( "--json", help="Print the json of the issues", default=False, action="store_true", ) args, accounts, config = parse_arguments( ["--json", "--accounts", "demo", "--config", "config.json.demo"], parser) assert_equal(args.json, True)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--max-age", help= "Number of days a user or role hasn't been used before it's marked dead", default=90, type=int) parser.add_argument("--graph", help="Do not create and display a graph", dest='show_graph', action='store_true') parser.set_defaults(show_graph=False) args, accounts, config = parse_arguments(arguments, parser) iam_report(accounts, config, args)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--max-age", help="Number of days a user or role hasn't been used before it's marked inactive", default=90, type=int) parser.add_argument( "--stats_all_resources", help="Show stats for all resource types", action='store_true', default=False, dest='stats_all_resources') args, accounts, config = parse_arguments(arguments, parser) report(accounts, config, args)
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--json", help="Print the json of the issues", default=False, action="store_true", ) parser.add_argument( "--markdown", help="Print issue as markdown (for Slack)", default=False, action="store_true", ) args, accounts, config = parse_arguments(arguments, parser) audit_command(accounts, config, args)
def test_audit(self): args, accounts, config = parse_arguments( ["--accounts", "demo", "--config", "config.json.demo"], None) findings = audit(accounts) issue_ids = set() for finding in findings: print(finding) issue_ids.add(finding.issue_id) assert_equal( issue_ids, set([ # The trail includes "IsMultiRegionTrail": false "CLOUDTRAIL_NOT_MULTIREGION", # No password policy exists, so no file for it exists "PASSWORD_POLICY_NOT_SET", "ROOT_USER_HAS_ACCESS_KEYS", "USER_HAS_NOT_USED_ACCESS_KEY_FOR_MAX_DAYS", "USER_HAS_UNUSED_ACCESS_KEY", "USER_HAS_TWO_ACCESS_KEYS", "USER_HAS_NOT_LOGGED_IN_FOR_OVER_MAX_DAYS", "USER_WITH_PASSWORD_LOGIN_BUT_NO_MFA", "S3_ACCESS_BLOCK_OFF", "S3_PUBLIC_POLICY_GETOBJECT_ONLY", "GUARDDUTY_OFF", "REDSHIFT_PUBLIC_IP", "ECR_PUBLIC", "SQS_PUBLIC", "SNS_PUBLIC", "IAM_BAD_MFA_POLICY", "IAM_CUSTOM_POLICY_ALLOWS_ADMIN", "IAM_KNOWN_BAD_POLICY", "IAM_ROLE_ALLOWS_ASSUMPTION_FROM_ANYWHERE", "EC2_OLD", "IAM_UNEXPECTED_S3_EXFIL_PRINCIPAL", "IAM_LINTER", "EC2_IMDSV2_NOT_ENFORCED", "REQUEST_SMUGGLING", "ELBV1_DESYNC_MITIGATION", ]), )
def run(arguments): parser = argparse.ArgumentParser() parser.add_argument( "--json", help="Print the json of the issues", default=False, action="store_true", ) parser.add_argument( "--markdown", help="Print issue as markdown (for Slack)", default=False, action="store_true", ) parser.add_argument( "--minimum_severity", help="Only report issues that are greater than this. Default: LOW", default="INFO", choices=['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO', 'MUTE']) args, accounts, config = parse_arguments(arguments, parser) audit_command(accounts, config, args)
def run(arguments): _, accounts, config = parse_arguments(arguments) api_endpoints(accounts, config)
def run(arguments): _, accounts, config = parse_arguments(arguments) public(accounts, config)