def shellbag_rec(hive, key, bag_prefix, path_prefix): try: # First, consider the current key, and extract shellbag items result, valueNames, valueTypes = objRegistry.EnumValues( hDefKey=hive, sSubKeyName=key) if result == 0: if valueTypes == None or len(valueTypes) == 0: pass else: for x in range(0, len(valueNames)): if valueNames[x] == "NodeSlot" and valueTypes[ x] == _winreg.REG_DWORD: result, slot = objRegistry.GetDWORDValue( hDefKey=hive, sSubKeyName=key, sValueName=valueNames[x]) slot = str(slot) if result == 0: result, subkeys = objRegistry.EnumKey( hDefKey=hive, sSubKeyName=bags_key + "\\" + slot) if result == 0: for bag in subkeys: result, valueNames2, valueTypes2 = objRegistry.EnumValues( hDefKey=hive, sSubKeyName=bags_key + "\\" + slot + "\\" + bag) if result == 0: if valueTypes2 == None or len( valueTypes2) == 0: pass else: for x in range( 0, len(valueNames2)): if "ItemPos" in valueNames2[ x] and valueTypes2[ x] == _winreg.REG_BINARY: result, itemPos = objRegistry.GetBinaryValue( hDefKey=hive, sSubKeyName=bags_key + "\\" + slot + "\\" + bag, sValueName= valueNames2[x]) if result == 0: cachebin = "" for decimal in itemPos: cachebin += chr( decimal) buf = cachebin block = Block( buf, 0x0, False) offset = 0x10 while True: offset += 0x8 size = block.unpack_word( offset) if size == 0: break elif size < 0x15: pass else: item = ITEMPOS_FILEENTRY( buf, offset, False) shellbags.append({ "path": path_prefix + "\\" + item. name(), "mtime": item. m_date( ), "atime": item. a_date( ), "crtime": item. cr_date( ) }) offset += size except Exception as ex: print ex # Next, recurse into each BagMRU key result, valueNames, valueTypes = objRegistry.EnumValues( hDefKey=hive, sSubKeyName=key) if result == 0: if valueTypes == None or len(valueTypes) == 0: pass else: for x in range(0, len(valueNames)): if re.match("\d+", valueNames[x] ) and valueTypes[x] == _winreg.REG_BINARY: result, reg_value = objRegistry.GetBinaryValue( hDefKey=hive, sSubKeyName=key, sValueName=valueNames[x]) if result == 0: cachebin = "" for decimal in reg_value: cachebin += chr(decimal) buf = cachebin try: l = SHITEMLIST(buf, 0, False) for item in l.items(): # assume there is only one entry in the value, or take the last # as the path component path = path_prefix + "\\" + item.name() shellbags.append({ "path": path, "mtime": item.m_date(), "atime": item.a_date(), "crtime": item.cr_date() }) except OverrunBufferException as ex: raise shellbag_rec(hive, key + "\\" + valueNames[x], bag_prefix + "\\" + valueNames[x], path)
def shellbag_rec(key, bag_prefix, path_prefix): """ Function to recursively parse the BagMRU Registry key structure. Arguments: `key`: The current 'BagsMRU' key to recurse into. `bag_prefix`: A string containing the current subkey path of the relevant 'Bags' key. It will look something like '1\\2\\3\\4'. `path_prefix` A string containing the current human-readable, file system path so far constructed. Throws: """ debug("Considering BagMRU key %s" % (key.path())) debug_increase_indent() try: # First, consider the current key, and extract shellbag items slot = key.value("NodeSlot").value() for bag in bags_key.subkey(str(slot)).subkeys(): for value in [value for value in bag.values() if "ItemPos" in value.name()]: buf = value.value() debug("Slot %s ITEMPOS @ %s" % (str(slot), value.name())) block = Block(buf, 0x0, False) offset = 0x10 while True: offset += 0x8 size = block.unpack_word(offset) if size == 0: break elif size < 0x15: pass else: item = ITEMPOS_FILEENTRY(buf, offset, False) debug("Name: " + item.name()) shellbags.append({ "path": path_prefix + "\\" + item.name(), "mtime": item.m_date(), "atime": item.a_date(), "crtime": item.cr_date(), "source": bag.path() + " @ " + hex(item.offset()), "regsource": bag.path() + "\\" + value.name(), "klwt": key.timestamp() }) offset += size except Registry.RegistryValueNotFoundException: debug("Registry.RegistryValueNotFoundException") pass except Registry.RegistryKeyNotFoundException: debug("Registry.RegistryKeyNotFoundException") pass except: debug("Unexpected error %s" % sys.exc_info()[0]) # Next, recurse into each BagMRU key for value in [value for value in key.values() if re.match("\d+", value.name())]: debug("BagMRU value %s (%s)" % (value.name(), key.path())) try: # TODO(wb): removeme l = SHITEMLIST(value.value(), 0, False) for item in l.items(): # assume there is only one entry in the value, or take the last # as the path component debug("Name: " + item.name()) path = path_prefix + "\\" + item.name() shellbags.append({ "path": path, "mtime": item.m_date(), "atime": item.a_date(), "crtime": item.cr_date(), "source": key.path() + " @ " + hex(item.offset()), "regsource": key.path() + "\\" + value.name(), "klwt": key.timestamp() }) except OverrunBufferException: print key.path() print value.name() raise shellbag_rec(key.subkey(value.name()), bag_prefix + "\\" + value.name(), path) debug_decrease_indent()
def shellbag_rec(hive,key,bag_prefix,path_prefix): try: # First, consider the current key, and extract shellbag items result,valueNames,valueTypes = objRegistry.EnumValues(hDefKey=hive,sSubKeyName=key) if result == 0: if valueTypes == None or len(valueTypes) == 0: pass else: for x in range(0,len(valueNames)): if valueNames[x] == "NodeSlot" and valueTypes[x] == _winreg.REG_DWORD: result,slot = objRegistry.GetDWORDValue(hDefKey=hive,sSubKeyName=key,sValueName=valueNames[x]) slot = str(slot) if result == 0: result,subkeys = objRegistry.EnumKey(hDefKey=hive,sSubKeyName=bags_key+"\\"+slot) if result == 0: for bag in subkeys: result,valueNames2,valueTypes2 = objRegistry.EnumValues(hDefKey=hive,sSubKeyName=bags_key+"\\"+slot+"\\"+bag) if result == 0: if valueTypes2 == None or len(valueTypes2) == 0: pass else: for x in range(0,len(valueNames2)): if "ItemPos" in valueNames2[x] and valueTypes2[x] == _winreg.REG_BINARY: result,itemPos = objRegistry.GetBinaryValue(hDefKey=hive,sSubKeyName=bags_key+"\\"+slot+"\\"+bag,sValueName=valueNames2[x]) if result == 0: cachebin = "" for decimal in itemPos: cachebin += chr(decimal) buf = cachebin block = Block(buf, 0x0, False) offset = 0x10 while True: offset += 0x8 size = block.unpack_word(offset) if size == 0: break elif size < 0x15: pass else: item = ITEMPOS_FILEENTRY(buf, offset, False) shellbags.append({ "path": path_prefix + "\\" + item.name(), "mtime": item.m_date(), "atime": item.a_date(), "crtime": item.cr_date() }) offset += size except Exception as ex: print ex # Next, recurse into each BagMRU key result,valueNames,valueTypes = objRegistry.EnumValues(hDefKey=hive,sSubKeyName=key) if result == 0: if valueTypes == None or len(valueTypes) == 0: pass else: for x in range(0,len(valueNames)): if re.match("\d+", valueNames[x]) and valueTypes[x] == _winreg.REG_BINARY: result,reg_value = objRegistry.GetBinaryValue(hDefKey=hive,sSubKeyName=key,sValueName=valueNames[x]) if result == 0: cachebin = "" for decimal in reg_value: cachebin += chr(decimal) buf = cachebin try: l = SHITEMLIST(buf, 0, False) for item in l.items(): # assume there is only one entry in the value, or take the last # as the path component path = path_prefix + "\\" + item.name() shellbags.append({ "path": path, "mtime": item.m_date(), "atime": item.a_date(), "crtime": item.cr_date() }) except OverrunBufferException as ex: raise shellbag_rec(hive, key+"\\"+valueNames[x],bag_prefix + "\\" + valueNames[x],path)