Esempio n. 1
0
def audit_sg(findings, region):
    # TODO Check if security groups allow large CIDR range (ex. 1.2.3.4/3)
    # TODO Check if an SG restricts IPv4 and then opens IPv6 or vice versa.

    cidrs = {}
    sg_json = query_aws(region.account, 'ec2-describe-security-groups', region)
    sgs = pyjq.all('.SecurityGroups[]', sg_json)
    for sg in sgs:
        cidr_and_name_list = pyjq.all('.IpPermissions[].IpRanges[]|[.CidrIp,.Description]', sg)
        for cidr, name in cidr_and_name_list:
            if not is_external_cidr(cidr):
                continue

            if is_unblockable_cidr(cidr):
                findings.add(Finding(
                    region,
                    'SG_CIDR_UNNEEDED',
                    sg['GroupId'],
                    resource_details={'cidr': cidr}))
                continue

            if cidr.startswith('0.0.0.0') and not cidr.endswith('/0'):
                findings.add(Finding(
                    region,
                    'SG_CIDR_UNEXPECTED',
                    sg['GroupId'],
                    resource_details={'cidr': cidr}))
                continue

            if cidr == '0.0.0.0/0':
                continue

            cidrs[cidr] = cidrs.get(cidr, set())
            cidrs[cidr].add(sg['GroupId'])

        for ip_permissions in sg['IpPermissions']:
            cidrs_seen = set()
            for ip_ranges in ip_permissions['IpRanges']:
                if 'CidrIp' not in ip_ranges:
                    continue
                cidr = ip_ranges['CidrIp']
                for cidr_seen in cidrs_seen:
                    if (IPNetwork(cidr_seen) in IPNetwork(cidr) or
                            IPNetwork(cidr) in IPNetwork(cidr_seen)):
                        findings.add(Finding(
                            region,
                            'SG_CIDR_OVERLAPS',
                            sg['GroupId'],
                            resource_details={'cidr1': cidr, 'cidr2': cidr_seen}))
                cidrs_seen.add(cidr)

    for cidr in cidrs:
        ip = IPNetwork(cidr)
        if ip.size > 2048:
            findings.add(Finding(
                region,
                'SG_LARGE_CIDR',
                cidr,
                resource_details={'size': ip.size, 'security_groups': cidrs[cidr]}))
Esempio n. 2
0
def get_cidrs_for_account(account, cidrs):
    account = Account(None, account)

    for region_json in get_regions(account):
        region = Region(account, region_json)
        sg_json = query_aws(account, "ec2-describe-security-groups", region)
        sgs = pyjq.all(".SecurityGroups[]", sg_json)
        for sg in sgs:
            cidr_and_name_list = pyjq.all(
                ".IpPermissions[].IpRanges[]|[.CidrIp,.Description]", sg
            )
            for cidr, name in cidr_and_name_list:
                if not is_external_cidr(cidr):
                    continue

                if is_unblockable_cidr(cidr):
                    print(
                        "WARNING: Unneeded cidr used {} in {}".format(
                            cidr, sg["GroupId"]
                        )
                    )
                    continue

                if cidr.startswith("0.0.0.0") and not cidr.endswith("/0"):
                    print(
                        "WARNING: Unexpected CIDR for attempted public access {} in {}".format(
                            cidr, sg["GroupId"]
                        )
                    )
                    continue

                if cidr == "0.0.0.0/0":
                    continue

                cidrs[cidr] = cidrs.get(cidr, set())
                if name is not None:
                    cidrs[cidr].add(name)

            for ip_permissions in sg["IpPermissions"]:
                cidrs_seen = set()
                for ip_ranges in ip_permissions["IpRanges"]:
                    if "CidrIp" not in ip_ranges:
                        continue
                    cidr = ip_ranges["CidrIp"]
                    for cidr_seen in cidrs_seen:
                        if IPNetwork(cidr_seen) in IPNetwork(cidr) or IPNetwork(
                            cidr
                        ) in IPNetwork(cidr_seen):
                            print(
                                "WARNING: Overlapping CIDRs in {}, {} and {}".format(
                                    sg["GroupId"], cidr, cidr_seen
                                )
                            )
                    cidrs_seen.add(cidr)
Esempio n. 3
0
def audit_sg(findings, region):
    # TODO Check if security groups allow large CIDR range (ex. 1.2.3.4/3)
    # TODO Check if an SG restricts IPv4 and then opens IPv6 or vice versa.

    cidrs = {}
    sg_json = query_aws(region.account, "ec2-describe-security-groups", region)
    sgs = pyjq.all(".SecurityGroups[]", sg_json)
    for sg in sgs:
        cidr_and_name_list = pyjq.all(
            ".IpPermissions[]?.IpRanges[]|[.CidrIp,.Description]", sg)
        for cidr, name in cidr_and_name_list:
            if not is_external_cidr(cidr):
                continue

            if is_unblockable_cidr(cidr):
                findings.add(
                    Finding(
                        region,
                        "SG_CIDR_UNNEEDED",
                        sg["GroupId"],
                        resource_details={"cidr": cidr},
                    ))
                continue

            if cidr.startswith("0.0.0.0") and not cidr.endswith("/0"):
                findings.add(
                    Finding(
                        region,
                        "SG_CIDR_UNEXPECTED",
                        sg["GroupId"],
                        resource_details={"cidr": cidr},
                    ))
                continue

            if cidr == "0.0.0.0/0":
                continue

            cidrs[cidr] = cidrs.get(cidr, list())
            cidrs[cidr].append(sg["GroupId"])

        for ip_permissions in sg.get("IpPermissions", []):
            cidrs_seen = set()
            for ip_ranges in ip_permissions.get("IpRanges", []):
                if "CidrIp" not in ip_ranges:
                    continue
                cidr = ip_ranges["CidrIp"]
                for cidr_seen in cidrs_seen:
                    if IPNetwork(cidr_seen) in IPNetwork(cidr) or IPNetwork(
                            cidr) in IPNetwork(cidr_seen):
                        findings.add(
                            Finding(
                                region,
                                "SG_CIDR_OVERLAPS",
                                sg["GroupId"],
                                resource_details={
                                    "cidr1": cidr,
                                    "cidr2": cidr_seen
                                },
                            ))
                cidrs_seen.add(cidr)

    for cidr in cidrs:
        ip = IPNetwork(cidr)
        if ip.size > 2048:
            findings.add(
                Finding(
                    region,
                    "SG_LARGE_CIDR",
                    cidr,
                    resource_details={
                        "size": ip.size,
                        "security_groups": list(cidrs[cidr]),
                    },
                ))