def check_thrdproc(self, _addr_space): """Enumerate processes indirectly by ETHREAD scanning""" ret = dict() for ethread in modscan.ThrdScan(self._config).calculate(): if ethread.ExitTime != 0: continue # Bounce back to the threads owner process = None if hasattr(ethread.Tcb, 'Process'): process = ethread.Tcb.Process.dereference_as('_EPROCESS') elif hasattr(ethread, 'ThreadsProcess'): process = ethread.ThreadsProcess.dereference() # Make sure the bounce succeeded if (process and process.ExitTime == 0 and process.UniqueProcessId > 0 and process.UniqueProcessId < 65535): ret[process.obj_vm.vtop(process.obj_offset)] = process return ret
def calculate(self): thread_start_module = None thread_start_function = None # Checks that subclass AbstractThreadCheck checks = registry.get_plugin_classes(threads.AbstractThreadCheck) addr_space = utils.load_as(self._config) # Are we on x86 or x64. Save this for render_text self.bits32 = addr_space.profile.metadata.\ get("memory_model", "32bit") == "32bit" seen_threads = dict() # Gather threads by list traversal of active/linked processes for task in taskmods.DllList(self._config).calculate(): for thread in task.ThreadListHead.\ list_of_type("_ETHREAD", "ThreadListEntry"): seen_threads[thread.obj_vm.vtop(thread.obj_offset)] = (False, thread) # Now scan for threads and save any that haven't been seen for thread in modscan.ThrdScan(self._config).calculate(): if not seen_threads.has_key(thread.obj_offset): seen_threads[thread.obj_offset] = (True, thread) # Keep a record of processes whose DLLs we've already enumerated process_dll_info = {} for _offset, (found_by_scanner, thread) in seen_threads.items(): if self.pidlist: if not thread.attached_process( ).UniqueProcessId in self.pidlist: continue thread_callstack = parse_callstack(thread, self.bits32, self._config) yield thread, addr_space, \ thread_start_function, thread_callstack
) in self.suspiciouspids.keys(): suspiciousline = "{0}/{1}/{2}/{3:<#10x}".format( net_object.Owner.UniqueProcessId, proto, state, net_object.obj_offset) self.suspicious[suspiciousline] = { "reason": "Process flagged: " + self.suspiciouspids[ net_object.Owner.UniqueProcessId.v()]["reason"], "color": "YELLOW" } # Get threads threads = [] if "Thread" in self._config.TYPE: threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") line = "[{4}THREAD]{0} {1}{0} PID: {2}/TID: {3}".format( "" if body else "|", image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, self._config.MACHINE) yield self.getoutput(line, thread.CreateTime, end=thread.ExitTime, body=body) if not detections: continue suspiciousline = "PID: {0}/TID: {1}".format( thread.Cid.UniqueProcess, thread.Cid.UniqueThread) if thread.Cid.UniqueProcess.v() in self.suspiciouspids.keys():
def calculate(self): # Checks that subclass AbstractThreadCheck checks = registry.get_plugin_classes(AbstractThreadCheck) # If --listtags is chosen, just print the tags and return if self._config.LISTTAGS: for cls_name, cls in list(checks.items()): sys.stdout.write("{0:<20} {1}\n".format( cls_name, pydoc.getdoc(cls))) return addr_space = utils.load_as(self._config) # Only show threads owned by particular processes if self._config.PID: pidlist = [int(p) for p in self._config.PID.split(',')] else: pidlist = [] # Get sorted list of kernel modules mods = dict((mod.DllBase, mod) for mod in modules.lsmod(addr_space)) mod_addrs = sorted(mods.keys()) # Gather processes all_tasks = list(tasks.pslist(addr_space)) # Are we on x86 or x64. Save this for render_text self.bits32 = addr_space.profile.metadata.\ get("memory_model", "32bit") == "32bit" # Get a list of hooked SSDTs but only on x86 if self.bits32: hooked_tables = self.get_hooked_tables(addr_space) else: hooked_tables = None # Dictionary to store threads. Keys are physical offsets of # ETHREAD objects. Values are tuples, where the first item is # a boolean specifying if the object was found by scanning and # the second item is the actual ETHREAD object. seen_threads = dict() # Gather threads by list traversal of active/linked processes for task in self.filter_tasks(all_tasks): for thread in task.ThreadListHead.\ list_of_type("_ETHREAD", "ThreadListEntry"): seen_threads[thread.obj_vm.vtop(thread.obj_offset)] = (False, thread) # Now scan for threads and save any that haven't been seen for thread in modscan.ThrdScan(self._config).calculate(): if thread.obj_offset not in seen_threads: seen_threads[thread.obj_offset] = (True, thread) for _offset, (found_by_scanner, thread) in list(seen_threads.items()): # Skip processes the user doesn't want to see if pidlist and thread.Cid.UniqueProcess not in pidlist: continue # Replace the dummy class with an instance for cls_name, cls in list(checks.items()): instances = dict((cls_name, cls(thread, mods, mod_addrs, hooked_tables, found_by_scanner)) for cls_name, cls in list(checks.items())) yield thread, addr_space, mods, mod_addrs, instances, hooked_tables
def calculate(self): if not has_distorm3: debug.warning("For best results please install distorm3") # Checks that subclass AbstractThreadCheck checks = registry.get_plugin_classes(AbstractThreadCheck) # If --listtags is chosen, just print the tags and return if self._config.LISTTAGS: for cls_name, cls in checks.items(): sys.stdout.write("{0:<20} {1}\n".format(cls_name, pydoc.getdoc(cls))) return addr_space = utils.load_as(self._config) system_range = tasks.get_kdbg(addr_space).MmSystemRangeStart.dereference_as("Pointer") # Only show threads owned by particular processes pidlist = [] if self._config.PID: pidlist = [int(p) for p in self._config.PID.split(',')] elif self._config.OFFSET: process = self.virtual_process_from_physical_offset(addr_space, self._config.OFFSET) if process: pidlist = [int(process.UniqueProcessId)] # Get sorted list of kernel modules mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in modules.lsmod(addr_space)) mod_addrs = sorted(mods.keys()) # Are we on x86 or x64. Save this for render_text self.bits32 = addr_space.profile.metadata.\ get("memory_model", "32bit") == "32bit" # Get a list of hooked SSDTs but only on x86 if self.bits32: hooked_tables = self.get_hooked_tables(addr_space) else: hooked_tables = None # Dictionary to store threads. Keys are physical offsets of # ETHREAD objects. Values are tuples, where the first item is # a boolean specifying if the object was found by scanning and # the second item is the actual ETHREAD object. seen_threads = dict() # Gather threads by list traversal of active/linked processes for task in taskmods.DllList(self._config).calculate(): for thread in task.ThreadListHead.\ list_of_type("_ETHREAD", "ThreadListEntry"): seen_threads[thread.obj_vm.vtop(thread.obj_offset)] = (False, thread) # Now scan for threads and save any that haven't been seen for thread in modscan.ThrdScan(self._config).calculate(): if not seen_threads.has_key(thread.obj_offset): seen_threads[thread.obj_offset] = (True, thread) # Keep a record of processes whose DLLs we've already enumerated process_dll_info = {} for _offset, (found_by_scanner, thread) in seen_threads.items(): # Skip processes the user doesn't want to see if ((self._config.PID or self._config.OFFSET) and not pidlist) or (pidlist and thread.Cid.UniqueProcess not in pidlist): continue # Do we need to gather DLLs for module resolution if addr_space.address_compare(thread.StartAddress, system_range) != -1: owner = tasks.find_module(mods, mod_addrs, addr_space.address_mask(thread.StartAddress)) else: owning_process = thread.owning_process() if not owning_process.is_valid(): owner = None else: try: user_mod_addrs, user_mods = process_dll_info[owning_process.obj_offset] except KeyError: user_mods = dict((addr_space.address_mask(mod.DllBase), mod) for mod in owning_process.get_load_modules()) user_mod_addrs = sorted(user_mods.keys()) process_dll_info[owning_process.obj_offset] = (user_mod_addrs, user_mods) owner = tasks.find_module(user_mods, user_mod_addrs, addr_space.address_mask(thread.StartAddress)) if owner: owner_name = str(owner.BaseDllName or '') else: owner_name = "UNKNOWN" # Replace the dummy class with an instance instances = dict( (cls_name, cls(thread, mods, mod_addrs, hooked_tables, found_by_scanner)) for cls_name, cls in checks.items() ) yield thread, addr_space, mods, mod_addrs, \ instances, hooked_tables, system_range, owner_name
def calculate(self): if self._config.OUTPUT == "xlsx" and not has_openpyxl: debug.error( "You must install OpenPyxl for xlsx format:\n\thttps://bitbucket.org/ericgazoni/openpyxl/wiki/Home" ) elif self._config.OUTPUT == "xlsx" and not self._config.OUTPUT_FILE: debug.error( "You must specify an output *.xlsx file!\n\t(Example: --output-file=OUTPUT.xlsx)" ) if (self._config.HIVE or self._config.USER) and not (self._config.REGISTRY): debug.error( "You must use -R/--registry in conjuction with -H/--hive and/or -U/--user" ) addr_space = utils.load_as(self._config) version = (addr_space.profile.metadata.get('major', 0), addr_space.profile.metadata.get('minor', 0)) pids = {} #dictionary of process IDs/ImageFileName offsets = [] #process offsets im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) body = False if self._config.OUTPUT == "body": body = True if not body: event = "{0}|[END LIVE RESPONSE]\n".format(im['ImageDatetime']) else: event = "0|[END LIVE RESPONSE]|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( im['ImageDatetime'].v()) yield event # Get EPROCESS psscan = filescan.PSScan(self._config).calculate() for eprocess in psscan: if eprocess.obj_offset not in offsets: offsets.append(eprocess.obj_offset) if not body: line = "{0}|{1}|{2}|{3}|{4}|{5}|0x{6:08x}||\n".format( eprocess.CreateTime or '-1', "[PROCESS]", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.ExitTime or '', eprocess.obj_offset) else: line = "0|[PROCESS] {2}/PID: {3}/PPID: {4}/POffset: 0x{5:08x}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( eprocess.CreateTime.v(), eprocess.ExitTime.v(), eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, eprocess.obj_offset) pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName yield line # Get Sockets and Evtlogs XP/2k3 only if addr_space.profile.metadata.get('major', 0) == 5: socks = sockets.Sockets(self._config).calculate() #socks = sockscan.SockScan(self._config).calculate() # you can use sockscan instead if you uncomment for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) if not body: line = "{0}|[SOCKET]|{1}|{2}|Protocol: {3} ({4})|{5:#010x}|||\n".format( sock.CreateTime, sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) else: line = "0|[SOCKET] PID: {1}/LocalIP: {2}/Protocol: {3}({4})/POffset: 0x{5:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( sock.CreateTime.v(), sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset) yield line evt = evtlogs.EvtLogs(self._config) stuff = evt.calculate() for name, buf in stuff: for fields in evt.parse_evt_info(name, buf, rawtime=True): if not body: line = '{0} |[EVT LOG]|{1}|{2}|{3}|{4}|{5}|{6}|{7}\n'.format( fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) else: line = "0|[EVT LOG] {1}/{2}/{3}/{4}/{5}/{6}/{7}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( fields[0].v(), fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7]) yield line else: # Vista+ nets = netscan.Netscan(self._config).calculate() for net_object, proto, laddr, lport, raddr, rport, state in nets: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) if not body: line = "{0}|[NETWORK CONNECTION]|{1}|{2}|{3}|{4}|{5:<#10x}||\n".format( str(net_object.CreateTime or "-1"), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) else: line = "0|[NETWORK CONNECTION] {1}/{2}/{3}/{4}/{5:<#10x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( net_object.CreateTime.v(), net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset) yield line # Get threads threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") if not body: line = "{0}|[THREAD]|{1}|{2}|{3}|{4}|||\n".format( thread.CreateTime or '-1', image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, thread.ExitTime or '', ) else: line = "0|[THREAD] {2}/PID: {3}/TID: {4}|0|---------------|0|0|0|{0}|{1}|{0}|{0}\n".format( thread.CreateTime.v(), thread.ExitTime.v(), image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, ) yield line # now we get to the PE part. All PE's are dumped in case you want to inspect them later data = moddump.ModDump(self._config).calculate() for addr_space, procs, mod_base, mod_name in data: mod_name = str(mod_name or '') space = tasks.find_space(addr_space, procs, mod_base) if space != None: try: header = procdump.ProcExeDump(self._config).get_nt_header( space, mod_base) except ValueError, ve: continue try: if not body: line = "{0}|[PE Timestamp (module)]|{1}||{2:#010x}|||||\n".format( header.FileHeader.TimeDateStamp or '-1', mod_name, mod_base) else: line = "0|[PE Timestamp (module)] {1}/Base: {2:#010x}|0|---------------|0|0|0|{0}|{0}|{0}|{0}\n".format( header.FileHeader.TimeDateStamp.v(), mod_name, mod_base) except ValueError, ve: if not body: line = "-1|[PE Timestamp (module)]|{0}||{1}|||||\n".format( mod_name, mod_base) else: line = "0|[PE Timestamp (module)] {0}/Base: {1:#010x}|0|---------------|0|0|0|0|0|0|0\n".format( mod_name, mod_base) yield line
def calculate(self): space = utils.load_as(self._config) # enumerate system threads (0x00000010 = PS_CROSS_THREAD_FLAGS_SYSTEM) system_threads = [ t for t in modscan.ThrdScan(self._config).calculate() if t.CrossThreadFlags & 0x00000010 ] # find and dump the malicious kernel driver for item in filescan.DriverScan(self._config).calculate(): # unpack the parameters (object, driver, extension, object_name) = item # looking for unnamed driver objects if driver.DriverName.Length != 0: continue # the first and only device should be ACPI#PNP[...] device = obj.Object("_DEVICE_OBJECT", offset=driver.DeviceObject, vm=space) # get the device's object header object = obj.Object("_OBJECT_HEADER", \ offset = device.obj_offset - \ device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"), \ vm = space) object.kas = space device_name = object.get_object_name() # did we find zeroaccess? if not str(device_name).startswith("ACPI#PNP"): continue sys.stdout.write("DriverObject: {0:#x}\n".format( device.DriverObject)) sys.stdout.write(" DriverStart: {0:#x}\n".format( driver.DriverStart)) sys.stdout.write(" DriverSize: {0:#x}\n".format( driver.DriverSize)) sys.stdout.write("DeviceObject: {0:#x} {1}\n".format( device.obj_offset, device_name)) # dump the driver file_name = "Driver.{0:#x}.sys".format(driver.DriverStart) self.dump_pe(space, driver.DriverStart, file_name) # now what we know the memory range, look for bad threads for thread in system_threads: if thread.StartAddress > driver.DriverStart and \ thread.StartAddress < driver.DriverStart + driver.DriverSize: sys.stdout.write("Bad Thread: {0:#x} Tid {1}\n".format(\ thread.obj_offset, thread.Cid.UniqueThread)) # now find and dump the fake usermode ADS process for proc in tasks.pslist(space): for dll in proc.Peb.Ldr.InLoadOrderModuleList.list_of_type(\ "_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks"): # look for the ADS name if str(dll.BaseDllName).find(":") != -1: sys.stdout.write("Fake ADS EXE: {0} pid {1} base {2:#x}\n".format(\ proc.ImageFileName, proc.UniqueProcessId, dll.DllBase)) file_name = "Dll.{0:#x}.{1:#x}.dll".format( proc.obj_offset, dll.DllBase) self.dump_pe(proc.get_process_address_space(), dll.DllBase, file_name)
def calculate(self): if (self._config.HIVE or self._config.USER) and "Registry" not in self._config.TYPE: debug.error( "You must use --registry in conjuction with -H/--hive and/or -U/--user" ) if self._config.TYPE != None: for t in self._config.TYPE.split(","): if t.strip() not in self.types and t.strip() != "Registry": debug.error( "You have entered an incorrect type: {0}".format(t)) addr_space = utils.load_as(self._config) version = ( addr_space.profile.metadata.get('major', 0), addr_space.profile.metadata.get('minor', 0), ) pids = {} # dictionary of process IDs/ImageFileName body = False if self._config.OUTPUT == "body": body = True if self._config.MACHINE != "": self._config.update("MACHINE", "{0} ".format(self._config.MACHINE)) if "ImageDate" in self._config.TYPE: im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) yield self.getoutput( "[{0}LIVE RESPONSE]{1} (System time){1}".format( self._config.MACHINE, "" if body else "|"), im['ImageDatetime'], body=body, ) if version <= (6, 1) and "IEHistory" in self._config.TYPE: self._config.update("LEAK", True) data = iehistory.IEHistory(self._config).calculate() for process, record in data: ## Extended fields are available for these records if record.obj_name == "_URL_RECORD": line = "[{6}IEHISTORY]{0} {1}->{5}{0} PID: {2}/Cache type \"{3}\" at {4:#x}".format( "" if body else "|", process.ImageFileName, process.UniqueProcessId, record.Signature, record.obj_offset, record.Url, self._config.MACHINE, ) yield self.getoutput( line, record.LastModified, end=record.LastAccessed, body=body, ) self._config.remove_option("REDR") self._config.remove_option("LEAK") psx = [] if ("Process" in self._config.Type or "TimeDateStamp" in self._config.Type or "LoadTime" in self._config.Type or "_CM_KEY_BODY" in self._config.Type): psx = psxview.PsXview(self._config).calculate() for offset, eprocess, ps_sources in psx: pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName if "Process" in self._config.TYPE: line = "[{5}PROCESS]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput(line, eprocess.CreateTime, end=eprocess.ExitTime, body=body) if not hasattr(eprocess.obj_vm, "vtop"): eprocess = taskmods.DllList( self._config).virtual_process_from_physical_offset( addr_space, eprocess.obj_offset) if eprocess == None: continue else: ps_ad = eprocess.get_process_address_space() if ps_ad == None: continue if version[0] == 5 and "Process" in self._config.TYPE: line = "[{5}PROCESS LastTrimTime]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput(line, eprocess.Vm.LastTrimTime, body=body) if (eprocess.ObjectTable.HandleTableList and "_CM_KEY_BODY" in self._config.TYPE): for handle in eprocess.ObjectTable.handles(): if not handle.is_valid(): continue name = "" object_type = handle.get_object_type() if object_type == "Key": key_obj = handle.dereference_as("_CM_KEY_BODY") name = key_obj.full_key_name() line = "[{6}Handle (Key)]{0} {1}{0} {2} PID: {3}/PPID: {4}/POffset: 0x{5:08x}".format( "" if body else "|", name, eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput( line, key_obj.KeyControlBlock.KcbLastWriteTime, body=body, ) if eprocess.Peb == None or eprocess.Peb.ImageBaseAddress == None: continue # Get DLL PE timestamps for Wow64 processes (excluding 64-bit ones) if eprocess.IsWow64 and "TimeDateStamp" in self._config.TYPE: for vad, address_space in eprocess.get_vads( vad_filter=eprocess._mapped_file_filter): if vad.FileObject.FileName: name = str(vad.FileObject.FileName).lower() basename = ntpath.basename(name) if not basename.endswith("dll") or basename in [ "wow64cpu.dll", "ntdll.dll", "wow64.dll", "wow64win.dll", ]: continue data = ps_ad.zread(vad.Start, vad.Length) bufferas = addrspace.BufferAddressSpace(self._config, data=data) try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset=0, vm=bufferas) header = pe_file.get_nt_header() except ValueError as ve: continue line = "[{7}PE HEADER 32-bit (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, vad.Start, self._config.MACHINE, ) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body) # get DLL PE timestamps mods = dict() if ("TimeDateStamp" in self._config.TYPE or "LoadTime" in self._config.TYPE): mods = dict((mod.DllBase.v(), mod) for mod in eprocess.get_load_modules()) for mod in list(mods.values()): basename = str(mod.BaseDllName or "") if basename == str(eprocess.ImageFileName): line = "[{7}PE HEADER (exe)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) else: line = "[{7}PE HEADER (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) if "TimeDateStamp" in self._config.TYPE: yield self.getoutput(line, mod.TimeDateStamp, body=body) line2 = "[{7}PE DEBUG]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) yield self.getoutput( line2, mod.get_debug_directory().TimeDateStamp, body=body, ) if (hasattr(mod, "LoadTime") and "LoadTime" in self._config.TYPE): temp = line.replace( "[{0}PE HEADER ".format(self._config.MACHINE), "[{0}DLL LOADTIME ".format(self._config.MACHINE), ) yield self.getoutput(temp, mod.LoadTime, body=body) # Get Sockets and Evtlogs XP/2k3 only if version[0] == 5: # socks = sockets.Sockets(self._config).calculate() socks = [] if "Socket" in self._config.TYPE: socks = sockscan.SockScan(self._config).calculate( ) # you can use sockscan instead if you uncomment for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) line = "[{6}SOCKET]{0} LocalIP: {2}/Protocol: {3}({4}){0} PID: {1}/POffset: 0x{5:#010x}".format( "" if body else "|", sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset, self._config.MACHINE, ) yield self.getoutput(line, sock.CreateTime, body=body) stuff = [] if "EvtLog" in self._config.TYPE: evt = evtlogs.EvtLogs(self._config) stuff = evt.calculate() for name, buf in stuff: for fields in evt.parse_evt_info(name, buf, rawtime=True): line = "[{8}EVT LOG]{0} {1}{0} {2}/{3}/{4}/{5}/{6}/{7}".format( "" if body else "|", fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7], self._config.MACHINE, ) yield self.getoutput(line, fields[0], body=body) elif version <= (6, 1): # Vista+ nets = [] if "Socket" in self._config.TYPE: nets = netscan.Netscan(self._config).calculate() for net_object, proto, laddr, lport, raddr, rport, state in nets: if net_object.CreateTime.v() == 0: continue if raddr == "*" and rport == "*": conn = "{0}:{1}".format(laddr, lport) socket_type = "SOCKET" else: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) socket_TYPE = "CONNECTION" line = ( "[{6}NETWORK {7}]{0} {2}{0} {1}/{3}/{4}/{5:<#10x}".format( "" if body else "|", net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset, self._config.MACHINE, socket_type, )) yield self.getoutput(line, net_object.CreateTime, body=body) # Get threads threads = [] if "Thread" in self._config.TYPE: threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") line = "[{4}THREAD]{0} {1}{0} PID: {2}/TID: {3}".format( "" if body else "|", image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, self._config.MACHINE, ) yield self.getoutput(line, thread.CreateTime, end=thread.ExitTime, body=body) data = [] if "Symlink" in self._config.TYPE: data = filescan.SymLinkScan(self._config).calculate() for link in data: objct = link.get_object_header() line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format( "" if body else "|", str(objct.NameInfo.Name or ''), str(link.LinkTarget or ''), link.obj_offset, objct.PointerCount, objct.HandleCount, self._config.MACHINE, ) yield self.getoutput(line, link.CreationTime, body=body) data = [] if "TimeDateStamp" in self._config.TYPE: data = moddump.ModDump(self._config).calculate() for aspace, procs, mod_base, mod_name in data: mod_name = str(mod_name or '') space = tasks.find_space(aspace, procs, mod_base) if space != None: try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset=mod_base, vm=space) header = pe_file.get_nt_header() except ValueError as ve: continue line = ( "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format( "" if body else "|", mod_name, mod_base, self._config.MACHINE, )) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body) uastuff = [] if "Userassist" in self._config.TYPE: uastuff = userassist.UserAssist(self._config).calculate() for win7, reg, key in uastuff: ts = "{0}".format(key.LastWriteTime) for v in rawreg.values(key): tp, dat = rawreg.value_data(v) subname = v.Name if tp == 'REG_BINARY': dat_raw = dat try: subname = codecs.encode(subname, 'rot_13') except UnicodeDecodeError: pass if win7: guid = subname.split("\\")[0] if guid in userassist.folder_guids: subname = subname.replace( guid, userassist.folder_guids[guid]) bufferas = addrspace.BufferAddressSpace(self._config, data=dat_raw) uadata = obj.Object("_VOLUSER_ASSIST_TYPES", offset=0, vm=bufferas) ID = "N/A" count = "N/A" fc = "N/A" tf = "N/A" lw = "N/A" if (len(dat_raw) < bufferas.profile.get_obj_size( '_VOLUSER_ASSIST_TYPES') or uadata == None): continue else: if hasattr(uadata, "ID"): ID = "{0}".format(uadata.ID) if hasattr(uadata, "Count"): count = "{0}".format(uadata.Count) else: count = "{0}".format( uadata.CountStartingAtFive if uadata.CountStartingAtFive < 5 else uadata.CountStartingAtFive - 5) if hasattr(uadata, "FocusCount"): seconds = (uadata.FocusTime + 500) / 1000.0 time = (datetime.timedelta(seconds=seconds) if seconds > 0 else uadata.FocusTime) fc = "{0}".format(uadata.FocusCount) tf = "{0}".format(time) lw = "{0}".format(uadata.LastUpdated) subname = subname.replace("|", "%7c") line = "[{7}USER ASSIST]{0} {2}{0} Registry: {1}/ID: {3}/Count: {4}/FocusCount: {5}/TimeFocused: {6}".format( "" if body else "|", reg, subname, ID, count, fc, tf, self._config.MACHINE, ) yield self.getoutput(line, uadata.LastUpdated, body=body) shimdata = [] if "Shimcache" in self._config.TYPE: shimdata = shimcache.ShimCache(self._config).calculate() for path, lm, lu in shimdata: line = "[{2}SHIMCACHE]{0} {1}{0} ".format("" if body else "|", path, self._config.MACHINE) if lu: yield self.getoutput(line, lm, end=lu, body=body) else: yield self.getoutput(line, lm, body=body) if ("_HBASE_BLOCK" in self._config.TYPE or "_CMHIVE" in self._config.TYPE or "Registry" in self._config.TYPE): regapi = registryapi.RegistryApi(self._config) for o in regapi.all_offsets: if "_HBASE_BLOCK" in self._config.TYPE: line = "[{2}_HBASE_BLOCK TimeStamp]{0} {1}{0} ".format( "" if body else "|", regapi.all_offsets[o], self._config.MACHINE, ) h = obj.Object("_HHIVE", o, addr_space) yield self.getoutput(line, h.BaseBlock.TimeStamp, body=body) if ("_CMHIVE" in self._config.TYPE and version[0] == 6 and addr_space.profile.metadata.get('build', 0) >= 7601): line = ( line) = "[{2}_CMHIVE LastWriteTime]{0} {1}{0} ".format( "" if body else "|", regapi.all_offsets[o], self._config.MACHINE, ) cmhive = obj.Object("_CMHIVE", o, addr_space) yield self.getoutput(line, cmhive.LastWriteTime, body=body) if "Registry" in self._config.TYPE: regapi.reset_current() regdata = regapi.reg_get_all_keys(self._config.HIVE, self._config.USER, reg=True, rawtime=True) for lwtime, reg, item in regdata: item = item.replace("|", "%7c") line = "[{3}REGISTRY]{0} {2}{0} Registry: {1}".format( "" if body else "|", reg, item, self._config.MACHINE) yield self.getoutput(line, lwtime, body=body) if "Timer" in self._config.TYPE: volmagic = obj.VolMagic(addr_space) KUSER_SHARED_DATA = obj.Object( "_KUSER_SHARED_DATA", offset=volmagic.KUSER_SHARED_DATA.v(), vm=addr_space, ) interrupt = (KUSER_SHARED_DATA.InterruptTime.High1Time << 32) | KUSER_SHARED_DATA.InterruptTime.LowPart now = KUSER_SHARED_DATA.SystemTime.as_windows_timestamp() data = timers.Timers(self._config).calculate() for timer, module in data: signaled = "-" if timer.Header.SignalState.v(): signaled = "Yes" module_name = "UNKNOWN" if module: module_name = str(module.BaseDllName or '') try: # human readable time taken from http://computer.forensikblog.de/en/2011/10/timers-and-times.html bufferas = addrspace.BufferAddressSpace( self._config, data=struct.pack( '<Q', timer.DueTime.QuadPart - interrupt + now), ) due_time = obj.Object("WinTimeStamp", is_utc=True, offset=0, vm=bufferas) except TypeError: due_time = 0 line = "[{6}TIMER]{0} {1}{0} Signaled: {2}/Routine: 0x{3:x}/Period(ms): {4}/Offset: 0x{5:x}".format( "" if body else "|", module_name, signaled, timer.Dpc.DeferredRoutine, timer.Period, timer.obj_offset, self._config.MACHINE, ) yield self.getoutput(line, due_time, body=body)