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") ]
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)
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")
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")
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")]
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"))
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")
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")]
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) ]
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") ]
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)]
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")
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")
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")]
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)]
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)
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")