Ejemplo n.º 1
0
  def __init__(self, input_reader=None, output_writer=None):
    """Initializes the CLI tool object.

    Args:
      input_reader (InputReader): the input reader.
                    The default is None which indicates the use of the stdin
                    input reader.
      output_writer (OutputWriter): the output writer.
                     The default is None which indicates the use of the stdout
                     output writer.
    """
    super(PstealTool, self).__init__(
        input_reader=input_reader, output_writer=output_writer)

    self._analysis_front_end = psort.PsortFrontend()
    self._command_line_arguments = None
    self._deduplicate_events = True
    self._enable_sigsegv_handler = False
    self._extraction_front_end = log2timeline.Log2TimelineFrontend()
    self._force_preprocessing = False
    self._hasher_names_string = None
    self._number_of_extraction_workers = 0
    self._options = None
    self._output_format = u'dynamic'
    self._output_filename = None
    self._output_module = None
    self._parser_filter_expression = None
    self._preferred_year = None
    self._single_process_mode = False
    self._source_type = None
    self._status_view_mode = u'window'
    self._time_slice = None
    self._use_time_slicer = False
    self._yara_rules_string = None
Ejemplo n.º 2
0
    def __init__(self, input_reader=None, output_writer=None):
        """Initializes the CLI tool object.

    Args:
      input_reader (Optional[InputReader]): input reader, where None indicates
          that the stdin input reader should be used.
      output_writer (Optional[OutputWriter]): output writer, where None
          indicates that the stdout output writer should be used.
    """
        super(Log2TimelineTool, self).__init__(input_reader=input_reader,
                                               output_writer=output_writer)
        self._command_line_arguments = None
        self._enable_sigsegv_handler = False
        self._filter_expression = None
        self._front_end = log2timeline.Log2TimelineFrontend()
        self._number_of_extraction_workers = 0
        self._output = None
        self._source_type = None
        self._source_type_string = u'UNKNOWN'
        self._status_view_mode = u'linear'
        self._stdout_output_writer = isinstance(self._output_writer,
                                                cli_tools.StdoutOutputWriter)
        self._temporary_directory = None
        self._text_prepend = None
        self._worker_memory_limit = None

        self.dependencies_check = True
        self.list_output_modules = False
        self.show_info = False
Ejemplo n.º 3
0
    def __init__(self, input_reader=None, output_writer=None):
        """Initializes the CLI tool object.

    Args:
      input_reader: the input reader (instance of InputReader).
                    The default is None which indicates the use of the stdin
                    input reader.
      output_writer: the output writer (instance of OutputWriter).
                     The default is None which indicates the use of the stdout
                     output writer.
    """
        super(Log2TimelineTool, self).__init__(input_reader=input_reader,
                                               output_writer=output_writer)
        self._command_line_arguments = None
        self._enable_sigsegv_handler = False
        self._filter_expression = None
        self._foreman_verbose = False
        self._front_end = log2timeline.Log2TimelineFrontend()
        self._number_of_extraction_workers = 0
        self._stdout_output_writer = isinstance(self._output_writer,
                                                cli_tools.StdoutOutputWriter)
        self._source_type = None
        self._source_type_string = u'UNKNOWN'
        self._status_view_mode = u'linear'
        self._output = None

        self.dependencies_check = True
        self.list_output_modules = False
        self.show_info = False
Ejemplo n.º 4
0
    def testGetStorageInformation(self):
        """Tests the get storage information function."""
        test_front_end = log2timeline.Log2TimelineFrontend()

        options = test_lib.Options()
        options.source = self._GetTestFilePath(['image.dd'])

        storage_file_path = os.path.join(self._temp_directory, 'plaso.db')

        test_front_end.ParseOptions(options)
        test_front_end.SetStorageFile(storage_file_path=storage_file_path)
        test_front_end.SetRunForeman(run_foreman=False)

        test_front_end.ProcessSource(options)

        try:
            storage_file = storage.StorageFile(storage_file_path,
                                               read_only=True)
        except IOError:
            # This is not a storage file, we should fail.
            self.assertTrue(False)

        # Make sure we can read an event out of the storage.
        event_object = storage_file.GetSortedEntry()
        self.assertIsNotNone(event_object)
Ejemplo n.º 5
0
    def testGetOutputClasses(self):
        """Tests the GetOutputClasses function."""
        test_front_end = log2timeline.Log2TimelineFrontend()
        output_classes = list(test_front_end.GetOutputClasses())

        self.assertIsNotNone(output_classes)

        available_output_names = [name for name, _ in output_classes]
        self.assertIn(u'dynamic', available_output_names)
        self.assertIn(u'json', available_output_names)
Ejemplo n.º 6
0
    def testGetOutputModulesInformation(self):
        """Tests the _GetOutputModulesInformation function."""
        test_front_end = log2timeline.Log2TimelineFrontend()
        modules_info = test_front_end._GetOutputModulesInformation()

        self.assertIsNotNone(modules_info)

        available_module_names = [name for name, _ in modules_info]
        self.assertIn(u'dynamic', available_module_names)
        self.assertIn(u'json', available_module_names)
Ejemplo n.º 7
0
    def testGetFiltersInformation(self):
        """Tests the _GetFiltersInformation function."""
        test_front_end = log2timeline.Log2TimelineFrontend()
        filters_info = test_front_end._GetFiltersInformation()

        self.assertIsNotNone(filters_info)

        available_filter_names = [name for name, _ in filters_info]
        self.assertIn(u'DynamicFilter', available_filter_names)
        self.assertIn(u'EventObjectFilter', available_filter_names)
Ejemplo n.º 8
0
    def testGetPluginData(self):
        """Tests the GetPluginData function."""
        test_front_end = log2timeline.Log2TimelineFrontend()
        plugin_info = test_front_end.GetPluginData()

        self.assertIn(u'Hashers', plugin_info)
        available_hasher_names = []
        for hasher_info in plugin_info[u'Hashers']:
            available_hasher_names.append(hasher_info[0])
        self.assertIn(u'sha256', available_hasher_names)
        self.assertIn(u'sha1', available_hasher_names)

        self.assertIn(u'Parsers', plugin_info)
        self.assertIsNotNone(plugin_info[u'Parsers'])
        self.assertIn(u'Plugins', plugin_info)
        self.assertIsNotNone(plugin_info[u'Plugins'])
Ejemplo n.º 9
0
    def __init__(self, input_reader=None, output_writer=None):
        """Initializes the CLI tool object.

    Args:
      input_reader: the input reader (instance of InputReader).
                    The default is None which indicates the use of the stdin
                    input reader.
      output_writer: the output writer (instance of OutputWriter).
                     The default is None which indicates the use of the stdout
                     output writer.
    """
        super(Log2TimelineTool, self).__init__(input_reader=input_reader,
                                               output_writer=output_writer)
        self._filter_expression = None
        self._foreman_verbose = False
        self._front_end = log2timeline.Log2TimelineFrontend()
        self._output = None
        self.list_timezones = False
        self.list_parsers_and_plugins = False
Ejemplo n.º 10
0
def Main():
    """Start the tool."""
    multiprocessing.freeze_support()

    front_end = log2timeline.Log2TimelineFrontend()

    epilog = u'\n'.join([
        u'', u'Example usage:', u'',
        u'Run the tool against an image (full kitchen sink)',
        u'    log2timeline.py /cases/mycase/plaso.dump ímynd.dd', u'',
        u'Instead of answering questions, indicate some of the options on the',
        u'command line (including data from particular VSS stores).',
        (u'    log2timeline.py -o 63 --vss_stores 1,2 /cases/plaso_vss.dump '
         u'image.E01'), u'',
        u'And that\'s how you build a timeline using log2timeline...', u''
    ])

    description = u'\n'.join([
        u'',
        u'log2timeline is the main front-end to the plaso back-end, used to',
        u'collect and correlate events extracted from a filesystem.', u'',
        u'More information can be gathered from here:',
        u'    http://plaso.kiddaland.net/usage/log2timeline', u''
    ])

    arg_parser = argparse.ArgumentParser(
        description=textwrap.dedent(description),
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=textwrap.dedent(epilog),
        add_help=False)

    # Create few argument groups to make formatting help messages clearer.
    info_group = arg_parser.add_argument_group('Informational Arguments')
    function_group = arg_parser.add_argument_group('Functional Arguments')
    deep_group = arg_parser.add_argument_group('Deep Analysis Arguments')
    performance_group = arg_parser.add_argument_group('Performance Arguments')

    function_group.add_argument(
        '-z',
        '--zone',
        '--timezone',
        dest='timezone',
        action='store',
        type=str,
        default='UTC',
        help=
        (u'Define the timezone of the IMAGE (not the output). This is usually '
         u'discovered automatically by preprocessing but might need to be '
         u'specifically set if preprocessing does not properly detect or to '
         u'overwrite the detected time zone.'))

    function_group.add_argument(
        '-t',
        '--text',
        dest='text_prepend',
        action='store',
        type=unicode,
        default=u'',
        metavar='TEXT',
        help=(u'Define a free form text string that is prepended to each path '
              u'to make it easier to distinguish one record from another in a '
              u'timeline (like c:\\, or host_w_c:\\)'))

    function_group.add_argument(
        '--parsers',
        dest='parsers',
        type=str,
        action='store',
        default='',
        metavar='PARSER_LIST',
        help=
        (u'Define a list of parsers to use by the tool. This is a comma '
         u'separated list where each entry can be either a name of a parser '
         u'or a parser list. Each entry can be prepended with a minus sign '
         u'to negate the selection (exclude it). The list match is an '
         u'exact match while an individual parser matching is a case '
         u'insensitive substring match, with support for glob patterns. '
         u'Examples would be: "reg" that matches the substring "reg" in '
         u'all parser names or the glob pattern "sky[pd]" that would match '
         u'all parsers that have the string "skyp" or "skyd" in it\'s name. '
         u'All matching is case insensitive.'))

    function_group.add_argument(
        '--hashers',
        dest='hashers',
        type=str,
        action='store',
        default='',
        metavar='HASHER_LIST',
        help=(
            u'Define a list of hashers to use by the tool. This is a comma '
            u'separated list where each entry is the name of a hasher. eg. md5,'
            u'sha256.'))

    info_group.add_argument('-h',
                            '--help',
                            action='help',
                            help=u'Show this help message and exit.')

    info_group.add_argument(
        '--logfile',
        action='store',
        metavar='FILENAME',
        dest='logfile',
        type=unicode,
        default=u'',
        help=(u'If defined all log messages will be redirected to this file '
              u'instead the default STDERR.'))

    function_group.add_argument(
        '-p',
        '--preprocess',
        dest='preprocess',
        action='store_true',
        default=False,
        help=(u'Turn on preprocessing. Preprocessing is turned on by default '
              u'when parsing image files, however if a mount point is being '
              u'parsed then this parameter needs to be set manually.'))

    front_end.AddPerformanceOptions(performance_group)

    performance_group.add_argument(
        '--workers',
        dest='workers',
        action='store',
        type=int,
        default=0,
        help=(u'The number of worker threads [defaults to available system '
              u'CPU\'s minus three].'))

    # TODO: seems to be no longer used, remove.
    # function_group.add_argument(
    #     '-i', '--image', dest='image', action='store_true', default=False,
    #     help=(
    #         'Indicates that this is an image instead of a regular file. It is '
    #         'not necessary to include this option if -o (offset) is used, then '
    #         'this option is assumed. Use this when parsing an image with an '
    #         'offset of zero.'))

    front_end.AddVssProcessingOptions(deep_group)

    performance_group.add_argument(
        '--single_thread',
        '--single-thread',
        '--single_process',
        '--single-process',
        dest='single_process',
        action='store_true',
        default=False,
        help=(u'Indicate that the tool should run in a single process.'))

    function_group.add_argument(
        '-f',
        '--file_filter',
        '--file-filter',
        dest='file_filter',
        action='store',
        type=unicode,
        default=None,
        help=(
            u'List of files to include for targeted collection of files to '
            u'parse, one line per file path, setup is /path|file - where each '
            u'element can contain either a variable set in the preprocessing '
            u'stage or a regular expression.'))

    deep_group.add_argument('--scan_archives',
                            dest='scan_archives',
                            action='store_true',
                            default=False,
                            help=argparse.SUPPRESS)

    # This option is "hidden" for the time being, still left in there for testing
    # purposes, but hidden from the tool usage and help messages.
    #    help=('Indicate that the tool should try to open files to extract embedd'
    #          'ed files within them, for instance to extract files from compress'
    #          'ed containers, etc. Be AWARE THAT THIS IS EXTREMELY SLOW.'))

    front_end.AddImageOptions(function_group)

    function_group.add_argument(
        '--partition',
        dest='partition_number',
        action='store',
        type=int,
        default=None,
        help=(u'Choose a partition number from a disk image. This partition '
              u'number should correspond to the partion number on the disk '
              u'image, starting from partition 1.'))

    # Build the version information.
    version_string = u'log2timeline - plaso back-end {0:s}'.format(
        plaso.GetVersion())

    info_group.add_argument('-v',
                            '--version',
                            action='version',
                            version=version_string,
                            help=u'Show the current version of the back-end.')

    info_group.add_argument(
        '--info',
        dest='show_info',
        action='store_true',
        default=False,
        help=u'Print out information about supported plugins and parsers.')

    info_group.add_argument(
        '--show_memory_usage',
        '--show-memory-usage',
        action='store_true',
        default=False,
        dest='foreman_verbose',
        help=(u'Indicates that basic memory usage should be included in the '
              u'output of the process monitor. If this option is not set the '
              u'tool only displays basic status and counter information.'))

    info_group.add_argument(
        '--disable_worker_monitor',
        '--disable-worker-monitor',
        action='store_false',
        default=True,
        dest='foreman_enabled',
        help=
        (u'Turn off the foreman. The foreman monitors all worker processes '
         u'and periodically prints out information about all running workers.'
         u'By default the foreman is run, but it can be turned off using this '
         u'parameter.'))

    front_end.AddExtractionOptions(function_group)

    function_group.add_argument(
        '--output',
        dest='output_module',
        action='store',
        type=unicode,
        default='',
        help=(
            u'Bypass the storage module directly storing events according to '
            u'the output module. This means that the output will not be in the '
            u'pstorage format but in the format chosen by the output module. '
            u'[Please not this feature is EXPERIMENTAL at this time, use at '
            u'own risk (eg. sqlite output does not yet work)]'))

    function_group.add_argument(
        '--serializer-format',
        '--serializer_format',
        dest='serializer_format',
        action='store',
        default='proto',
        metavar='FORMAT',
        help=(u'By default the storage uses protobufs for serializing event '
              u'objects. This parameter can be used to change that behavior. '
              u'The choices are "proto" and "json".'))

    front_end.AddInformationalOptions(info_group)

    arg_parser.add_argument(
        'output',
        action='store',
        metavar='STORAGE_FILE',
        nargs='?',
        type=unicode,
        help=(u'The path to the output file, if the file exists it will get '
              u'appended to.'))

    arg_parser.add_argument(
        'source',
        action='store',
        metavar='SOURCE',
        nargs='?',
        type=unicode,
        help=
        (u'The path to the source device, file or directory. If the source is '
         u'a supported storage media device or image file, archive file or '
         u'a directory, the files within are processed recursively.'))

    arg_parser.add_argument(
        'filter',
        action='store',
        metavar='FILTER',
        nargs='?',
        default=None,
        type=unicode,
        help=(u'A filter that can be used to filter the dataset before it '
              u'is written into storage. More information about the filters '
              u'and it\'s usage can be found here: http://plaso.kiddaland.'
              u'net/usage/filters'))

    # Properly prepare the attributes according to local encoding.
    if front_end.preferred_encoding == 'ascii':
        logging.warning(
            u'The preferred encoding of your system is ASCII, which is not optimal '
            u'for the typically non-ASCII characters that need to be parsed and '
            u'processed. The tool will most likely crash and die, perhaps in a way '
            u'that may not be recoverable. A five second delay is introduced to '
            u'give you time to cancel the runtime and reconfigure your preferred '
            u'encoding, otherwise continue at own risk.')
        time.sleep(5)

    u_argv = [x.decode(front_end.preferred_encoding) for x in sys.argv]
    sys.argv = u_argv
    try:
        options = arg_parser.parse_args()
    except UnicodeEncodeError:
        # If we get here we are attempting to print help in a "dumb" terminal.
        print arg_parser.format_help().encode(front_end.preferred_encoding)
        return False

    if options.timezone == 'list':
        front_end.ListTimeZones()
        return True

    if options.show_info:
        front_end.ListPluginInformation()
        return True

    format_str = (
        u'%(asctime)s [%(levelname)s] (%(processName)-10s) PID:%(process)d '
        u'<%(module)s> %(message)s')

    if options.debug:
        if options.logfile:
            logging.basicConfig(level=logging.DEBUG,
                                format=format_str,
                                filename=options.logfile)
        else:
            logging.basicConfig(level=logging.DEBUG, format=format_str)

        logging_filter = log2timeline.LoggingFilter()
        root_logger = logging.getLogger()
        root_logger.addFilter(logging_filter)
    elif options.logfile:
        logging.basicConfig(level=logging.INFO,
                            format=format_str,
                            filename=options.logfile)
    else:
        logging.basicConfig(level=logging.INFO, format=format_str)

    if not options.output:
        arg_parser.print_help()
        print u''
        arg_parser.print_usage()
        print u''
        logging.error(u'Wrong usage: need to define an output.')
        return False

    try:
        front_end.ParseOptions(options)
        front_end.SetStorageFile(options.output)
    except errors.BadConfigOption as exception:
        arg_parser.print_help()
        print u''
        logging.error(u'{0:s}'.format(exception))
        return False

    # Configure the foreman (monitors workers).
    front_end.SetShowMemoryInformation(show_memory=options.foreman_verbose)
    front_end.SetRunForeman(run_foreman=options.foreman_enabled)

    try:
        front_end.ProcessSource(options)
        logging.info(u'Processing completed.')

    except (KeyboardInterrupt, errors.UserAbort):
        logging.warning(u'Aborted by user.')
        return False

    except errors.SourceScannerError as exception:
        logging.warning(
            (u'Unable to scan for a supported filesystem with error: {0:s}\n'
             u'Most likely the image format is not supported by the '
             u'tool.').format(exception))
        return False

    return True
Ejemplo n.º 11
0
    def testGetDisabledOutputClasses(self):
        """Tests the GetDisabledOutputClasses function."""
        test_front_end = log2timeline.Log2TimelineFrontend()
        output_classes = list(test_front_end.GetDisabledOutputClasses())

        self.assertIsNotNone(output_classes)