def get_all(self): ''' Mimics Volatility's psxview, pslist, psscan, cmdline plugins ''' import volatility.plugins.malware.psxview as psxview for offset, process, ps_sources in psxview.PsXview( self.vol.config).calculate(): yield Process(process, ps_sources, offset)
def __getProcesses(self, scan=False): """ Intern method to scan the memory for processes. """ if not scan: plist = pslist(self.Memory) p = list(plist) else: _raw = [] for offset, process, _ in psxview.PsXview(self.config).calculate(): _raw.append(process) p = _raw return [Process(process, self.Memory) for process in p]
def start(self, args): if not with_volatility: raise RuntimeError("Volatility not found. Please install it") self.memdump = args["file"].value() self._config.updateCtx('location', "file://" + self.memdump.absolute()) self._config.updateCtx('filename', self.memdump.name()) self._config.updateCtx('debug', True) self.__processes = [] self.__dlls = {} self.__step = 1 self.__steps = 6 starttime = time.time() if args.has_key("profile"): self.stateinfo = "Using provided profile: " + args[ 'profile'].toString() self._config.updateCtx('profile', args['profile'].value()) self._aspace = utils.load_as(self._config) self._kdbg = tasks.get_kdbg(self._aspace) self._config.updateCtx('kdbg', self._kdbg.obj_offset) else: try: self.__guessProfile() except: traceback.print_exc() try: self.root = WinRootNode("Windows RAM", self.memdump, self) self.registerTree(self.memdump, self.root) self.__psxview = psxview.PsXview(self._config) self.__findConnections() self.__findProcesses() self.__createProcessTree() self.__createDlls() self.__createModules() self.__createProcessesVadTree() self.stateinfo = "" except: traceback.print_exc() aspace = self._aspace count = 0 if debug: while aspace: count += 1 print 'AS Layer', str( count), aspace.__class__.__name__, "(", aspace.name, ")" aspace = aspace.base print time.time() - starttime
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 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 do_action(self): ########################### # Memory analysis CACHE ########################### self.console_print("Calculating memory hash: "+self.filepath) hresult = self.sha256hash(self.filepath) self.console_print("SHA256: " + hresult) cache = False # WE CHECK IF THIS MEMORY HAS CACHE cache_process = hresult+"_"+"process" if os.path.exists(cache_process): with open (cache_process, 'r') as outfile: vprocess = json.load(outfile) cache = True outfile.close() cache_threads = hresult+"_"+"threads" if os.path.exists(cache_threads): with open (cache_threads, 'r') as outfile: vthreads = json.load(outfile) #cache = True outfile.close() cache_vads = hresult+"_"+"vads" if os.path.exists(cache_vads): with open (cache_vads, 'r') as outfile: vvads = json.load(outfile) #cache = True outfile.close() cache_tokens = hresult+"_"+"tokens" if os.path.exists(cache_tokens): with open (cache_tokens, 'r') as outfile: vtokens = json.load(outfile) #cache = True outfile.close() if cache: self.console_print("Using process cache file: "+cache_process) self.console_print("Using threads cache file: "+cache_threads) self.console_print("Using vads cache file: "+cache_vads) self.console_print("Using tokens cache file: "+cache_tokens) self.send_message(vprocess) self.send_message(vthreads) self.send_message(vvads) self.send_message(vtokens) self.terminate() ########################### # Get MachineGUID ########################### if self._running: self._config.KEY = 'Microsoft\\Cryptography' for reg,key in self.get_registry_keys(): if key: for v in rawreg.values(key): tp, dat = rawreg.value_data(v) if (v.Name == "MachineGuid"): self.machineguid = dat if self.machineguid == "": self.machineguid = "ffffffff-2cf2-4c6d-919d-686204658ab6" mg_vector = self.machineguid.split("-") computerid = mg_vector[0] self.console_print("MACHINEGUID detected: " + str(computerid)) ########################### # Plugin psxview volatility ########################### if self._running: proc = psxv.PsXview(self._config) pslist1 = {} vprocess = [] vthreads = [] vvads = [] vtokens = [] ## ## PRINCIPAL LOOP TO GET THE PROCESSES ## for offset, process, ps_sources in proc.calculate(): # Check if PEB structure is ready (psxview is a pool tag plugin) PEB = str(process.Peb) peb_empty = False if PEB == "": peb_empty = True # PEB pslist1['CommandLine'] = str(process.Peb.ProcessParameters.CommandLine).replace('\"','') pslist1['CurrentDirectory'] = str(process.Peb.ProcessParameters.CurrentDirectory.DosPath) pslist1['Image'] = str(process.Peb.ProcessParameters.ImagePathName) pslist1['BeingDebugged'] = str(process.Peb.BeingDebugged) pslist1['DllPath'] = str(process.Peb.ProcessParameters.DllPath) # EPROCESS pslist1['UtcTime'] = self.normalize_utc_time(str(process.CreateTime)) pslist1['ProcessId'] = str(int(process.UniqueProcessId)) pslist1['ParentProcessId'] = str(int(process.InheritedFromUniqueProcessId)) pslist1['TerminalSessionId'] = str(int(process.SessionId)) pslist1['ExitTime'] = str(process.ExitTime) pslist1['IsWow64'] = str(process.IsWow64) pslist1['NumHandles'] = str(int(process.ObjectTable.HandleCount)) pslist1['NumThreads'] = str(int(process.ActiveThreads)) pslist1['computer'] = computerid pslist1['Source'] = "Memory" pslist1['LogonGuid'] = "{" + computerid + "-0000-0000-0000-000000000000}" pslist1['idEvent'] = 1 pslist1['IntegrityLevel'] = "" # por calcular pslist1['User'] = "" # por calcular pslist1['ParentImage'] = "" pslist1['ParentCommandLine'] = "" pslist1['ParentProcessGuid'] = "" pslist1["UnknownThreads"] = "False" pslist1['PsList'] = str(offset in ps_sources["pslist"]) pslist1['PsScan'] = str(offset in ps_sources["psscan"]) pslist1['ThreadProc'] = str(offset in ps_sources["thrdproc"]) pslist1['PsPcid'] = str(offset in ps_sources["pspcid"]) pslist1['Csrss'] = str(offset in ps_sources["csrss"]) pslist1['Session'] = str(offset in ps_sources["session"]) pslist1['DeskThrd'] = str(offset in ps_sources["deskthrd"]) self.console_print("Extraction information of process with PID: "+str(pslist1['ProcessId'])) # Exception (I) If we don't find smss.exe in PEB structure, we get ImageFileName from EPROCESS. if pslist1['Image'] == "": pslist1['Image'] = str(process.ImageFileName) if pslist1['Image'] == "smss.exe": pslist1['CommandLine'] = "C:\\Windows\\System32\\smss.exe" pslist1['Image'] = "C:\\Windows\\System32\\smss.exe" pslist1['TerminalSessionId'] = "0" # Exception (II) Exception with terminated process if pslist1['ExitTime'] != "1970-01-01 00:00:00 UTC+0000": pslist1['Image'] = str(process.ImageFileName) pslist1['CommandLine'] = str(process.ImageFileName) # Exception (III) with kernel if pslist1['ProcessId'] == '4' and pslist1['TerminalSessionId'] == "-1": pslist1['Image'] = "system" pslist1['CommandLine'] = "system" pslist1['TerminalSessionId'] = "0" pslist1['IntegrityLevel'] = "System" pslist1['User'] = "******" # Exception (IV) with smss.exe if pslist1['Image'] == "\\SystemRoot\\System32\\smss.exe" and pslist1['TerminalSessionId'] == "-1": pslist1['CommandLine'] = "C:\\Windows\\System32\\smss.exe" pslist1['Image'] = "C:\\Windows\\System32\\smss.exe" pslist1['CurrentDirectory'] = "C:\\Windows\\System32\\" pslist1['TerminalSessionId'] = "0" # We build the "PROCESSGUID" to MERGE this event ID with Sysmon ################################################################ date_time_obj = datetime.datetime.strptime(pslist1["UtcTime"], '%Y-%m-%d %H:%M:%S.%f') epoch = datetime.datetime.utcfromtimestamp(0) t = (date_time_obj-epoch).total_seconds() hex_string = '{:02x}'.format(int(t)) firstpart, secondpart = hex_string[:len(hex_string)/2], hex_string[len(hex_string)/2:] if pslist1['Image'] != "" and pslist1['ProcessId'] != "": result2 = hashlib.md5(pslist1['computer']+"-"+secondpart+"-"+firstpart+"-"+pslist1['ProcessId']+pslist1['Image'].lower()) else: result2 = hashlib.md5(pslist1['computer']+"-"+secondpart+"-"+firstpart+"-"+"666666"+"C:\syspce\dummy.exe") syspceid_datetime = date_time_obj.strftime('%Y-%m-%d %H:%M:%S') result = hashlib.md5(pslist1["ProcessId"]+pslist1["ParentProcessId"]+pslist1["computer"]+syspceid_datetime) pslist1['ProcessGuid'] = result2.hexdigest() pslist1['SyspceId'] = result.hexdigest() ########### # Privileges ########### if self._running: privileges = process.get_token().privileges() for value, present, enabled, default in privileges: try: name, desc = privm.PRIVILEGE_INFO[int(value)] #print name except KeyError: continue privileges_logged = ["SeImpersonatePrivilege","SeAssignPrimaryPrivilege","SeTcbPrivilege","SeBackupPrivilege","SeRestorePrivilege", "SeCreateTokenPrivilege","SeLoadDriverPrivilege","SeTakeOwnershipPrivilege","SeDebugPrivilege"] if str(name) in privileges_logged: #print str(name+"Present") #print str(name+"Enabled") pslist1[str(name)+"Present"] = "False" pslist1[str(name)+"Enabled"] = "False" if present: pslist1[name+"Present"] = "True" if enabled or default: pslist1[name+"Enabled"] = "True" else: sys.exit() ########### # Process Integrity Level and User ########### if self._running: tokenprocess = process.get_token() user_sids = self.lookup_user_sids(self._config) if tokenprocess.is_valid(): cont = 0 for sid_string in tokenprocess.get_sids(): if sid_string in well_known_sids: sid_name = well_known_sids[sid_string] elif sid_string in getservicesids.servicesids: sid_name = getservicesids.servicesids[sid_string] elif sid_string in user_sids: sid_name = user_sids[sid_string] else: sid_name_re = self.find_sid_re(sid_string, well_known_sid_re) if sid_name_re: sid_name = sid_name_re else: sid_name = "" if cont == 0: pslist1["User"] = str(sid_name) cont = cont + 1 if sid_string == "S-1-16-8192": pslist1["IntegrityLevel"] = "Medium" elif sid_string == "S-1-16-8448": pslist1["IntegrityLevel"] = "MediumPlus" elif sid_string == "S-1-16-4096": pslist1["IntegrityLevel"] = "Low" elif sid_string == "S-1-16-12288": pslist1["IntegrityLevel"] = "High" elif sid_string == "S-1-16-16384": pslist1["IntegrityLevel"] = "System" else: sys.exit() ################################# ## HANDLES TOKENS OPENS IN OTHER PROCESS ################################# token1 = {} if self._running: #user_sids = self.lookup_user_sids(self._config) for handle in process.ObjectTable.handles(): token = handle.dereference_as("_TOKEN") if token.is_valid(): token1["idEvent"] = 103 token1["ProcessId"] = pslist1["ProcessId"] token1["ProcessGuid"] = pslist1["ProcessGuid"] token1["SyspceId"] = pslist1["SyspceId"] token1["Image"] = pslist1["Image"] token1["Source"] = "Memory" token1['computer'] = pslist1['computer'] token1["TokenOffset"] = "" token1["TokenHandleValue"] = "" token1["TokenGrantAccess"] = "" token1["User"] = "" token1["UserSid"] = "" token1["IntegrityToken"] = "" token1["IntegritySid"] = "" token_with_sid = 0 list_tokens = token.get_sids() cont = 0 for sid_string in list_tokens: if sid_string in well_known_sids: sid_name = well_known_sids[sid_string] elif sid_string in getservicesids.servicesids: sid_name = getservicesids.servicesids[sid_string] elif sid_string in user_sids: sid_name = user_sids[sid_string] else: sid_name_re = self.find_sid_re(sid_string, well_known_sid_re) if sid_name_re: sid_name = sid_name_re else: sid_name = "" if cont == 0: token1["UserSid"] = str(sid_string) token1["User"] = str(sid_name) cont = cont + 1 token_with_sid = 1 #TOKEN INTEGRITY LEVEL if sid_string == "S-1-16-8192": token1["IntegrityToken"] = "Medium" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-8448": token1["IntegrityToken"] = "MediumPlus" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-4096": token1["IntegrityToken"] = "Low" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-12288": token1["IntegrityToken"] = "High" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-16384": token1["IntegrityToken"] = "System" token1["IntegritySid"] = str(sid_string) if token_with_sid: token1["TokenOffset"] = str(handle.Body.obj_offset) token1["TokenHandleValue"] = str(handle.HandleValue) token1["TokenGrantAccess"] = str(handle.GrantedAccess) token_with_sid = 0 vtokens.append(token1) token1 = {} else: sys.exit() ## MODULES ########### modules = "" if self._running: for module in process.get_load_modules(): if module is not None: modules = modules + "," + str(module.FullDllName) pslist1['Modules'] = modules else: sys.exit() ## VADS ######## """ This looks for private allocations that are committed, memory-resident, non-empty (not all zeros) and with an original protection that includes write and execute. """ vad1 = {} if self._running: pslist1["RwxPage"] = "False" vads = process.get_vads(vad_filter=process._injection_filter) #vads = process.get_vads() for vad, address_space in vads: if self.is_vad_empty(vad, address_space): vad1["VadEmpty"] = "True" else: vad1["VadEmpty"] = "False" protect_flags = str(vadinfo.PROTECT_FLAGS.get(vad.VadFlags.Protection.v(), "")) # Process fields necessaries to a new idEvent vad1["idEvent"] = 102 vad1["ProcessId"] = pslist1["ProcessId"] vad1["ProcessGuid"] = pslist1["ProcessGuid"] vad1["SyspceId"] = pslist1["SyspceId"] vad1["Image"] = pslist1["Image"] vad1["Source"] = "Memory" vad1['computer'] = pslist1['computer'] # Fields VADs vad1["VadNode"] = str(vad.obj_offset) vad1["VadProtection"] = str(protect_flags) vad1["VadStart"] = str(vad.Start) vad1["VadEnd"] = str(vad.End) vvads.append(vad1) vad1 = {} pslist1["RwxPage"] = "True" else: sys.exit() ## THREADS ########### if self._running: self.get_threads(process,vthreads,pslist1) else: sys.exit() vprocess.append(pslist1) pslist1 = {} ## POST-EXTRACTION TASKS ## 1) FILL PARENT INFORMATION computer_alerts = 0 for p in vprocess: for x in vprocess: if p['ParentProcessId'] == x['ProcessId']: p['ParentImage'] = x['Image'] p['ParentCommandLine'] = x['CommandLine'] p['ParentProcessGuid'] = x['ProcessGuid'] p['RealParent'] = x['Image'] # Exception (VII) with lsass.exe if p["Image"].find("lsass.exe") != -1 and p["ParentImage"].find("wininit.exe")!= -1 and p['TerminalSessionId'] == "0": p['CommandLine'] = "C:\\Windows\\System32\\lsass.exe" p['CurrentDirectory'] = "C:\\Windows\\System32\\" # Exception (V) with svchost.exe if p["Image"].find("svchost.exe") != -1 and (p['TerminalSessionId'] == "0" or p['TerminalSessionId'] == "-1") and p["ParentImage"].find("services.exe") != -1: p['CommandLine'] = "C:\\Windows\\System32\\svchost.exe" p['Image'] = "C:\\Windows\\System32\\svchost.exe" p['CurrentDirectory'] = "C:\\Windows\\System32\\" p['TerminalSessionId'] = "0" # Exception (VI) with sppsvc.exe if p["Image"].find("sppsvc.exe") != -1 and p['TerminalSessionId'] == "-1" and p["ParentImage"].find("services.exe") != -1: p['CommandLine'] = "C:\\Windows\\System32\\sppsvc.exe" p['Image'] = "C:\\Windows\\System32\\sppsvc.exe" p['CurrentDirectory'] = "C:\\Windows\\System32\\" p['TerminalSessionId'] = "0" # Check computer self.check_fields(p) if p['computer'] == 'ffffffff' and computer_alerts == 0: print "[SYSPCE] Warning computer is ffffffff, problems while we try to read registry key" computer_alerts = 1 winlogon_fake_father = False winlogon_csrss_father = False wininit_fake_father = False wininit_csrss_father = False winlogon_father_pid = -1 wininit_father_pid = -1 ## POST-EXTRACTION TASKS ## 2) FIX PROBLEMS WITH MEMORY EXTRACTION for p in vprocess: ## WINLOGON problems with hierarchy in memory dumps (SMSS.exe die then it's possible collisions by pid) if p['Image'].find('winlogon') != -1: for x in vprocess: if p['ParentProcessId'] == x['ParentProcessId']: if p['Image'].find('smss.exe') == -1: winlogon_fake_father = True winlogon_father_pid = p['ParentProcessId'] break for z in vprocess: if z['Image'].find('csrss') != -1: if z['ParentProcessId'] == winlogon_father_pid: winlogon_csrss_father = True z['ParentImage'] = "smss.exe" z['ParentCommandLine'] = 'smss.exe' z['RealParent'] = "smss.exe" z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' for z in vprocess: if z['Image'].find('winlogon') != -1: if z['ParentProcessId'] == winlogon_father_pid: z['ParentImage'] = 'smss.exe' z['ParentCommandLine'] = 'smss.exe' z['RealParent'] = 'smss.exe' z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' ## WININIT problems with hierarchy in memory dumps (SMSS.exe die then it's possible collisions by pid) if p['Image'].find('wininit') != -1: for x in vprocess: if p['ParentProcessId'] == x['ParentProcessId']: if p['Image'].find('smss.exe') == -1: wininit_fake_father = True wininit_father_pid = p['ParentProcessId'] break for z in vprocess: if z['Image'].find('csrss.exe') != -1: if z['ParentProcessId'] == wininit_father_pid: wininit_csrss_father = True z['ParentImage'] = "smss.exe" z['ParentCommandLine'] = 'smss.exe' z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' for z in vprocess: if z['Image'].find('wininit') != -1: if z['ParentProcessId'] == wininit_father_pid: z['ParentImage'] = 'smss.exe' z['ParentCommandLine'] = 'smss.exe' z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' ########################### # Plugin privs volatility ########################### #if self._running: # priv = privm.Privs(self._config) # privs_1 = {} # privs_2 = {} # priv_vector = [] # for privs in priv.calculate(): # privileges = privs.get_token().privileges() # for value, present, enabled, default in privileges: # try: # name, desc = privm.PRIVILEGE_INFO[int(value)] # except KeyError: # continue # privs_1 = {} # privs_1['ProcessId'] = str(int(privs.UniqueProcessId)) # privs_1['Name'] = name # # privileges_logged = ["SeImpersonatePrivilege","SeAssignPrimaryPrivilege","SeTcbPrivilege","SeBackupPrivilege","SeRestorePrivilege", # "SeCreateTokenPrivilege","SeLoadDriverPrivilege","SeTakeOwnershipPrivilege","SeDebugPrivilege"] # privs_1['Present'] = "False" # privs_1['Enabled'] = "False" # if str(name) in privileges_logged: # if present: # privs_1['Present'] = "True" # if enabled or default: # privs_1["Enabled"] = "True" # priv_vector.append(privs_1) # # for p in vprocess: # for x in priv_vector: # if p['ProcessId'] == x['ProcessId']: # pvp = x['Name'] + "Present" # p[pvp] = x['Present'] # pve = x['Name'] + "Enabled" # p[pve] = x['Enabled'] # To Send to the CORE ############################ if self._running: events_list = vprocess self.send_message(events_list) thread_list = vthreads self.send_message(thread_list) vads_list = vvads self.send_message(vads_list) token_list = vtokens self.send_message(token_list) # WE BUILD MEMORY CACHE (PROCESS, THREADS AND VADS) cache_process = hresult+"_"+"process" if not os.path.exists(cache_process): with open (cache_process, 'w') as outfile: json.dump(vprocess,outfile) outfile.close() cache_threads = hresult+"_"+"threads" if not os.path.exists(cache_threads): with open (cache_threads, 'w') as outfile: json.dump(vthreads,outfile) outfile.close() cache_vads = hresult+"_"+"vads" if not os.path.exists(cache_vads): with open (cache_vads, 'w') as outfile: json.dump(vvads,outfile) outfile.close() cache_tokens = hresult+"_"+"tokens" if not os.path.exists(cache_tokens): with open (cache_tokens, 'w') as outfile: json.dump(vtokens,outfile) outfile.close()
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)