示例#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")
            ]
示例#2
0
 def collect(self, hint, zones):
     for element, state in self.collect_base_objects(
             zone_name=self.zone_name, zones=zones):
         yield definitions.MemoryObject(
             base_object=element,
             type=self.type_name,
             state=state)
示例#3
0
    def collect(self, hint):
        # Note that _pgrphash is initialized through:
        #
        # xnu-1699.26.8/bsd/kern/kern_proc.c:195
        # hashinit(int elements, int type, u_long *hashmask)
        #
        # /xnu-1699.26.8/bsd/kern/kern_subr.c: 327
        # hashinit(int elements, int type, u_long *hashmask) {
        #    ...
        # *hashmask = hashsize - 1;
        #
        # Hence the value in _pgrphash is one less than the size of the hash
        # table.
        pgr_hash_table = self.profile.get_constant_object(
            "_pgrphashtbl",
            target="Pointer",
            target_args=dict(target="Array",
                             target_args=dict(
                                 target="pgrphashhead",
                                 count=self.profile.get_constant_object(
                                     "_pgrphash", "unsigned long") + 1)))

        for slot in pgr_hash_table.deref():
            for pgrp in slot.lh_first.walk_list("pg_hash.le_next"):
                for proc in pgrp.pg_members.lh_first.walk_list(
                        "p_pglist.le_next"):
                    yield definitions.MemoryObject(base_object=proc,
                                                   type="proc")
示例#4
0
    def collect(self, hint, eprocesses):
        for entity in eprocesses:
            eproc = entity["MemoryObject/base_object"]
            for handle in eproc.ObjectTable.handles():
                resource_type = handle.get_object_type(eproc.obj_vm)

                if resource_type == "Process":
                    yield definitions.MemoryObject(base_object=eproc,
                                                   type="_EPROCESS")
示例#5
0
    def collect(self, hint):
        ifnet_head = self.profile.get_constant_object(
            "_dlil_ifnet_head",
            target="Pointer",
            target_args=dict(
                target="ifnet"))

        for ifnet in ifnet_head.walk_list("if_link.tqe_next"):
            yield [
                definitions.MemoryObject(
                    base_object=ifnet,
                    type="ifnet")]
示例#6
0
    def collect(self, hint):
        PspCidTable = self.profile.get_constant_object(
            "PspCidTable",
            target="Pointer",
            target_args=dict(target="_PSP_CID_TABLE"))

        # Walk the handle table
        for handle in PspCidTable.handles():
            if handle.get_object_type() == "Process":
                yield definitions.MemoryObject(
                    type="_EPROCESS",
                    base_object=handle.dereference_as("_EPROCESS"))
示例#7
0
    def collect(self, hint):
        tasks = self.profile.get_constant_object(
            "_tasks",
            target="queue_entry",
            vm=self.session.kernel_address_space)

        for task in tasks.list_of_type("task", "tasks"):
            proc = task.bsd_info.deref()
            if not proc:
                continue

            yield definitions.MemoryObject(base_object=proc, type="proc")
示例#8
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.MemoryObject(
                        base_object=unp.unp_socket,
                        type="socket"),
                    definitions.Named(
                        kind="Unix Socket")]
示例#9
0
    def collect(self, hint, ttys):
        for entity in ttys:
            file_identity = None
            session_identity = None

            tty = entity["MemoryObject/base_object"]
            session = tty.t_session.deref()
            vnode = session.s_ttyvp

            if session:
                session_identity = self.manager.identify(
                    {"MemoryObject/base_object": session})

            if vnode:
                # Look, it has a vnode!
                yield definitions.MemoryObject(base_object=vnode, type="vnode")
                file_identity = self.manager.identify(
                    {"MemoryObject/base_object": vnode})

            # Yield just the stubs of the input and output ring buffers.
            # DarwinClistParser will grab these if it cares.
            yield [
                definitions.MemoryObject(base_object=tty.t_rawq, type="clist"),
                definitions.Buffer(purpose="terminal_input",
                                   context=entity.identity)
            ]
            yield [
                definitions.MemoryObject(base_object=tty.t_outq, type="clist"),
                definitions.Buffer(purpose="terminal_output",
                                   context=entity.identity)
            ]

            # Last, but not least, the Terminal itself.
            yield [
                entity.identity,
                definitions.Terminal(session=session_identity,
                                     file=file_identity)
            ]
示例#10
0
    def collect(self, hint, processes):
        manager = self.manager
        for process in processes:
            proc = process["MemoryObject/base_object"]

            for fd, fileproc, flags in proc.get_open_files():
                fg_data = fileproc.autocast_fg_data()

                # The above can return None if the data in memory is invalid.
                # There's nothing we can do about that, other than rely on
                # collector redundancy. Skip.
                if not fg_data:
                    continue

                # In addition to yielding the handle, we will also yield the
                # resource it's pointing to, because other collectors rely on
                # memory objects already being out there when they parse them
                # for resource (File/Socket/etc.) specific information.
                resource_identity = manager.identify(
                    {"MemoryObject/base_object": fg_data})
                handle_identity = manager.identify(
                    {"MemoryObject/base_object": fileproc})

                yield [
                    resource_identity,
                    definitions.MemoryObject(base_object=fg_data,
                                             type=fg_data.obj_type)
                ]

                yield [
                    handle_identity,
                    definitions.Handle(process=process.identity,
                                       fd=fd,
                                       flags=flags,
                                       resource=resource_identity),
                    definitions.MemoryObject(base_object=fileproc,
                                             type="fileproc")
                ]
示例#11
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)]
示例#12
0
    def collect(self, hint):
        pid_hash_table = self.profile.get_constant_object(
            "_pidhashtbl",
            target="Pointer",
            target_args=dict(target="Array",
                             target_args=dict(
                                 target="pidhashhead",
                                 count=self.profile.get_constant_object(
                                     "_pidhash", "unsigned long") + 1)))

        for plist in pid_hash_table.deref():
            for proc in plist.lh_first.walk_list("p_hash.le_next"):
                if not proc:
                    continue

                yield definitions.MemoryObject(base_object=proc, type="proc")
示例#13
0
    def collect(self, hint):
        session_hash_table_size = self.profile.get_constant_object(
            "_sesshash", "unsigned long")

        # The hashtable is an array to session list heads.
        session_hash_table = self.profile.get_constant_object(
            "_sesshashtbl",
            target="Pointer",
            target_args=dict(target="Array",
                             target_args=dict(
                                 target="sesshashhead",
                                 count=session_hash_table_size.v())))

        for sesshashhead in session_hash_table:
            for session in sesshashhead.lh_first.walk_list("s_hash.le_next"):
                yield definitions.MemoryObject(base_object=session,
                                               type="session")
示例#14
0
    def collect(self, hint):
        first_zone = self.profile.get_constant_object(
            "_first_zone",
            target="Pointer",
            target_args=dict(
                target="zone"))

        for zone in first_zone.walk_list("next_zone"):
            yield [
                definitions.AllocationZone(
                    name=zone.zone_name.deref(),
                    count_active=int(zone.count),
                    count_free=int(zone.m("sum_count") - zone.count),
                    element_size=zone.elem_size,
                    tracks_pages=bool(zone.m("use_page_list")),
                    allows_foreign=bool(zone.allows_foreign)),
                definitions.MemoryObject(
                    base_object=zone,
                    type="zone")]
示例#15
0
    def collect(self, hint, sockets):
        for socket in sockets:
            base_socket = socket["MemoryObject/base_object"]
            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.MemoryObject(
                            base_object=base_socket.vnode.deref(),
                            type="vnode")]
            else:
                yield [
                    socket.identity,
                    definitions.Named(
                        kind="Unknown Socket"),
                    definitions.Connection(
                        protocol_family=family)]
示例#16
0
 def collect(self, hint):
     phead = self.session.GetParameter("PsActiveProcessHead")
     for proc in phead.list_of_type("_EPROCESS", "ActiveProcessLinks"):
         yield definitions.MemoryObject(type="_EPROCESS", base_object=proc)
示例#17
0
 def collect(self, hint):
     allproc = self.profile.get_constant_object("_allproc",
                                                target="proclist")
     for proc in allproc.lh_first.p_list:
         yield definitions.MemoryObject(base_object=proc, type="proc")