# This file is Copyright 2020 Volatility Foundation and licensed under the Volatility Software License 1.0 # which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 # from struct import unpack from Crypto.Cipher import ARC4, AES from Crypto.Hash import HMAC from volatility.framework import interfaces, renderers from volatility.framework.configuration import requirements from volatility.framework.symbols.windows import versions from volatility.plugins.windows import hashdump, lsadump from volatility.plugins.windows.registry import hivelist class Cachedump(interfaces.plugins.PluginInterface): """Dumps lsa secrets from memory""" _version = (1, 0, 0) @classmethod def get_requirements(cls): return [ requirements.TranslationLayerRequirement(name = 'primary', description = 'Memory layer for the kernel', architectures = ["Intel32", "Intel64"]), requirements.SymbolTableRequirement(name = "nt_symbols", description = "Windows kernel symbols"), requirements.PluginRequirement(name = 'hivelist', plugin = hivelist.HiveList, version = (1, 0, 0)), requirements.PluginRequirement(name = 'lsadump', plugin = lsadump.Lsadump, version = (1, 0, 0)) ] def get_nlkm(self, sechive, lsakey, is_vista_or_later): return lsadump.Lsadump.get_secret_by_name(sechive, 'NL$KM', lsakey, is_vista_or_later) def decrypt_hash(self, edata, nlkm, ch, xp): if xp: hmac_md5 = HMAC.new(nlkm, ch) rc4key = hmac_md5.digest() rc4 = ARC4.new(rc4key) data = rc4.encrypt(edata) else: # based on Based on code from http://lab.mediaservice.net/code/cachedump.rb aes = AES.new(nlkm[16:32], AES.MODE_CBC, ch) data = "" for i in range(0, len(edata), 16): buf = edata[i:i + 16] if len(buf) < 16: buf += (16 - len(buf)) * "\00" data += aes.decrypt(buf) return data def parse_cache_entry(self, cache_data): (uname_len, domain_len) = unpack("