def get_bootkey(cls, syshive: registry.RegistryHive) -> Optional[bytes]: cs = 1 lsa_base = "ControlSet{0:03}".format(cs) + "\\Control\\Lsa" lsa_keys = ["JD", "Skew1", "GBG", "Data"] lsa = syshive.get_key(lsa_base) if not lsa: return None bootkey = '' for lk in lsa_keys: key = syshive.get_key(lsa_base + '\\' + lk) class_data = syshive.read(key.Class + 4, key.ClassLength) if class_data is None: return None bootkey += class_data.decode('utf-16-le') bootkey_str = binascii.unhexlify(bootkey) bootkey_scrambled = bytes([ bootkey_str[cls.bootkey_perm_table[i]] for i in range(len(bootkey_str)) ]) return bootkey_scrambled
def get_hbootkey(cls, samhive: registry.RegistryHive, bootkey: bytes) -> Optional[bytes]: sam_account_path = "SAM\\Domains\\Account" if not bootkey: return None sam_account_key = samhive.get_key(sam_account_path) if not sam_account_key: return None sam_data = None for v in sam_account_key.get_values(): if v.get_name() == 'F': sam_data = samhive.read(v.Data + 4, v.DataLength) if not sam_data: return None revision = sam_data[0x00] if revision == 2: md5 = hashlib.md5() md5.update(sam_data[0x70:0x80] + cls.aqwerty + bootkey + cls.anum) rc4_key = md5.digest() rc4 = ARC4.new(rc4_key) hbootkey = rc4.encrypt(sam_data[0x80:0xA0]) return hbootkey elif revision == 3: # AES encrypted iv = sam_data[0x78:0x88] encryptedHBootKey = sam_data[0x88:0xA8] cipher = AES.new(bootkey, AES.MODE_CBC, iv) hbootkey = cipher.decrypt(encryptedHBootKey) return hbootkey[:16] return None
def get_user_keys(cls, samhive: registry.RegistryHive) -> List[interfaces.objects.ObjectInterface]: user_key_path = "SAM\\Domains\\Account\\Users" user_key = samhive.get_key(user_key_path) if not user_key: return [] return [k for k in user_key.get_subkeys() if k.Name != "Names"]