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"]))
Exemple #3
0
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)
Exemple #5
0
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)
Exemple #6
0
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)
Exemple #7
0
    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"]))
Exemple #10
0
    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)
Exemple #11
0
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)
Exemple #12
0
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))
Exemple #13
0
    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'
            ]))
Exemple #14
0
    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"}])
Exemple #16
0
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)
Exemple #17
0
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)
Exemple #18
0
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)
Exemple #19
0
    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)
Exemple #21
0
    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'
        }])
Exemple #22
0
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)
Exemple #23
0
    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)
Exemple #24
0
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)
Exemple #25
0
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)
Exemple #26
0
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)
Exemple #27
0
    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)
Exemple #29
0
def run(arguments):
    _, accounts, config = parse_arguments(arguments)
    api_endpoints(accounts, config)
Exemple #30
0
def run(arguments):
    _, accounts, config = parse_arguments(arguments)
    public(accounts, config)