def _registry_walker(self, layer_name: str, symbol_table: str, hive_offsets: List[int] = None, key: str = None, recurse: bool = False): for hive in hivelist.HiveList.list_hives(self.context, self.config_path, layer_name = layer_name, symbol_table = symbol_table, hive_offsets = hive_offsets): try: # Walk it if key is not None: node_path = hive.get_key(key, return_list = True) else: node_path = [hive.get_node(hive.root_cell_offset)] for (x, y) in self._printkey_iterator(hive, node_path, recurse = recurse): yield (x - len(node_path), y) except (exceptions.InvalidAddressException, KeyError, RegistryFormatException) as excp: if type(excp) == KeyError: vollog.debug("Key '{}' not found in Hive at offset {}.".format(key, hex(hive.hive_offset))) elif type(excp) == RegistryFormatException: vollog.debug(excp) else: vollog.debug("Invalid address identified in Hive: {}".format(hex(excp.invalid_address))) result = (0, (renderers.UnreadableValue(), format_hints.Hex(hive.hive_offset), "Key", '?\\' + (key or ''), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue())) yield result
def _generator(self, procs): pe_table_name = intermed.IntermediateSymbolTable.create( self.context, self.config_path, "windows", "pe", class_types=pe.class_types) kuser = info.Info.get_kuser_structure(self.context, self.config['primary'], self.config['nt_symbols']) nt_major_version = int(kuser.NtMajorVersion) nt_minor_version = int(kuser.NtMinorVersion) # LoadTime only applies to versions higher or equal to Window 7 (6.1 and higher) dll_load_time_field = (nt_major_version > 6) or ( nt_major_version == 6 and nt_minor_version >= 1) for proc in procs: proc_id = proc.UniqueProcessId proc_layer_name = proc.add_process_layer() for entry in proc.load_order_modules(): BaseDllName = FullDllName = renderers.UnreadableValue() try: BaseDllName = entry.BaseDllName.get_string() # We assume that if the BaseDllName points to an invalid buffer, so will FullDllName FullDllName = entry.FullDllName.get_string() except exceptions.InvalidAddressException: pass if dll_load_time_field: # Versions prior to 6.1 won't have the LoadTime attribute # and 32bit version shouldn't have the Quadpart according to MSDN try: DllLoadTime = conversion.wintime_to_datetime( entry.LoadTime.QuadPart) except exceptions.InvalidAddressException: DllLoadTime = renderers.UnreadableValue() else: DllLoadTime = renderers.NotApplicableValue() dumped = False if self.config['dump']: filedata = self.dump_pe(self.context, pe_table_name, entry, proc_layer_name) if filedata: filedata.preferred_filename = "pid.{0}.".format( proc_id) + filedata.preferred_filename dumped = True self.produce_file(filedata) yield (0, (proc.UniqueProcessId, proc.ImageFileName.cast( "string", max_length=proc.ImageFileName.vol.count, errors='replace'), format_hints.Hex(entry.DllBase), format_hints.Hex(entry.SizeOfImage), BaseDllName, FullDllName, DllLoadTime, dumped))
def _printkey_iterator(self, hive: RegistryHive, node_path: Sequence[objects.StructType] = None, recurse: bool = False): """Method that wraps the more generic key_iterator, to provide output for printkey specifically. Args: hive: The registry hive to walk node_path: The list of nodes that make up the recurse: Traverse down the node tree or stay only on the same level Yields: The depth, and a tuple of results (last write time, hive offset, type, path, name, data and volatile) """ for depth, is_key, last_write_time, key_path, volatile, node in self.key_iterator( hive, node_path, recurse): if is_key: try: key_node_name = node.get_name() except (exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) key_node_name = renderers.UnreadableValue() yield (depth, (last_write_time, renderers.format_hints.Hex(hive.hive_offset), "Key", key_path, key_node_name, "", volatile)) else: try: value_node_name = node.get_name() or "(Default)" except (exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) value_node_name = renderers.UnreadableValue() try: value_data = str( node.decode_data() ) # type: Union[interfaces.renderers.BaseAbsentValue, str] except (ValueError, exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) value_data = renderers.UnreadableValue() try: value_type = RegValueTypes.get(node.Type).name except (exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) value_type = renderers.UnreadableValue() result = (depth, (last_write_time, renderers.format_hints.Hex(hive.hive_offset), value_type, key_path, value_node_name, value_data, volatile)) yield result
def _generator(self): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) try: list_head = kernel.object_from_symbol(symbol_name="ifnet_head") except exceptions.SymbolError: list_head = kernel.object_from_symbol( symbol_name="dlil_ifnet_head") for ifnet in mac.MacUtilities.walk_tailq(list_head, "if_link"): name = utility.pointer_to_string(ifnet.if_name, 32) unit = ifnet.if_unit prom = ifnet.if_flags & 0x100 == 0x100 # IFF_PROMISC sock_addr_dl = ifnet.sockaddr_dl() if sock_addr_dl is None: mac_addr = renderers.UnreadableValue() else: mac_addr = str(sock_addr_dl) for ifaddr in mac.MacUtilities.walk_tailq(ifnet.if_addrhead, "ifa_link"): ip = ifaddr.ifa_addr.get_address() yield (0, ("{0}{1}".format(name, unit), ip, mac_addr, prom))
def get_session_id(self): try: if self.has_member("Session"): if self.Session == 0: return renderers.NotApplicableValue() symbol_table_name = self.get_symbol_table_name() kvo = self._context.layers[ self.vol.native_layer_name].config['kernel_virtual_offset'] ntkrnlmp = self._context.module( symbol_table_name, layer_name=self.vol.native_layer_name, offset=kvo, native_layer_name=self.vol.native_layer_name) session = ntkrnlmp.object(object_type="_MM_SESSION_SPACE", offset=self.Session, absolute=True) if session.has_member("SessionId"): return session.SessionId except exceptions.InvalidAddressException: vollog.log( constants.LOGLEVEL_VVV, "Cannot access _EPROCESS.Session.SessionId at {0:#x}".format( self.vol.offset)) return renderers.UnreadableValue()
def environment_variables(self): """Generator for environment variables. The PEB points to our env block - a series of null-terminated unicode strings. Each string cannot be more than 0x7FFF chars. End of the list is a quad-null. """ context = self._context process_space = self.add_process_layer() try: block = self.get_peb().ProcessParameters.Environment try: block_size = self.get_peb().ProcessParameters.EnvironmentSize except AttributeError: # Windows XP block_size = self.get_peb().ProcessParameters.Length envars = context.layers[process_space].read(block, block_size).decode("utf-16-le", errors='replace').split('\x00')[:-1] except exceptions.InvalidAddressException: return renderers.UnreadableValue() for envar in envars: split_index = envar.find('=') env = envar[:split_index] var = envar[split_index+1:] # Exlude parse problem with some types of env if env and var: yield env, var
def get_display(self) -> Union[str, interfaces.renderers.BaseAbsentValue]: """Returns the service display.""" try: return self.DisplayName.dereference().cast("string", encoding="utf-16", errors="replace", max_length=512) except exceptions.InvalidAddressException: return renderers.UnreadableValue()
def get_pid(self) -> Union[int, interfaces.renderers.BaseAbsentValue]: """Return the pid of the process, if any.""" if self.State.description != "SERVICE_RUNNING" or "PROCESS" not in self.get_type( ): return renderers.NotApplicableValue() try: return self.ServiceProcess.ProcessId except exceptions.InvalidAddressException: return renderers.UnreadableValue()
def get_handle_count(self): try: if self.has_member("ObjectTable"): if self.ObjectTable.has_member("HandleCount"): return self.ObjectTable.HandleCount except exceptions.InvalidAddressException: vollog.log(constants.LOGLEVEL_VVV, "Cannot access _EPROCESS.ObjectTable.HandleCount at {0:#x}".format(self.vol.offset)) return renderers.UnreadableValue()
def _generator(self, mods): session_layers = list( self.get_session_layers(self.context, self.config['primary'], self.config['nt_symbols'])) pe_table_name = intermed.IntermediateSymbolTable.create( self.context, self.config_path, "windows", "pe", class_types=pe.class_types) for mod in mods: try: BaseDllName = mod.BaseDllName.get_string() except exceptions.InvalidAddressException: BaseDllName = renderers.UnreadableValue() session_layer_name = self.find_session_layer( self.context, session_layers, mod.DllBase) if session_layer_name is None: result_text = "Cannot find a viable session layer for {0:#x}".format( mod.DllBase) else: try: dos_header = self.context.object( pe_table_name + constants.BANG + "_IMAGE_DOS_HEADER", offset=mod.DllBase, layer_name=session_layer_name) filedata = interfaces.plugins.FileInterface( "module.{0:#x}.dmp".format(mod.DllBase)) for offset, data in dos_header.reconstruct(): filedata.data.seek(offset) filedata.data.write(data) self.produce_file(filedata) result_text = "Stored {}".format( filedata.preferred_filename) except ValueError: result_text = "PE parsing error" except exceptions.SwappedInvalidAddressException as exp: result_text = "Required memory at {0:#x} is inaccessible (swapped)".format( exp.invalid_address) except exceptions.InvalidAddressException as exp: result_text = "Required memory at {0:#x} is not valid".format( exp.invalid_address) yield (0, (format_hints.Hex(mod.DllBase), BaseDllName, result_text))
def list_bugcheck_callbacks( cls, context: interfaces.context.ContextInterface, layer_name: str, symbol_table: str, callback_table_name: str) -> Iterable[Tuple[str, int, str]]: """Lists all kernel bugcheck callbacks. Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate symbol_table: The name of the table containing the kernel symbols callback_table_name: The nae of the table containing the callback symbols Yields: A name, location and optional detail string """ kvo = context.layers[layer_name].config['kernel_virtual_offset'] ntkrnlmp = context.module(symbol_table, layer_name=layer_name, offset=kvo) try: list_offset = ntkrnlmp.get_symbol( "KeBugCheckCallbackListHead").address except exceptions.SymbolError: vollog.debug("Cannot find KeBugCheckCallbackListHead") return full_type_name = callback_table_name + constants.BANG + "_KBUGCHECK_CALLBACK_RECORD" callback_record = context.object(full_type_name, offset=kvo + list_offset, layer_name=layer_name) for callback in callback_record.Entry: try: context.layers[layer_name].is_valid(callback.CallbackRoutine) except exceptions.InvalidAddressException: continue try: component = context.object(symbol_table + constants.BANG + "string", layer_name=layer_name, offset=callback.Component, max_length=64, errors="replace") except exceptions.InvalidAddressException: component = renderers.UnreadableValue() yield "KeBugCheckCallbackListHead", callback.CallbackRoutine, component
def file_name_with_device(self) -> Union[str, interfaces.renderers.BaseAbsentValue]: name = renderers.UnreadableValue() # type: Union[str, interfaces.renderers.BaseAbsentValue] if self._context.layers[self.DeviceObject.vol.native_layer_name].is_valid(self.DeviceObject): try: name = "\\Device\\{}".format(self.DeviceObject.get_device_name()) except ValueError: pass try: name += self.FileName.String except (TypeError, exceptions.InvalidAddressException): pass return name
def _generator(self, procs): pe_table_name = intermed.IntermediateSymbolTable.create( self.context, self.config_path, "windows", "pe", class_types=pe.class_types) for proc in procs: proc_id = proc.UniqueProcessId proc_layer_name = proc.add_process_layer() for entry in proc.load_order_modules(): BaseDllName = FullDllName = renderers.UnreadableValue() try: BaseDllName = entry.BaseDllName.get_string() # We assume that if the BaseDllName points to an invalid buffer, so will FullDllName FullDllName = entry.FullDllName.get_string() except exceptions.InvalidAddressException: pass dumped = False if self.config['dump']: filedata = self.dump_pe(self.context, pe_table_name, entry, proc_layer_name) if filedata: filedata.preferred_filename = "pid.{0}.".format( proc_id) + filedata.preferred_filename dumped = True self.produce_file(filedata) yield (0, (proc.UniqueProcessId, proc.ImageFileName.cast( "string", max_length=proc.ImageFileName.vol.count, errors='replace'), format_hints.Hex(entry.DllBase), format_hints.Hex(entry.SizeOfImage), BaseDllName, FullDllName, dumped))
def file_name_with_device( self) -> Union[str, interfaces.renderers.BaseAbsentValue]: name = renderers.UnreadableValue( ) # type: Union[str, interfaces.renderers.BaseAbsentValue] # this pointer needs to be checked against native_layer_name because the object may # be instantiated from a primary (virtual) layer or a memory (physical) layer. if self._context.layers[self.vol.native_layer_name].is_valid( self.DeviceObject): try: name = "\\Device\\{}".format( self.DeviceObject.get_device_name()) except ValueError: pass try: name += self.FileName.String except (TypeError, exceptions.InvalidAddressException): pass return name
def get_binary(self) -> Union[str, interfaces.renderers.BaseAbsentValue]: """Returns the binary associated with the service.""" if self.State.description != "SERVICE_RUNNING": return renderers.NotApplicableValue() # depending on whether the service is for a process # or kernel driver, the binary path is stored differently try: if "PROCESS" in self.get_type(): return self.ServiceProcess.BinaryPath.dereference().cast( "string", encoding="utf-16", errors="replace", max_length=512) else: return self.DriverName.dereference().cast("string", encoding="utf-16", errors="replace", max_length=512) except exceptions.InvalidAddressException: return renderers.UnreadableValue()
def _generator(self, procs): for proc in procs: for entry in proc.load_order_modules(): BaseDllName = FullDllName = renderers.UnreadableValue() try: BaseDllName = entry.BaseDllName.get_string() # We assume that if the BaseDllName points to an invalid buffer, so will FullDllName FullDllName = entry.FullDllName.get_string() except exceptions.InvalidAddressException: pass yield (0, (proc.UniqueProcessId, proc.ImageFileName.cast( "string", max_length=proc.ImageFileName.vol.count, errors='replace'), format_hints.Hex(entry.DllBase), format_hints.Hex(entry.SizeOfImage), BaseDllName, FullDllName))
def _generator(self, procs, output_netscan): netscan_LocalAddr = {} netscan_ForeignAddr = {} netscan_State = {} netscan_Known = {} for row in output_netscan: _depth, row_data = row row_data = [ "N/A" if isinstance(i, renderers.UnreadableValue) or isinstance(i, renderers.UnparsableValue) else i for i in row_data ] try: if ((row_data[2] + ":" + str(row_data[3])) not in netscan_LocalAddr[row_data[7]]): netscan_LocalAddr[ row_data[7]] = netscan_LocalAddr[row_data[7]] + "," + ( row_data[2] + ":" + str(row_data[3])) if ((row_data[4] + ":" + str(row_data[5])) not in netscan_ForeignAddr[row_data[7]]): netscan_ForeignAddr[row_data[7]] = netscan_ForeignAddr[ row_data[7]] + "," + (row_data[4] + ":" + str(row_data[5])) #netscan_State[row_data[7]] = netscan_State[row_data[7]] + "," + (row_data[6]) except: netscan_LocalAddr[row_data[7]] = row_data[2] + ":" + str( row_data[3]) netscan_ForeignAddr[row_data[7]] = row_data[4] + ":" + str( row_data[5]) netscan_State[row_data[7]] = row_data[6] netscan_Known[row_data[7]] = "-" pass #response = requests.get("http://check.getipintel.net/check.php?ip=" + row_data[4] + "&[email protected]") #if response.text == "1": # netscan_Known[row_data[7]] = "getipintel" # list from https://malwareworld.com/textlists/suspiciousIPs.txt url = 'https://malwareworld.com/textlists/suspiciousIPs.txt' r = requests.get(url, allow_redirects=True) open('suspiciousIPs.txt', 'wb').write(r.content) with open('suspiciousIPs.txt') as f: if str(row_data[4]) in f.read(): netscan_Known[row_data[0]] = "malwareworld" #print(open('suspiciousIPs.txt', 'r').read().find(str(row_data[4]))) for proc in procs: for entry in proc.load_order_modules(): BaseDllName = FullDllName = renderers.UnreadableValue() try: BaseDllName = entry.BaseDllName.get_string() # We assume that if the BaseDllName points to an invalid buffer, so will FullDllName FullDllName = entry.FullDllName.get_string() except exceptions.InvalidAddressException: pass try: localaddr = netscan_LocalAddr[proc.UniqueProcessId] except: localaddr = "-" try: foreignaddr = netscan_ForeignAddr[proc.UniqueProcessId] except: foreignaddr = "-" try: state = netscan_State[proc.UniqueProcessId] except: state = "-" try: suspicious = netscan_Known[proc.UniqueProcessId] except: suspicious = "n/a" if (localaddr != "-"): yield (0, (proc.UniqueProcessId, proc.InheritedFromUniqueProcessId, proc.ImageFileName.cast( "string", max_length=proc.ImageFileName.vol.count, errors='replace'), BaseDllName, FullDllName, localaddr, foreignaddr, state, suspicious))
def _generator(self, show_corrupt_results: Optional[bool] = None): """ Generates the network objects for use in rendering. """ netscan_symbol_table = self.create_netscan_symbol_table( self.context, self.config["primary"], self.config["nt_symbols"], self.config_path) for netw_obj in self.scan(self.context, self.config['primary'], self.config['nt_symbols'], netscan_symbol_table): vollog.debug("Found netw obj @ 0x{:2x} of assumed type {}".format( netw_obj.vol.offset, type(netw_obj))) # objects passed pool header constraints. check for additional constraints if strict flag is set. if not show_corrupt_results and not netw_obj.is_valid(): continue if isinstance(netw_obj, network._UDP_ENDPOINT): vollog.debug("Found UDP_ENDPOINT @ 0x{:2x}".format( netw_obj.vol.offset)) # For UdpA, the state is always blank and the remote end is asterisks for ver, laddr, _ in netw_obj.dual_stack_sockets(): yield (0, (format_hints.Hex(netw_obj.vol.offset), "UDP" + ver, laddr, netw_obj.Port, "*", 0, "", netw_obj.get_owner_pid() or renderers.UnreadableValue(), netw_obj.get_owner_procname() or renderers.UnreadableValue(), netw_obj.get_create_time() or renderers.UnreadableValue())) elif isinstance(netw_obj, network._TCP_ENDPOINT): vollog.debug("Found _TCP_ENDPOINT @ 0x{:2x}".format( netw_obj.vol.offset)) if netw_obj.get_address_family() == network.AF_INET: proto = "TCPv4" elif netw_obj.get_address_family() == network.AF_INET6: proto = "TCPv6" else: proto = "TCPv?" try: state = netw_obj.State.description except ValueError: state = renderers.UnreadableValue() yield (0, (format_hints.Hex(netw_obj.vol.offset), proto, netw_obj.get_local_address() or renderers.UnreadableValue(), netw_obj.LocalPort, netw_obj.get_remote_address() or renderers.UnreadableValue(), netw_obj.RemotePort, state, netw_obj.get_owner_pid() or renderers.UnreadableValue(), netw_obj.get_owner_procname() or renderers.UnreadableValue(), netw_obj.get_create_time() or renderers.UnreadableValue())) # check for isinstance of tcp listener last, because all other objects are inherited from here elif isinstance(netw_obj, network._TCP_LISTENER): vollog.debug("Found _TCP_LISTENER @ 0x{:2x}".format( netw_obj.vol.offset)) # For TcpL, the state is always listening and the remote port is zero for ver, laddr, raddr in netw_obj.dual_stack_sockets(): yield (0, (format_hints.Hex(netw_obj.vol.offset), "TCP" + ver, laddr, netw_obj.Port, raddr, 0, "LISTENING", netw_obj.get_owner_pid() or renderers.UnreadableValue(), netw_obj.get_owner_procname() or renderers.UnreadableValue(), netw_obj.get_create_time() or renderers.UnreadableValue())) else: # this should not happen therefore we log it. vollog.debug( "Found network object unsure of its type: {} of type {}". format(netw_obj, type(netw_obj)))
def _generator(self, procs): conhost_pids = [] appinfo_service_pid = 0 suspicious_procs = {} # For unknown reasons, the owner process id will point to the actual parent id + 2 with the exception of conhost which is +1. # OWNER_PROCESS_ID_OFFSET will be used to get the real parent PID from the OwnerProcessId field. OWNER_PROCESS_ID_OFFSET = -2 # CONHOST_PROCESS_ID_OFFSET will be used to check if OwnerProcessId actually points to a console host process. CONHOST_PROCESS_ID_OFFSET = -1 # OwnerProcessId only exists as a union from Windows 8 or later. is_win8_or_later = poolscanner.os_distinguisher( version_check=lambda x: x >= (6, 2), fallback_checks=[("_EPROCESS", "OwnerProcessId", True)]) if not is_win8_or_later(self.context, self.config["nt_symbols"]): vollog.warning( "check_parent_spoof doesn't work in Windows versions prior to Windows 8" ) return for proc in procs: if not proc.has_member("OwnerProcessId"): continue process_name = utility.array_to_string(proc.ImageFileName) inherited_process_pid = proc.InheritedFromUniqueProcessId # Save appinfo's service pid to exclude, this is hosted only by svchost.exe. if (appinfo_service_pid == 0) and ("svchost" in process_name): for entry in proc.load_order_modules(): dll_name = renderers.UnreadableValue() try: dll_name = entry.FullDllName.get_string() if "appinfo.dll" not in dll_name: continue except exceptions.InvalidAddressException: continue appinfo_service_pid = proc.UniqueProcessId # If a process was already flagged as suspicious and it's actually pointing to the appinfo service, it should not be flagged. if proc.UniqueProcessId in suspicious_procs: suspicious_procs.pop(proc.UniqueProcessId) # The Owner process id field is used a union for the owner process id and console host process id # We save the conhost process id's in order to exclude them from the check. if "conhost" in process_name: conhost_pids.append(proc.UniqueProcessId) # If a process was already flagged as suspicious and it's actually pointing to a conhost process, it should not be flagged. # Since suspicious_procs saves everything at OWNER_PROCESS_ID_OFFSET we correct the offset check here by adding the conhost offset. conhost_pid = proc.UniqueProcessId + CONHOST_PROCESS_ID_OFFSET if conhost_pid in suspicious_procs: suspicious_procs.pop(conhost_pid) try: owner_process_pid = proc.OwnerProcessId # There are several checks here: # Most services and system processes are initialized with 0, exclude them and System by checking if the pid is under 0. # AppInfo service is responsible for UAC and could be triggered as a false positive as well. if (owner_process_pid < 10) or (owner_process_pid + OWNER_PROCESS_ID_OFFSET == inherited_process_pid) \ or (owner_process_pid + OWNER_PROCESS_ID_OFFSET == appinfo_service_pid) or (owner_process_pid + CONHOST_PROCESS_ID_OFFSET) in conhost_pids: continue except Exception as e: continue suspicious_procs[owner_process_pid + OWNER_PROCESS_ID_OFFSET] = ( proc.UniqueProcessId, process_name, inherited_process_pid, owner_process_pid + OWNER_PROCESS_ID_OFFSET) for owner_process_id, suspicious_proc in suspicious_procs.items(): yield (0, (suspicious_proc[0], suspicious_proc[1], suspicious_proc[2], suspicious_proc[3]))
def _printkey_iterator(self, hive: RegistryHive, node_path: Sequence[objects.StructType] = None, recurse: bool = False): """Method that wraps the more generic key_iterator, to provide output for printkey specifically. Args: hive: The registry hive to walk node_path: The list of nodes that make up the recurse: Traverse down the node tree or stay only on the same level Yields: The depth, and a tuple of results (last write time, hive offset, type, path, name, data and volatile) """ for depth, is_key, last_write_time, key_path, volatile, node in self.key_iterator( hive, node_path, recurse): if is_key: try: key_node_name = node.get_name() except (exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) key_node_name = renderers.UnreadableValue() yield (depth, (last_write_time, renderers.format_hints.Hex(hive.hive_offset), "Key", key_path, key_node_name, renderers.NotApplicableValue(), volatile)) else: try: value_node_name = node.get_name() or "(Default)" except (exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) value_node_name = renderers.UnreadableValue() try: value_type = RegValueTypes.get(node.Type).name except (exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) value_type = renderers.UnreadableValue() if isinstance(value_type, renderers.UnreadableValue): vollog.debug( "Couldn't read registry value type, so data is unreadable" ) value_data = renderers.UnreadableValue() else: try: value_data = node.decode_data( ) # type: Union[interfaces.renderers.BaseAbsentValue, bytes] if isinstance(value_data, int): value_data = format_hints.MultiTypeData( value_data, encoding='utf-8') elif RegValueTypes.get( node.Type) == RegValueTypes.REG_BINARY: value_data = format_hints.MultiTypeData( value_data, show_hex=True) elif RegValueTypes.get( node.Type) == RegValueTypes.REG_MULTI_SZ: value_data = format_hints.MultiTypeData( value_data, encoding='utf-16-le', split_nulls=True) else: value_data = format_hints.MultiTypeData( value_data, encoding='utf-16-le') except (ValueError, exceptions.InvalidAddressException, RegistryFormatException) as excp: vollog.debug(excp) value_data = renderers.UnreadableValue() result = (depth, (last_write_time, renderers.format_hints.Hex(hive.hive_offset), value_type, key_path, value_node_name, value_data, volatile)) yield result
def _generator(self, procs: Generator[interfaces.objects.ObjectInterface, None, None], mods: Generator[interfaces.objects.ObjectInterface, None, None], session_layers: Generator[str, None, None]): """Generates a list of PE file version info for processes, dlls, and modules. Args: procs: <generator> of processes mods: <generator> of modules session_layers: <generator> of layers in the session to be checked """ pe_table_name = intermed.IntermediateSymbolTable.create(self.context, self.config_path, "windows", "pe", class_types = pe.class_types) for mod in mods: try: BaseDllName = mod.BaseDllName.get_string() except exceptions.InvalidAddressException: BaseDllName = renderers.UnreadableValue() session_layer_name = modules.Modules.find_session_layer(self.context, session_layers, mod.DllBase) (major, minor, product, build) = [ renderers.NotAvailableValue() ] * 4 # type: Tuple[Union[int, interfaces.renderers.BaseAbsentValue],Union[int, interfaces.renderers.BaseAbsentValue],Union[int, interfaces.renderers.BaseAbsentValue],Union[int, interfaces.renderers.BaseAbsentValue]] try: (major, minor, product, build) = self.get_version_information(self._context, pe_table_name, session_layer_name, mod.DllBase) except (exceptions.InvalidAddressException, TypeError, AttributeError): (major, minor, product, build) = [renderers.UnreadableValue()] * 4 # the pid and process are not applicable for kernel modules yield (0, (renderers.NotApplicableValue(), renderers.NotApplicableValue(), format_hints.Hex(mod.DllBase), BaseDllName, major, minor, product, build)) # now go through the process and dll lists for proc in procs: proc_id = "Unknown" try: proc_id = proc.UniqueProcessId proc_layer_name = proc.add_process_layer() except exceptions.InvalidAddressException as excp: vollog.debug("Process {}: invalid address {} in layer {}".format(proc_id, excp.invalid_address, excp.layer_name)) continue for entry in proc.load_order_modules(): try: BaseDllName = entry.BaseDllName.get_string() except exceptions.InvalidAddressException: BaseDllName = renderers.UnreadableValue() try: DllBase = format_hints.Hex(entry.DllBase) except exceptions.InvalidAddressException: DllBase = renderers.UnreadableValue() try: (major, minor, product, build) = self.get_version_information(self._context, pe_table_name, proc_layer_name, entry.DllBase) except (exceptions.InvalidAddressException, ValueError, AttributeError): (major, minor, product, build) = [renderers.UnreadableValue()] * 4 yield (0, (proc.UniqueProcessId, proc.ImageFileName.cast("string", max_length = proc.ImageFileName.vol.count, errors = "replace"), DllBase, BaseDllName, major, minor, product, build))
def _generator(self): hive_offsets = None if self.config.get('offset', None) is not None: hive_offsets = [self.config.get('offset', None)] # get all the user hive offsets or use the one specified for hive in hivelist.HiveList.list_hives( context=self.context, base_config_path=self.config_path, layer_name=self.config['primary'], symbol_table=self.config['nt_symbols'], filter_string='ntuser.dat', hive_offsets=hive_offsets): try: yield from self.list_userassist(hive) continue except exceptions.PagedInvalidAddressException as excp: vollog.debug("Invalid address identified in Hive: {}".format( hex(excp.invalid_address))) except exceptions.InvalidAddressException as excp: vollog.debug( "Invalid address identified in lower layer {}: {}".format( excp.layer_name, excp.invalid_address)) except KeyError: vollog.debug("Key '{}' not found in Hive at offset {}.".format( "software\\microsoft\\windows\\currentversion\\explorer\\userassist", hex(hive.hive_offset))) # yield UnreadableValues when an exception occurs for a given hive_offset result = ( 0, (renderers.format_hints.Hex(hive.hive_offset), hive.name if hive.name else renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue(), renderers.UnreadableValue())) yield result
def _generator(self, procs, output_netscan): netscan_LocalAddr = {} netscan_ForeignAddr = {} netscan_State = {} netscan_Known = {} for row in output_netscan: _depth, row_data = row row_data = [ "N/A" if isinstance(i, renderers.UnreadableValue) or isinstance(i, renderers.UnparsableValue) else i for i in row_data ] try: if ((row_data[2] + ":" + str(row_data[3])) not in netscan_LocalAddr[row_data[7]]): netscan_LocalAddr[ row_data[7]] = netscan_LocalAddr[row_data[7]] + "," + ( row_data[2] + ":" + str(row_data[3])) if ((row_data[4] + ":" + str(row_data[5])) not in netscan_ForeignAddr[row_data[7]]): netscan_ForeignAddr[row_data[7]] = netscan_ForeignAddr[ row_data[7]] + "," + (row_data[4] + ":" + str(row_data[5])) #netscan_State[row_data[7]] = netscan_State[row_data[7]] + "," + (row_data[6]) except: netscan_LocalAddr[row_data[7]] = row_data[2] + ":" + str( row_data[3]) netscan_ForeignAddr[row_data[7]] = row_data[4] + ":" + str( row_data[5]) netscan_State[row_data[7]] = row_data[6] netscan_Known[row_data[7]] = "-" pass #response = requests.get("http://check.getipintel.net/check.php?ip=" + row_data[4] + "&[email protected]") #if response.text == "1": # netscan_Known[row_data[7]] = "y" # list from https://malwareworld.com/textlists/suspiciousIPs.txt url = 'https://malwareworld.com/textlists/suspiciousIPs.txt' r = requests.get(url, allow_redirects=True) open('suspiciousIPs.txt', 'wb').write(r.content) with open('suspiciousIPs.txt') as f: if str(row_data[4]) in f.read(): netscan_Known[row_data[7]] = "y" pe_table_name = intermed.IntermediateSymbolTable.create( self.context, self.config_path, "windows", "pe", class_types=pe.class_types) for proc in procs: for entry in proc.load_order_modules(): BaseDllName = FullDllName = renderers.UnreadableValue() try: BaseDllName = entry.BaseDllName.get_string() # We assume that if the BaseDllName points to an invalid buffer, so will FullDllName FullDllName = entry.FullDllName.get_string() except exceptions.InvalidAddressException: pass try: localaddr = netscan_LocalAddr[proc.UniqueProcessId] except: localaddr = "-" try: foreignaddr = netscan_ForeignAddr[proc.UniqueProcessId] except: foreignaddr = "-" try: state = netscan_State[proc.UniqueProcessId] except: state = "-" try: suspicious = netscan_Known[proc.UniqueProcessId] except: suspicious = "n/a" #for vad in proc.get_vad_root().traverse(): # filedata = vadinfo.VadInfo.vad_dump(self.context, proc, vad) vt_result = "n/a" peinfo = "n/a" file_md5 = "n/a" filedata = dlllist.DllList.dump_pe(self.context, pe_table_name, entry, proc.add_process_layer()) if filedata: file_md5 = hashlib.md5( filedata.data.getvalue()).hexdigest() #filedata.preferred_filename = "pid.{0}.".format(proc.UniqueProcessId) + filedata.preferred_filename try: #self.produce_file(filedata) #peheader = pefile.PE(filedata.preferred_filename) peheader = pefile.PE(data=filedata.data.getvalue()) peinfo = "none" if (peheader.is_exe() is True): peinfo = "EXE" vt_result = self.vtscan(file_md5) if (peheader.is_dll() is True): peinfo = "DLL" vt_result = "-" if (peheader.is_driver() is True): peinfo = "DRIVER" vt_result = "-" #malicious file? if (peinfo == "n/a"): vt_result = self.vtscan(file_md5) except pefile.PEFormatError as err: peinfo = "n/a" logger.info("Problem wit PE header, err: %s", err) except Exception as e: vt_result = "?" peinfo = "none" logger.info("Problem wit PE header, err: %s", e) yield (0, (proc.UniqueProcessId, proc.InheritedFromUniqueProcessId, proc.ImageFileName.cast( "string", max_length=proc.ImageFileName.vol.count, errors='replace'), BaseDllName, FullDllName, peinfo, file_md5, vt_result, localaddr, foreignaddr, state, suspicious))