From ac9304786702b974c6d0ea13680a7ce22925f21e Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 16 Jan 2021 21:43:37 -0800 Subject: [PATCH] Update version to 2021.01.16, readying for PyPI/GH release, and minor syntax fixes. --- hindsight_gui.py | 2 +- pyhindsight/__init__.py | 2 +- pyhindsight/analysis.py | 8 ++++---- pyhindsight/browsers/chrome.py | 24 ++++++++++++------------ pyhindsight/utils.py | 5 +++-- setup.py | 3 +-- spec/file_version_info_cmd.txt | 10 +++++----- spec/file_version_info_gui.txt | 10 +++++----- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/hindsight_gui.py b/hindsight_gui.py index 7854af9..d81f64b 100644 --- a/hindsight_gui.py +++ b/hindsight_gui.py @@ -150,7 +150,7 @@ def do_run(): # Hindsight version info log.info( - '\n' + '#' * 80 + '\n### Hindsight v{} (https://github.com/obsidianforensics/hindsight) ###\n' + '\n' + '#' * 80 + '\n### Hindsight v{} (https://github.com/obsidianforensics/hindsight) ###\n' .format(pyhindsight.__version__) + '#' * 80) if 'windows' in ui_selected_decrypts: diff --git a/pyhindsight/__init__.py b/pyhindsight/__init__.py index 6ea9ab1..8fac4bf 100644 --- a/pyhindsight/__init__.py +++ b/pyhindsight/__init__.py @@ -1,3 +1,3 @@ __author__ = "Ryan Benson" -__version__ = "20201120" +__version__ = "2021.01.16" __email__ = "ryan@dfir.blog" diff --git a/pyhindsight/analysis.py b/pyhindsight/analysis.py index 7352e5b..fdb9319 100644 --- a/pyhindsight/analysis.py +++ b/pyhindsight/analysis.py @@ -790,15 +790,15 @@ def generate_excel(self, output_object): w.write_string(row_number, 2, item.url, gray_url_format) # URL except Exception as e: print(e, item.url, item.location) - w.write_string(row_number, 3, str(item.name), gray_field_format) # cached status // Normal (data cached) - w.write_string(row_number, 4, item.value, gray_value_format) # content-type (size) // image/jpeg (2035 bytes) + w.write_string(row_number, 3, str(item.name), gray_field_format) # status // Normal (data cached) + w.write_string(row_number, 4, item.value, gray_value_format) # type (size) // image/jpeg (35 bytes) w.write(row_number, 5, item.interpretation, gray_value_format) # cookie interpretation w.write(row_number, 6, item.profile, gray_value_format) # Profile w.write(row_number, 16, item.etag, gray_value_format) # ETag w.write(row_number, 17, item.last_modified, gray_value_format) # Last Modified w.write(row_number, 18, item.server_name, gray_value_format) # Server name - w.write(row_number, 19, item.location, gray_value_format) # Cached data location // data_2 [1542523] - w.write(row_number, 20, item.http_headers_str, gray_value_format) # Cached data location // data_2 [1542523] + w.write(row_number, 19, item.location, gray_value_format) # data location // data_2 [1542523] + w.write(row_number, 20, item.http_headers_str, gray_value_format) # headers elif item.row_type.startswith("local storage"): w.write_string(row_number, 0, item.row_type, gray_type_format) # record_type diff --git a/pyhindsight/browsers/chrome.py b/pyhindsight/browsers/chrome.py index 4327853..b03df77 100644 --- a/pyhindsight/browsers/chrome.py +++ b/pyhindsight/browsers/chrome.py @@ -274,7 +274,7 @@ def get_history(self, path, history_file, version, row_type): while compatible_version not in list(query.keys()) and compatible_version > 0: compatible_version -= 1 - if compatible_version is not 0: + if compatible_version != 0: log.info(f' - Using SQL query for History items for Chrome {compatible_version}') try: # Copy and connect to copy of 'History' SQLite DB @@ -344,7 +344,7 @@ def get_media_history(self, path, history_file, version, row_type): while compatible_version not in list(query.keys()) and compatible_version > 0: compatible_version -= 1 - if compatible_version is not 0: + if compatible_version != 0: log.info(f' - Using SQL query for Media History items for Chrome {compatible_version}') try: # Copy and connect to copy of 'Media History' SQLite DB @@ -430,7 +430,7 @@ def get_downloads(self, path, database, version, row_type): while compatible_version not in list(query.keys()) and compatible_version > 0: compatible_version -= 1 - if compatible_version is not 0: + if compatible_version != 0: log.info(f' - Using SQL query for Download items for Chrome v{compatible_version}') try: # Copy and connect to copy of 'History' SQLite DB @@ -517,13 +517,13 @@ def clean(x): if encrypted_value is not None: if len(encrypted_value) >= 2: # If running Chrome on Windows - if sys.platform == 'win32' and self.available_decrypts['windows'] is 1: + if sys.platform == 'win32' and self.available_decrypts['windows'] == 1: try: decrypted_value = win32crypt.CryptUnprotectData(encrypted_value, None, None, None, 0)[1] except: decrypted_value = "" # If running Chrome on OSX - elif sys.platform == 'darwin' and self.available_decrypts['mac'] is 1: + elif sys.platform == 'darwin' and self.available_decrypts['mac'] == 1: try: if not self.cached_key: my_pass = keyring.get_password('Chrome Safe Storage', 'Chrome') @@ -538,7 +538,7 @@ def clean(x): # If running Chromium on Linux. # Unlike Win/Mac, we can decrypt Linux cookies without the user's pw - if decrypted_value is "" and self.available_decrypts['linux'] is 1: + if decrypted_value == "" and self.available_decrypts['linux'] == 1: try: if not self.cached_key: my_pass = 'peanuts' @@ -583,7 +583,7 @@ def get_cookies(self, path, database, version): while compatible_version not in list(query.keys()) and compatible_version > 0: compatible_version -= 1 - if compatible_version is not 0: + if compatible_version != 0: log.info(" - Using SQL query for Cookie items for Chrome v{}".format(compatible_version)) try: # Copy and connect to copy of 'Cookies' SQLite DB @@ -664,7 +664,7 @@ def get_login_data(self, path, database, version): while compatible_version not in list(query.keys()) and compatible_version > 0: compatible_version -= 1 - if compatible_version is not 0: + if compatible_version != 0: log.info(f' - Using SQL query for Login items for Chrome v{compatible_version}') # Copy and connect to copy of 'Login Data' SQLite DB @@ -708,7 +708,7 @@ def get_login_data(self, path, database, version): username_row.row_type = 'login (username)' results.append(username_row) - if row.get('password_value') is not None and self.available_decrypts['windows'] is 1: + if row.get('password_value') is not None and self.available_decrypts['windows'] == 1: try: # Windows is all I've had time to test; Ubuntu uses built-in password manager password = win32crypt.CryptUnprotectData( @@ -734,7 +734,7 @@ def get_login_data(self, path, database, version): while compatible_version not in list(query.keys()) and compatible_version > 0: compatible_version -= 1 - if compatible_version is not 0: + if compatible_version != 0: log.info(f' - Using SQL query for Login Stat items for Chrome v{compatible_version}') # Copy and connect to copy of 'Login Data' SQLite DB @@ -779,7 +779,7 @@ def get_autofill(self, path, database, version): while compatible_version not in list(query.keys()) and compatible_version > 0: compatible_version -= 1 - if compatible_version is not 0: + if compatible_version != 0: log.info(" - Using SQL query for Autofill items for Chrome v{}".format(compatible_version)) try: # Copy and connect to copy of 'Web Data' SQLite DB @@ -1420,7 +1420,7 @@ def expand_language_code(code): prefs['profile']['content_settings']['exceptions']['sound'].items(): if pref_data.get('last_modified'): interpretation = '' - if pref_data.get('setting') is 2: + if pref_data.get('setting') == 2: interpretation = 'Muted site' pref_item = Chrome.PreferenceItem( self.profile_path, url=origin, diff --git a/pyhindsight/utils.py b/pyhindsight/utils.py index 138327d..a6d4cdb 100644 --- a/pyhindsight/utils.py +++ b/pyhindsight/utils.py @@ -159,7 +159,7 @@ def get_ldb_records(ldb_path, prefix=''): try: db = ccl_leveldb.RawLevelDb(ldb_path) except Exception as e: - log.warning(f' - Couldn\'t open {ldb_path} as LevelDB; {e}') + log.warning(f' - Could not open {ldb_path} as LevelDB; {e}') return [] cleaned_records = [] @@ -177,6 +177,7 @@ def get_ldb_records(ldb_path, prefix=''): cleaned_records.append(cleaned_record) + db.close() return cleaned_records @@ -234,7 +235,7 @@ def read_int64(input_bytes, ptr): | | | | | | | | (_| \__ \ | (_| | | | | |_ |_| |_|_|_| |_|\__,_|___/_|\__, |_| |_|\__| __/ | - by @_RyanBenson |___/ v{} + by @_RyanBenson |___/ v{} ################################################################################ '''.format(__version__) diff --git a/setup.py b/setup.py index 6ce2f1d..d7576aa 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ packages=find_packages(), include_package_data=True, scripts=['hindsight.py', 'hindsight_gui.py'], - version='20200607', + version='20210116', description='Browser forensics for Google Chrome/Chromium', url='https://github.com/obsidianforensics/hindsight', author='Ryan Benson', @@ -15,7 +15,6 @@ install_requires=[ 'bottle>=0.12.18', 'keyring>=21.2.1', - # 'plyvel>=1.2', 'pycryptodomex>=3.9.7', # 'pypiwin32>=219', 'pytz>=2020.1', diff --git a/spec/file_version_info_cmd.txt b/spec/file_version_info_cmd.txt index de36978..081a53c 100644 --- a/spec/file_version_info_cmd.txt +++ b/spec/file_version_info_cmd.txt @@ -6,8 +6,8 @@ VSVersionInfo( ffi=FixedFileInfo( # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4) # Set not needed items to zero 0. - filevers=(2, 3, 0, 0), - prodvers=(2, 3, 0, 0), + filevers=(2021, 1, 16, 0), + prodvers=(2021, 1, 16, 0), # Contains a bitmask that specifies the valid bits 'flags'r mask=0x0, # Contains a bitmask that specifies the Boolean attributes of the file. @@ -33,10 +33,10 @@ VSVersionInfo( [StringStruct(u'Comments', u'Internet history forensics for Google Chrome/Chromium'), StringStruct(u'CompanyName', u'dfir.blog'), StringStruct(u'FileDescription', u'Hindsight'), - StringStruct(u'LegalCopyright', u'Copyright© 2012 - 2019 Ryan Benson'), + StringStruct(u'LegalCopyright', u'Copyright© 2012 - 2021 Ryan Benson'), StringStruct(u'ProductName', u'Hindsight'), - StringStruct(u'FileVersion', u'2.3.0'), - StringStruct(u'ProductVersion', u'2.3.0'), + StringStruct(u'FileVersion', u'2021.01.16'), + StringStruct(u'ProductVersion', u'2021.01.16'), StringStruct(u'InternalName', u'Hindsight'), StringStruct(u'OriginalFilename', u'hindsight.exe')]) ]) diff --git a/spec/file_version_info_gui.txt b/spec/file_version_info_gui.txt index 0b25711..4ae7935 100644 --- a/spec/file_version_info_gui.txt +++ b/spec/file_version_info_gui.txt @@ -6,8 +6,8 @@ VSVersionInfo( ffi=FixedFileInfo( # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4) # Set not needed items to zero 0. - filevers=(2, 3, 0, 0), - prodvers=(2, 3, 0, 0), + filevers=(2021, 1, 16, 0), + prodvers=(2021, 1, 16, 0), # Contains a bitmask that specifies the valid bits 'flags'r mask=0x0, # Contains a bitmask that specifies the Boolean attributes of the file. @@ -33,10 +33,10 @@ VSVersionInfo( [StringStruct(u'Comments', u'Internet history forensics for Google Chrome/Chromium'), StringStruct(u'CompanyName', u'dfir.blog'), StringStruct(u'FileDescription', u'Hindsight'), - StringStruct(u'LegalCopyright', u'Copyright© 2012 - 2019 Ryan Benson'), + StringStruct(u'LegalCopyright', u'Copyright© 2012 - 2021 Ryan Benson'), StringStruct(u'ProductName', u'Hindsight'), - StringStruct(u'FileVersion', u'2.3.0'), - StringStruct(u'ProductVersion', u'2.3.0'), + StringStruct(u'FileVersion', u'2021.01.16'), + StringStruct(u'ProductVersion', u'2021.01.16'), StringStruct(u'InternalName', u'Hindsight'), StringStruct(u'OriginalFilename', u'hindsight_gui.exe')]) ])