Ejemplo n.º 1
0
def main():

    def write_excel(analysis_session):
        import io

        # Set up a StringIO object to save the XLSX content to before saving to disk
        string_buffer = io.BytesIO()

        # Generate the XLSX content using the function in the AnalysisSession and save it to the StringIO object
        analysis_session.generate_excel(string_buffer)

        # Go back to the beginning (be kind, rewind)
        string_buffer.seek(0)

        # Write the StringIO object to a file on disk named what the user specified
        with open(f'{os.path.join(real_path, analysis_session.output_name)}.{analysis_session.selected_output_format}', 'wb') as file_output:
            shutil.copyfileobj(string_buffer, file_output)

    def write_sqlite(analysis_session):
        output_file = analysis_session.output_name + '.sqlite'

        if os.path.exists(output_file):
            if os.path.getsize(output_file) > 0:
                print(('\nDatabase file "{}" already exists.\n'.format(output_file)))
                user_input = input('Would you like to (O)verwrite it, (R)ename output file, or (E)xit? ')
                over_re = re.compile(r'(^o$|overwrite)', re.IGNORECASE)
                rename_re = re.compile(r'(^r$|rename)', re.IGNORECASE)
                exit_re = re.compile(r'(^e$|exit)', re.IGNORECASE)
                if re.search(exit_re, user_input):
                    print("Exiting... ")
                    sys.exit()
                elif re.search(over_re, user_input):
                    os.remove(output_file)
                    print(("Deleted old \"%s\"" % output_file))
                elif re.search(rename_re, user_input):
                    output_file = "{}_1.sqlite".format(output_file[:-7])
                    print(("Renaming new output to {}".format(output_file)))
                else:
                    print("Did not understand response.  Exiting... ")
                    sys.exit()

        analysis_session.generate_sqlite(output_file)

    def write_jsonl(analysis_session):
        output_file = analysis_session.output_name + '.jsonl'
        analysis_session.generate_jsonl(output_file)

    print(banner)

    # Useful when Hindsight is run from a different directory than where the file is located
    real_path = os.path.dirname(os.path.realpath(sys.argv[0]))

    # Set up the AnalysisSession object, and transfer the relevant input arguments to it
    analysis_session = AnalysisSession()

    # parse_arguments needs the analysis_session as an input to set things like available decrypts
    args = parse_arguments(analysis_session)

    if args.output:
        analysis_session.output_name = args.output

    if args.cache:
        analysis_session.cache_path = args.cache

    analysis_session.selected_output_format = args.format
    analysis_session.browser_type = args.browser_type
    analysis_session.timezone = args.timezone

    if args.log == 'hindsight.log':
        args.log = os.path.join(real_path, args.log)
    analysis_session.log_path = args.log

    # Set up logging
    logging.basicConfig(filename=analysis_session.log_path, level=logging.DEBUG,
                        format='%(asctime)s.%(msecs).03d | %(levelname).01s | %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    log = logging.getLogger(__name__)

    # Hindsight version info
    log.info(
        '\n' + '#' * 80 + '\n###    Hindsight v{} (https://github.com/obsidianforensics/hindsight)    ###\n'
        .format(pyhindsight.__version__) + '#' * 80)

    # Analysis start time
    print((format_meta_output("Start time", str(datetime.datetime.now())[:-3])))

    # Read the input directory
    analysis_session.input_path = args.input
    print((format_meta_output('Input directory', args.input)))
    log.info(f'Reading files from {args.input}')
    input_listing = os.listdir(args.input)
    log.debug("Input directory contents: " + str(input_listing))

    # Search input directory for browser profiles to analyze
    input_profiles = analysis_session.find_browser_profiles(args.input)
    log.info(f' - Found {len(input_profiles)} browser profile(s): {input_profiles}')
    analysis_session.profile_paths = input_profiles

    print((format_meta_output(
        'Output name', f'{analysis_session.output_name}.{analysis_session.selected_output_format}')))

    # Run the AnalysisSession
    print("\n Processing:")
    analysis_session.run()

    print("\n Running plugins:")
    log.info("Plugins:")
    completed_plugins = []

    # First run built-in plugins that ship with Hindsight
    log.info(" Built-in Plugins:")
    for plugin in pyhindsight.plugins.__all__:
        # Check to see if we've already run this plugin (likely from a different path)
        if plugin in completed_plugins:
            continue

        log.debug(" - Loading '{}'".format(plugin))
        try:
            module = importlib.import_module("pyhindsight.plugins.{}".format(plugin))
        except ImportError as e:
            log.error(" - Error: {}".format(e))
            print((format_plugin_output(plugin, "-unknown", 'import failed (see log)')))
            continue
        try:
            log.info(" - Running '{}' plugin".format(module.friendlyName))
            parsed_items = module.plugin(analysis_session)
            print((format_plugin_output(module.friendlyName, module.version, parsed_items)))
            log.info(" - Completed; {}".format(parsed_items))
            completed_plugins.append(plugin)
        except Exception as e:
            print((format_plugin_output(module.friendlyName, module.version, 'failed')))
            log.info(" - Failed; {}".format(e))

    # Then look for any custom user-provided plugins in a 'plugins' directory
    log.info(" Custom Plugins:")

    if real_path not in sys.path:
        sys.path.insert(0, real_path)

    # Loop through all paths, to pick up all potential locations for custom plugins
    for potential_path in sys.path:
        # If a subdirectory exists called 'plugins' or 'pyhindsight/plugins' at the current path, continue on
        for potential_plugin_path in [os.path.join(potential_path, 'plugins'),
                                      os.path.join(potential_path, 'pyhindsight', 'plugins')]:
            if os.path.isdir(potential_plugin_path):
                log.info(" Found custom plugin directory {}:".format(potential_plugin_path))
                try:
                    # Insert the current plugin location to the system path, so we can import plugin modules by name
                    sys.path.insert(0, potential_plugin_path)

                    # Get list of available plugins and run them
                    plugin_listing = os.listdir(potential_plugin_path)

                    log.debug(" - Contents of plugin folder: " + str(plugin_listing))
                    for plugin in plugin_listing:
                        if plugin[-3:] == ".py" and plugin[0] != '_':
                            plugin = plugin.replace(".py", "")

                            # Check to see if we've already run this plugin (likely from a different path)
                            if plugin in completed_plugins:
                                log.debug(" - Skipping '{}'; a plugin with that name has run already".format(plugin))
                                continue

                            log.debug(" - Loading '{}'".format(plugin))
                            try:
                                module = __import__(plugin)
                            except ImportError as e:
                                log.error(" - Error: {}".format(e))
                                print((format_plugin_output(plugin, "-unknown", 'import failed (see log)')))
                                continue
                            try:
                                log.info(" - Running '{}' plugin".format(module.friendlyName))
                                parsed_items = module.plugin(analysis_session)
                                print((format_plugin_output(module.friendlyName, module.version, parsed_items)))
                                log.info(" - Completed; {}".format(parsed_items))
                                completed_plugins.append(plugin)
                            except Exception as e:
                                print((format_plugin_output(module.friendlyName, module.version, 'failed')))
                                log.info(" - Failed; {}".format(e))
                except Exception as e:
                    log.debug(' - Error loading plugins ({})'.format(e))
                    print('  - Error loading plugins')
                finally:
                    # Remove the current plugin location from the system path, so we don't loop over it again
                    sys.path.remove(potential_plugin_path)

    # Check if output directory exists; attempt to create if it doesn't
    if os.path.dirname(analysis_session.output_name) != "" \
            and not os.path.exists(os.path.dirname(analysis_session.output_name)):
        os.makedirs(os.path.dirname(analysis_session.output_name))

    # Get desired output type form args.format and call the correct output creation function
    if analysis_session.selected_output_format == 'xlsx':
        log.info("Writing output; XLSX format selected")
        try:
            print(("\n Writing {}.xlsx".format(analysis_session.output_name)))
            write_excel(analysis_session)
        except IOError:
            type, value, traceback = sys.exc_info()
            print((value, "- is the file open?  If so, please close it and try again."))
            log.error("Error writing XLSX file; type: {}, value: {}, traceback: {}".format(type, value, traceback))

    elif args.format == 'jsonl':
        log.info("Writing output; JSONL format selected")
        print(("\n Writing {}.jsonl".format(analysis_session.output_name)))
        write_jsonl(analysis_session)

    elif args.format == 'sqlite':
        log.info("Writing output; SQLite format selected")
        print(("\n Writing {}.sqlite".format(analysis_session.output_name)))
        write_sqlite(analysis_session)

    # Display and log finish time
    print(f'\n Finish time: {str(datetime.datetime.now())[:-3]}')
    log.info(f'Finish time: {str(datetime.datetime.now())[:-3]}\n\n')
Ejemplo n.º 2
0
def main():
    def write_excel(analysis_session):
        import StringIO

        # Set up a StringIO object to save the XLSX content to before saving to disk
        string_buffer = StringIO.StringIO()

        # Generate the XLSX content using the function in the AnalysisSession and save it to the StringIO object
        analysis_session.generate_excel(string_buffer)

        # Go back to the beginning (be kind, rewind)
        string_buffer.seek(0)

        # Write the StringIO object to a file on disk named what the user specified
        with open(
                "{}.{}".format(
                    os.path.join(real_path, analysis_session.output_name),
                    analysis_session.selected_output_format),
                'wb') as file_output:
            shutil.copyfileobj(string_buffer, file_output)

    def write_sqlite(analysis_session):
        output_file = analysis_session.output_name + '.sqlite'

        if not os.path.exists(output_file):
            analysis_session.generate_sqlite(output_file)
        else:
            print(
                "\n Database file \"{}\" already exists. Please choose a different output location.\n"
                .format(output_file))

    print(banner)

    # Useful when Hindsight is run from a different directory than where the file is located
    real_path = os.path.dirname(os.path.realpath(sys.argv[0]))

    # Set up the AnalysisSession object, and transfer the relevant input arguments to it
    analysis_session = AnalysisSession()

    # parse_arguments needs the analysis_session as an input to set things like available decrypts
    args = parse_arguments(analysis_session)

    if args.output:
        analysis_session.output_name = args.output

    if args.cache:
        analysis_session.cache_path = args.cache

    analysis_session.selected_output_format = args.format
    analysis_session.browser_type = args.browser_type
    analysis_session.timezone = args.timezone

    if args.log == 'hindsight.log':
        args.log = os.path.join(real_path, args.log)
    analysis_session.log_path = args.log

    # Set up logging
    logging.basicConfig(
        filename=analysis_session.log_path,
        level=logging.DEBUG,
        format='%(asctime)s.%(msecs).03d | %(levelname).01s | %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S')
    log = logging.getLogger(__name__)

    # Hindsight version info
    log.info(
        '\n' + '#' * 80 +
        '\n###    Hindsight v{} (https://github.com/obsidianforensics/hindsight)    ###\n'
        .format(pyhindsight.__version__) + '#' * 80)

    # Analysis start time
    print(format_meta_output("Start time", str(datetime.datetime.now())[:-3]))

    # Read the input directory
    analysis_session.input_path = args.input
    print(format_meta_output("Input directory", args.input))
    log.info("Reading files from %s" % args.input)
    input_listing = os.listdir(args.input)
    log.debug("Input directory contents: " + str(input_listing))

    # Search input directory for browser profiles to analyze
    input_profiles = analysis_session.find_browser_profiles(args.input)
    log.info(" - Found {} browser profile(s): {}".format(
        len(input_profiles), input_profiles))
    analysis_session.profile_paths = input_profiles

    print(
        format_meta_output(
            "Output name",
            "{}.{}".format(analysis_session.output_name,
                           analysis_session.selected_output_format)))

    # Run the AnalysisSession
    print("\n Processing:")
    analysis_session.run()

    print("\n Running plugins:")
    log.info("Plugins:")
    completed_plugins = []

    # First run built-in plugins that ship with Hindsight
    log.info(" Built-in Plugins:")
    for plugin in pyhindsight.plugins.__all__:
        # Check to see if we've already run this plugin (likely from a different path)
        if plugin in completed_plugins:
            continue

        log.debug(" - Loading '{}'".format(plugin))
        try:
            module = importlib.import_module(
                "pyhindsight.plugins.{}".format(plugin))
        except ImportError, e:
            log.error(" - Error: {}".format(e))
            print(
                format_plugin_output(plugin, "-unknown",
                                     'import failed (see log)'))
            continue
        try:
            log.info(" - Running '{}' plugin".format(module.friendlyName))
            parsed_items = module.plugin(analysis_session)
            print(
                format_plugin_output(module.friendlyName, module.version,
                                     parsed_items))
            log.info(" - Completed; {}".format(parsed_items))
            completed_plugins.append(plugin)
        except Exception, e:
            print(
                format_plugin_output(module.friendlyName, module.version,
                                     'failed'))
            log.info(" - Failed; {}".format(e))
Ejemplo n.º 3
0
def main():

    def write_excel(analysis_session):
        import StringIO

        # Set up a StringIO object to save the XLSX content to before saving to disk
        string_buffer = StringIO.StringIO()

        # Generate the XLSX content using the function in the AnalysisSession and save it to the StringIO object
        analysis_session.generate_excel(string_buffer)

        # Go back to the beginning (be kind, rewind)
        string_buffer.seek(0)

        # Write the StringIO object to a file on disk named what the user specified
        with open("{}.{}".format(os.path.join(real_path, analysis_session.output_name), analysis_session.selected_output_format), 'wb') as file_output:
            shutil.copyfileobj(string_buffer, file_output)

    def write_sqlite(analysis_session):
        output_file = analysis_session.output_name + '.sqlite'

        if os.path.exists(output_file):
            if os.path.getsize(output_file) > 0:
                print('\nDatabase file "{}" already exists.\n'.format(output_file))
                user_input = raw_input('Would you like to (O)verwrite it, (R)ename output file, or (E)xit? ')
                over_re = re.compile(r'(^o$|overwrite)', re.IGNORECASE)
                rename_re = re.compile(r'(^r$|rename)', re.IGNORECASE)
                exit_re = re.compile(r'(^e$|exit)', re.IGNORECASE)
                if re.search(exit_re, user_input):
                    print("Exiting... ")
                    sys.exit()
                elif re.search(over_re, user_input):
                    os.remove(output_file)
                    print("Deleted old \"%s\"" % output_file)
                elif re.search(rename_re, user_input):
                    output_file = "{}_1.sqlite".format(output_file[:-7])
                    print("Renaming new output to {}".format(output_file))
                else:
                    print("Did not understand response.  Exiting... ")
                    sys.exit()

        analysis_session.generate_sqlite(output_file)

    def write_jsonl(analysis_session):
        output_file = analysis_session.output_name + '.jsonl'
        analysis_session.generate_jsonl(output_file)

    print(banner)

    # Useful when Hindsight is run from a different directory than where the file is located
    real_path = os.path.dirname(os.path.realpath(sys.argv[0]))

    # Set up the AnalysisSession object, and transfer the relevant input arguments to it
    analysis_session = AnalysisSession()

    # parse_arguments needs the analysis_session as an input to set things like available decrypts
    args = parse_arguments(analysis_session)

    if args.output:
        analysis_session.output_name = args.output

    if args.cache:
        analysis_session.cache_path = args.cache

    analysis_session.selected_output_format = args.format
    analysis_session.browser_type = args.browser_type
    analysis_session.timezone = args.timezone

    if args.log == 'hindsight.log':
        args.log = os.path.join(real_path, args.log)
    analysis_session.log_path = args.log

    # Set up logging
    logging.basicConfig(filename=analysis_session.log_path, level=logging.DEBUG,
                        format='%(asctime)s.%(msecs).03d | %(levelname).01s | %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    log = logging.getLogger(__name__)

    # Hindsight version info
    log.info(
        '\n' + '#' * 80 + '\n###    Hindsight v{} (https://github.com/obsidianforensics/hindsight)    ###\n'
        .format(pyhindsight.__version__) + '#' * 80)

    # Analysis start time
    print(format_meta_output("Start time", str(datetime.datetime.now())[:-3]))

    # Read the input directory
    analysis_session.input_path = args.input
    print(format_meta_output("Input directory", args.input))
    log.info("Reading files from %s" % args.input)
    input_listing = os.listdir(args.input)
    log.debug("Input directory contents: " + str(input_listing))

    # Search input directory for browser profiles to analyze
    input_profiles = analysis_session.find_browser_profiles(args.input)
    log.info(" - Found {} browser profile(s): {}".format(len(input_profiles), input_profiles))
    analysis_session.profile_paths = input_profiles

    print(format_meta_output("Output name", "{}.{}".format(analysis_session.output_name, analysis_session.selected_output_format)))

    # Run the AnalysisSession
    print("\n Processing:")
    analysis_session.run()

    print("\n Running plugins:")
    log.info("Plugins:")
    completed_plugins = []

    # First run built-in plugins that ship with Hindsight
    log.info(" Built-in Plugins:")
    for plugin in pyhindsight.plugins.__all__:
        # Check to see if we've already run this plugin (likely from a different path)
        if plugin in completed_plugins:
            continue

        log.debug(" - Loading '{}'".format(plugin))
        try:
            module = importlib.import_module("pyhindsight.plugins.{}".format(plugin))
        except ImportError, e:
            log.error(" - Error: {}".format(e))
            print(format_plugin_output(plugin, "-unknown", 'import failed (see log)'))
            continue
        try:
            log.info(" - Running '{}' plugin".format(module.friendlyName))
            parsed_items = module.plugin(analysis_session)
            print(format_plugin_output(module.friendlyName, module.version, parsed_items))
            log.info(" - Completed; {}".format(parsed_items))
            completed_plugins.append(plugin)
        except Exception, e:
            print(format_plugin_output(module.friendlyName, module.version, 'failed'))
            log.info(" - Failed; {}".format(e))