Beispiel #1
0
def attacks(args):
    """
    awspx attacks
    """
    max_attack_iterations = int(args.max_attack_iterations) \
        if args.max_attack_iterations else 5
    max_attack_depth = args.max_attack_depth \
        if args.max_attack_depth else ""
    ignore_conditionals = False \
        if args.include_conditionals else True

    # Resolve only & except attacks
    except_attacks = []
    if args.except_attacks:
        except_attacks = [
            k for k in Attacks.definitions.keys()
            if k.lower() in args.except_attacks.lower()
        ]

    only_attacks = []
    if args.only_attacks:
        only_attacks = [
            k for k in Attacks.definitions.keys()
            if k.lower() in args.only_attacks.lower()
        ]

    if args.func == attacks:
        print("[+] Computing attack paths")
        Attacks.compute(max_iterations=max_attack_iterations,
                        except_attacks=except_attacks,
                        only_attacks=only_attacks,
                        max_search_depth=max_attack_depth,
                        ignore_actions_with_conditions=ignore_conditionals)
    else:
        return max_attack_iterations, max_attack_depth, ignore_conditionals, except_attacks, only_attacks
Beispiel #2
0
def handle_attacks(args, console=console):
    """
    awspx attacks
    """

    attacks = Attacks(
        skip_conditional_actions=args.include_conditional_attacks == False,
        skip_attacks=args.skip_attacks,
        only_attacks=args.only_attacks,
        console=console)

    attacks.compute(max_iterations=args.max_attack_iterations,
                    max_search_depth=str(args.max_attack_depth if args.
                                         max_attack_depth is not None else ""))
Beispiel #3
0
def handle_attacks(args):
    """
    awspx attacks
    """

    try:
        Attacks.compute(
            max_iterations=args.max_attack_iterations,
            except_attacks=args.except_attacks,
            only_attacks=args.only_attacks,
            max_search_depth=str(args.max_attack_depth if args.
                                 max_attack_depth is not None else ""),
            ignore_actions_with_conditions=(
                not args.include_conditional_attacks))
    except Exception as attack:
        if attack in Attacks.definitions:
            print(f"[!] Attack: `{attack}` failed, to exclude this "
                  f"attack in future append --except-attacks='{attack}'")
        else:
            print("[-]", attack)
Beispiel #4
0
def ingest(args):
    """
    awspx ingest
    """

    account = "0000000000000"
    ingested = Elements()
    iam = None

    profile = args.profile if args.profile else "default"

    # offer to create profile it doesn't exist
    try:
        session = boto3.session.Session(profile_name=profile)
    except ProfileNotFound:
        create_new_profile(profile)
        session = boto3.session.Session(profile_name=profile)

    if not args.region:
        r = boto3.session.Session(profile_name=profile).region_name
        region = r if r != None else "eu-west-1"
    else:
        region = args.region

    if not args.database:
        database = profile + ".db"
    else:
        if args.database[-3:] == ".db":
            database = args.database
        else:
            database = args.database + ".db"

    if args.services and args.services != "all":
        services = [
            s for s in SERVICES
            if s.__name__.upper() in map(str.upper,
                                         args.services.strip(" ").split(','))
        ]
    else:
        services = SERVICES

    # Always ingest IAM
    if IAM not in services:
        services.insert(0, IAM)

    # Resolve only & except resources types & ARNs
    optional_resource_args = ""
    selections = {}
    if args.except_types:
        selections["except_types"] = args.except_types.split(",")
        validate_types(selections["except_types"])
        optional_resource_args = optional_resource_args + \
            f"                     --except-types {args.except_types} \\\n"
    else:
        selections["except_types"] = []

    if args.only_types:
        selections["only_types"] = args.only_types.split(",")
        validate_types(selections["only_types"])
        optional_resource_args = optional_resource_args + \
            f"                     --only-types {args.only_types} \\\n"
    else:
        selections["only_types"] = []

    if args.except_arns:
        selections["except_arns"] = args.except_arns.lower().split(",")
        optional_resource_args = optional_resource_args + \
            f"                     --except-arns {args.except_arns} \\\n"
    else:
        selections["except_arns"] = []

    if args.only_arns:
        selections["only_arns"] = args.only_arns.lower().split(",")
        optional_resource_args = optional_resource_args + \
            f"                     --only-arns {args.only_arns} \\\n"
    else:
        selections["only_arns"] = []

    if args.role_to_assume:
        assume_role_arg = f"                     --assume-role {args.role_to_assume} \\\n"
    else:
        assume_role_arg = ""

    max_attack_iterations, max_attack_depth, ignore_conditionals, except_attacks, only_attacks = attacks(
        args)

    if args.skip_attacks:
        attack_args = "                     --skip-attacks"
    else:
        attack_args = f"""                     --max-attack-iterations {str(max_attack_iterations)} \\
                     --ignore-conditionals {str(ignore_conditionals)} \\
    """

        if max_attack_depth != "":
            attack_args = attack_args + \
                f"                     --max-attack-depth {max_attack_depth} \\"

        if except_attacks:
            attack_args = attack_args + \
                f"                 --except-attacks {','.join(except_attacks)}"
        elif only_attacks:
            attack_args = attack_args + \
                f"                 --only-attacks {','.join(only_attacks)}"

    print(f"""
[+] Running awspx ingest --profile {profile} --region {region} --database {database} \\
                     --services {','.join([s.__name__ for s in services])} \\
{assume_role_arg+optional_resource_args+attack_args}
          """)

    try:
        session = boto3.session.Session(profile_name=profile,
                                        region_name=region)
        identity = session.client('sts').get_caller_identity()
        account = identity["Account"]
        print(f"[+] User set to {identity['Arn']}.")
        print(f"[+] Region set to {region}.")
    except:
        print(
            "[-] Request to establish identity (sts:GetCallerIdentity) failed."
        )

    if args.role_to_assume:
        response = session.client('sts').assume_role(
            RoleArn=args.role_to_assume,
            RoleSessionName=f"awspx",
            DurationSeconds=7200)
        if response:
            print(f"[+] Assumed role {args.role_to_assume}")
            session = boto3.session.Session(
                aws_access_key_id=response["Credentials"]["AccessKeyId"],
                aws_secret_access_key=response["Credentials"]
                ["SecretAccessKey"],
                aws_session_token=response["Credentials"]["SessionToken"],
                region_name=region)
        try:
            identity = session.client('sts').get_caller_identity()
            account = identity["Account"]
            print(f"[+] Running as {identity['Arn']}.")
            print(f"[+] Region set to {region}.")
        except:
            print(
                "[-] Request to establish identity (sts:GetCallerIdentity) failed."
            )

        if not args.database:
            database = f"{args.role_to_assume.split('::')[1].split(':')[0]}-{database}"

    print(f"[+] Using database {database}")

    if IAM in services:
        iam = IAM(session, db=database)
        account = iam.root.account()

    for service in [s for s in services if s != IAM]:
        resources = service(session, **selections, account=account)
        ingested += resources

    if IAM not in services:
        iam = IAM(session, db=database, resources=ingested)
    else:
        iam += ingested

    archive = iam.post()
    print(f"[+] Results exported to {archive}")
    Neo4j.load(archive, database)

    if not args.skip_attacks:
        print("[+] Computing attack paths")
        Attacks.compute(max_iterations=max_attack_iterations,
                        except_attacks=except_attacks,
                        only_attacks=only_attacks,
                        max_search_depth=max_attack_depth,
                        ignore_actions_with_conditions=ignore_conditionals)

    print("[+] Done.")