Example #1
0
    def transitive(self):

        instances = self.get(
            "AWS::Ec2::Instance").get(
            "Resource")

        functions = self.get(
            "AWS::Lambda::Function").get(
            "Resource")

        roles = self.get(
            "AWS::Iam::Role").get(
            "Resource")

        instance_profiles = self.get(
            "AWS::Iam::InstanceProfile").get(
            "Resource")

        # Instance - [TRANSITIVE] -> Iam Instance Profile

        for instance in instances:

            if "IamInstanceProfile" not in instance.properties():
                continue

            target = next((ip for ip in instance_profiles
                           if ip.id() == instance.properties()["IamInstanceProfile"]["Arn"]),
                          None)

            del instance.properties()["IamInstanceProfile"]

            self.add(Transitive(
                {"Name": "Attached"}, source=instance, target=target))

        # Lambda - [TRANSITIVE] -> Role

        for function in functions:

            if "Role" not in function.properties():
                continue

            role = next((r for r in roles
                         if r.id() == function.properties()["Role"]),
                        None)

            del function.properties()["Role"]

            self.add(Transitive(
                {"Name": "Attached"}, source=function, target=role))
Example #2
0
    def get_account_authorization_details(self, only_arns, except_arns):

        elements = Elements()
        edges = {"Groups": [], "Policies": [], "InstanceProfiles": []}

        def get_aad_element(label, entry):

            properties = dict()
            for pk, pv in sorted(entry.items()):

                if pk.endswith("PolicyList"):
                    properties["Documents"] = [{
                        p["PolicyName"]: p["PolicyDocument"]
                        for p in pv
                    }]

                elif pk == "AssumeRolePolicyDocument":
                    properties["Trusts"] = pv

                elif pk in [
                        "GroupList", "InstanceProfileList",
                        "AttachedManagedPolicies"
                ]:
                    continue

                elif pk == "PolicyVersionList":

                    properties["Document"] = [{
                        "DefaultVersion":
                        [p for p in pv if p["IsDefaultVersion"]][0]["Document"]
                    }]

                else:
                    properties[pk.replace(label, "")] = pv

            element = Resource(properties=properties,
                               labels=["Resource", f"AWS::Iam::{label}"])

            if f"AWS::Iam::Group" in self.run and "GroupList" in entry.keys():

                edges["Groups"].extend([(element, g)
                                        for g in entry["GroupList"]])

            if f"AWS::Iam::InstanceProfile" in self.run \
                    and "InstanceProfileList" in entry.keys():

                edges["InstanceProfiles"].extend([
                    (get_aad_element("InstanceProfile", ip), element)
                    for ip in entry["InstanceProfileList"]
                ])

            if f"AWS::Iam::Policy" in self.run \
                    and "AttachedManagedPolicies" in entry.keys():
                edges["Policies"].extend([
                    (element, p["PolicyArn"])
                    for p in entry["AttachedManagedPolicies"]
                ])

            if (str(f"AWS::Iam::{label}") in self.run and
                (len(except_arns) == 0 or properties["Arn"] not in except_arns)
                    and (len(only_arns) == 0 or properties["Arn"] in only_arns)
                    and element not in elements):
                self._print(f"[*] Adding {element}")
                elements.append(element)

            return element

        account_authorization_details = [
            aad for aad in self.client.get_paginator(
                "get_account_authorization_details").paginate()
        ]

        account_authorization_details = [
            (label.replace("DetailList", "").replace("Policies",
                                                     "Policy"), entry)
            for aad in account_authorization_details
            for (label, v) in aad.items() if isinstance(v, list) for entry in v
        ]

        for label, entry in account_authorization_details:
            get_aad_element(label, entry)

        # Ensure edge nodes exist
        for k, v in edges.items():
            edges[k] = list(
                filter(lambda e: e[0] is not None and e[1] is not None, [
                    e if type(e[1]) == Resource else
                    (e[0],
                     next((t for t in elements
                           if (k == "Groups" and str(t).endswith(str(e[1])))
                           or str(t) == str(e[1])), None)) for e in v
                ]))

        # (:User|Group|Role)-[:TRANSITIVE{Attached}]->(:Policy)
        for (s, t) in edges["Policies"]:
            elements.append(
                Transitive(properties={"Name": "Attached"}, source=s,
                           target=t))

        # # (:User)-[:TRANSITIVE{MemberOf}]->(:Group)
        for (s, t) in edges["Groups"]:
            elements.append(
                Transitive(properties={"Name": "MemberOf"}, source=s,
                           target=t))

        # (:InstanceProfile)-[:TRANSITIVE{Attached}]->(:Role)
        for (s, t) in edges["InstanceProfiles"]:
            del s.properties()["Roles"]
            elements.append(
                Transitive(properties={"Name": "Attached"}, source=s,
                           target=t))

        return elements
Example #3
0
    def load_transitives(self):

        resources = self.get("Resource")
        groups = resources.get("AWS::Iam::Group")
        roles = resources.get("AWS::Iam::Role")
        policies = resources.get("AWS::Iam::Policy")
        instance_profiles = resources.get("AWS::Iam::InstanceProfile")

        for resource in self.console.tasklist(
                "Adding Transitive relationships",
                iterables=resources,
                done="Added Transitive relationships",
        ):

            if resource.label() in [
                    "AWS::Iam::User", "AWS::Iam::Group", "AWS::Iam::Role"
            ]:

                # (User|Group|Role) --> (Policy)
                if "AttachedManagedPolicies" in resource.properties():

                    policy_arns = [
                        policy["PolicyArn"]
                        for policy in resource.get("AttachedManagedPolicies")
                    ]

                    for policy in filter(lambda r: r.id() in policy_arns,
                                         policies):

                        self.add(
                            Transitive(properties={"Name": "Attached"},
                                       source=resource,
                                       target=policy))

                        policy_arns = [
                            p for p in policy_arns if p != str(policy)
                        ]

                    if not len(policy_arns) > 0:
                        del resource.properties()["AttachedManagedPolicies"]

                # (User)-->(Group)
                if (resource.label() in ["AWS::Iam::User"]
                        and "GroupList" in resource.properties()):

                    group_names = resource.get("GroupList")

                    for group in filter(lambda r: r.get("Name") in group_names,
                                        groups):

                        self.add(
                            Transitive(properties={"Name": "Attached"},
                                       source=resource,
                                       target=group))

                        group_names = [
                            g for g in group_names if g != str(group)
                        ]

                    if not len(group_names) > 0:
                        del resource.properties()["GroupList"]

            # (Instance) --> (Instance Profile)
            if (resource.label() in ["AWS::Ec2::Instance"]
                    and "IamInstanceProfile" in resource.properties()):

                instance_profile = next(
                    (i for i in instance_profiles
                     if str(i) == resource.get("IamInstanceProfile")["Arn"]),
                    None)

                if instance_profile is not None:

                    self.add(
                        Transitive({"Name": "Attached"},
                                   source=resource,
                                   target=instance_profile))

                    del resource.properties()["IamInstanceProfile"]

            # (InstanceProfile) --> (Role)
            if (resource.label() in ["AWS::Iam::InstanceProfile"]
                    and "Roles" in resource.properties()):

                role_arns = list(map(lambda r: r["Arn"],
                                     resource.get("Roles")))

                for role in filter(lambda r: r.id() in role_arns, roles):

                    self.add(
                        Transitive(properties={"Name": "Attached"},
                                   source=resource,
                                   target=role))

                    role_arns = [r for r in role_arns if r != str(role)]

                if not len(role_arns) > 0:
                    del resource.properties()["Roles"]

            # (Function) --> (Role)
            if (resource.label() in ["AWS::Lambda::Function"]
                    and "Role" in resource.properties()):

                role = next(
                    (r for r in roles if str(r) == resource.get("Role")), None)

                if role is not None:

                    self.add(
                        Transitive(properties={"Name": "Attached"},
                                   source=resource,
                                   target=role))

                    del resource.properties()["Role"]
Example #4
0
    def get_account_authorization_details(self):

        elements = Elements()
        edges = {"Groups": [], "Policies": [], "InstanceProfiles": []}

        def get_aad_element(label, entry):

            properties = dict()

            for pk, pv in sorted(entry.items()):

                if pk.endswith("PolicyList"):
                    properties["Documents"] = [{
                        p["PolicyName"]: p["PolicyDocument"]
                        for p in pv
                    }]

                elif pk == "AssumeRolePolicyDocument":
                    properties["Trusts"] = pv

                elif pk in [
                        "GroupList", "InstanceProfileList",
                        "AttachedManagedPolicies"
                ]:
                    continue

                elif pk == "PolicyVersionList":

                    properties["Document"] = [{
                        "DefaultVersion":
                        [p for p in pv if p["IsDefaultVersion"]][0]["Document"]
                    }]

                else:
                    properties[pk.replace(label, "")] = pv

            element = Resource(properties=properties,
                               labels=["Resource",
                                       "AWS::Iam::%s" % label])

            if "GroupList" in entry.keys():

                edges["Groups"].extend([(element, g)
                                        for g in entry["GroupList"]])

            if "InstanceProfileList" in entry.keys():

                edges["InstanceProfiles"].extend([
                    (get_aad_element("InstanceProfile", ip), element)
                    for ip in entry["InstanceProfileList"]
                ])

            if "AttachedManagedPolicies" in entry.keys():
                edges["Policies"].extend([
                    (element, p["PolicyArn"])
                    for p in entry["AttachedManagedPolicies"]
                ])

            if element not in elements:
                print(f" \-> Adding {element}")
                elements.append(element)

            return element

        account_authorization_details = [
            aad for aad in self.client.get_paginator(
                "get_account_authorization_details").paginate()
        ]

        account_authorization_details = [
            (label.replace("DetailList", "").replace("Policies",
                                                     "Policy"), entry)
            for aad in account_authorization_details
            for (label, v) in aad.items() if isinstance(v, list) for entry in v
        ]

        for label, entry in account_authorization_details:
            get_aad_element(label, entry)

        # User|Group|Role - Attached -> Policy

        for (s, t) in edges["Policies"]:
            t = next(entry for entry in elements if entry.id() == t)
            elements.append(
                Transitive(properties={"Name": "Attached"}, source=s,
                           target=t))

        # User - [MemberOf] -> Group

        for (s, t) in edges["Groups"]:
            t = next(entry for entry in elements.get("AWS::Iam::Group")
                     if str(entry).endswith(t))
            elements.append(
                Transitive(properties={"Name": "MemberOf"}, source=s,
                           target=t))

        # InstanceProfile - [Attached] -> Role

        for (s, t) in edges["InstanceProfiles"]:
            del s.properties()["Roles"]
            elements.append(
                Transitive(properties={"Name": "Attached"}, source=s,
                           target=t))

        return elements