Beispiel #1
0
    def _generator(self, tasks):
        # determine if we're on a 32 or 64 bit kernel
        if self.context.symbol_space.get_type(self.config["vmlinux"] +
                                              constants.BANG +
                                              "pointer").size == 4:
            is_32bit_arch = True
        else:
            is_32bit_arch = False

        for task in tasks:
            process_name = utility.array_to_string(task.comm)

            for vma, data in self._list_injections(task):
                if is_32bit_arch:
                    architecture = "intel"
                else:
                    architecture = "intel64"

                disasm = interfaces.renderers.Disassembly(
                    data, vma.vm_start, architecture)

                yield (0, (task.pid, process_name,
                           format_hints.Hex(vma.vm_start),
                           format_hints.Hex(vma.vm_end), vma.get_protection(),
                           format_hints.HexBytes(data), disasm))
Beispiel #2
0
    def _generator(self, procs):
        # determine if we're on a 32 or 64 bit kernel
        kernel = self.context.modules[self.config['kernel']]

        is_32bit_arch = not symbols.symbol_table_is_64bit(
            self.context, kernel.symbol_table_name)

        for proc in procs:
            process_name = utility.array_to_string(proc.ImageFileName)

            for vad, data in self.list_injections(self.context,
                                                  kernel.layer_name,
                                                  kernel.symbol_table_name,
                                                  proc):

                # if we're on a 64 bit kernel, we may still need 32 bit disasm due to wow64
                if is_32bit_arch or proc.get_is_wow64():
                    architecture = "intel"
                else:
                    architecture = "intel64"

                disasm = interfaces.renderers.Disassembly(
                    data, vad.get_start(), architecture)

                file_output = "Disabled"
                if self.config['dump']:
                    file_output = "Error outputting to file"
                    try:
                        file_handle = vadinfo.VadInfo.vad_dump(
                            self.context, proc, vad, self.open)
                        file_handle.close()
                        file_output = file_handle.preferred_filename
                    except (exceptions.InvalidAddressException,
                            OverflowError) as excp:
                        vollog.debug(
                            "Unable to dump PE with pid {0}.{1:#x}: {2}".
                            format(proc.UniqueProcessId, vad.get_start(),
                                   excp))

                yield (0, (proc.UniqueProcessId, process_name,
                           format_hints.Hex(vad.get_start()),
                           format_hints.Hex(vad.get_end()), vad.get_tag(),
                           vad.get_protection(
                               vadinfo.VadInfo.protect_values(
                                   self.context, kernel.layer_name,
                                   kernel.symbol_table_name),
                               vadinfo.winnt_protections),
                           vad.get_commit_charge(), vad.get_private_memory(),
                           file_output, format_hints.HexBytes(data), disasm))
Beispiel #3
0
    def _generator(self, tasks):
        # determine if we're on a 32 or 64 bit kernel
        if self.context.modules[self.config['kernel']].get_type(
                "pointer").size == 4:
            is_32bit_arch = True
        else:
            is_32bit_arch = False

        for task in tasks:
            process_name = utility.array_to_string(task.p_comm)

            for vma, data in self._list_injections(task):
                if is_32bit_arch:
                    architecture = "intel"
                else:
                    architecture = "intel64"

                disasm = interfaces.renderers.Disassembly(
                    data, vma.links.start, architecture)

                yield (0, (task.p_pid, process_name,
                           format_hints.Hex(vma.links.start),
                           format_hints.Hex(vma.links.end), vma.get_perms(),
                           format_hints.HexBytes(data), disasm))
Beispiel #4
0
    def list_userassist(
            self,
            hive: RegistryHive) -> Generator[Tuple[int, Tuple], None, None]:
        """Generate userassist data for a registry hive."""

        hive_name = hive.hive.cast(self.config["nt_symbols"] + constants.BANG +
                                   "_CMHIVE").get_name()

        if self._win7 is None:
            try:
                self._win7 = self._win7_or_later()
            except exceptions.SymbolError:
                # self._win7 will be None and only registry value rawdata will be output
                pass

        self._determine_userassist_type()

        userassist_node_path = hive.get_key(
            "software\\microsoft\\windows\\currentversion\\explorer\\userassist",
            return_list=True)

        if not userassist_node_path:
            vollog.warning(
                "list_userassist did not find a valid node_path (or None)")
            return

        if not isinstance(userassist_node_path, list):
            vollog.warning(
                "userassist_node_path did not return a list as expected")
            return
        userassist_node = userassist_node_path[-1]
        # iterate through the GUIDs under the userassist key
        for guidkey in userassist_node.get_subkeys():
            # each guid key should have a Count key in it
            for countkey in guidkey.get_subkeys():
                countkey_path = countkey.get_key_path()
                countkey_last_write_time = conversion.wintime_to_datetime(
                    countkey.LastWriteTime.QuadPart)

                # output the parent Count key
                result = (
                    0, (renderers.format_hints.Hex(hive.hive_offset),
                        hive_name, countkey_path, countkey_last_write_time,
                        "Key", renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue())
                )  # type: Tuple[int, Tuple[format_hints.Hex, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any]]
                yield result

                # output any subkeys under Count
                for subkey in countkey.get_subkeys():

                    subkey_name = subkey.get_name()
                    result = (1, (
                        renderers.format_hints.Hex(hive.hive_offset),
                        hive_name,
                        countkey_path,
                        countkey_last_write_time,
                        "Subkey",
                        subkey_name,
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                        renderers.NotApplicableValue(),
                    ))
                    yield result

                # output any values under Count
                for value in countkey.get_values():

                    value_name = value.get_name()
                    try:
                        value_name = codecs.encode(value_name, "rot_13")
                    except UnicodeDecodeError:
                        pass

                    if self._win7:
                        guid = value_name.split("\\")[0]
                        if guid in self._folder_guids:
                            value_name = value_name.replace(
                                guid, self._folder_guids[guid])

                    userassist_data_dict = self.parse_userassist_data(value)
                    result = (1, (
                        renderers.format_hints.Hex(hive.hive_offset),
                        hive_name,
                        countkey_path,
                        countkey_last_write_time,
                        "Value",
                        value_name,
                        userassist_data_dict["id"],
                        userassist_data_dict["count"],
                        userassist_data_dict["focus"],
                        userassist_data_dict["time"],
                        userassist_data_dict["lastupdated"],
                        format_hints.HexBytes(userassist_data_dict["rawdata"]),
                    ))
                    yield result
Beispiel #5
0
    def _generator(self) -> Iterator[Tuple]:
        kernel = self.context.modules[self.config['kernel']]
        physical_layer_name = self.context.layers[
            kernel.layer_name].config.get('memory_layer', None)

        # Decide of Memory Dump Architecture
        layer = self.context.layers[physical_layer_name]
        architecture = "intel" if not symbols.symbol_table_is_64bit(
            self.context, kernel.symbol_table_name) else "intel64"

        # Read in the Symbol File
        symbol_table = intermed.IntermediateSymbolTable.create(
            context=self.context,
            config_path=self.config_path,
            sub_path="windows",
            filename="mbr",
            class_types={
                'PARTITION_TABLE': mbr.PARTITION_TABLE,
                'PARTITION_ENTRY': mbr.PARTITION_ENTRY
            })

        partition_table_object = symbol_table + constants.BANG + "PARTITION_TABLE"

        # Define Signature and Data Length
        mbr_signature = b"\x55\xAA"
        mbr_length = 0x200
        bootcode_length = 0x1B8

        # Scan the Layer for Raw Master Boot Record (MBR) and parse the fields
        for offset, _value in layer.scan(
                context=self.context,
                scanner=scanners.MultiStringScanner(patterns=[mbr_signature])):
            try:
                mbr_start_offset = offset - (mbr_length - len(mbr_signature))
                partition_table = self.context.object(partition_table_object,
                                                      offset=mbr_start_offset,
                                                      layer_name=layer.name)

                # Extract only BootCode
                full_mbr = layer.read(mbr_start_offset, mbr_length, pad=True)
                bootcode = full_mbr[:bootcode_length]

                all_zeros = None

                if bootcode:
                    all_zeros = bootcode.count(b"\x00") == len(bootcode)

                if not all_zeros:

                    partition_entries = [
                        partition_table.FirstEntry,
                        partition_table.SecondEntry,
                        partition_table.ThirdEntry, partition_table.FourthEntry
                    ]

                    if not self.config.get("full", True):
                        yield (0, (format_hints.Hex(offset),
                                   partition_table.get_disk_signature(),
                                   self.get_hash(bootcode),
                                   self.get_hash(full_mbr),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   interfaces.renderers.Disassembly(
                                       bootcode, 0, architecture)))
                    else:
                        yield (0, (format_hints.Hex(offset),
                                   partition_table.get_disk_signature(),
                                   self.get_hash(bootcode),
                                   self.get_hash(full_mbr),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   renderers.NotApplicableValue(),
                                   interfaces.renderers.Disassembly(
                                       bootcode, 0, architecture),
                                   format_hints.HexBytes(bootcode)))

                    for partition_index, partition_entry_object in enumerate(
                            partition_entries, start=1):

                        if not self.config.get("full", True):
                            yield (1, (
                                format_hints.Hex(offset),
                                partition_table.get_disk_signature(),
                                self.get_hash(bootcode),
                                self.get_hash(full_mbr), partition_index,
                                partition_entry_object.is_bootable(),
                                partition_entry_object.get_partition_type(),
                                format_hints.Hex(partition_entry_object.
                                                 get_size_in_sectors()),
                                renderers.NotApplicableValue()))
                        else:
                            yield (1, (
                                format_hints.Hex(offset),
                                partition_table.get_disk_signature(),
                                self.get_hash(bootcode),
                                self.get_hash(full_mbr), partition_index,
                                partition_entry_object.is_bootable(),
                                format_hints.Hex(partition_entry_object.
                                                 get_bootable_flag()),
                                partition_entry_object.get_partition_type(),
                                format_hints.Hex(
                                    partition_entry_object.PartitionType),
                                format_hints.Hex(
                                    partition_entry_object.get_starting_lba()),
                                partition_entry_object.get_starting_cylinder(),
                                partition_entry_object.get_starting_chs(),
                                partition_entry_object.get_starting_sector(),
                                partition_entry_object.get_ending_cylinder(),
                                partition_entry_object.get_ending_chs(),
                                partition_entry_object.get_ending_sector(),
                                format_hints.Hex(partition_entry_object.
                                                 get_size_in_sectors()),
                                renderers.NotApplicableValue(),
                                renderers.NotApplicableValue()))
                else:
                    vollog.log(
                        constants.LOGLEVEL_VVVV,
                        f"Not a valid MBR: Data all zeroed out : {format_hints.Hex(offset)}"
                    )
                    continue

            except exceptions.PagedInvalidAddressException as excp:
                vollog.log(
                    constants.LOGLEVEL_VVVV,
                    f"Invalid address identified in guessed MBR: {hex(excp.invalid_address)}"
                )
                continue