def testGetTSKPartitionIdentifiersOnPartitionedImage(self): """Tests the _GetTSKPartitionIdentifiers function on a partitioned image.""" # Test with mediator. test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['tsk_volume_system.raw']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) identifiers = test_scanner._GetPartitionIdentifiers( scan_node, test_options) self.assertEqual(len(identifiers), 2) self.assertEqual(identifiers, ['p1', 'p2']) # Test without mediator. test_scanner = volume_scanner.VolumeScanner() test_options = volume_scanner.VolumeScannerOptions() scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) with self.assertRaises(errors.ScannerError): test_scanner._GetPartitionIdentifiers(scan_node, test_options)
def testScanVolumeOnEncryptedAPFS(self): """Tests the _ScanVolume function on an encrypted APFS image.""" resolver.Resolver.key_chain.Empty() test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['apfs_encrypted.dmg']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) apfs_container_scan_node = scan_node.sub_nodes[4].sub_nodes[0] # Test on volume system root node. base_path_specs = [] test_scanner._ScanVolume(scan_context, apfs_container_scan_node, test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1) # Test on volume system sub node. base_path_specs = [] test_scanner._ScanVolume(scan_context, apfs_container_scan_node.sub_nodes[0], test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1)
def testScanVolumeOnVSS(self): """Tests the _ScanVolume function on VSS.""" test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['vsstest.qcow2']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) vss_scan_node = scan_node.sub_nodes[0] # Test on volume system root node. base_path_specs = [] test_scanner._ScanVolume(scan_context, vss_scan_node, test_options, base_path_specs) self.assertEqual(len(base_path_specs), 2) # Test on volume system sub node. base_path_specs = [] test_scanner._ScanVolume(scan_context, vss_scan_node.sub_nodes[0], test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1)
def testScanVolumeSystemRootOnAPFS(self): """Tests the _ScanVolumeSystemRoot function on an APFS image.""" resolver.Resolver.key_chain.Empty() test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['apfs.dmg']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) apfs_container_scan_node = scan_node.sub_nodes[4].sub_nodes[0] base_path_specs = [] test_scanner._ScanVolumeSystemRoot(scan_context, apfs_container_scan_node, test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1) # Test error conditions. with self.assertRaises(errors.ScannerError): test_scanner._ScanVolumeSystemRoot( scan_context, apfs_container_scan_node.sub_nodes[0], test_options, base_path_specs)
def Enumerate(evidence): """Uses dfVFS to enumerate partitions in a disk / image. Args: evidence: Evidence object to be scanned. Raises: TurbiniaException if source evidence can't be scanned. Returns: list[dfVFS.path_spec]: path specs for identified partitions """ options = volume_scanner.VolumeScannerOptions() options.partitions = ['all'] options.volumes = ['all'] # Not processing volume snapshots options.snapshots = ['none'] options.credentials = evidence.credentials path_specs = [] try: # Setting the volume scanner mediator to None will cause the volume scanner # to operate in unattended mode scanner = volume_scanner.VolumeScanner(mediator=None) path_specs = scanner.GetBasePathSpecs(evidence.local_path, options=options) except dfvfs_errors.ScannerError as e: raise TurbiniaException( 'Could not enumerate partitions [{0!s}]: {1!s}'.format( evidence.local_path, e)) return path_specs
def testGetVSSStoreIdentifiers(self): """Tests the _GetVSSStoreIdentifiers function.""" # Test with mediator. test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['vsstest.qcow2']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) identifiers = test_scanner._GetVSSStoreIdentifiers( scan_node.sub_nodes[0], test_options) self.assertEqual(len(identifiers), 2) self.assertEqual(identifiers, ['vss1', 'vss2']) # Test without mediator. test_scanner = volume_scanner.VolumeScanner() test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['vsstest.qcow2']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) with self.assertRaises(errors.ScannerError): test_scanner._GetVSSStoreIdentifiers(scan_node.sub_nodes[0], test_options) # Test error conditions. with self.assertRaises(errors.ScannerError): test_scanner._GetVSSStoreIdentifiers(None, test_options) scan_node = source_scanner.SourceScanNode(None) with self.assertRaises(errors.ScannerError): test_scanner._GetVSSStoreIdentifiers(scan_node, test_options)
def testScanVolumeOnEncryptedAPFS(self): """Tests the _ScanVolume function on an encrypted APFS image.""" resolver.Resolver.key_chain.Empty() test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['apfs_encrypted.dmg']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = scan_context.GetRootScanNode() self.assertIsNotNone(scan_node) self.assertEqual(scan_node.type_indicator, definitions.TYPE_INDICATOR_OS) self.assertEqual(len(scan_node.sub_nodes), 1) scan_node = scan_node.sub_nodes[0] self.assertIsNotNone(scan_node) self.assertEqual(scan_node.type_indicator, definitions.TYPE_INDICATOR_RAW) self.assertEqual(len(scan_node.sub_nodes), 1) scan_node = scan_node.sub_nodes[0] self.assertIsNotNone(scan_node) self.assertEqual(scan_node.type_indicator, definitions.PREFERRED_GPT_BACK_END) if scan_node.type_indicator == definitions.TYPE_INDICATOR_GPT: self.assertEqual(len(scan_node.sub_nodes), 1) scan_node = scan_node.sub_nodes[0] else: # The pytsk partition back-end yields more than 1 scan node for various # metadata and unallocated parts of the GPT. self.assertEqual(len(scan_node.sub_nodes), 6) scan_node = scan_node.sub_nodes[4] apfs_container_scan_node = scan_node.sub_nodes[0] # Test on volume system root node. base_path_specs = [] test_scanner._ScanVolume(scan_context, apfs_container_scan_node, test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1) # Test on volume system sub node. base_path_specs = [] test_scanner._ScanVolume(scan_context, apfs_container_scan_node.sub_nodes[0], test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1)
def testGetPartitionIdentifiers(self): """Tests the _GetPartitionIdentifiers function.""" test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() # Test error conditions. with self.assertRaises(errors.ScannerError): test_scanner._GetPartitionIdentifiers(None, test_options) scan_node = source_scanner.SourceScanNode(None) with self.assertRaises(errors.ScannerError): test_scanner._GetPartitionIdentifiers(scan_node, test_options)
def run(self, evidence, result): """Task to execute (dfimagetools) FileEntryLister. Args: evidence (Evidence object): The evidence we will process. result (TurbiniaTaskResult): The object to place task results into. Returns: TurbiniaTaskResult object. """ bodyfile_output = os.path.join(self.output_dir, 'file_system.bodyfile') output_evidence = BodyFile(source_path=bodyfile_output) number_of_entries = 0 # Set things up for the FileEntryLister client. We will scan all # partitions in the volume. volume_scanner_options = volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = self.task_config.get('partitions') # Create the FileEntryLister client and generate the path specs # for all available partitions. entry_lister = file_entry_lister.FileEntryLister() base_path_specs = entry_lister.GetBasePathSpecs( evidence.device_path, options=volume_scanner_options) # Iterate over all file entries and generate the output in bodyfile # format. try: with open(bodyfile_output, 'w') as file_object: for file_entry, path_segments in entry_lister.ListFileEntries( base_path_specs): bodyfile_entries = entry_lister.GetBodyfileEntries( file_entry, path_segments) for bodyfile_entry in bodyfile_entries: file_object.write(bodyfile_entry) file_object.write('\n') number_of_entries += 1 output_evidence.number_of_entries = number_of_entries result.add_evidence(output_evidence, evidence.config) status = 'Generated file system timeline containing [{0:d}] entries'.format( number_of_entries) result.close(self, success=True, status=status) except dfvfs_errors.ScannerError as exception: result.log('Error generating bodyfile {0!s}'.format(exception)) status = 'Unable to generate bodyfile using provided evidence data.' result.close(self, success=False, status=status) raise TurbiniaException( 'Could not process volume: {0!s}'.format(exception)) return result
def testScanVolume(self): """Tests the _ScanVolume function.""" test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() scan_context = source_scanner.SourceScannerContext() # Test error conditions. with self.assertRaises(errors.ScannerError): test_scanner._ScanVolume(scan_context, None, test_options, []) scan_node = source_scanner.SourceScanNode(None) with self.assertRaises(errors.ScannerError): test_scanner._ScanVolume(scan_context, scan_node, test_options, [])
def testScanVolumeOnRAW(self): """Tests the _ScanVolume function on a RAW image.""" test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['ext2.raw']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = scan_context.GetRootScanNode() base_path_specs = [] test_scanner._ScanVolume(scan_context, scan_node, test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1)
def Enumerate(evidence, location=None): """Uses dfVFS to enumerate partitions in a disk / image. Args: evidence: Evidence object to be scanned. location: dfVFS partition location to be scanned Raises: TurbiniaException if source evidence can't be scanned. Returns: list[dfVFS.path_spec]: path specs for identified partitions """ options = volume_scanner.VolumeScannerOptions() options.partitions = ['all'] options.volumes = ['all'] if location: log.debug( 'Scanning {0:s} for partition at location {1!s}'.format( evidence.name, location)) # APFS and LVM are volumes rather than partitions. if location.find('apfs') != -1 or location.find('lvm') != -1: options.volumes = [location.replace('/', '')] elif location in ('/', '\\'): options.partitions = [location] else: options.partitions = [location.replace('/', '')] # Not processing volume snapshots options.snapshots = ['none'] options.credentials = evidence.credentials path_specs = [] try: # Setting the volume scanner mediator to None will cause the volume scanner # to operate in unattended mode scanner = volume_scanner.VolumeScanner(mediator=None) path_specs = scanner.GetBasePathSpecs(evidence.local_path, options=options) except dfvfs_errors.ScannerError as e: raise TurbiniaException( 'Could not enumerate partitions [{0!s}]: {1!s}'.format( evidence.local_path, e)) return path_specs
def testScanVolumeSystemRootOnPartitionedImage(self): """Tests the _ScanVolumeSystemRoot function on a partitioned image.""" test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['tsk_volume_system.raw']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) # Test error conditions. with self.assertRaises(errors.ScannerError): test_scanner._ScanVolumeSystemRoot(scan_context, scan_node, test_options, [])
def testGetTSKPartitionIdentifiersOnAPFS(self): """Tests the _GetTSKPartitionIdentifiers function on an APFS image.""" # Test with mediator. test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['apfs.dmg']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) identifiers = test_scanner._GetPartitionIdentifiers( scan_node, test_options) self.assertEqual(len(identifiers), 1) self.assertEqual(identifiers, ['p1'])
def testScanVolumeOnBDE(self): """Tests the _ScanVolume function on a BDE image.""" resolver.Resolver.key_chain.Empty() test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['bdetogo.raw']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = self._GetTestScanNode(scan_context) bde_scan_node = scan_node.sub_nodes[0] base_path_specs = [] test_scanner._ScanVolume(scan_context, bde_scan_node, test_options, base_path_specs) self.assertEqual(len(base_path_specs), 1)
def testGetPartitionIdentifiersOnAPFS(self): """Tests the _GetPartitionIdentifiers function on an APFS image.""" # Test with mediator. test_mediator = TestVolumeScannerMediator() test_scanner = volume_scanner.VolumeScanner(mediator=test_mediator) test_options = volume_scanner.VolumeScannerOptions() test_path = self._GetTestFilePath(['apfs_encrypted.dmg']) self._SkipIfPathNotExists(test_path) scan_context = source_scanner.SourceScannerContext() scan_context.OpenSourcePath(test_path) test_scanner._source_scanner.Scan(scan_context) scan_node = scan_context.GetRootScanNode() self.assertIsNotNone(scan_node) self.assertEqual(scan_node.type_indicator, definitions.TYPE_INDICATOR_OS) self.assertEqual(len(scan_node.sub_nodes), 1) scan_node = scan_node.sub_nodes[0] self.assertIsNotNone(scan_node) self.assertEqual(scan_node.type_indicator, definitions.TYPE_INDICATOR_RAW) self.assertEqual(len(scan_node.sub_nodes), 1) scan_node = scan_node.sub_nodes[0] self.assertIsNotNone(scan_node) self.assertEqual(scan_node.type_indicator, definitions.PREFERRED_GPT_BACK_END) identifiers = test_scanner._GetPartitionIdentifiers( scan_node, test_options) self.assertEqual(len(identifiers), 1) self.assertEqual(identifiers, ['p1'])
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts Windows Event Log providers from the Windows Registry.')) argument_parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=('path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a SOFTWARE or SYSTEM Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume(options.source, options=volume_scanner_options): print( ('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False collector_object = eventlog_providers.EventLogProvidersCollector( debug=options.debug) output_writer_object = StdoutWriter() if not output_writer_object.Open(): print('Unable to open output writer.') print('') return False try: has_results = False for eventlog_provider in collector_object.Collect(scanner.registry): output_writer_object.WriteEventLogProvider(eventlog_provider) has_results = True finally: output_writer_object.Close() if not has_results: print('No Windows Event Log providers found.') return True
def ScanForOperatingSystemVolumes(self, source_path, options=None): """Scans for volumes containing an operating system. Args: source_path (str): source path. options (Optional[dfvfs.VolumeScannerOptions]): volume scanner options. If None the default volume scanner options are used, which are defined in the VolumeScannerOptions class. Returns: bool: True if a volume with an operating system was found. Raises: ScannerError: if the source path does not exists, or if the source path is not a file or directory, or if the format of or within the source file is not supported. """ if not options: options = dfvfs_volume_scanner.VolumeScannerOptions() scan_context = self._ScanSource(source_path) self._source_path = source_path self._source_type = scan_context.source_type base_path_specs = self._GetBasePathSpecs(scan_context, options) if (not base_path_specs or scan_context.source_type == dfvfs_definitions.SOURCE_TYPE_FILE): return False for path_spec in base_path_specs: file_system = dfvfs_resolver.Resolver.OpenFileSystem(path_spec) if path_spec.type_indicator == dfvfs_definitions.TYPE_INDICATOR_OS: mount_point = path_spec else: mount_point = path_spec.parent file_system_searcher = dfvfs_file_system_searcher.FileSystemSearcher( file_system, mount_point) system_directories = [] for system_directory_path_spec in file_system_searcher.Find( find_specs=self._SYSTEM_DIRECTORY_FIND_SPECS): relative_path = file_system_searcher.GetRelativePath( system_directory_path_spec) if relative_path: system_directories.append(relative_path.lower()) if system_directories or len(base_path_specs) == 1: self._file_system_searcher = file_system_searcher self._file_system = file_system self._mount_point = mount_point if self._WINDOWS_SYSTEM_DIRECTORIES.intersection( set(system_directories)): path_resolver = dfvfs_windows_path_resolver.WindowsPathResolver( file_system, mount_point) # TODO: determine Windows directory based on system directories. windows_directory = None for windows_path in self._WINDOWS_DIRECTORIES: windows_path_spec = path_resolver.ResolvePath(windows_path) if windows_path_spec is not None: windows_directory = windows_path break if windows_directory: path_resolver.SetEnvironmentVariable( 'SystemRoot', windows_directory) path_resolver.SetEnvironmentVariable( 'WinDir', windows_directory) registry_file_reader = ( windows_registry. StorageMediaImageWindowsRegistryFileReader( file_system, path_resolver)) winregistry = dfwinreg_registry.WinRegistry( registry_file_reader=registry_file_reader) collector = (environment_variables. WindowsEnvironmentVariablesCollector()) self._environment_variables = list( collector.Collect(winregistry)) self._path_resolver = path_resolver self._windows_directory = windows_directory self._windows_registry = winregistry if system_directories: # TODO: on Mac OS prevent detecting the Recovery volume. break self._filter_generator = ( artifact_filters.ArtifactDefinitionFiltersGenerator( self._artifacts_registry, self._environment_variables, [])) return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts the services information from a SYSTEM Registry file.')) argument_parser.add_argument( '--all', dest='all_control_sets', action='store_true', default=False, help=( 'Process all control sets instead of only the current control set.' )) argument_parser.add_argument( '--diff', dest='diff_control_sets', action='store_true', default=False, help='Only list differences between control sets.') argument_parser.add_argument('--tsv', dest='use_tsv', action='store_true', default=False, help='Use tab separated value (TSV) output.') argument_parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=('path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a SYSTEM Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume(options.source, options=volume_scanner_options): print( ('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False collector_object = services.WindowsServicesCollector(debug=options.debug) output_writer_object = StdoutWriter(use_tsv=options.use_tsv) if not output_writer_object.Open(): print('Unable to open output writer.') print('') return False try: if options.diff_control_sets: has_results = collector_object.Compare(scanner.registry, output_writer_object) else: has_results = False for windows_service in collector_object.Collect( scanner.registry, all_control_sets=options.all_control_sets): output_writer_object.WriteWindowsService(windows_service) has_results = True finally: output_writer_object.Close() if not has_results: print('No Services key found.') return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts Application Compatibility Cache information from ' 'a SYSTEM Registry file.')) argument_parser.add_argument( '--all', dest='all_control_sets', action='store_true', default=False, help=( 'Process all control sets instead of only the current control set.' )) argument_parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=('path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a SYSTEM Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume(options.source, options=volume_scanner_options): print( ('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False output_writer = output_writers.StdoutOutputWriter() if not output_writer.Open(): print('Unable to open output writer.') print('') return False try: collector_object = appcompatcache.AppCompatCacheCollector( debug=options.debug, output_writer=output_writer) # TODO: change collector to generate AppCompatCacheCachedEntry has_results = collector_object.Collect( scanner.registry, all_control_sets=options.all_control_sets) if has_results: for cached_entry in collector_object.cached_entries: output_writer.WriteFiletimeValue( 'Last modification time', cached_entry.last_modification_time) output_writer.WriteValue('Path', cached_entry.path) output_writer.WriteText('\n') finally: output_writer.Close() if not has_results: print('No application compatibility cache entries found.') return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts the program cache from a NTUSER.DAT Registry file.')) argument_parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=('path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a NTUSER.DAT Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') # TODO: add support to select user. mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume(options.source, options=volume_scanner_options): print( ('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False output_writer = output_writers.StdoutOutputWriter() if not output_writer.Open(): print('Unable to open output writer.') print('') return False try: collector_object = programscache.ProgramsCacheCollector( debug=options.debug, output_writer=output_writer) # TODO: change collector to generate ProgramCacheEntry has_results = collector_object.Collect(scanner.registry) finally: output_writer.Close() if not has_results: print('No program cache entries found.') return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts Most Recently Used information from a NTUSER.DAT Registry ' 'file.')) argument_parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=('path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a NTUSER.DAT Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') output_writer = StdoutWriter() if not output_writer.Open(): print('Unable to open output writer.') print('') return False mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume(options.source, options=volume_scanner_options): print( ('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False collector_object = mru.MostRecentlyUsedCollector( debug=options.debug, output_writer=output_writer) # TODO: change collector to generate MostRecentlyUsedEntry result = collector_object.Collect(scanner.registry) if not result: print('No Most Recently Used key found.') else: for mru_entry in collector_object.mru_entries: output_writer.WriteValue('Key path', mru_entry.key_path) output_writer.WriteValue('Value name', mru_entry.value_name) if mru_entry.string: output_writer.WriteValue('String', mru_entry.string) if mru_entry.shell_item_data: shell_item = pyfwsi.item() shell_item.copy_from_byte_stream(mru_entry.shell_item_data) output_writer.WriteShellItem(shell_item) elif mru_entry.shell_item_list_data: shell_item_list = pyfwsi.item_list() shell_item_list.copy_from_byte_stream( mru_entry.shell_item_list_data) for shell_item in iter(shell_item_list.items): output_writer.WriteShellItem(shell_item) output_writer.WriteText('') output_writer.Close() return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts the shell folder class identifiers from the Windows Registry.')) argument_parser.add_argument( '-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( '--db', dest='database', action='store', metavar='shellitems.db', default=None, help='path of the sqlite3 database to write to.') argument_parser.add_argument( '-w', '--windows_version', '--windows-version', dest='windows_version', action='store', metavar='Windows XP', default=None, help='string that identifies the Windows version.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=( 'path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a SOFTWARE Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False if options.database and not options.windows_version: print('Windows version missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig( level=logging.INFO, format='[%(levelname)s] %(message)s') mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume( options.source, options=volume_scanner_options): print(('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False # TODO: map collector to available Registry keys. collector_object = shellfolders.ShellFoldersCollector( debug=options.debug) if options.database: output_writer_object = Sqlite3DatabaseFileWriter( options.database, options.windows_version) else: output_writer_object = StdoutWriter() if not output_writer_object.Open(): print('Unable to open output writer.') print('') return False try: has_results = False for shell_folder in collector_object.Collect(scanner.registry): output_writer_object.WriteShellFolder(shell_folder) has_results = True finally: output_writer_object.Close() if not has_results: print('No shell folder identifiers found.') return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts the cached credentials from a SECURITY Registry file.')) argument_parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help=('enable debug output.')) argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=('path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a SECURITY and SYSTEM Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') output_writer = output_writers.StdoutOutputWriter() if not output_writer.Open(): print('Unable to open output writer.') print('') return False mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume(options.source, options=volume_scanner_options): print( ('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False if scanner.IsSingleFileRegistry(): print('Both SECURITY and SYSYEM Registry files are required.') print('') return False # TODO: map collector to available Registry keys. collector_object = cached_credentials.CachedCredentialsKeyCollector( debug=options.debug, output_writer=output_writer) result = collector_object.Collect(scanner.registry) if not result: print('No Cache key found.') else: output_writer.WriteText('\n') output_writer.Close() return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts time zone information for the Windows Registry.')) argument_parser.add_argument( '-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( '--csv', dest='csv_file', action='store', metavar='time_zones.csv', default=None, help='path of the CSV file to write to.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=( 'path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a SOFTWARE Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig( level=logging.INFO, format='[%(levelname)s] %(message)s') if options.csv_file: output_writer_object = CSVFileWriter(options.csv_file) else: output_writer_object = StdoutWriter() if not output_writer_object.Open(): print('Unable to open output writer.') print('') return False mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume( options.source, options=volume_scanner_options): print(('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False # TODO: map collector to available Registry keys. collector_object = time_zones.TimeZonesCollector(debug=options.debug) result = collector_object.Collect(scanner.registry, output_writer_object) if not result: print('No "Time Zones" key found.') output_writer_object.Close() return True
def testInitialize(self): """Tests the __init__ function.""" test_options = volume_scanner.VolumeScannerOptions() self.assertIsNotNone(test_options)
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser( description=('Checks artifact definitions on a storage media image.')) argument_parser.add_argument( '--artifact_definitions', '--artifact-definitions', dest='artifact_definitions', type=str, metavar='PATH', action='store', help=('Path to a directory or file containing the artifact definition ' '.yaml files.')) argument_parser.add_argument('--back_end', '--back-end', dest='back_end', action='store', metavar='NTFS', default=None, help='preferred dfVFS back-end.') argument_parser.add_argument( '--partitions', '--partition', dest='partitions', action='store', type=str, default=None, help= ('Define partitions to be processed. A range of partitions can be ' 'defined as: "3..5". Multiple partitions can be defined as: "1,3,5" ' '(a list of comma separated values). Ranges and lists can also be ' 'combined as: "1,3..5". The first partition is 1. All partitions ' 'can be specified with: "all".')) argument_parser.add_argument( '--snapshots', '--snapshot', dest='snapshots', action='store', type=str, default=None, help= ('Define snapshots to be processed. A range of snapshots can be ' 'defined as: "3..5". Multiple snapshots can be defined as: "1,3,5" ' '(a list of comma separated values). Ranges and lists can also be ' 'combined as: "1,3..5". The first snapshot is 1. All snapshots can ' 'be specified with: "all".')) argument_parser.add_argument( '--volumes', '--volume', dest='volumes', action='store', type=str, default=None, help= ('Define volumes to be processed. A range of volumes can be defined ' 'as: "3..5". Multiple volumes can be defined as: "1,3,5" (a list ' 'of comma separated values). Ranges and lists can also be combined ' 'as: "1,3..5". The first volume is 1. All volumes can be specified ' 'with: "all".')) argument_parser.add_argument( '-w', '--windows_version', '--windows-version', dest='windows_version', action='store', metavar='Windows XP', default=None, help='string that identifies the Windows version.') argument_parser.add_argument('source', nargs='?', action='store', metavar='image.raw', default=None, help='path of the storage media image.') options = argument_parser.parse_args() if not options.source: print('Path to source storage media image is missing.') print('') argument_parser.print_help() print('') return False if not options.artifact_definitions: print('Path to artifact definitions is missing.') print('') argument_parser.print_help() print('') return False dfimagetools_helpers.SetDFVFSBackEnd(options.back_end) logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') registry = artifacts_registry.ArtifactDefinitionsRegistry() reader = artifacts_reader.YamlArtifactsReader() if os.path.isdir(options.artifact_definitions): registry.ReadFromDirectory(reader, options.artifact_definitions) elif os.path.isfile(options.artifact_definitions): registry.ReadFromFile(reader, options.artifact_definitions) mediator = dfvfs_command_line.CLIVolumeScannerMediator() scanner = volume_scanner.ArtifactDefinitionsVolumeScanner( registry, mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = mediator.ParseVolumeIdentifiersString( options.partitions) if options.snapshots == 'none': volume_scanner_options.snapshots = ['none'] else: volume_scanner_options.snapshots = mediator.ParseVolumeIdentifiersString( options.snapshots) volume_scanner_options.volumes = mediator.ParseVolumeIdentifiersString( options.volumes) try: if not scanner.ScanForOperatingSystemVolumes( options.source, options=volume_scanner_options): print('Unable to retrieve an operating system volume from: {0:s}.'. format(options.source)) print('') return False definitions_with_check_results = {} for artifact_definition in registry.GetDefinitions(): group_only = True for source in artifact_definition.sources: if source.type_indicator != ( artifacts_definitions.TYPE_INDICATOR_ARTIFACT_GROUP): group_only = False break if group_only: # Not interested in results of group-only artifact definitions. continue check_result = scanner.CheckArtifactDefinition(artifact_definition) if check_result.number_of_file_entries: definitions_with_check_results[ artifact_definition.name] = check_result except dfvfs_errors.ScannerError as exception: print('[ERROR] {0!s}'.format(exception), file=sys.stderr) print('') return False except KeyboardInterrupt: print('Aborted by user.', file=sys.stderr) print('') return False print('Aritfact definitions found:') for name, check_result in sorted(definitions_with_check_results.items()): text = '* {0:s} [results: {1:d}]'.format( name, check_result.number_of_file_entries) if check_result.data_formats: text = '{0:s} [formats: {1:s}]'.format( text, ', '.join(sorted(check_result.data_formats))) print(text) print('') return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Extracts the UserAssist information from a NTUSER.DAT Registry file.' )) argument_parser.add_argument( '--codepage', dest='codepage', action='store', metavar='CODEPAGE', default='cp1252', help='the codepage of the extended ASCII strings.') argument_parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='enable debug output.') argument_parser.add_argument( 'source', nargs='?', action='store', metavar='PATH', default=None, help=('path of the volume containing C:\\Windows, the filename of ' 'a storage media image containing the C:\\Windows directory, ' 'or the path of a NTUSER.DAT Registry file.')) options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') output_writer = output_writers.StdoutOutputWriter() if not output_writer.Open(): print('Unable to open output writer.') print('') return False mediator = volume_scanner.WindowsRegistryVolumeScannerMediator() scanner = volume_scanner.WindowsRegistryVolumeScanner(mediator=mediator) volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ['all'] volume_scanner_options.snapshots = ['none'] volume_scanner_options.volumes = ['none'] if not scanner.ScanForWindowsVolume(options.source, options=volume_scanner_options): print( ('Unable to retrieve the volume with the Windows directory from: ' '{0:s}.').format(options.source)) print('') return False # TODO: map collector to available Registry keys. collector_object = userassist.UserAssistCollector( debug=options.debug, output_writer=output_writer) result = collector_object.Collect(scanner.registry) if not result: print('No UserAssist key found.') else: guid = None for user_assist_entry in collector_object.user_assist_entries: if user_assist_entry.guid != guid: print('GUID\t\t: {0:s}'.format(user_assist_entry.guid)) guid = user_assist_entry.guid print('Name\t\t: {0:s}'.format(user_assist_entry.name)) print('Original name\t: {0:s}'.format( user_assist_entry.value_name)) print('') output_writer.Close() return True
def Main(): """The main program function. Returns: bool: True if successful or False if not. """ argument_parser = argparse.ArgumentParser(description=( 'Lists file entries in a directory or storage media image.')) argument_parser.add_argument('--back_end', '--back-end', dest='back_end', action='store', metavar='NTFS', default=None, help='preferred dfVFS back-end.') argument_parser.add_argument( '--output_file', '--output-file', dest='output_file', action='store', metavar='source.hashes', default=None, help=('path of the output file, default is to output to stdout.')) argument_parser.add_argument( '--partitions', '--partition', dest='partitions', action='store', type=str, default=None, help= ('Define partitions to be processed. A range of partitions can be ' 'defined as: "3..5". Multiple partitions can be defined as: "1,3,5" ' '(a list of comma separated values). Ranges and lists can also be ' 'combined as: "1,3..5". The first partition is 1. All partitions ' 'can be specified with: "all".')) argument_parser.add_argument( '--snapshots', '--snapshot', dest='snapshots', action='store', type=str, default=None, help= ('Define snapshots to be processed. A range of snapshots can be ' 'defined as: "3..5". Multiple snapshots can be defined as: "1,3,5" ' '(a list of comma separated values). Ranges and lists can also be ' 'combined as: "1,3..5". The first snapshot is 1. All snapshots can ' 'be specified with: "all".')) argument_parser.add_argument( '--volumes', '--volume', dest='volumes', action='store', type=str, default=None, help= ('Define volumes to be processed. A range of volumes can be defined ' 'as: "3..5". Multiple volumes can be defined as: "1,3,5" (a list ' 'of comma separated values). Ranges and lists can also be combined ' 'as: "1,3..5". The first volume is 1. All volumes can be specified ' 'with: "all".')) argument_parser.add_argument( 'source', nargs='?', action='store', metavar='image.raw', default=None, help='path of the directory or storage media image.') options = argument_parser.parse_args() if not options.source: print('Source value is missing.') print('') argument_parser.print_help() print('') return False helpers.SetDFVFSBackEnd(options.back_end) logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') if options.output_file: output_writer = FileOutputWriter(options.output_file) else: output_writer = StdoutWriter() try: output_writer.Open() except IOError as exception: print('Unable to open output writer with error: {0!s}.'.format( exception)) print('') return False mediator = command_line.CLIVolumeScannerMediator() file_entry_lister = FileEntryLister(mediator=mediator) volume_scanner_options = volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = mediator.ParseVolumeIdentifiersString( options.partitions) if options.snapshots == 'none': volume_scanner_options.snapshots = ['none'] else: volume_scanner_options.snapshots = mediator.ParseVolumeIdentifiersString( options.snapshots) volume_scanner_options.volumes = mediator.ParseVolumeIdentifiersString( options.volumes) return_value = True try: base_path_specs = file_entry_lister.GetBasePathSpecs( options.source, options=volume_scanner_options) if not base_path_specs: print('No supported file system found in source.') print('') return False file_entry_lister.ListFileEntries(base_path_specs, output_writer) print('') print('Completed.') except errors.ScannerError as exception: return_value = False print('') print('[ERROR] {0!s}'.format(exception)) except KeyboardInterrupt: return_value = False print('') print('Aborted by user.') output_writer.Close() return return_value
def run(self, evidence, result): """Task to execute (dfimagetools) FileEntryLister. Args: evidence (Evidence object): The evidence we will process. result (TurbiniaTaskResult): The object to place task results into. Returns: TurbiniaTaskResult object. """ bodyfile_output = os.path.join(self.output_dir, 'file_system.bodyfile') output_evidence = BodyFile(source_path=bodyfile_output) number_of_entries = 0 # Set things up for the FileEntryLister client. We will scan all # partitions in the volume. volume_scanner_options = volume_scanner.VolumeScannerOptions() config_partitions = self.task_config.get('partitions') if config_partitions is None or (len(config_partitions) == 1 and config_partitions[0] == 'all'): volume_scanner_options.partitions = ['all'] volume_scanner_options.volumes = ['all'] else: volume_scanner_options.partitions = [] volume_scanner_options.volumes = [] for partition in config_partitions: if partition.find('apfs') != -1 or partition.find('lvm') != -1: volume_scanner_options.volumes.append(partition) else: volume_scanner_options.partitions.append(partition) volume_scanner_options.snapshots = ['none'] volume_scanner_options.credentials = evidence.credentials # Create the FileEntryLister client and generate the path specs # for all available partitions. entry_lister = file_entry_lister.FileEntryLister() try: base_path_specs = entry_lister.GetBasePathSpecs( evidence.device_path, options=volume_scanner_options) except dfvfs_errors.ScannerError as exception: status = 'Unable to open evidence: {0!s}'.format(exception) result.close(self, success=False, status=status) return result # Iterate over all file entries and generate the output in bodyfile # format. try: bodyfile_fileobj = open(bodyfile_output, 'w', encoding='utf-8') except IOError as exception: status = 'Failed to open local output file: {0!s}'.format(exception) result.close(self, success=False, status=status) return result for base_path_spec in base_path_specs: file_entries_generator = entry_lister.ListFileEntries([base_path_spec]) bodyfile_generator = bodyfile.BodyfileGenerator() try: for file_entry, path_segments in file_entries_generator: for bodyfile_entry in bodyfile_generator.GetEntries(file_entry, path_segments): bodyfile_fileobj.write(bodyfile_entry) bodyfile_fileobj.write('\n') number_of_entries += 1 except (dfvfs_errors.AccessError, dfvfs_errors.BackEndError, dfvfs_errors.MountPointError, dfvfs_errors.PathSpecError, IOError) as exception: status = 'Unable to process file entry: {0!s}'.format(exception) result.log(status) bodyfile_fileobj.close() if number_of_entries > 0: output_evidence.number_of_entries = number_of_entries result.add_evidence(output_evidence, evidence.config) status = 'Generated file system timeline containing [{0:d}] entries'.format( number_of_entries) result.close(self, success=True, status=status) else: status = 'Unable to process any file entries.' result.close(self, success=False, status=status) return result