def decrypt_lsa_key(self, data): logger.debug('[SECURITY] Decrypting LSA key...') if self.lsa_secret_key_vista_type is True: record = LSA_SECRET.from_bytes(data) key = SECURITY.sha256_multi(self.bootkey, record.data[:32]) secret_dec = b'' cipher = AESModeOfOperationECB(key) n = 16 for block in [ record.data[32:][i:i + n] for i in range(0, len(record.data[32:]), n) ]: #terrible, terrible workaround if len(block) < n: block += b'\x00' * (n - len(block)) secret_dec += cipher.decrypt(block) record = LSA_SECRET_BLOB.from_bytes(secret_dec) self.lsa_key = record.secret[52:][:32] else: ctx = hashlib.md5(self.bootkey) for i in range(1000): ctx.update(data[60:76]) cipher = RC4(ctx.digest()) record = cipher.decrypt(data[12:60]) self.lsa_key = record[0x10:0x20] logger.debug('[SECURITY] LSA key value: %s' % self.lsa_key.hex()) return self.lsa_key
async def get_NKLM_key(self): logger.debug('[SECURITY] Fetching NK$LM key...') if self.lsa_key is None: await self.get_lsa_key() value = await self.hive.get_value( 'Policy\\Secrets\\NL$KM\\CurrVal\\default') if value is None: logger.error('[SECURITY] Could not find NL$KM in registry') raise Exception('Could not find NL$KM in registry :(') if self.lsa_secret_key_vista_type is True: self.NKLM_key = b'' record = LSA_SECRET.from_bytes(value[1]) key = SECURITY.sha256_multi(self.lsa_key, record.data[:32]) cipher = AESModeOfOperationECB(key) n = 16 for block in [ record.data[32:][i:i + n] for i in range(0, len(record.data[32:]), n) ]: #terrible, terrible workaround if len(block) < n: block += b'\x00' * (16 - len(block)) self.NKLM_key += cipher.decrypt(block) else: self.NKLM_key = self.decrypt_secret(self.lsa_key, value[1]) logger.debug('[SECURITY] NL$KM key: %s' % self.NKLM_key.hex()) return self.NKLM_key
def decrypt_lsa_key(self, data): if self.lsa_secret_key_vista_type is True: record = LSA_SECRET.from_bytes(data) key = SECURITY.sha256_multi(self.bootkey, record.data[:32]) secret_dec = b'' cipher = AESModeOfOperationECB(key) n = 16 for block in [ record.data[32:][i:i + n] for i in range(0, len(record.data[32:]), n) ]: #terrible, terrible workaround secret_dec += cipher.decrypt(block) record = LSA_SECRET_BLOB.from_bytes(secret_dec) self.lsa_key = record.secret[52:][:32] else: ctx = hashlib.md5(self.bootkey) for i in range(1000): ctx.update(value[60:76]) cipher = RC4.new(ctx.digest()) record = rc4.decrypt(value[12:60]) self.lsa_key = record[0x10:0x20] return self.lsa_key
def get_secrets(self): logger.debug('[SECURITY] get_secrets') self.get_lsa_key() self.dump_dcc() # Let's first see if there are cached entries keys = self.hive.enum_key('Policy\\Secrets') if keys is None: logger.debug('[SECURITY] No cached secrets found in hive') return if b'NL$Control' in keys: keys.remove(b'NL$Control') for key_name in keys: for vl in ['CurrVal', 'OldVal']: key_path = 'Policy\\Secrets\\{}\\{}\\default'.format( key_name, vl) logger.debug('[SECURITY] Parsing secrets in %s' % key_path) v = self.hive.get_value(key_path, False) if v and v[1] != 0: logger.log(1, '[SECURITY] Key %s Value %s' % (key_path, v[1])) if self.lsa_secret_key_vista_type is True: record = LSA_SECRET.from_bytes(v[1]) key = SECURITY.sha256_multi(self.lsa_key, record.data[:32]) secret_dec = b'' cipher = AESModeOfOperationECB(key) n = 16 for block in [ record.data[32:][i:i + n] for i in range(0, len(record.data[32:]), n) ]: #terrible, terrible workaround if len(block) < n: block += b'\x00' * (n - len(block)) secret_dec += cipher.decrypt(block) record = LSA_SECRET_BLOB.from_bytes(secret_dec) dec_blob = record.secret else: dec_blob = self.decrypt_secret(self.lsa_key, v[1]) secret = LSASecret.process(key_name, dec_blob, vl == 'OldVal', self.system_hive) if secret is not None: self.cached_secrets.append(secret) else: logger.debug('[SECURITY] Could not open %s, skipping!' % key_path)
def dump_secrets(self): self.get_lsa_key() self.get_NKLM_key() # Let's first see if there are cached entries keys = self.hive.enum_key('Policy\\Secrets') if keys is None: # No entries return if b'NL$Control' in keys: keys.remove(b'NL$Control') for key_name in keys: for vl in ['CurrVal', 'OldVal']: key_path = 'Policy\\Secrets\\{}\\{}\\default'.format( key_name, vl) print(key_path) v = self.hive.get_value(key_path) if v and v[1] != 0: if self.lsa_secret_key_vista_type is True: record = LSA_SECRET.from_bytes(v[1]) key = SECURITY.sha256_multi(self.lsa_key, record.data[:32]) secret_dec = b'' cipher = AESModeOfOperationECB(key) n = 16 for block in [ record.data[32:][i:i + n] for i in range(0, len(record.data[32:]), n) ]: #terrible, terrible workaround secret_dec += cipher.decrypt(block) record = LSA_SECRET_BLOB.from_bytes(secret_dec) dec_blob = record.secret else: dec_blob = self.decrypt_secret(self.lsa_key, v[1]) secret = LSASecret.process(key_name, dec_blob, vl == 'OldVal') print(str(secret))
def get_NKLM_key(self): if self.lsa_key is None: self.get_lsa_secret_key() value = self.hive.get_value('Policy\\Secrets\\NL$KM\\CurrVal\\default') if value is None: raise Exception('Could not find NL$KM in registry :(') if self.lsa_secret_key_vista_type is True: self.NKLM_key = b'' record = LSA_SECRET.from_bytes(value[1]) key = SECURITY.sha256_multi(self.lsa_key, record.data[:32]) cipher = AESModeOfOperationECB(key) n = 16 for block in [ record.data[32:][i:i + n] for i in range(0, len(record.data[32:]), n) ]: #terrible, terrible workaround self.NKLM_key += cipher.decrypt(block) else: self.NKLM_key = self.decrypt_secret(self.lsa_key, value[1]) return self.NKLM_key