def get_HBoot_key(self): logger.debug('SAM parsing hashed bootkey') QWERTY = b"!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0" DIGITS = b"0123456789012345678901234567890123456789\0" F = self.hive.get_value(r'SAM\Domains\Account\F')[1] logger.log(1,'[SAM] F key value: %s' % F) domain_properties = DOMAIN_ACCOUNT_F.from_bytes(F) if isinstance(domain_properties.key_0, SAM_KEY_DATA): rc4_key = hashlib.md5(domain_properties.key_0.salt + QWERTY + self.bootkey +DIGITS).digest() self.hashed_bootkey = RC4(rc4_key).encrypt(domain_properties.key_0.key + domain_properties.key_0.checksum) checksum = hashlib.md5(self.hashed_bootkey[:16] + DIGITS + self.hashed_bootkey[:16] + QWERTY).digest() if checksum != self.hashed_bootkey[16:]: logger.error('[SAM] HBootkey checksum verification failed!') raise Exception('[SAM] HBootkey checksum verification failed!') elif isinstance(domain_properties.key_0, SAM_KEY_DATA_AES): self.hashed_bootkey = b'' cipher = AESModeOfOperationCBC(self.bootkey, iv = domain_properties.key_0.salt) n = 16 for block in [domain_properties.key_0.data[i:i+n] for i in range(0, len(domain_properties.key_0.data), n)]: #terrible, terrible workaround self.hashed_bootkey += cipher.decrypt(block) logger.debug('[SAM] HBootkey: %s' % self.hashed_bootkey.hex()) return self.hashed_bootkey
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 = AES(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)