예제 #1
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")
            ]
예제 #2
0
    def collect(self, hint):
        if self.profile_name:
            profile = self.session.address_resolver.LoadProfileForName(
                self.profile_name)
        else:
            profile = self.session.profile

        if not profile:
            raise RuntimeError("Unable to load profile %s" % self.profile_name)

        if self.scan_kernel_vm:
            address_space = self.session.kernel_address_space
        else:
            address_space = self.session.physical_address_space

        scanner = ConfiguredPoolScanner.configure(
            type_name=self.type_name,
            tag_name=self.tag_name,
            session=self.session,
            profile=profile,
            address_space=address_space)

        for pool_obj in scanner.scan():
            pool_header_end = pool_obj.obj_offset + pool_obj.obj_size
            struct = profile.Object(type_name=self.type_name,
                                    vm=address_space,
                                    offset=pool_header_end)
            yield definitions.Struct(base=struct,
                                     type=self.type_name)
예제 #3
0
파일: zones.py 프로젝트: the80srobot/rekall
 def collect(self, hint, zones):
     for element, state in self.collect_base_objects(
             zone_name=self.zone_name, zones=zones):
         yield definitions.Struct(
             base=element,
             type=self.type_name,
             state=state)
예제 #4
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.Struct(base=proc, type="proc")
예제 #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.Struct(base=ifnet, type="ifnet")]
예제 #6
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")
                ]
예제 #7
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.Struct(
                    type="_EPROCESS", base=handle.dereference_as("_EPROCESS"))
예제 #8
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.Struct(base=proc, type="proc")
예제 #9
0
    def collect(self, hint, processes):
        manager = self.manager
        for process in processes:
            proc = process["Struct/base"]

            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({
                    "Struct/base": fg_data})
                handle_identity = manager.identify({
                    "Struct/base": fileproc})

                yield [
                    resource_identity,
                    definitions.Struct(
                        base=fg_data,
                        type=fg_data.obj_type)]

                yield [
                    handle_identity,
                    definitions.Handle(
                        process=process.identity,
                        fd=fd,
                        flags=flags,
                        resource=resource_identity),
                    definitions.Struct(
                        base=fileproc,
                        type="fileproc")]
예제 #10
0
    def collect(self, hint, ttys):
        for entity in ttys:
            file_identity = None
            session_identity = None

            tty = entity["Struct/base"]
            session = tty.t_session.deref()
            vnode = session.s_ttyvp

            if session:
                session_identity = self.manager.identify(
                    {"Struct/base": session})

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

            # Yield just the stubs of the input and output ring buffers.
            # DarwinClistParser will grab these if it cares.
            yield [
                definitions.Struct(base=tty.t_rawq, type="clist"),
                definitions.Buffer(purpose="terminal_input",
                                   context=entity.identity)
            ]
            yield [
                definitions.Struct(base=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)
            ]
예제 #11
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
            session_identity = self.manager.identify({
                "Session/sid": sid}) | entity.identity

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

            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")]
예제 #12
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.Struct(base=session, type="session")
예제 #13
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.Struct(base=proc, type="proc")
예제 #14
0
    def collect(self, hint, procs):
        manager = self.manager
        for entity in procs:
            proc = entity["Struct/base"]
            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({"Struct/base": session})

                yield definitions.Struct(base=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)]
예제 #15
0
파일: zones.py 프로젝트: the80srobot/rekall
    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.Struct(
                    base=zone,
                    type="zone")]
예제 #16
0
    def collect(self, hint, eprocesses):
        for process in eprocesses:
            eproc = process["Struct/base"]
            for handle in eproc.ObjectTable.handles():
                resource_type = handle.get_object_type(eproc.obj_vm)
                vtype = self.TYPES_MAP.get(resource_type)

                if not vtype:
                    continue

                base = handle.dereference_as(vtype)
                base_id = self.manager.identify({"Struct/base": base})
                _, handle = self.prebuild(components=[
                    definitions.Handle(process=process.identity,
                                       resource=base_id,
                                       fd=handle.HandleValue)
                ],
                                          keys=("Handle/process", "Handle/fd",
                                                "Handle/resource"))

                yield [base_id, definitions.Struct(base=base, type=vtype)]
                yield handle
예제 #17
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)
                ]
예제 #18
0
 def collect(self, hint):
     allproc = self.profile.get_constant_object("_allproc",
                                                target="proclist")
     for proc in allproc.lh_first.p_list:
         yield definitions.Struct(base=proc, type="proc")
예제 #19
0
 def collect(self, hint):
     phead = self.session.GetParameter("PsActiveProcessHead")
     for proc in phead.list_of_type("_EPROCESS", "ActiveProcessLinks"):
         yield definitions.Struct(type="_EPROCESS", base=proc)
예제 #20
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