Exemple #1
0
    def method_kdbg_offset(
        self,
        context: interfaces.context.ContextInterface,
        vlayer: layers.intel.Intel,
        progress_callback: constants.ProgressCallback = None
    ) -> ValidKernelsType:
        vollog.debug(
            "Kernel base determination - using KDBG structure for kernel offset"
        )
        valid_kernels = {}  # type: ValidKernelsType
        physical_layer_name = self.get_physical_layer_name(context, vlayer)
        physical_layer = context.layers[physical_layer_name]
        results = physical_layer.scan(context,
                                      scanners.BytesScanner(b"KDBG"),
                                      progress_callback=progress_callback)

        seen = set()  # type: Set[int]
        for result in results:
            # TODO: Identify the specific structure we're finding and document this a bit better
            pointer = context.object("pdbscan!unsigned long long",
                                     offset=result + 8,
                                     layer_name=physical_layer_name)
            address = pointer & vlayer.address_mask
            if address in seen:
                continue
            seen.add(address)

            valid_kernels = self.check_kernel_offset(context, vlayer, address,
                                                     progress_callback)

            if valid_kernels:
                break

        return valid_kernels
Exemple #2
0
    def method_module_offset(self,
                             context: interfaces.context.ContextInterface,
                             vlayer: layers.intel.Intel,
                             progress_callback: constants.ProgressCallback = None) -> ValidKernelsType:
        """Method for finding a suitable kernel offset based on a module
        table."""
        vollog.debug("Kernel base determination - searching layer module list structure")
        valid_kernels = {}  # type: ValidKernelsType
        # If we're here, chances are high we're in a Win10 x64 image with kernel base randomization
        virtual_layer_name = vlayer.name
        physical_layer_name = self.get_physical_layer_name(context, vlayer)
        physical_layer = context.layers[physical_layer_name]
        # TODO:  On older windows, this might be \WINDOWS\system32\nt rather than \SystemRoot\system32\nt
        results = physical_layer.scan(context,
                                      scanners.BytesScanner(b"\\SystemRoot\\system32\\nt"),
                                      progress_callback = progress_callback)
        seen = set()  # type: Set[int]
        # Because this will launch a scan of the virtual layer, we want to be careful
        for result in results:
            # TODO: Identify the specific structure we're finding and document this a bit better
            pointer = context.object("pdbscan!unsigned long long",
                                     offset = (result - 16 - int(vlayer.bits_per_register / 8)),
                                     layer_name = physical_layer_name)
            address = pointer & vlayer.address_mask
            if address in seen:
                continue
            seen.add(address)

            valid_kernels = self.check_kernel_offset(context, vlayer, address, progress_callback)

            if valid_kernels:
                break
        return valid_kernels
Exemple #3
0
    def _generator(self, tasks):
        is_32bit = not symbols.symbol_table_is_64bit(self.context,
                                                     self.config["darwin"])
        if is_32bit:
            pack_format = "I"
            bash_json_file = "bash32"
        else:
            pack_format = "Q"
            bash_json_file = "bash64"

        bash_table_name = BashIntermedSymbols.create(self.context,
                                                     self.config_path, "linux",
                                                     bash_json_file)

        ts_offset = self.context.symbol_space.get_type(
            bash_table_name + constants.BANG +
            "hist_entry").relative_child_offset("timestamp")

        for task in tasks:
            task_name = utility.array_to_string(task.p_comm)
            if task_name not in ["bash", "sh", "dash"]:
                continue

            proc_layer_name = task.add_process_layer()
            if proc_layer_name is None:
                continue

            proc_layer = self.context.layers[proc_layer_name]

            bang_addrs = []

            # find '#' values on the heap
            for address in proc_layer.scan(
                    self.context,
                    scanners.BytesScanner(b"#"),
                    sections=task.get_process_memory_sections(
                        self.context, self.config['darwin'], rw_no_file=True)):
                bang_addrs.append(struct.pack(pack_format, address))

            history_entries = []

            for address, _ in proc_layer.scan(
                    self.context,
                    scanners.MultiStringScanner(bang_addrs),
                    sections=task.get_process_memory_sections(
                        self.context, self.config['darwin'], rw_no_file=True)):
                hist = self.context.object(bash_table_name + constants.BANG +
                                           "hist_entry",
                                           offset=address - ts_offset,
                                           layer_name=proc_layer_name)

                if hist.is_valid():
                    history_entries.append(hist)

            for hist in sorted(history_entries,
                               key=lambda x: x.get_time_as_integer()):
                yield (0, (int(task.p_pid), task_name, hist.get_time_object(),
                           hist.get_command()))
Exemple #4
0
    def _generator(self):

        service_table_name = self.create_service_table(
            self.context, self.config["nt_symbols"], self.config_path)

        relative_tag_offset = self.context.symbol_space.get_type(
            service_table_name + constants.BANG +
            "_SERVICE_RECORD").relative_child_offset("Tag")

        filter_func = pslist.PsList.create_name_filter(["services.exe"])

        is_vista_or_later = SvcScan.is_vista_or_later(
            context=self.context, symbol_table=self.config["nt_symbols"])

        if is_vista_or_later:
            service_tag = b"serH"
        else:
            service_tag = b"sErv"

        seen = []

        for task in pslist.PsList.list_processes(
                context=self.context,
                layer_name=self.config['primary'],
                symbol_table=self.config['nt_symbols'],
                filter_func=filter_func):

            try:
                proc_layer_name = task.add_process_layer()
            except exceptions.InvalidAddressException:
                continue

            layer = self.context.layers[proc_layer_name]

            for offset in layer.scan(
                    context=self.context,
                    scanner=scanners.BytesScanner(needle=service_tag),
                    sections=vadyarascan.VadYaraScan.get_vad_maps(task)):

                if not is_vista_or_later:
                    service_record = self.context.object(
                        service_table_name + constants.BANG +
                        "_SERVICE_RECORD",
                        offset=offset - relative_tag_offset,
                        layer_name=proc_layer_name)

                    if not service_record.is_valid():
                        continue

                    yield (0, self.get_record_tuple(service_record))
                else:
                    service_header = self.context.object(
                        service_table_name + constants.BANG +
                        "_SERVICE_HEADER",
                        offset=offset,
                        layer_name=proc_layer_name)

                    if not service_header.is_valid():
                        continue

                    # since we walk the s-list backwards, if we've seen
                    # an object, then we've also seen all objects that
                    # exist before it, thus we can break at that time.
                    for service_record in service_header.ServiceRecord.traverse(
                    ):
                        if service_record in seen:
                            break
                        seen.append(service_record)
                        yield (0, self.get_record_tuple(service_record))