def calculate(self): ## Select the tags to scan for. Always find visited URLs, ## but make freed and redirected records optional. tags = ["URL "] if self._config.LEAK: tags.append("LEAK") if self._config.REDR: tags.append("REDR") ## Define the record type based on the tag tag_records = { "URL ": "_URL_RECORD", "LEAK": "_URL_RECORD", "REDR": "_REDR_RECORD" } ## Enumerate processes based on the --pid and --offset for proc in taskmods.DllList(self._config).calculate(): ## Acquire a process specific AS ps_as = proc.get_process_address_space() for hit in proc.search_process_memory(tags): ## Get a preview of the data to see what tag was detected tag = ps_as.read(hit, 4) ## Create the appropriate object type based on the tag record = obj.Object(tag_records[tag], offset=hit, vm=ps_as) if record.is_valid(): yield proc, record
def calculate(self): ## Select the tags to scan for. Always find visited URLs, ## but make freed and redirected records optional. tags = ["URL ", "DEST"] if self._config.LEAK: tags.append("LEAK") if self._config.REDR: tags.append("REDR") ## Define the record type based on the tag tag_records = { "URL ": "_URL_RECORD", "LEAK": "_URL_RECORD", "REDR": "_REDR_RECORD", "DEST": "_DEST_RECORD" } vad_filter = lambda x: (hasattr(x, 'ControlArea') and str( x.FileObject.FileName or '').endswith("index.dat")) or ( x.VadFlags.Protection.v() == 4) ## Enumerate processes based on the --pid and --offset for proc in taskmods.DllList(self._config).calculate(): ## Acquire a process specific AS ps_as = proc.get_process_address_space() for hit in proc.search_process_memory(tags, vad_filter=vad_filter): ## Get a preview of the data to see what tag was detected tag = ps_as.read(hit, 4) ## Create the appropriate object type based on the tag record = obj.Object(tag_records[tag], offset=hit, vm=ps_as) if record.is_valid(): yield proc, record
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
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 "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)) detections = False if self._config.OUTPUT == "xlsx" and self._config.HIGHLIGHT != None: detections = True 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)".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 detections and "Process" in self._config.TYPE: injected = False for vad, address_space in eprocess.get_vads( vad_filter=eprocess._injection_filter): if malfind.Malfind(self._config)._is_vad_empty( vad, address_space): continue line = "PID: {0}/PPID: {1}/POffset: 0x{2:08x}".format( eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset) self.suspicious[line.strip()] = { "reason": "MALFIND", "color": "RED" } self.suspiciouspids[eprocess.UniqueProcessId.v()] = { "reason": "MALFIND", "color": "RED" } injected = True proc_okay = False if not injected and (eprocess.ExitTime.v() > 0 or str(eprocess.ImageFileName).lower() in ["system", "smss.exe", "csrss.exe"]): proc_okay = True elif not injected and ps_sources['psscan'].has_key(offset) and (not ps_sources['pslist'].has_key(offset) or not \ ps_sources['thrdproc'].has_key(offset) or not ps_sources['pspcid'].has_key(offset) or not \ ps_sources['csrss'].has_key(offset) or not ps_sources['session'].has_key(offset) or not \ ps_sources['deskthrd'].has_key(offset)): proc_okay = True if not proc_okay and (not ps_sources['pslist'].has_key(offset) or not ps_sources['psscan'].has_key(offset) or not ps_sources['thrdproc'].has_key(offset) \ or not ps_sources['pspcid'].has_key(offset) or not ps_sources['csrss'].has_key(offset) or not ps_sources['session'].has_key(offset) \ or not ps_sources['deskthrd'].has_key(offset)): if self.suspicious.get(line.strip(), {}).get("reason", None) == None: self.suspicious[line.strip()] = { "reason": "PSXVIEW", "color": "RED" } self.suspiciouspids[eprocess.UniqueProcessId.v()] = { "reason": "PSXVIEW", "color": "RED" } else: self.suspicious[line.strip()] = { "reason": "MALFIND and PSXVIEW", "color": "RED" } self.suspiciouspids[eprocess.UniqueProcessId.v()] = { "reason": "MALFIND and PSXVIEW", "color": "RED" } 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, 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 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.TimeDateStamp, end=mod.LoadTime, body=body) if detections and eprocess.UniqueProcessId.v( ) in self.suspiciouspids.keys(): suspiciousline = "Process: {0}/PID: {1}/PPID: {2}/Process POffset: 0x{3:08x}/DLL Base: 0x{4:08x}".format( eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, mod.DllBase.v()) self.suspicious[suspiciousline] = { "reason": "Process flagged: " + self.suspiciouspids[ eprocess.UniqueProcessId.v()]["reason"], "color": "BLUE" }
def render_text(self, outfd, data): mal_ids = [] for mal_process, addr, magic_keyword, encrypted, decrypted, os_version in data: outfd.write("Gh0stRat Variant: {0}\n".format(magic_keyword)) for proc in mal_process: outfd.write("Malicious Process: {0}(pid:{1})\n".format( proc, str(mal_process[proc]))) mal_ids.append((proc, mal_process[proc])) outfd.write("Gh0strat Encrypted Communicaton:\n") outfd.write("-" * 78 + "\n") outfd.write("".join([ "{0:#010x} {1:<48} {2}\n".format(addr + o, h, ''.join(c)) for o, h, c in utils.Hexdump(encrypted) ])) outfd.write("\n") outfd.write("Decrypted Communication:\n") outfd.write("-" * 78 + "\n") outfd.write("".join([ "{0:#010x} {1:<48} {2}\n".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(decrypted) ])) outfd.write("\n") for proc, pid in list(set(mal_ids)): if os_version == 5: outfd.write( "connections - Network Connections of Malicious Process:\n" ) outfd.write("-" * 78 + "\n") net_con = Connections(self._config) net_connections = net_con.calculate() for tcp_obj in net_connections: if tcp_obj.Pid == pid: local = "{0}:{1}".format(tcp_obj.LocalIpAddress, tcp_obj.LocalPort) remote = "{0}:{1}".format(tcp_obj.RemoteIpAddress, tcp_obj.RemotePort) outfd.write("{0}\t{1}\t{2}(pid:{3})\n".format( local, remote, proc, tcp_obj.Pid)) outfd.write("\n") outfd.write( "connscan - Network Connections of Malicious Process:\n") outfd.write("-" * 78 + "\n") net_scan = ConnScan(self._config) net_connscan = net_scan.calculate() for tcp_obj in net_connscan: if tcp_obj.Pid == pid: local = "{0}:{1}".format(tcp_obj.LocalIpAddress, tcp_obj.LocalPort) remote = "{0}:{1}".format(tcp_obj.RemoteIpAddress, tcp_obj.RemotePort) outfd.write("{0}\t{1}\t{2}(pid:{3})\n".format( local, remote, proc, tcp_obj.Pid)) outfd.write("\n") elif os_version == 6: outfd.write( "netscan - Network Connections of Malicious Process({0} - pid:{1}):\n" .format(proc, pid)) outfd.write("-" * 78 + "\n") network = Netscan(self._config) net_data = network.calculate() outfd.write( "{0:<10} {1:<8} {2:<30} {3:<20} {4:<16} {5:<8} {6:<14} {7}\n" .format("Offset(P)", "Proto", "Local Address", "Foreign Address", "State", "Pid", "Owner", "Created")) for net_object, proto, laddr, lport, raddr, rport, state in net_data: if net_object.Owner.UniqueProcessId == pid: lendpoint = "{0}:{1}".format(laddr, lport) rendpoint = "{0}:{1}".format(raddr, rport) print( "{0:<#10x} {1:<8} {2:<30} {3:<20} {4:<16} {5:<8} {6:<14} {7}\n" .format(net_object.obj_offset, proto, lendpoint, rendpoint, state, net_object.Owner.UniqueProcessId, net_object.Owner.ImageFileName, str(net_object.CreateTime or ''))) outfd.write("\n") outfd.write("DLL's Loaded by the Malicious Process:\n") outfd.write("-" * 78 + "\n") self._config.PID = str(pid) dl = taskmods.DllList(self._config) dldata = dl.calculate() dl.render_text(outfd, dldata)
def calculate(self): if self._config.BASELINEIMG == None: print "Baseline image required!" sys.exit(-1) if self._config.ONLYKNOWN and self._config.ONLYUNKNOWN: print "Select only one of the options (-K, -U)!" sys.exit(-1) ####################################### #Searching for processes in the baseline image ###################################### # Saving original image orig_img = self._config.LOCATION # Setting up baseline image self._config.LOCATION = "file://" + self._config.BASELINEIMG addr_space = utils.load_as(self._config) dlllist = taskmods.DllList(self._config) for task in dlllist.calculate(): if task.ProcessExiting != 0: # We don't care about the exited processes continue proc = None if task.Peb == None: continue #if str(task.ImageFileName).lower() not in self.baseline_proc_list: if str(task.Peb.ProcessParameters.ImagePathName).lower( ) not in self.baseline_proc_list: # We haven't seen the process yet # Let's create a new object and add it proc = { 'pid': [], 'ppid': [], 'image': str(task.ImageFileName).lower() or '', 'path': str(task.Peb.ProcessParameters.ImagePathName).lower() if task.Peb.ProcessParameters != None else '', 'cmd': str(task.Peb.ProcessParameters.CommandLine).lower() if task.Peb.ProcessParameters != None else '', 'offset': [], 'exited': [], 'dlls': { 'load': {}, # load list 'mem': {}, # mem list 'init': {}, # init list 'comb': {}, # combined list, contains all dlls 'vad': {} # vad list } } #self.baseline_proc_list[proc['image']] = proc self.baseline_proc_list[proc['path']] = proc # Get process from our list #proc = self.baseline_proc_list[str(task.ImageFileName).lower()] proc = self.baseline_proc_list[str( task.Peb.ProcessParameters.ImagePathName).lower()] proc['pid'].append(task.UniqueProcessId) proc['ppid'].append(task.InheritedFromUniqueProcessId) proc['offset'].append(task.obj_offset) for m in task.get_load_modules(): mod = { 'dll': str(m.FullDllName).lower(), 'base': m.DllBase.v(), 'size': m.SizeOfImage or -1 } if mod['dll'] not in proc['dlls']['load']: proc['dlls']['load'][mod['dll']] = mod if mod['dll'] not in proc['dlls']['comb']: proc['dlls']['comb'][mod['dll']] = mod for m in task.get_mem_modules(): mod = { 'dll': str(m.FullDllName).lower(), 'base': m.DllBase.v(), 'size': m.SizeOfImage or -1 } if mod['dll'] not in proc['dlls']['mem']: proc['dlls']['mem'][mod['dll']] = mod if mod['dll'] not in proc['dlls']['comb']: proc['dlls']['comb'][mod['dll']] = mod for m in task.get_init_modules(): mod = { 'dll': str(m.FullDllName).lower(), 'base': m.DllBase.v(), 'size': m.SizeOfImage or -1 } if mod['dll'] not in proc['dlls']['init']: proc['dlls']['init'][mod['dll']] = mod if mod['dll'] not in proc['dlls']['comb']: proc['dlls']['comb'][mod['dll']] = mod # Check VADs # Add only the missing modules for vad, address_space in task.get_vads( vad_filter=task._mapped_file_filter): if obj.Object("_IMAGE_DOS_HEADER", offset=vad.Start, vm=address_space).e_magic != 0x5A4D: continue mod = { 'dll': str(vad.FileObject.FileName or '').lower(), 'base': int(vad.Start), 'size': int(vad.Length) } if mod['dll'] not in proc['dlls']['vad']: proc['dlls']['vad'][mod['dll']] = mod f = False for m in proc['dlls']['comb']: if proc['dlls']['comb'][m]['base'] == mod['base']: f = True if not f: proc['dlls']['comb'][mod['dll']] = mod #################################### #Searching for processes in the image to be analyzed ################################## # Restoring original image self._config.LOCATION = orig_img addr_space = utils.load_as(self._config) dlllist = taskmods.DllList(self._config) for task in dlllist.calculate(): if task.Peb == None: continue proc = { 'pid': task.UniqueProcessId, 'ppid': task.InheritedFromUniqueProcessId, 'image': str(task.ImageFileName).lower(), 'path': str(task.Peb.ProcessParameters.ImagePathName).lower() if task.Peb.ProcessParameters != None else '', 'cmd': str(task.Peb.ProcessParameters.CommandLine).lower() if task.Peb.ProcessParameters != None else '', 'offset': task.obj_offset, 'dlls': { 'load': {}, 'mem': {}, 'init': {}, 'comb': {}, 'vad': {} } } for m in task.get_load_modules(): mod = { 'dll': str(m.FullDllName).lower(), 'base': m.DllBase.v(), 'size': m.SizeOfImage or -1 } proc['dlls']['load'][mod['dll']] = mod proc['dlls']['comb'][mod['dll']] = mod for m in task.get_mem_modules(): mod = { 'dll': str(m.FullDllName).lower(), 'base': m.DllBase.v(), 'size': m.SizeOfImage or -1 } proc['dlls']['mem'][mod['dll']] = mod if mod['dll'] not in proc['dlls']['comb']: proc['dlls']['comb'][mod['dll']] = mod for m in task.get_init_modules(): mod = { 'dll': str(m.FullDllName).lower(), 'base': m.DllBase.v(), 'size': m.SizeOfImage or -1 } proc['dlls']['init'][mod['dll']] = mod if mod['dll'] not in proc['dlls']['comb']: proc['dlls']['comb'][mod['dll']] = mod # Check the VADs # Add only the missing modules for vad, address_space in task.get_vads( vad_filter=task._mapped_file_filter): if obj.Object("_IMAGE_DOS_HEADER", offset=vad.Start, vm=address_space).e_magic != 0x5A4D: continue mod = { 'dll': str(vad.FileObject.FileName or '').lower(), 'base': int(vad.Start), 'size': int(vad.Length) } proc['dlls']['vad'][mod['dll']] = mod f = False for m in proc['dlls']['comb']: if proc['dlls']['comb'][m]['base'] == mod['base']: f = True if not f: proc['dlls']['comb'][mod['dll']] = mod self.image_proc_list.append(proc) # Compare the lists for task in self.image_proc_list: # Check all the processes in the image #if task['path'] != '': image = task['path'] #else: # image = task['image'] p_found = False if image in self.baseline_proc_list: # If the process is found task_bl = self.baseline_proc_list[image] p_found = True if self._config.VERBOSE: for m in task['dlls']['comb']: # Check if we have the dll in our combined list of the baseline m_found = False for m_bl in self.baseline_proc_list[image]['dlls'][ 'comb']: if task['dlls']['comb'][m]['dll'] == task_bl[ 'dlls']['comb'][m_bl]['dll']: m_found = True # Check in which lists we can find it in the baseline m_l = False for m_bl in self.baseline_proc_list[image]['dlls'][ 'load']: if task['dlls']['comb'][m]['dll'] == task_bl[ 'dlls']['load'][m_bl]['dll']: m_l = True m_i = False for m_bl in self.baseline_proc_list[image]['dlls'][ 'init']: if task['dlls']['comb'][m]['dll'] == task_bl[ 'dlls']['init'][m_bl]['dll']: m_i = True m_m = False for m_bl in self.baseline_proc_list[image]['dlls'][ 'mem']: if task['dlls']['comb'][m]['dll'] == task_bl[ 'dlls']['mem'][m_bl]['dll']: m_m = True # Check in which lists we can find it in our image m_l_i = False if task['dlls']['comb'][m]['dll'] in task['dlls'][ 'load']: m_l_i = True m_i_i = False if task['dlls']['comb'][m]['dll'] in task['dlls'][ 'init']: m_i_i = True m_m_i = False if task['dlls']['comb'][m]['dll'] in task['dlls'][ 'mem']: m_m_i = True if not self._config.ONLYKNOWN and not self._config.ONLYUNKNOWN: yield (task, m, p_found, m_found, m_l, m_i, m_m, m_l_i, m_i_i, m_m_i) if self._config.ONLYKNOWN and m_found: yield (task, m, p_found, m_found, m_l, m_i, m_m, m_l_i, m_i_i, m_m_i) if self._config.ONLYUNKNOWN and not m_found: yield (task, m, p_found, m_found, m_l, m_i, m_m, m_l_i, m_i_i, m_m_i) else: if not self._config.ONLYKNOWN and not self._config.ONLYUNKNOWN: yield (task, p_found) if self._config.ONLYKNOWN and p_found: yield (task, p_found) if self._config.ONLYUNKNOWN and not p_found: yield (task, p_found) else: # The process is not in our baseline m_found = False if self._config.VERBOSE: for m in task['dlls']['comb']: m_l_i = False if task['dlls']['comb'][m]['dll'] in task['dlls'][ 'load']: m_l_i = True m_i_i = False if task['dlls']['comb'][m]['dll'] in task['dlls'][ 'init']: m_i_i = True m_m_i = False if task['dlls']['comb'][m]['dll'] in task['dlls'][ 'mem']: m_m_i = True if not self._config.ONLYKNOWN: yield (task, m, p_found, m_found, False, False, False, m_l_i, m_i_i, m_m_i) else: if not self._config.ONLYKNOWN: yield (task, p_found)
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.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, 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 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)
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)