def testAddProcessingOptions(self): """Tests the AddProcessingOptions function.""" argument_parser = argparse.ArgumentParser( prog=u'log2timeline_test.py', description=u'Test argument parser.', add_help=False, formatter_class=test_lib.SortedArgumentsHelpFormatter) test_tool = log2timeline_tool.Log2TimelineTool() test_tool.AddProcessingOptions(argument_parser) output = self._RunArgparseFormatHelp(argument_parser) self.assertEqual(output, self._EXPECTED_PROCESSING_OPTIONS)
def Main(): """The main function.""" multiprocessing.freeze_support() tool = log2timeline_tool.Log2TimelineTool() if not tool.ParseArguments(): return False if tool.show_info: tool.ShowInfo() return True have_list_option = False if tool.list_hashers: tool.ListHashers() have_list_option = True if tool.list_parsers_and_plugins: tool.ListParsersAndPlugins() have_list_option = True if tool.list_profilers: tool.ListProfilers() have_list_option = True if tool.list_timezones: tool.ListTimeZones() have_list_option = True if have_list_option: return True if tool.dependencies_check and not dependencies.CheckDependencies( verbose_output=False): return False try: tool.ExtractEventsFromSources() except (KeyboardInterrupt, errors.UserAbort): logging.warning('Aborted by user.') return False except (errors.BadConfigOption, errors.SourceScannerError) as exception: logging.warning(exception) return False return True
def testGetPluginData(self): """Tests the _GetPluginData function.""" test_tool = log2timeline_tool.Log2TimelineTool() plugin_info = test_tool._GetPluginData() self.assertIn('Hashers', plugin_info) available_hasher_names = [name for name, _ in plugin_info['Hashers']] self.assertIn('sha256', available_hasher_names) self.assertIn('sha1', available_hasher_names) self.assertIn('Parsers', plugin_info) self.assertIsNotNone(plugin_info['Parsers']) self.assertIn('Parser Plugins', plugin_info) self.assertIsNotNone(plugin_info['Parser Plugins'])
def testShowInfo(self): """Tests the output of the tool in info mode.""" output_writer = test_lib.TestOutputWriter(encoding=self._OUTPUT_ENCODING) test_tool = log2timeline_tool.Log2TimelineTool(output_writer=output_writer) options = test_lib.TestOptions() options.artifact_definitions_path = self._GetTestFilePath(['artifacts']) options.show_info = True test_tool.ParseOptions(options) test_tool.ShowInfo() output = output_writer.ReadOutput() section_headings = [ 'Hashers', 'Parsers', 'Parser Plugins', 'Parser Presets', 'Versions'] for heading in section_headings: self.assertIn(heading, output) self.assertNotIn('<class', output)
def testParseOptions(self): """Tests the ParseOptions function.""" test_artifacts_path = self._GetTestFilePath(['artifacts']) self._SkipIfPathNotExists(test_artifacts_path) test_file_path = self._GetTestFilePath(['testdir']) self._SkipIfPathNotExists(test_file_path) yara_rules_path = self._GetTestFilePath(['rules.yara']) self._SkipIfPathNotExists(yara_rules_path) options = test_lib.TestOptions() options.artifact_definitions_path = test_artifacts_path options.source = test_file_path options.storage_file = 'storage.plaso' options.storage_format = definitions.STORAGE_FORMAT_SQLITE options.task_storage_format = definitions.STORAGE_FORMAT_SQLITE options.yara_rules_path = yara_rules_path output_writer = test_lib.TestOutputWriter( encoding=self._OUTPUT_ENCODING) test_tool = log2timeline_tool.Log2TimelineTool( output_writer=output_writer) test_tool.ParseOptions(options) self.assertIsNotNone(test_tool._yara_rules_string) options = test_lib.TestOptions() options.artifact_definitions_path = test_artifacts_path # ParseOptions will raise if source is not set. with self.assertRaises(errors.BadConfigOption): test_tool.ParseOptions(options) options = test_lib.TestOptions() options.artifact_definitions_path = test_artifacts_path options.source = test_file_path with self.assertRaises(errors.BadConfigOption): test_tool.ParseOptions(options)
def testExtractEventsFromSourcesWithFilestat(self): """Tests the ExtractEventsFromSources function with filestat parser.""" output_writer = test_lib.TestOutputWriter( encoding=self._OUTPUT_ENCODING) test_tool = log2timeline_tool.Log2TimelineTool( output_writer=output_writer) source_path = self._GetTestFilePath(['test_pe.exe']) options = self._CreateExtractionOptions(source_path) options.parsers = 'filestat,pe' with shared_test_lib.TempDirectory() as temp_directory: options.storage_file = os.path.join(temp_directory, 'storage.plaso') options.storage_format = definitions.STORAGE_FORMAT_SQLITE options.task_storage_format = definitions.STORAGE_FORMAT_SQLITE test_tool.ParseOptions(options) test_tool.ExtractEventsFromSources() storage_file = sqlite_file.SQLiteStorageFile() try: storage_file.Open(path=options.storage_file, read_only=True) except IOError as exception: self.fail(( 'Unable to open storage file after processing with error: ' '{0!s}.').format(exception)) # There should be 3 filestat and 3 pe parser generated events. # Typically there are 3 filestat events, but there can be 4 on platforms # that support os.stat_result st_birthtime. expected_event_counters = { 'fs:stat': [3, 4], 'pe:delay_import:import_time': 1, 'pe:import:import_time': 1, 'pe:compilation:compilation_time': 1 } self.CheckEventCounters(storage_file, expected_event_counters)
def testExtractEventsFromSourcesOnVSSImage(self): """Tests the ExtractEventsFromSources function on VSS image.""" test_file_path = self._GetTestFilePath(['vsstest.qcow2']) self._SkipIfPathNotExists(test_file_path) options = self._CreateExtractionOptions(test_file_path) options.unattended = True options.vss_stores = 'all' output_writer = test_lib.TestOutputWriter(encoding=self._OUTPUT_ENCODING) test_tool = log2timeline_tool.Log2TimelineTool(output_writer=output_writer) with shared_test_lib.TempDirectory() as temp_directory: options.storage_file = os.path.join(temp_directory, 'storage.plaso') options.storage_format = definitions.STORAGE_FORMAT_SQLITE options.task_storage_format = definitions.STORAGE_FORMAT_SQLITE test_tool.ParseOptions(options) test_tool.ExtractEventsFromSources() expected_output = [ '', 'Source path\t\t: {0:s}'.format(options.source), 'Source type\t\t: storage media image', 'Processing time\t\t: 00:00:00', '', 'Processing started.', 'Processing completed.', '', 'Number of warnings generated while extracting events: 3.', '', 'Use pinfo to inspect warnings in more detail.', '', ''] output = output_writer.ReadOutput() self._CheckOutput(output, expected_output)
def testExtractEventsFromSourcesOnVSSImage(self): """Tests the ExtractEventsFromSources function on VSS image.""" output_writer = test_lib.TestOutputWriter(encoding='utf-8') test_tool = log2timeline_tool.Log2TimelineTool(output_writer=output_writer) options = test_lib.TestOptions() options.artifact_definitions_path = self._GetTestFilePath(['artifacts']) options.quiet = True options.single_process = True options.status_view_mode = 'none' options.source = self._GetTestFilePath(['vsstest.qcow2']) options.vss_stores = 'all' with shared_test_lib.TempDirectory() as temp_directory: options.storage_file = os.path.join(temp_directory, 'storage.plaso') options.storage_format = definitions.STORAGE_FORMAT_ZIP test_tool.ParseOptions(options) test_tool.ExtractEventsFromSources() expected_output = [ b'', b'Source path\t: {0:s}'.format(options.source.encode('utf-8')), b'Source type\t: storage media image', b'', b'Processing started.', b'Processing completed.', b'', b'Number of errors encountered while extracting events: 1.', b'', b'Use pinfo to inspect errors in more detail.', b'', b''] output = output_writer.ReadOutput() self.assertEqual(output.split(b'\n'), expected_output)
def testExtractEventsFromSourcesWithFilestat(self): """Tests the ExtractEventsFromSources function with filestat parser.""" output_writer = test_lib.TestOutputWriter( encoding=self._OUTPUT_ENCODING) test_tool = log2timeline_tool.Log2TimelineTool( output_writer=output_writer) options = test_lib.TestOptions() options.artifact_definitions_path = self._GetTestFilePath( ['artifacts']) options.quiet = True options.parsers = 'filestat,pe' options.single_process = True options.status_view_mode = 'none' options.source = self._GetTestFilePath(['test_pe.exe']) with shared_test_lib.TempDirectory() as temp_directory: options.storage_file = os.path.join(temp_directory, 'storage.plaso') options.storage_format = definitions.STORAGE_FORMAT_SQLITE test_tool.ParseOptions(options) test_tool.ExtractEventsFromSources() storage_file = sqlite_file.SQLiteStorageFile() try: storage_file.Open(path=options.storage_file, read_only=True) except IOError as exception: self.fail(( 'Unable to open storage file after processing with error: ' '{0:s}.').format(exception)) # There should be 3 filestat and 3 pe parser generated events. events = list(storage_file.GetSortedEvents()) self.assertEqual(len(events), 6)
def Main(): """The main function.""" multiprocessing.freeze_support() tool = log2timeline_tool.Log2TimelineTool() if not tool.ParseArguments(): return False if tool.show_info: tool.ShowInfo() return True if tool.show_troubleshooting: print('Using Python version {0!s}'.format(sys.version)) print() print('Path: {0:s}'.format(os.path.abspath(__file__))) print() print(tool.GetVersionInformation()) print() dependencies.CheckDependencies(verbose_output=True) print('Also see: https://plaso.readthedocs.io/en/latest/sources/user/' 'Troubleshooting.html') return True have_list_option = False if tool.list_hashers: tool.ListHashers() have_list_option = True if tool.list_parsers_and_plugins: tool.ListParsersAndPlugins() have_list_option = True if tool.list_profilers: tool.ListProfilers() have_list_option = True if tool.list_timezones: tool.ListTimeZones() have_list_option = True if have_list_option: return True if tool.dependencies_check and not dependencies.CheckDependencies( verbose_output=False): return False try: tool.ExtractEventsFromSources() except (KeyboardInterrupt, errors.UserAbort): logging.warning('Aborted by user.') return False except (errors.BadConfigOption, errors.SourceScannerError) as exception: logging.warning(exception) return False return True
def Main(): """The main function.""" tool = log2timeline_tool.Log2TimelineTool() if not tool.ParseArguments(sys.argv[1:]): return False if tool.show_troubleshooting: print('Using Python version {0!s}'.format(sys.version)) print() print('Path: {0:s}'.format(os.path.abspath(__file__))) print() print(tool.GetVersionInformation()) print() dependencies.CheckDependencies(verbose_output=True) print('Also see: https://plaso.readthedocs.io/en/latest/sources/user/' 'Troubleshooting.html') return True try: tool.CheckOutDated() except KeyboardInterrupt: return False if tool.show_info: tool.ShowInfo() return True have_list_option = False if tool.list_hashers: tool.ListHashers() have_list_option = True if tool.list_parsers_and_plugins: tool.ListParsersAndPlugins() have_list_option = True if tool.list_profilers: tool.ListProfilers() have_list_option = True if tool.list_time_zones: tool.ListTimeZones() have_list_option = True if have_list_option: return True if tool.dependencies_check and not dependencies.CheckDependencies( verbose_output=False): return False try: tool.ExtractEventsFromSources() # Writing to stdout and stderr will raise BrokenPipeError if it # receives a SIGPIPE. except BrokenPipeError: pass except (KeyboardInterrupt, errors.UserAbort): logging.warning('Aborted by user.') return False except (errors.BadConfigOption, errors.SourceScannerError) as exception: # Display message on stdout as well as the log file. print(exception) logging.error(exception) return False return True