Coverage for /private/tmp/im/impacket/impacket/winregistry.py : 57%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. # # This software is provided under under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # Author: Alberto Solino (@agsolino) # # Description: A Windows Registry Library Parser # # Data taken from https://bazaar.launchpad.net/~guadalinex-members/dumphive/trunk/view/head:/winreg.txt # http://sentinelchicken.com/data/TheWindowsNTRegistryFileFormat.pdf # # # ToDo: # # [ ] Parse li records, probable the same as the ri but couldn't find any to probe
# Constants
# Structs ('Magic','"regf'), ('Unknown','<L=0'), ('Unknown2','<L=0'), ('lastChange','<Q=0'), ('MajorVersion','<L=0'), ('MinorVersion','<L=0'), ('0','<L=0'), ('11','<L=0'), ('OffsetFirstRecord','<L=0'), ('DataSize','<L=0'), ('1111','<L=0'), ('Name','48s=""'), ('Remaining1','411s=b""'), ('CheckSum','<L=0xffffffff'), # Sum of all DWORDs from 0x0 to 0x1FB ('Remaining2','3585s=b""'), )
('Magic','"hbin'), ('OffsetFirstHBin','<L=0'), ('OffsetNextHBin','<L=0'), ('BlockSize','<L=0'), )
('DataBlockSize','<l=0'), ('_Data','_-Data','self["DataBlockSize"]*(-1)-4'), ('Data',':'), )
('Magic','"nk'), ('Type','<H=0'), ('lastChange','<Q=0'), ('Unknown','<L=0'), ('OffsetParent','<l=0'), ('NumSubKeys','<L=0'), ('Unknown2','<L=0'), ('OffsetSubKeyLf','<l=0'), ('Unknown3','<L=0'), ('NumValues','<L=0'), ('OffsetValueList','<l=0'), ('OffsetSkRecord','<l=0'), ('OffsetClassName','<l=0'), ('UnUsed','20s=b""'), ('NameLength','<H=0'), ('ClassNameLength','<H=0'), ('_KeyName','_-KeyName','self["NameLength"]'), ('KeyName',':'), )
('Magic','"vk'), ('NameLength','<H=0'), ('DataLen','<l=0'), ('OffsetData','<L=0'), ('ValueType','<L=0'), ('Flag','<H=0'), ('UnUsed','<H=0'), ('_Name','_-Name','self["NameLength"]'), ('Name',':'), )
('Magic','"lf'), ('NumKeys','<H=0'), ('HashRecords',':'), )
('Magic','"lh'), ('NumKeys','<H=0'), ('HashRecords',':'), )
('Magic','"ri'), ('NumKeys','<H=0'), ('HashRecords',':'), )
('Magic','"sk'), ('UnUsed','<H=0'), ('OffsetPreviousSk','<l=0'), ('OffsetNextSk','<l=0'), ('UsageCounter','<L=0'), ('SizeSk','<L=0'), ('Data',':'), )
('OffsetNk','<L=0'), ('KeyName','4s=b""'), )
b'vk': REG_VK, b'lf': REG_LF, b'lh': REG_LH, b'ri': REG_RI, b'sk': REG_SK, }
else: self.fd = open(hive,'rb') LOG.error("Can't find root key!") LOG.warning("Unsupported version (%d.%d) - things might not work!" % (self.__regf['MajorVersion'], self.__regf['MinorVersion']))
# Read the remaining bytes for this hbin
return None
return None else: else: LOG.debug("Unknown type 0x%s" % block['Data'][:2]) return block return None
#blockSize = unpack('<l',data[:calcsize('l')])[0]
# We should receive a VK record return '' # if DataLen < 5 the value itself is stored in the Offset field else:
res = 0 for bb in key.upper(): res *= 37 res += ord(bb) return res % 0x100000000
elif magic == 'lh': hashRec = REG_HASH(hashData) if unpack('<L',hashRec['KeyName'])[0] == self.__getLhHash(key): return hashRec['OffsetNk'] elif magic == 'ri': # Special case here, don't know exactly why, an ri pointing to a NK :-o offset = unpack('<L', hashData[:4])[0] nk = self.__getBlock(offset) if nk['KeyName'] == key: return offset else: LOG.critical("UNKNOWN Magic %s" % magic) sys.exit(1)
# Let's search the hash records for the name # ri points to lf/lh records, so we must parse them before records = b'' for i in range(lf['NumKeys']): offset = unpack('<L', data[:4])[0] l = self.__getBlock(offset) records = records + l['HashRecords'][:l['NumKeys']*8] data = data[4:] data = records
#for record in range(lf['NumKeys']): # We have a match, now let's check the whole record
return None
nk = self.__getBlock(rec['OffsetNk']) if isinstance(nk, REG_NK): print("%s%s" % (self.indent, nk['KeyName'].decode('utf-8'))) self.indent += ' ' if nk['OffsetSubKeyLf'] < 0: self.indent = self.indent[:-2] return lf = self.__getBlock(nk['OffsetSubKeyLf']) else: lf = nk
data = lf['HashRecords']
if lf['Magic'] == 'ri': # ri points to lf/lh records, so we must parse them before records = '' for i in range(lf['NumKeys']): offset = unpack('<L', data[:4])[0] l = self.__getBlock(offset) records = records + l['HashRecords'][:l['NumKeys']*8] data = data[4:] data = records
for key in range(lf['NumKeys']): hashRec = REG_HASH(data[:8]) self.__walkSubNodes(hashRec) data = data[8:]
if isinstance(nk, REG_NK): self.indent = self.indent[:-2]
key = self.findKey(parentKey)
if key is None or key['OffsetSubKeyLf'] < 0: return
lf = self.__getBlock(key['OffsetSubKeyLf']) data = lf['HashRecords'] for record in range(lf['NumKeys']): hashRec = REG_HASH(data[:8]) self.__walkSubNodes(hashRec) data = data[8:]
# Let's strip '\' from the beginning, except for the case of # only asking for the root node
else: #LOG.error("Key %s not found!" % key) return None
if valueType == REG_SZ or valueType == REG_EXPAND_SZ: if type(valueData) is int: print('NULL') else: print("%s" % (valueData.decode('utf-16le'))) elif valueType == REG_BINARY: print('') hexdump(valueData, self.indent) elif valueType == REG_DWORD: print("%d" % valueData) elif valueType == REG_QWORD: print("%d" % (unpack('<Q',valueData)[0])) elif valueType == REG_NONE: try: if len(valueData) > 1: print('') hexdump(valueData, self.indent) else: print(" NULL") except: print(" NULL") elif valueType == REG_MULTISZ: print("%s" % (valueData.decode('utf-16le'))) else: print("Unknown Type 0x%x!" % valueType) hexdump(valueData)
# If we're here.. we have a valid NK record for the key # Now let's searcht the subkeys
# ri points to lf/lh records, so we must parse them before records = '' for i in range(lf['NumKeys']): offset = unpack('<L', data[:4])[0] l = self.__getBlock(offset) records = records + l['HashRecords'][:l['NumKeys']*8] data = data[4:] data = records
# If we're here.. we have a valid NK record for the key # Now let's search its values
else: resp.append(b'default')
# returns a tuple with (ValueType, ValueData) for the requested keyValue
return None
return None
key = self.findKey(className)
if key is None: return None
#print key.dump() if key['OffsetClassName'] > 0: value = self.__getBlock(key['OffsetClassName']) return value['Data'] |