def main_screen(): global analysis_session analysis_session = AnalysisSession() bottle_args = analysis_session.__dict__ analysis_session.plugin_descriptions = get_plugins_info() bottle_args['plugins_info'] = analysis_session.plugin_descriptions return bottle.template(os.path.join('templates', 'run.tpl'), bottle_args)
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))
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')
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))