Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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))
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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))
Exemplo n.º 5
0
    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()
Exemplo n.º 6
0
    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()
Exemplo n.º 9
0
    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()
Exemplo n.º 10
0
    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))
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
    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
Exemplo n.º 13
0
    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))
Exemplo n.º 14
0
    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
Exemplo n.º 15
0
    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()
Exemplo n.º 16
0
    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))
Exemplo n.º 17
0
    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))
Exemplo n.º 18
0
    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)))
Exemplo n.º 19
0
    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]))
Exemplo n.º 20
0
    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
Exemplo n.º 21
0
    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))
Exemplo n.º 22
0
    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
Exemplo n.º 23
0
    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))