示例#1
0
    def extract_artifact(self, artifact_name):  # pylint: disable=invalid-name
        """
        Extract a particular artifact from all possible locations within this dfvfs-image
        """
        real_partitions: List[PartitionInfo] = []

        print("all", list(self.dfvfs_list[0].all_files()))

        # forensic images can have more than one partition, but we always only process one image at a time
        real_partitions = [
            PartitionInfo(helper=self.dfvfs_list[0],
                          path_spec=partition,
                          name=chr(ord('c') + i))
            for i, partition in enumerate(self.dfvfs_list[0].partitions())
            if not dfvfs_utils.is_on_filesystem(
                partition, dfvfs_defs.TYPE_INDICATOR_VSHADOW)
        ]
        LOGGER.info("Found %d partitions", len(real_partitions))
        for partinfo in real_partitions:
            current_os = self._guess_os(partinfo.helper, partinfo.path_spec)
            try:
                if current_os == definitions.OPERATING_SYSTEM_WINDOWS:
                    system = WindowsSystem(partinfo.helper, partinfo.path_spec)

                elif current_os == definitions.OPERATING_SYSTEM_UNKNOWN:
                    system = UnknownOS()
                    LOGGER.warning(
                        "Operating system not detected on partition %s. Only basic extraction possible.",
                        dfvfs_utils.reconstruct_full_path(partinfo.path_spec))
                else:
                    LOGGER.warning(
                        "Operating system %s is not yet supported on %s. Using basic extraction.",
                        dfvfs_utils.reconstruct_full_path(partinfo.path_spec),
                        current_os)
                    system = UnknownOS()

                LOGGER.info("=== Starting processing of partition")
                resolver = ArtifactResolver(partinfo, self.artifact_registry,
                                            system)
                resolver.process_artifact(artifact_name, self.store)

                if current_os == definitions.OPERATING_SYSTEM_WINDOWS:
                    system._reg_reader._cleanup_open_files("")  # TODO

            except RuntimeError as err:
                LOGGER.exception(
                    "Encountered exception during processing of %s: %s",
                    dfvfs_utils.reconstruct_full_path(partinfo.path_spec), err)
                if 'pytest' in sys.modules:
                    raise  # we want to see what exactly is failing when tests are running

        self.store.close()
    def _extract_files(self, artifact: ResolvedArtifact,
                       artifact_output: ForensicStore) -> bool:
        """
        Extract an artifact's files and folders to the forensic store
        :param artifact: artifact to extract
        :param artifact_output: Output forensic store
        :type artifact_output: ForensicStore
        :type artifact: ResolvedArtifact
        :return: True on success, False if nothing was written
        """

        artifact_name = artifact.artifact.name
        success = False

        for export_file in artifact.files:
            success = True
            file_infos = get_file_infos(export_file)
            if not file_infos:
                LOGGER.warning("Could not get file infos for \"%s\". Skipping",
                               dfvfs_utils.reconstruct_full_path(export_file))
                continue

            if file_infos['type'] != dfvfs_defs.FILE_ENTRY_TYPE_FILE:
                LOGGER.debug("Not exporting entry of wrong type: %s",
                             dfvfs_utils.reconstruct_full_path(export_file))
                continue

            store_obj_id = artifact_output.add_file_element(
                artifact_name,
                file_infos['name'],
                created=file_infos.get('created', None),
                modified=file_infos.get('modified', None),
                accessed=file_infos.get('accessed', None),
                origin={
                    'path': file_infos['path'],
                    'partition': self.partition_name
                },
                errors=None)
            output_name = f"{self.partition_name}_" \
                          f"{dfvfs_utils.get_relative_path(export_file).replace('/', '_').strip('_')}"
            file_contents = dfvfs_helper.get_file_handle(export_file)
            with artifact_output.add_file_element_export(
                    store_obj_id, export_name=output_name) as file_export:
                chunk_size = 65536
                data = file_contents.read(chunk_size)
                while data:
                    file_export.write(data)
                    data = file_contents.read(chunk_size)
            file_contents.close()

        return success
示例#3
0
    def _read_system_infos(self):
        """
        Determine some basic system information. We need this to bootstrap registry access.
        The rest of interesting system data can then be resolved with artifacts
        """
        # find %SystemRoot%
        systemroot = list(
            self.dfvfs.find_paths(['/Windows', '/WINNT'], partitions=[self.partition]))
        if not systemroot:
            raise RuntimeError("No windows directory found on %s" % (
                dfvfs_utils.reconstruct_full_path(self.partition)))
        if len(systemroot) > 1:
            LOGGER.warning("More than one installation of Windows detected? Using %s",
                           dfvfs_utils.reconstruct_full_path(systemroot[0]))
        path_str = dfvfs_utils.get_relative_path(systemroot[0])
        self.set_var("%SystemRoot%", path_str)

        # %SystemDrive% is always '/'
        self.set_var('%SystemDrive%', '/')
示例#4
0
    def Open(self, path, ascii_codepage='cp1252'):
        LOGGER.info("open registry %s", path)
        """ Opens a path within the dfVFS volume """
        realpath = path.replace('\\', '/')
        if path in self.not_present:
            return None

        # check for variables and if we know them
        for match in re.finditer('%[a-zA-Z0-9_]+%', path):
            key = match.group(0)
            val = self.windows_system.get_var(key)
            if val:
                realpath = realpath.replace(key, val)
            else:
                LOGGER.warning("Could not resolve variable %s", key)
                return None

        if realpath.lower().startswith('c:/'):  # catch absolute paths
            realpath = '/' + realpath[3:]
        if not realpath[0] == '/':
            realpath = '/' + realpath

        if realpath in self.not_present:
            return None

        path_specs = list(
            self.dfvfs.find_paths([realpath], partitions=[self.partition]))
        if not path_specs:
            LOGGER.warning("Could not find requested registry hive %s [%s]",
                           path, realpath)
            self.not_present.add(path)
            self.not_present.add(realpath)
            return None
        if len(path_specs) > 1:
            LOGGER.warning(
                "Found multiple registry hives for query %s, using %s", path,
                dfvfs_utils.reconstruct_full_path(path_specs[0]))

        # extract the file locally
        filename = realpath.replace('/', '_')
        dfvfs_utils.export_file(path_specs[0], self.tmpfs, filename)

        try:
            file_object = self.tmpfs.open(filename, 'rb')
        except ResourceNotFound:
            files = self.tmpfs.listdir("/")
            LOGGER.warning("Could not open registry hive %s [%s] (%s)", path,
                           realpath, files)
            return None
        self.open_handles.append((filename, file_object))
        reg_file = regfile_impl.REGFWinRegistryFile(
            ascii_codepage=ascii_codepage)
        reg_file.Open(file_object)

        return reg_file
示例#5
0
    def __init__(self, dfvfs, partition):
        """
        Creates a new WindowsSystem instance and extracts basic information
        :param dfvfs[DFVFSHelper]: DFVFSHelper-object to access data
        :param partition[PathSpec]: A DFVFS-PathSpec object identifying the root of the
                system partition
        """
        super(WindowsSystem, self).__init__()
        self.dfvfs = dfvfs
        self.partition = partition

        LOGGER.info("Creating new WindowsSystem for %s",
                    dfvfs_utils.reconstruct_full_path(partition))

        self.users = {}
        self.vars = {}
        self._read_system_infos()  # MUST be done first, since registry access needs %SystemRoot% to be set
        self._reg_reader = RegistryFileOpener(self.dfvfs, self.partition, self)
        self._registry = dfwinreg_reg.WinRegistry(registry_file_reader=self._reg_reader)
        self._read_users()  # get user accounts from registry
        self._patch_dfwinreg()  # patch user SIDs into registry library TODO: Use dfwinreg native when bugs are fixed