def test_unreferenced(walk_everywhere): with open(hive_healed, 'rb') as f: hive = Registry.RegistryHive(f) if walk_everywhere: hive.walk_everywhere() assert len(hive.registry_file.cell_map_allocated - hive.registry_file.cell_map_referenced) == 5 else: hive.registry_file.build_map_free() assert len(hive.registry_file.cell_map_referenced) == 0 assert len(hive.registry_file.cell_map_free) == len( hive.registry_file.cell_map_unallocated) with open(hive_bigdata, 'rb') as f: hive = Registry.RegistryHive(f) if walk_everywhere: hive.walk_everywhere() assert len(hive.registry_file.cell_map_allocated - hive.registry_file.cell_map_referenced) == 0 else: hive.registry_file.build_map_free() assert len(hive.registry_file.cell_map_referenced) == 0 assert len(hive.registry_file.cell_map_free) == len( hive.registry_file.cell_map_unallocated)
def test_unicode_garbage(): s = b'a\x00b\x00\x00\x00c\x00d\x00' assert Registry.DecodeUnicode(s, True) == u'ab\x00' assert Registry.DecodeUnicode(s, False) == u'ab\x00cd' s = b'a\x00b\x00\x00\x00c\x00d\x00e' assert Registry.DecodeUnicode(s, True) == u'ab\x00' with pytest.raises(UnicodeDecodeError): Registry.DecodeUnicode(s, False) s = b'a\x00\x00\x00b\x00\x00\x00\x00\x00' assert Registry.DecodeUnicodeMulti(s, True) == u'a\x00b\x00\x00'
def test_bad_subkey(): with open(hive_bad_subkey, 'rb') as primary: hive = Registry.RegistryHive(primary) with pytest.raises(Registry.WalkException): for subkey_1 in hive.root_key().subkeys(): for subkey_2 in subkey_1.subkeys(): pass
def test_truncated_name(): with open(hive_truncated_name, 'rb') as f: hive = Registry.RegistryHive(f) with pytest.raises(RegistryRecords.ParseException): for subkey in hive.root_key().subkeys(): pass
def get_hive(self): """Get the RegistryHive for this handler. """ if not self.hive: self.hive = Registry.RegistryHive( open(self.primary_registry, 'rb') ) try: if self.log_files[u'LOG']: log_1 = open(self.log_files[u'LOG'], 'rb') else: log_1 = None if self.log_files[u'LOG1']: log_2 = open(self.log_files[u'LOG1'], 'rb') else: log_2 = None if self.log_files[u'LOG2']: log_3 = open(self.log_files[u'LOG2'], 'rb') else: log_3 = None recovery_result = self.hive.recover_auto( log_1, log_2, log_3 ) logging.info(u"Recovery Results: {}".format(recovery_result)) except Exception as error: logging.error(u"{}".format(error)) return self.hive
def test_effective_hbins_data_size(): with open(hive_effective_size, 'rb') as f: hive = Registry.RegistryHive(f) assert hive.registry_file.baseblock.effective_hbins_data_size == 487424 assert hive.registry_file.baseblock.get_hbins_data_size( ) != hive.registry_file.baseblock.effective_hbins_data_size
def test_bigdata(): with open(hive_bigdata, 'rb') as f: hive = Registry.RegistryHive(f) key = hive.root_key().subkey('key_with_bigdata') assert key.values_count() == 2 value = key.value() assert hive.registry_file.get_cell( value.key_value.get_data_offset())[:2] == b'db' data = value.data() assert len(data) == 16345 for c in data.decode('windows-1252'): assert c == '1' value = key.value('V') assert hive.registry_file.get_cell( value.key_value.get_data_offset())[:2] == b'db' data = value.data() assert len(data) == 81725 for c in data.decode('windows-1252'): assert c == '2' assert key.value('dont_exist') is None
def test_many_subkeys(): with open(hive_many_subkeys, 'rb') as f: hive = Registry.RegistryHive(f) key = hive.find_key('key_with_many_subkeys') assert key.subkeys_count() == 5000 assert hive.registry_file.get_cell( key.key_node.get_subkeys_list_offset())[:2] == b'ri' allowed_range = range(1, 5000 + 1) for subkey in key.subkeys(): assert int(subkey.name()) in allowed_range key = hive.find_key('key_with_MAny_subkeys\\2119\\find_me') assert key.path() == 'key_with_many_subkeys\\2119\\find_me' assert key.path_partial() == key.path() key = hive.find_key('\\key_with_maNY_sUBkeys\\2119\\Find_me') assert key.path() == 'key_with_many_subkeys\\2119\\find_me' assert key.path_partial() == key.path() key = hive.find_key('key_with_many_subkeys\\2119\\find_me') assert key.path() == 'key_with_many_subkeys\\2119\\find_me' assert key.path_partial() == key.path() key = hive.find_key('key_with_many_subkeys\\3000') assert key is not None key = hive.find_key('key_with_many_subkeys\\3000\\dont_exist') assert key is None key = hive.find_key('key_with_many_subkeys\\dont_exist\\dont_exist') assert key is None
def openRegistryFile(primaryPath): # A primary file is specified here. primary_path = primaryPath # Discover transaction log files to be used to recover the primary file, if required. transaction_logs = RegistryHelpers.DiscoverLogFiles(primary_path) # Open the primary file and each transaction log file discovered. primary_file = open(primary_path, 'rb') if transaction_logs.log_path is not None: log_file = open(transaction_logs.log_path, 'rb') else: log_file = None if transaction_logs.log1_path is not None: log1_file = open(transaction_logs.log1_path, 'rb') else: log1_file = None if transaction_logs.log2_path is not None: log2_file = open(transaction_logs.log2_path, 'rb') else: log2_file = None # Open the hive and recover it, if required. hive = Registry.RegistryHive(primary_file) recovery_result = hive.recover_auto(log_file, log1_file, log2_file) if recovery_result.recovered: print('The hive has been recovered') # Print basic information about the hive. print('Last written timestamp: {}'.format(hive.last_written_timestamp())) print('Last reorganized timestamp: {}'.format( hive.last_reorganized_timestamp())) return hive
def get_hive(reg_hive, log_files): hive = Registry.RegistryHive(open(reg_hive, 'rb')) try: if log_files['LOG'] != None: log0 = open(log_files[u'LOG'], 'rb') else: log0 = None if log_files['LOG1'] != None: log1 = open(log_files[u'LOG1'], 'rb') else: log1 = None if log_files['LOG2'] != None: log2 = open(log_files[u'LOG2'], 'rb') else: log2 = None recovery_result = hive.recover_auto(log0, log1, log2) # print(u"Recovery Results: {}".format(recovery_result)) except Exception as error: pass return hive
def test_bad_log3(): with open(hive_bad_log3, 'rb') as primary, open(hive_bad_log3_log1, 'rb') as log1, open( hive_bad_log3_log2, 'rb') as log2: hive = Registry.RegistryHive(primary) with pytest.raises(Registry.AutoRecoveryException): hive.recover_auto(None, log1, log2)
def _open_hive(self): """Open a registry hive with yarp. Must be an open file object with read permissions. Will attempt to recover the hive with transaction logs if present. """ self.hive = Registry.RegistryHive(self.reg_file) self._recover_hive()
def test_hive_save(): def check_saved_hive(filepath): with open(filepath, 'rb') as recovered: hive_recovered = Registry.RegistryHive(recovered) assert not hive_recovered.registry_file.baseblock.is_file_dirty hive_recovered.walk_everywhere() tmp_file = path.join(HIVES_DIR, 'temphive_delete_me') with open(hive_dirty_old, 'rb') as primary, open(hive_dirty_old_log, 'rb') as log: hive = Registry.RegistryHive(primary) with pytest.raises(RegistryFile.NotSupportedException): hive.registry_file.save_recovered_hive(tmp_file) with open(hive_dirty_old, 'rb') as primary, open(hive_dirty_old_log, 'rb') as log: hive = Registry.RegistryHive(primary) hive.recover_old(log) hive.registry_file.save_recovered_hive(tmp_file) check_saved_hive(tmp_file) with open(hive_dirty_new1, 'rb') as primary, open(hive_dirty_new1_log1, 'rb') as log1, open( hive_dirty_new1_log2, 'rb') as log2: hive = Registry.RegistryHive(primary) hive.recover_new(log1, log2) hive.registry_file.save_recovered_hive(tmp_file) check_saved_hive(tmp_file) with open(hive_dirty_new2, 'rb') as primary, open(hive_dirty_new2_log1, 'rb') as log1, open( hive_dirty_new2_log2, 'rb') as log2: hive = Registry.RegistryHive(primary) hive.recover_new(log1, log2) hive.registry_file.save_recovered_hive(tmp_file) check_saved_hive(tmp_file) with open(hive_bad_baseblock, 'rb') as primary, open( hive_bad_baseblock_log1, 'rb') as log1, open(hive_bad_baseblock_log2, 'rb') as log2: hive = Registry.RegistryHive(primary) hive.recover_auto(None, log1, log2) hive.registry_file.save_recovered_hive(tmp_file) check_saved_hive(tmp_file) remove(tmp_file)
def test_hive_slack(): with open(hive_slack, 'rb') as f: hive = Registry.RegistryHive(f) assert len(hive.effective_slack) == 0 hive.walk_everywhere() assert len(hive.effective_slack) > 0 assert b'SLCK' in hive.effective_slack
def test_bogus_keynames(): with open(hive_bogus_keynames, 'rb') as primary: hive = Registry.RegistryHive(primary) for k in hive.root_key().subkeys(): assert k.name() == 'testnew\r\nne' or k.name() == 'testnu\x00l' assert hive.find_key('testnew\r\nne') is not None assert hive.find_key('testnu\x00l') is not None
def test_data_slack(): with open(hive_bigdata, 'rb') as f: hive = Registry.RegistryHive(f) value = hive.root_key().subkey('key_with_bigdata').value() slack_list = value.data_slack() assert len(slack_list) == 4 for slack in slack_list: assert len(slack) == 4 or len(slack) == 16347 for c in slack.decode('windows-1252'): assert c == '\x00' with open(hive_strings, 'rb') as primary: hive = Registry.RegistryHive(primary) value = hive.find_key('key').value('3') assert value.data_slack() == [b'w Valu']
def test_strings(): with open(hive_strings, 'rb') as primary: hive = Registry.RegistryHive(primary) key = hive.find_key('key') assert key.value().data() == u'test тест\x00' assert key.value('1').data() == b'test' assert key.value('2').data() == u'test тест\x00' assert key.value('3').data() == u'test тест \x00'
def test_truncated(): with open(hive_truncated, 'rb') as f: hive = Registry.RegistryHiveTruncated(f) for i in hive.scan(): assert type(i) is Registry.RegistryKey assert i.name() in [ '{6214ff27-7b1b-41a3-9ae4-5fb851ffed63}', 'key_with_many_subkeys' ] or int(i.name()) > 0
def test_recovery_not_required(): with open(hive_dirty_old_recovered, 'rb') as recovered: hive = Registry.RegistryHive(recovered) dummy = BytesIO() with pytest.raises(RegistryFile.RecoveryException): hive.recover_old(dummy) with pytest.raises(RegistryFile.RecoveryException): hive.recover_new(dummy)
def test_dirty_old(): with open(hive_dirty_old, 'rb') as primary, open(hive_dirty_old_log, 'rb') as log: hive = Registry.RegistryHive(primary) key_1 = hive.find_key('\\key_with_many_subkeys\\1') assert key_1 is not None key_5000_1 = hive.find_key( 'key_with_many_subkeys\\5000\\find_me_in_log') assert key_5000_1 is None value_4500 = hive.find_key('key_with_many_subkeys\\4500').value('v') assert value_4500 is None hive.recover_old(log) key_1 = hive.find_key('\\key_with_many_subkeys\\1') assert key_1 is None key_5000_1 = hive.find_key( 'key_with_many_subkeys\\5000\\find_me_in_log') assert key_5000_1 is not None timestamp_1 = key_5000_1.last_written_timestamp() value_4500 = hive.find_key('key_with_many_subkeys\\4500').value('V') assert value_4500 is not None assert value_4500.data() == ['a\x00', 'bb\x00', 'ccc\x00', '\x00'] with open(hive_dirty_old_recovered, 'rb') as recovered: hive_r = Registry.RegistryHive(recovered) key_5000_1_r = hive_r.find_key( 'key_with_many_subkeys\\5000\\find_me_in_log') timestamp_2 = key_5000_1_r.last_written_timestamp() value_4500_r = hive_r.find_key( 'key_with_many_subkeys\\4500').value('v') assert timestamp_1 == timestamp_2 assert value_4500.data() == value_4500_r.data()
def test_duplicate_subkeys(): with open(hive_duplicate_subkeys, 'rb') as f: hive = Registry.RegistryHive(f) with pytest.raises(Registry.WalkException): key = hive.root_key().subkey('key_with_many_subkeys') assert key is not None for subkey in key.subkeys(): pass
def test_dirty_new2(): with open(hive_dirty_new2, 'rb') as primary, open(hive_dirty_new2_log1, 'rb') as log1, open( hive_dirty_new2_log2, 'rb') as log2: hive = Registry.RegistryHive(primary) assert hive.registry_file.baseblock.validate_checksum() assert hive.registry_file.log_apply_count == 0 hive.recover_new(log1, log2) assert hive.registry_file.log_apply_count == 1 assert hive.registry_file.last_sequence_number == 5
def test_garbage(): with open(hive_garbage, 'rb') as f: hive = Registry.RegistryHive(f) assert hive.registry_file.baseblock.get_hbins_data_size( ) == hive.registry_file.baseblock.effective_hbins_data_size == 4096 cnt = 0 for hive_bin in hive.registry_file.hive_bins(): cnt += 1 assert cnt == 1
def test_multisz(): with open(hive_multisz, 'rb') as primary: hive = Registry.RegistryHive(primary) key = hive.find_key('key') value_1 = key.value('1') value_2 = key.value('2') assert key.value() is None assert value_1.data() == [] l = value_2.data() assert len(l) == 3 and l[0] == u'привет\x00' and l[ 1] == u'как дела?\x00' and l[2] == '\x00'
def test_extended_ascii(): with open(hive_extended_ascii, 'rb') as f: hive = Registry.RegistryHive(f) key = hive.find_key(u'ëigenaardig') assert key is not None assert key.key_node.get_flags() & RegistryRecords.KEY_COMP_NAME > 0 assert key.path() == u'ëigenaardig' assert key.path_partial() == key.path() value = key.value(u'ëigenaardig') assert value.key_value.get_flags( ) & RegistryRecords.VALUE_COMP_NAME > 0 assert value.data() == u'ëigenaardig\x00'
def test_new_flags(): with open(hive_new_flags, 'rb') as primary: hive = Registry.RegistryHive(primary) key_1 = hive.find_key('1') assert key_1 is not None key_2 = hive.find_key('1\\2') assert key_2 is not None assert key_1.key_node.get_virtualization_control_flags() == 0 assert key_1.key_node.get_user_flags_new() == 0 assert key_2.key_node.get_virtualization_control_flags() == 0 assert key_2.key_node.get_user_flags_new( ) == RegistryRecords.KEY_FLAG_32BIT assert key_2.key_node.get_user_flags_old() == 0
def test_deleted_tree_partial_path(): with open(hive_deleted_tree_partial_path, 'rb') as f: hive = Registry.RegistryHive(f) hive.walk_everywhere() scanner = RegistryRecover.Scanner(hive) c = 0 for i in scanner.scan(): assert type(i) is Registry.RegistryKey assert i.path_partial() in [ '3', '3\\4', '3\\4\\5', '3\\4\\New Key #1' ] c += 1 assert c == 4
def test_deleted_value_assoc(): with open(hive_deleted_data, 'rb') as f: hive = Registry.RegistryHive(f) hive.walk_everywhere() key = hive.find_key('123') c = 0 for value in key.remnant_values(): assert value.name() == 'v2' assert value.type_raw() == RegistryRecords.REG_SZ assert value.data() == '456\x00' c += 1 assert c == 1
def test_wrong_order(): with open(hive_wrong_order, 'rb') as f: hive = Registry.RegistryHive(f) c = 0 with pytest.raises(Registry.WalkException): for subkey in hive.find_key('1').subkeys(): c += 1 assert c == 1 with pytest.raises(Registry.WalkException): for subkey in hive.find_key('2').subkeys(): c += 1 assert c == 4
def create_dictionary(registry): """ The create_dictionary function creates a list of dictionaries where keys are the ROT-13 decoded app names and values are the raw hex data of said app. :param registry: Registry Hive to process :return: apps_list, A list containing dictionaries for each app """ try: # Open the registry file to be parsed registry_file = open(registry, "rb") reg = Registry.RegistryHive(registry_file) except (IOError, UnicodeDecodeError) as e: msg = 'Invalid NTUSER.DAT path or Registry ID.' print('[-]', msg) logging.error(msg) sys.exit(2) # Navigate to the UserAssist key ua_key = reg.find_key( ('SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer' '\\UserAssist')) if ua_key is None: msg = 'UserAssist Key not found in Registry file.' print('[-]', msg) logging.error(msg) sys.exit(3) apps_list = [] # Loop through each subkey in the UserAssist key for ua_subkey in ua_key.subkeys(): # For each subkey in the UserAssist key, detect a subkey # called Count that has more than 0 values to parse. if(ua_subkey.subkey('Count') and ua_subkey.subkey('Count').values_count() > 0): apps = {} for v in ua_subkey.subkey('Count').values(): if sys.version_info[0] == 2: apps[v.name().encode('utf-8').decode( 'rot-13')] = v.data_raw() elif sys.version_info[0] == 3: import codecs enc = codecs.getencoder('rot-13') apps[enc(str(v.name()))[0]] = v.data_raw() apps_list.append(apps) return apps_list