Пример #1
0
def audit_ec2(findings, region):
    json_blob = query_aws(region.account, "ec2-describe-instances", region)
    route_table_json = query_aws(region.account, "ec2-describe-route-tables",
                                 region)

    for reservation in json_blob.get("Reservations", []):
        for instance in reservation.get("Instances", []):
            if instance.get("State", {}).get("Name", "") == "terminated":
                # Ignore EC2's that are off
                continue

            # Check for old instances
            if instance.get("LaunchTime", "") != "":
                MAX_RESOURCE_AGE_DAYS = 365
                collection_date = get_collection_date(region.account)
                launch_time = instance["LaunchTime"].split(".")[0]
                age_in_days = days_between(launch_time, collection_date)
                if age_in_days > MAX_RESOURCE_AGE_DAYS:
                    findings.add(
                        Finding(
                            region,
                            "EC2_OLD",
                            instance["InstanceId"],
                            resource_details={
                                "Age in days": age_in_days,
                                "Name": get_name(instance, "InstanceId"),
                                "Tags": instance.get("Tags", {}),
                            },
                        ))

            # Check for EC2 Classic
            if "vpc" not in instance.get("VpcId", ""):
                findings.add(
                    Finding(region, "EC2_CLASSIC", instance["InstanceId"]))

            if not instance.get("SourceDestCheck", True):
                route_to_instance = None
                for table in route_table_json["RouteTables"]:
                    if table["VpcId"] == instance.get("VpcId", ""):
                        for route in table["Routes"]:
                            if route.get("InstanceId",
                                         "") == instance["InstanceId"]:
                                route_to_instance = route
                                break
                    if route_to_instance is not None:
                        break
                findings.add(
                    Finding(
                        region,
                        "EC2_SOURCE_DEST_CHECK_OFF",
                        instance["InstanceId"],
                        resource_details={
                            "routes": route_to_instance,
                            "Name": get_name(instance, "InstanceId"),
                            "Tags": instance.get("Tags", {}),
                        },
                    ))
Пример #2
0
def audit_users(findings, region):
    MAX_DAYS_SINCE_LAST_USAGE = 90

    # TODO: Convert all of this into a table

    json_blob = query_aws(region.account, "iam-get-credential-report", region)
    csv_lines = json_blob["Content"].split("\n")
    collection_date = json_blob["GeneratedTime"]

    # Skip header
    csv_lines.pop(0)

    # Header:
    # user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,
    # password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,
    # access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,
    # access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,
    # access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,
    # cert_2_active,cert_2_last_rotated
    for line in csv_lines:
        parts = line.split(",")
        user = {
            "user": parts[0],
            "arn": parts[1],
            "user_creation_time": parts[2],
            "password_enabled": parts[3],
            "password_last_used": parts[4],
            "password_last_changed": parts[5],
            "password_next_rotation": parts[6],
            "mfa_active": parts[7],
            "access_key_1_active": parts[8],
            "access_key_1_last_rotated": parts[9],
            "access_key_1_last_used_date": parts[10],
            "access_key_1_last_used_region": parts[11],
            "access_key_1_last_used_service": parts[12],
            "access_key_2_active": parts[13],
            "access_key_2_last_rotated": parts[14],
            "access_key_2_last_used_date": parts[15],
            "access_key_2_last_used_region": parts[16],
            "access_key_2_last_used_service": parts[17],
            "cert_1_active": parts[18],
            "cert_1_last_rotated": parts[19],
            "cert_2_active": parts[20],
            "cert_2_last_rotated": parts[21],
        }

        user_age = days_between(collection_date, user["user_creation_time"])

        if user["password_enabled"] == "true":
            if user["mfa_active"] == "false":
                findings.add(
                    Finding(
                        region,
                        "USER_WITH_PASSWORD_LOGIN_BUT_NO_MFA",
                        user["user"],
                        resource_details={
                            "Number of days since user was created": user_age
                        },
                    ))

            if user["password_last_used"] == "no_information":
                findings.add(
                    Finding(
                        region,
                        "USER_HAS_NEVER_LOGGED_IN",
                        user["user"],
                        resource_details={
                            "Number of days since user was created": user_age
                        },
                    ))
            else:
                password_last_used_days = days_between(
                    collection_date, user["password_last_used"])
                if password_last_used_days > MAX_DAYS_SINCE_LAST_USAGE:
                    findings.add(
                        Finding(
                            region,
                            "USER_HAS_NOT_LOGGED_IN_FOR_OVER_MAX_DAYS",
                            user["user"],
                            resource_details={
                                "Number of days since user was created":
                                user_age,
                                "Number of days since last login":
                                password_last_used_days,
                            },
                        ))

        if (user["access_key_1_active"] == "true"
                and user["access_key_2_active"] == "true"):
            age_of_key1 = days_between(collection_date,
                                       user["access_key_1_last_rotated"])
            age_of_key2 = days_between(collection_date,
                                       user["access_key_2_last_rotated"])

            findings.add(
                Finding(
                    region,
                    "USER_HAS_TWO_ACCESS_KEYS",
                    user["user"],
                    resource_details={
                        "Number of days since key1 was rotated": age_of_key1,
                        "Number of days since key2 was rotated": age_of_key2,
                    },
                ))

        if user["access_key_1_active"] == "true":
            age_of_key = days_between(collection_date,
                                      user["access_key_1_last_rotated"])

            if user["access_key_1_last_used_date"] == "N/A":
                findings.add(
                    Finding(
                        region,
                        "USER_HAS_UNUSED_ACCESS_KEY",
                        user["user"],
                        resource_details={
                            "Unused key": 1,
                            "Number of days since key was rotated": age_of_key,
                        },
                    ))
            else:
                days_since_key_use = days_between(
                    collection_date, user["access_key_1_last_used_date"])
                if days_since_key_use > MAX_DAYS_SINCE_LAST_USAGE:
                    findings.add(
                        Finding(
                            region,
                            "USER_HAS_NOT_USED_ACCESS_KEY_FOR_MAX_DAYS",
                            user["user"],
                            resource_details={
                                "Days since key 1 used:": days_since_key_use,
                                "Number of days since key was rotated":
                                age_of_key,
                            },
                        ))
        if user["access_key_2_active"] == "true":
            age_of_key = days_between(collection_date,
                                      user["access_key_2_last_rotated"])
            if user["access_key_2_last_used_date"] == "N/A":
                findings.add(
                    Finding(
                        region,
                        "USER_HAS_UNUSED_ACCESS_KEY",
                        user["user"],
                        resource_details={
                            "Unused key": 2,
                            "Number of days since key was rotated": age_of_key,
                        },
                    ))
            else:
                days_since_key_use = days_between(
                    collection_date, user["access_key_2_last_used_date"])
                if days_since_key_use > MAX_DAYS_SINCE_LAST_USAGE:
                    findings.add(
                        Finding(
                            region,
                            "USER_HAS_NOT_USED_ACCESS_KEY_FOR_MAX_DAYS",
                            user["user"],
                            resource_details={
                                "Days since key 2 used:": days_since_key_use,
                                "Number of days since key was rotated":
                                age_of_key,
                            },
                        ))