Exemple #1
0
    def collect(self, hint, sessions):
        for entity in sessions:
            session = entity["MemoryObject/base_object"]

            # Have to sanitize the usernames to prevent issues when comparing
            # them later.
            username = str(session.s_login).replace("\x00", "")
            if username:
                user_identity = self.manager.identify(
                    {"User/username": username})
                yield [user_identity, definitions.User(username=username)]
            else:
                user_identity = None

            sid = session.s_sid
            session_identity = self.manager.identify({"Session/sid": sid
                                                      }) | entity.identity

            if session.s_ttyp:
                yield definitions.MemoryObject(base_object=session.s_ttyp,
                                               type="tty")

            yield definitions.MemoryObject(
                base_object=session.s_leader.deref(), type="proc")

            yield [
                session_identity,
                definitions.Session(user=user_identity, sid=sid),
                definitions.Named(name="SID %d" % int(sid), kind="Session")
            ]
Exemple #2
0
    def collect(self, hint, vnodes):
        manager = self.manager
        for entity in vnodes:
            vnode = entity["MemoryObject/base_object"]
            path = vnode.full_path

            components = [
                entity.identity,
                definitions.File(path=path),
                definitions.Named(name=path, kind="File")
            ]

            # Parse HFS-specific metadata. We could look at the mountpoint and
            # see if the filesystem is actually HFS, but it turns out that
            # cnodes are also used for stuff like the dev filesystem, so let's
            # just try and see if there's one that looks valid and go with it.
            cnode = vnode.v_data.dereference_as("cnode")
            if cnode.c_rwlock == cnode:
                cattr = vnode.v_data.dereference_as("cnode").c_attr

                # HFS+ stores timestamps as UTC.
                components.append(
                    definitions.Timestamps(
                        created_at=cattr.ca_ctime.as_datetime(),
                        modified_at=cattr.ca_mtime.as_datetime(),
                        accessed_at=cattr.ca_atime.as_datetime(),
                        backup_at=cattr.ca_btime.as_datetime()))

            posix_uid = vnode.v_cred.cr_posix.cr_ruid
            if posix_uid and posix_uid != 0:
                components.append(
                    definitions.Permissions(
                        owner=manager.identify({"User/uid": posix_uid})))

            yield components
Exemple #3
0
    def collect(self, hint, sessions):
        for entity in sessions:
            session = entity["Struct/base"]

            # Have to sanitize the usernames to prevent issues when comparing
            # them later.
            username = str(session.s_login).replace("\x00", "")
            if username:
                user_identity = self.manager.identify(
                    {"User/username": username})
                yield [user_identity, definitions.User(username=username)]
            else:
                user_identity = None

            sid = session.s_sid
            # Turns out, SID is not always unique. This is disabled as it is
            # not being currently used, and I need to investigate the causes
            # of duplicate sessions occurring on 10.10.
            # session_identity = self.manager.identify({
            #     "Session/sid": sid}) | entity.identity

            session_identity = entity.identity

            if session.s_ttyp:
                yield definitions.Struct(base=session.s_ttyp, type="tty")

            if session.s_leader:
                yield definitions.Struct(base=session.s_leader.deref(),
                                         type="proc")

            yield [
                session_identity,
                definitions.Session(user=user_identity, sid=sid),
                definitions.Named(name="SID %d" % int(sid), kind="Session")
            ]
Exemple #4
0
    def collect(self, hint, endpoints):
        for entity in endpoints:
            struct = entity["Struct/base"]
            af_inet = struct.InetAF.dereference(
                vm=self.session.kernel_address_space)

            if af_inet.AddressFamily == AF_INET:
                family = "INET"
            elif af_inet.AddressFamily == AF_INET6:
                family = "INET6"
            else:
                continue

            l4_port = struct.Port

            for ver, laddr, _ in struct.dual_stack_sockets(
                    vm=self.session.kernel_address_space):
                l3_protocol = "IP%s" % ver
                epoint_id = self.manager.identify({
                    ("OSILayer3/address", "OSILayer4/port", "OSILayer4/protocol"):
                    (laddr, l4_port, "UDP")
                })

                yield [
                    epoint_id,
                    definitions.Named(kind="UDP Endpoint",
                                      name="%s:%s (%s)" %
                                      (laddr, l4_port, "UDP")),
                    definitions.OSILayer3(address=laddr, protocol=l3_protocol),
                    definitions.OSILayer4(port=l4_port, protocol="UDP"),
                    definitions.Endpoint(addressing_family=family, local=True)
                ]
Exemple #5
0
 def collect(self, hint):
     for i in range(self.session.GetParameter("generate_ballast")):
         yield [
             definitions.Named(name="Ballast entry #%d" % i,
                               kind="Ballast"),
             definitions.Timestamps(
                 created_at=datetime.datetime.fromtimestamp(0))
         ]
Exemple #6
0
    def collect(self, users, hint):
        for user in users:
            username = user["User/username"]
            uid = user["User/uid"]
            if not (username and uid):
                continue

            name = "%s (uid=%d)" % (username, uid)
            yield [user.identity, definitions.Named(kind="User", name=name)]
Exemple #7
0
    def collect(self, hint):
        for head_const in ["_unp_dhead", "_unp_shead"]:
            lhead = self.session.get_constant_object(head_const,
                                                     target="unp_head")

            for unp in lhead.lh_first.walk_list("unp_link.le_next"):
                yield [
                    definitions.Struct(base=unp.unp_socket, type="socket"),
                    definitions.Named(kind="Unix Socket")
                ]
Exemple #8
0
    def collect(self, hint, procs):
        manager = self.manager
        for entity in procs:
            proc = entity["MemoryObject/base_object"]
            user_identity = manager.identify({"User/uid": proc.p_uid})
            process_identity = manager.identify({
                ("Process/pid", "Timestamps/created_at"):
                (proc.pid, proc.p_start.as_datetime())
            })

            # kern_proc.c:2706
            session = proc.p_pgrp.pg_session
            if session:
                session_identity = manager.identify(
                    {"MemoryObject/base_object": session})

                yield definitions.MemoryObject(base_object=session,
                                               type="session")
            else:
                session_identity = None

            cr3 = proc.task.map.pmap.pm_cr3
            if cr3:
                cr3_ptr = proc.obj_profile.Pointer(
                    vm=self.session.physical_address_space,
                    target="void",
                    value=proc.task.map.pmap.pm_cr3)
            else:
                cr3_ptr = None

            yield [
                # Reuse the base object identity but also use the PID.
                process_identity | entity.identity,
                definitions.Timestamps(created_at=proc.p_start.as_datetime()),
                definitions.Process(pid=proc.pid,
                                    command=utils.SmartUnicode(proc.p_comm),
                                    user=user_identity,
                                    cr3=cr3_ptr,
                                    is_64bit=proc.task.map.pmap.pm_task_map ==
                                    "TASK_MAP_64BIT",
                                    session=session_identity),
                definitions.Named(name="%s (pid=%d)" % (proc.p_comm, proc.pid),
                                  kind="Process")
            ]

            # We don't know much about the user at this stage, but this
            # is still kind of useful in getting at least a list of UIDs.
            # Once we have more robustness in listing users this can go away.
            yield [user_identity, definitions.User(uid=proc.p_uid)]
Exemple #9
0
 def collect(self, hint, procs):
     for entity in procs:
         eproc = entity["MemoryObject/base_object"]
         yield [
             entity.identity
             | self.manager.identify({"Process/pid": eproc.pid}),
             definitions.Process(pid=eproc.pid,
                                 parent=self.manager.identify({
                                     "Process/pid":
                                     eproc.InheritedFromUniqueProcessId
                                 }),
                                 command=eproc.name,
                                 is_64bit=eproc.IsWow64),
             definitions.Timestamps(created_at=eproc.CreateTime,
                                    destroyed_at=eproc.ExitTime),
             definitions.Named(name=eproc.name, kind="Process")
         ]
Exemple #10
0
    def collect(self, hint, sockets):
        for socket in sockets:
            base_socket = socket["Struct/base"]
            family = str(base_socket.addressing_family).replace("AF_", "")

            if family in ("INET", "INET6"):
                l3_protocol = "IPv4" if family == "INET" else "IPv6"

                source_identity, source = self.prebuild(
                    components=[
                        definitions.OSILayer3(address=base_socket.src_addr,
                                              protocol=l3_protocol),
                        definitions.OSILayer4(port=base_socket.src_port,
                                              protocol=base_socket.l4_protocol,
                                              state=base_socket.tcp_state)
                    ],
                    keys=("OSILayer3/address", "OSILayer4/port",
                          "OSILayer4/protocol"))

                destination_identity, destination = self.prebuild(
                    components=[
                        definitions.OSILayer3(address=base_socket.dst_addr,
                                              protocol=l3_protocol),
                        definitions.OSILayer4(port=base_socket.dst_port,
                                              protocol=base_socket.l4_protocol)
                    ],
                    keys=("OSILayer3/address", "OSILayer4/port",
                          "OSILayer4/protocol"))

                connection = [
                    socket.identity,
                    definitions.Named(name=base_socket.human_name,
                                      kind="IP Connection"),
                    definitions.Connection(protocol_family=family,
                                           source=source_identity,
                                           destination=destination_identity)
                ]

                yield source
                yield destination
                yield connection
            elif family == "UNIX":
                if base_socket.vnode:
                    path = base_socket.vnode.full_path
                    file_identity = self.session.entities.identify(
                        {"File/path": path})
                else:
                    path = None
                    file_identity = None

                yield [
                    socket.identity,
                    definitions.Named(name=base_socket.human_name,
                                      kind="Unix Socket"),
                    definitions.Connection(protocol_family="UNIX"),
                    definitions.Socket(
                        type=base_socket.unix_type,
                        file=file_identity,
                        address="0x%x" % int(base_socket.so_pcb),
                        connected="0x%x" % int(base_socket.unp_conn))
                ]

                # There may be a vnode here - if so, yield it.
                if path:
                    yield [
                        definitions.File(path=path, type="socket"),
                        definitions.Named(name=path, kind="Socket"),
                        definitions.Struct(base=base_socket.vnode.deref(),
                                           type="vnode")
                    ]
            else:
                yield [
                    socket.identity,
                    definitions.Named(kind="Unknown Socket"),
                    definitions.Connection(protocol_family=family)
                ]
Exemple #11
0
    def collect(self, hint, procs):
        # We're going to have a much better time if we can ignore processes
        # that aren't relevant.
        hint_filter = hint.run_engine("hinter",
                                      selector="MemoryDescriptor/process")

        for proc in procs:
            if (hint_filter
                    and not hint_filter.run_engine("matcher", bindings=proc)):
                continue

            vm = proc["Struct/base"].get_process_address_space()
            arch = "x86_32" if vm.end() <= 0x1000000000 else "x86_64"

            vm_identity, vm_entity = self.prebuild(components=[
                definitions.AddressSpace(dtb=vm.dtb,
                                         type="virtual",
                                         architecture=arch,
                                         owner=proc.identity),
                definitions.Named(kind="Virtual Address Space",
                                  name="DTB @%#016x" % vm.dtb)
            ],
                                                   keys=("AddressSpace/dtb", ))

            yield vm_entity

            for address in proc["Struct/base"].task.map.hdr.walk_list(
                    "links.next", include_current=False):

                # Is this range backed by a vnode? If so yield it, and save the
                # identity. This should take care of __TEXT, __LINKEDIT and
                # memory mapped sections.
                vnode = address.find_vnode_object()
                file_identity = None
                if vnode:
                    file_identity, file = self.prebuild(components=[
                        definitions.Struct(base=vnode, type="vnode")
                    ],
                                                        keys=("Struct/base", ))
                    yield file

                # Sort out shared memory flags.
                sharing_mode = address.sharing_mode
                if sharing_mode in ("SM_SHARED", "SM_LARGE_PAGE"):
                    sharing_enum = "shared"
                elif sharing_mode == "SM_COW":
                    sharing_enum = "copy-on-write"
                elif sharing_mode == "SM_PRIVATE":
                    sharing_enum = "private"
                elif sharing_mode == "SM_EMPTY":
                    sharing_mode = None
                else:
                    raise ValueError("Unknown sharing mode %r." % sharing_mode)

                # Sort out permission bits.
                perms = []
                max_perms = []
                for flag in address.protection:
                    perm = self.PROTECTION_FLAGS.get(flag)
                    if not perm:
                        raise ValueError("Unknown protection flag %r." % flag)
                    perms.append(perm)

                for flag in address.max_protection:
                    perm = self.PROTECTION_FLAGS.get(flag)
                    if not perm:
                        raise ValueError("Unknown protection flag %r." % flag)
                    max_perms.append(perm)

                _, result = self.prebuild(
                    components=[
                        definitions.MemoryDescriptor(
                            start=obj.Void(vm=vm,
                                           profile=self.session.profile,
                                           offset=address.links.start.v()),
                            end=obj.Void(vm=vm,
                                         profile=self.session.profile,
                                         offset=address.links.end.v()),
                            address_space=vm_identity,
                            permissions=perms,
                            max_permissions=max_perms,
                            file=file_identity,
                            shared=sharing_enum,
                            code_signed=address.code_signed),
                        definitions.Struct(base=address, type="vm_map_entry")
                    ],
                    keys=("MemoryDescriptor/address_space",
                          "MemoryDescriptor/start", "MemoryDescriptor/end"))

                yield result