def calculate(self): addr_space = utils.load_as(self._config) regapi = registryapi.RegistryApi(self._config) software_hive = "SOFTWARE" uninstall = "Microsoft\\Windows\\CurrentVersion\\Uninstall" hive_offsets = [] if not self._config.HIVE_OFFSET: for h in hivelist.HiveList.calculate(self): hive_name = self.hive_name(h) if software_hive in hive_name: hive_offsets = [(hive_name, h.obj_offset)] else: hive_offsets = [("User Specified", self._config.HIVE_OFFSET)] for name, hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error("Unable to find root key. Is the hive offset correct?") else: uninstall_key = rawreg.open_key(root, uninstall.split('\\')) if uninstall_key: yield name, uninstall_key else: outfd.write("The requested key could not be found in the hive(s) searched\n")
def reg_get_all_keys(self, hive_name, user = None, start = None, end = None, reg = False, rawtime = False): ''' This function enumerates all keys in specified hives and collects lastwrite times. ''' keys = [] if self.all_offsets == {}: self.populate_offsets() if self.current_offsets == {}: self.set_current(hive_name, user) # Collect the root keys for offset in self.current_offsets: reg_name = self.current_offsets[offset] h = hivemod.HiveAddressSpace(self.addr_space, self._config, offset) root = rawreg.get_root(h) if not root: pass else: time = "{0}".format(root.LastWriteTime) if not rawtime else root.LastWriteTime if reg: if start and end and str(time) >= start and str(time) <= end: yield (time, reg_name, root.Name) elif start == None and end == None: yield (time, reg_name, root.Name) else: if start and end and str(time) >= start and str(time) <= end: yield (time, root.Name) elif start == None and end == None: yield (time, root.Name) for s in rawreg.subkeys(root): if reg: keys.append([s, reg_name, root.Name + "\\" + s.Name]) else: keys.append([s, root.Name + "\\" + s.Name]) # Get subkeys if reg: for k, reg_name, name in keys: time = "{0}".format(k.LastWriteTime) if not rawtime else k.LastWriteTime if start and end and str(time) >= start and str(time) <= end: yield (time, reg_name, name) elif start == None and end == None: yield (time, reg_name, name) for s in rawreg.subkeys(k): if name and s.Name: item = name + '\\' + s.Name keys.append([s, reg_name, item]) else: for k, name in keys: time = "{0}".format(k.LastWriteTime) if not rawtime else k.LastWriteTime if start and end and str(time) >= start and str(time) <= end: yield (time, name) elif start == None and end == None: yield (time, name) for s in rawreg.subkeys(k): if name and s.Name: item = name + '\\' + s.Name keys.append([s, item])
def get_lsa_key(secaddr, bootkey): if not bootkey: return None root = rawreg.get_root(secaddr) if not root: return None enc_reg_key = rawreg.open_key(root, ["Policy", "PolSecretEncryptionKey"]) if not enc_reg_key: return None enc_reg_value = enc_reg_key.ValueList.List.dereference()[0] if not enc_reg_value: return None obf_lsa_key = secaddr.read(enc_reg_value.Data, enc_reg_value.DataLength) if not obf_lsa_key: return None md5 = MD5.new() md5.update(bootkey) for _i in range(1000): md5.update(obf_lsa_key[60:76]) rc4key = md5.digest() rc4 = ARC4.new(rc4key) lsa_key = rc4.decrypt(obf_lsa_key[12:60]) return lsa_key[0x10:0x20]
def get_hbootkey(samaddr, bootkey): sam_account_path = ["SAM", "Domains", "Account"] if not bootkey: return None root = rawreg.get_root(samaddr) if not root: return None sam_account_key = rawreg.open_key(root, sam_account_path) if not sam_account_key: return None F = None for v in rawreg.values(sam_account_key): if v.Name == 'F': F = samaddr.read(v.Data, v.DataLength) if not F: return None md5 = MD5.new() md5.update(F[0x70:0x80] + aqwerty + bootkey + anum) rc4_key = md5.digest() rc4 = ARC4.new(rc4_key) hbootkey = rc4.encrypt(F[0x80:0xA0]) return hbootkey
def reg_get_all_keys(self, hive_name, user = None, start = None, end = None, reg = False, rawtime = False): ''' This function enumerates all keys in specified hives and collects lastwrite times. ''' keys = [] if self.all_offsets == {}: self.populate_offsets() if self.current_offsets == {}: self.set_current(hive_name, user) # Collect the root keys for offset in self.current_offsets: reg_name = self.current_offsets[offset] h = hivemod.HiveAddressSpace(self.addr_space, self._config, offset) root = rawreg.get_root(h) if not root: pass else: time = "{0}".format(root.LastWriteTime) if not rawtime else root.LastWriteTime if reg: if start and end and str(time) >= start and str(time) <= end: yield (time, reg_name, root.Name) elif start == None and end == None: yield (time, reg_name, root.Name) else: if start and end and str(time) >= start and str(time) <= end: yield (time, root.Name) elif start == None and end == None: yield (time, root.Name) for s in rawreg.subkeys(root): if reg: keys.append([s, reg_name, root.Name + "\\" + s.Name]) else: keys.append([s, root.Name + "\\" + s.Name]) # Get subkeys if reg: for k, reg_name, name in keys: time = "{0}".format(k.LastWriteTime) if not rawtime else root.LastWriteTime if start and end and str(time) >= start and str(time) <= end: yield (time, reg_name, name) elif start == None and end == None: yield (time, reg_name, name) for s in rawreg.subkeys(k): if name and s.Name: item = name + '\\' + s.Name keys.append([s, reg_name, item]) else: for k, name in keys: time = "{0}".format(k.LastWriteTime) if not rawtime else root.LastWriteTime if start and end and str(time) >= start and str(time) <= end: yield (time, name) elif start == None and end == None: yield (time, name) for s in rawreg.subkeys(k): if name and s.Name: item = name + '\\' + s.Name keys.append([s, item])
def calculate(self): addr_space = utils.load_as(self._config) win7 = addr_space.profile.metadata.get('major', 0) == 6 and addr_space.profile.metadata.get('minor', 0) == 1 if not self._config.HIVE_OFFSET: hive_offsets = [(self.hive_name(h), h.obj_offset) for h in hivelist.HiveList.calculate(self)] else: hive_offsets = [("User Specified", self._config.HIVE_OFFSET)] for name, hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error("Unable to find root key. Is the hive offset correct?") else: skey = "software\\microsoft\\windows\\currentversion\\explorer\\userassist\\" if win7: uakey = skey + "{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\\Count" yield win7, name, rawreg.open_key(root, uakey.split('\\')) uakey = skey + "{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\\Count" yield win7, name, rawreg.open_key(root, uakey.split('\\')) else: uakey = skey + "{75048700-EF1F-11D0-9888-006097DEACF9}\\Count" yield win7, name, rawreg.open_key(root, uakey.split('\\')) uakey = skey + "{5E6AB780-7743-11CF-A12B-00AA004AE837}\\Count" yield win7, name, rawreg.open_key(root, uakey.split('\\'))
def get_secrets(sysaddr, secaddr): root = rawreg.get_root(secaddr) if not root: return None bootkey = hashdump.get_bootkey(sysaddr) lsakey = get_lsa_key(secaddr, bootkey) if not bootkey or not lsakey: return None secrets_key = rawreg.open_key(root, ["Policy", "Secrets"]) if not secrets_key: return None secrets = {} for key in rawreg.subkeys(secrets_key): sec_val_key = rawreg.open_key(key, ["CurrVal"]) if not sec_val_key: continue enc_secret_value = sec_val_key.ValueList.List.dereference()[0] if not enc_secret_value: continue enc_secret = secaddr.read(enc_secret_value.Data, enc_secret_value.DataLength) if not enc_secret: continue secret = decrypt_secret(enc_secret[0xC:], lsakey) secrets[key.Name] = secret return secrets
def calculate(self): addr_space = utils.load_as(self._config) regapi = registryapi.RegistryApi(self._config) software_hive = "SOFTWARE" uninstall = "Microsoft\\Windows\\CurrentVersion\\Uninstall" hive_offsets = [] if not self._config.HIVE_OFFSET: for h in hivelist.HiveList.calculate(self): hive_name = self.hive_name(h) if software_hive in hive_name: hive_offsets = [(hive_name, h.obj_offset)] else: hive_offsets = [("User Specified", self._config.HIVE_OFFSET)] for name, hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error( "Unable to find root key. Is the hive offset correct?") else: uninstall_key = rawreg.open_key(root, uninstall.split('\\')) if uninstall_key: yield name, uninstall_key else: outfd.write( "The requested key could not be found in the hive(s) searched\n" )
def services_from_registry(addr_space): """Enumerate services from the cached registry hive""" services = {} plugin = hivelist.HiveList(addr_space.get_config()) for hive in plugin.calculate(): ## find the SYSTEM hive name = hive.get_name() if not name.lower().endswith("system"): continue ## get the root key hive_space = hive.address_space() root = rawreg.get_root(hive_space) if not root: break ## open the services key key = rawreg.open_key(root, ["ControlSet001", "Services"]) if not key: break ## build a dictionary of the key names for subkey in rawreg.subkeys(key): services[(str(subkey.Name).lower())] = subkey ## we don't need to keep trying break return services
def get_bootkey(sysaddr): cs = find_control_set(sysaddr) lsa_base = ["ControlSet{0:03}".format(cs), "Control", "Lsa"] lsa_keys = ["JD", "Skew1", "GBG", "Data"] root = rawreg.get_root(sysaddr) if not root: return None lsa = rawreg.open_key(root, lsa_base) if not lsa: return None bootkey = "" for lk in lsa_keys: key = rawreg.open_key(lsa, [lk]) class_data = sysaddr.read(key.Class, key.ClassLength) if class_data == None: return "" bootkey += class_data.decode('utf-16-le').decode('hex') bootkey_scrambled = "" for i in range(len(bootkey)): bootkey_scrambled += bootkey[p[i]] return bootkey_scrambled
def get_secret_by_name(addr_space, secaddr, name, lsakey): root = rawreg.get_root(secaddr) if not root: return None enc_secret_key = rawreg.open_key( root, ["Policy", "Secrets", name, "CurrVal"] ) if not enc_secret_key: return None enc_secret_value = enc_secret_key.ValueList.List.dereference()[0] if not enc_secret_value: return None enc_secret = secaddr.read( enc_secret_value.Data, enc_secret_value.DataLength ) if not enc_secret: return None if addr_space.profile.metadata.get('major', 0) == 5: secret = decrypt_secret(enc_secret[0xC:], lsakey) else: secret = decrypt_aes(enc_secret, lsakey) return secret
def calculate(self): addr_space = utils.load_as(self._config) if self._config.BRUTE_FORCE: hiveroot = hl.HiveList.calculate(self) elif not self._config.hive_offset: debug.error("No hive offset provided!") else: hiveroot = [obj.Object("_CMHIVE", self._config.hive_offset, addr_space)] hive_offsets = [] for hive in hiveroot: if hive.obj_offset not in hive_offsets: try: name = hive.FileFullPath.v() or hive.FileUserName.v() or hive.HiveRootPath.v() or "[no name]" except: name = "[no name]" hive_offsets.append(hive.obj_offset) h = hivemod.HiveAddressSpace(addr_space, self._config, hive.obj_offset) root = rawreg.get_root(h) if not root: if not self._config.BRUTE_FORCE: debug.error("Unable to find root key. Is the hive offset correct?") else: if self._config.KEY: yield name, rawreg.open_key(root, self._config.KEY.split('\\')) else: yield name, root
def calculate(self): addr_space = utils.load_as(self._config) if not self._config.HIVE_OFFSET: hive_offsets = { h.obj_offset for h in hivelist.HiveList.calculate(self) } else: hive_offsets = {self._config.HIVE_OFFSET} for hoff in sorted(list(hive_offsets)): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) name = obj.Object("_CMHIVE", vm=addr_space, offset=hoff).get_name() root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error( "Unable to find root key. Is the hive offset correct?") else: if self._config.KEY: opened_key = rawreg.open_key(root, self._config.KEY.split('\\')) yield name, opened_key else: yield name, root
def calculate(self): addr_space = utils.load_as(self._config) if not self._config.hive_offset: debug.error("A Hive offset must be provided (--hive-offset)") h = hivemod.HiveAddressSpace(addr_space, self._config, self._config.hive_offset) return rawreg.get_root(h)
def find_control_set(sysaddr): root = rawreg.get_root(sysaddr) if not root: return 1 csselect = rawreg.open_key(root, ["Select"]) if not csselect: return 1 for v in rawreg.values(csselect): if v.Name == "Current": return v.Data
def get_user_keys(samaddr): user_key_path = ["SAM", "Domains", "Account", "Users"] root = rawreg.get_root(samaddr) if not root: return [] user_key = rawreg.open_key(root, user_key_path) if not user_key: return [] return [k for k in rawreg.subkeys(user_key) if k.Name != "Names"]
def dump_hashes(addr_space, sysaddr, secaddr): bootkey = hashdump.get_bootkey(sysaddr) if not bootkey: return [] lsakey = lsasecrets.get_lsa_key(addr_space, secaddr, bootkey) if not lsakey: return [] nlkm = get_nlkm(addr_space, secaddr, lsakey) if not nlkm: return [] root = rawreg.get_root(secaddr) if not root: return [] cache = rawreg.open_key(root, ["Cache"]) if not cache: return [] xp = addr_space.profile.metadata.get('major', 0) == 5 hashes = [] for v in rawreg.values(cache): if v.Name == "NL$Control": continue data = v.obj_vm.read(v.Data, v.DataLength) if data == None: continue ( uname_len, domain_len, domain_name_len, enc_data, ch, ) = parse_cache_entry(data) # Skip if nothing in this cache entry if uname_len == 0: continue dec_data = decrypt_hash(enc_data, nlkm, ch, xp) (username, domain, domain_name, hashh) = parse_decrypted_cache(dec_data, uname_len, domain_len, domain_name_len) hashes.append((username, domain, domain_name, hashh)) return hashes
def get_autoruns(self): debug.debug("Getting offsets") addr_space = utils.load_as(self._config) hive_offsets = [ h.obj_offset for h in hivelist.HiveList.calculate(self) ] debug.debug("Found %s hives" % len(hive_offsets)) hives = {} ntuser_hive_roots = [] software_hive_root = None system_hive_root = None # Cycle through all hives until we find NTUSER.DAT or SOFTWARE # This enables us to search all memory-resident NTUSER.DAT hives for hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) name = self.hive_name( obj.Object("_CMHIVE", vm=addr_space, offset=hoff)) root = rawreg.get_root(h) if 'ntuser.dat' in name.split('\\')[-1].lower(): keys = NTUSER_RUN_KEYS ntuser_hive_roots.append(root) elif 'software' in name.split('\\')[-1].lower(): keys = SOFTWARE_RUN_KEYS software_hive_root = root elif 'system' in name.split('\\')[-1].lower(): system_hive_root = root continue else: continue debug.debug("Searching for keys in %s" % name) for full_key in keys: results = [] debug.debug(" Opening %s" % (full_key)) key = rawreg.open_key(root, full_key.split('\\')) results = self.parse_autoruns_key(key) if len(results) > 0: h = hives.get(name, {}) h[(full_key, key.LastWriteTime)] = results hives[name] = h return hives
def dump_hashes(addr_space, sysaddr, secaddr): bootkey = hashdump.get_bootkey(sysaddr) if not bootkey: return [] lsakey = lsasecrets.get_lsa_key(addr_space, secaddr, bootkey) if not lsakey: return [] nlkm = get_nlkm(addr_space, secaddr, lsakey) if not nlkm: return [] root = rawreg.get_root(secaddr) if not root: return [] cache = rawreg.open_key(root, ["Cache"]) if not cache: return [] xp = addr_space.profile.metadata.get('major', 0) == 5 hashes = [] for v in rawreg.values(cache): if v.Name == "NL$Control": continue data = v.obj_vm.read(v.Data, v.DataLength) if data == None: continue (uname_len, domain_len, domain_name_len, enc_data, ch) = parse_cache_entry(data) # Skip if nothing in this cache entry if uname_len == 0: continue dec_data = decrypt_hash(enc_data, nlkm, ch, xp) (username, domain, domain_name, hashh) = parse_decrypted_cache(dec_data, uname_len, domain_len, domain_name_len) hashes.append((username, domain, domain_name, hashh)) return hashes
def get_autoruns(self): debug.debug("Getting offsets") addr_space = utils.load_as(self._config) hive_offsets = [h.obj_offset for h in hivelist.HiveList.calculate(self)] debug.debug("Found %s hives" % len(hive_offsets)) hives = {} ntuser_hive_roots = [] software_hive_root = None system_hive_root = None # Cycle through all hives until we find NTUSER.DAT or SOFTWARE # This enables us to search all memory-resident NTUSER.DAT hives for hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) name = self.hive_name(obj.Object("_CMHIVE", vm = addr_space, offset = hoff)) root = rawreg.get_root(h) if 'ntuser.dat' in name.split('\\')[-1].lower(): keys = NTUSER_RUN_KEYS ntuser_hive_roots.append(root) elif 'software' in name.split('\\')[-1].lower(): keys = SOFTWARE_RUN_KEYS software_hive_root = root elif 'system' in name.split('\\')[-1].lower(): system_hive_root = root continue else: continue debug.debug("Searching for keys in %s" % name) for full_key in keys: results = [] debug.debug(" Opening %s" % (full_key)) key = rawreg.open_key(root, full_key.split('\\')) results = self.parse_autoruns_key(key) if len(results) > 0: h = hives.get(name, {}) h[(full_key, key.LastWriteTime)] = results hives[name] = h return hives
def dump_hashes(sysaddr, secaddr): bootkey = hashdump.get_bootkey(sysaddr) if not bootkey: return None lsakey = lsasecrets.get_lsa_key(secaddr, bootkey) if not lsakey: return None nlkm = get_nlkm(secaddr, lsakey) if not nlkm: return None root = rawreg.get_root(secaddr) if not root: return None cache = rawreg.open_key(root, ["Cache"]) if not cache: return None hashes = [] for v in rawreg.values(cache): if v.Name == "NL$Control": continue data = v.obj_vm.read(v.Data, v.DataLength) (uname_len, domain_len, domain_name_len, enc_data, ch) = parse_cache_entry(data) # Skip if nothing in this cache entry if uname_len == 0: continue dec_data = decrypt_hash(enc_data, nlkm, ch) (username, domain, domain_name, hashh) = parse_decrypted_cache(dec_data, uname_len, domain_len, domain_name_len) hashes.append((username, domain, domain_name, hashh)) return hashes
def get_secret_by_name(secaddr, name, lsakey): root = rawreg.get_root(secaddr) if not root: return None enc_secret_key = rawreg.open_key(root, ["Policy", "Secrets", name, "CurrVal"]) if not enc_secret_key: return None enc_secret_value = enc_secret_key.ValueList.List.dereference()[0] if not enc_secret_value: return None enc_secret = secaddr.read(enc_secret_value.Data, enc_secret_value.DataLength) if not enc_secret: return None return decrypt_secret(enc_secret[0xC:], lsakey)
def calculate(self): addr_space = utils.load_as(self._config) if not self._config.HIVE_OFFSET: hive_offsets = [(self.hive_name(h), h.obj_offset) for h in hivelist.HiveList.calculate(self)] else: hive_offsets = [("User Specified", self._config.HIVE_OFFSET)] for name, hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error("Unable to find root key. Is the hive offset correct?") else: if self._config.KEY: yield name, rawreg.open_key(root, self._config.KEY.split('\\')) else: yield name, root
def calculate(self): addr_space = utils.load_as(self._config) if not self._config.HIVE_OFFSET: hive_offsets = [h.obj_offset for h in hivelist.HiveList.calculate(self)] else: hive_offsets = [self._config.HIVE_OFFSET] for hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) name = self.hive_name(obj.Object("_CMHIVE", vm = addr_space, offset = hoff)) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error("Unable to find root key. Is the hive offset correct?") else: if self._config.KEY: yield name, rawreg.open_key(root, self._config.KEY.split('\\')) else: yield name, root
def reg_yield_key(self, hive_name, key, user = None, given_root = None): ''' Use this function if you are collecting keys from more than one hive ''' if self.all_offsets == {}: self.populate_offsets() if self.current_offsets == {}: self.set_current(hive_name, user) if key: for offset in self.current_offsets: name = self.current_offsets[offset] if given_root == None: h = hivemod.HiveAddressSpace(self.addr_space, self._config, offset) root = rawreg.get_root(h) else: root = given_root if root != None: k = rawreg.open_key(root, key.split('\\')) if k: yield k, name
def reg_get_key(self, hive_name, key, user = None, given_root = None): ''' Returns a key from a requested hive; assumes this is from a single hive if more than one hive is specified, the hive/key found is returned ''' if self.all_offsets == {}: self.populate_offsets() if self.current_offsets == {}: self.set_current(hive_name, user) if key: for offset in self.current_offsets: if given_root == None: h = hivemod.HiveAddressSpace(self.addr_space, self._config, offset) root = rawreg.get_root(h) else: root = given_root if root != None: k = rawreg.open_key(root, key.split('\\')) if k: return k return None
def calculate(self): addr_space = utils.load_as(self._config) regapi = registryapi.RegistryApi(self._config) user_hive = "ntuser.dat" trustrecords = { "Software\\Microsoft\\Office\\14.0\\Word\\Security\\Trusted Documents\\TrustRecords", "Software\\Microsoft\\Office\\14.0\\Excel\\Security\\Trusted Documents\\TrustRecords", "Software\\Microsoft\\Office\\14.0\\PowerPoint\\Security\\Trusted Documents\\TrustRecords", "Software\\Microsoft\\Office\\14.0\\Access\\Security\\Trusted Documents\\TrustRecords", } hive_offsets = {} if not self._config.HIVE_OFFSET: for h in hivelist.HiveList.calculate(self): hive_name = self.hive_name(h) if user_hive in hive_name.lower(): hive_offsets[h.obj_offset] = hive_name else: hive_offsets = [("User Specified", self._config.HIVE_OFFSET)] found = False for hoff, name in hive_offsets.iteritems(): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error( "Unable to find root key. Is the hive offset correct?") else: for r in trustrecords: trustrecord_key = rawreg.open_key(root, r.split('\\')) if trustrecord_key: yield name, r, trustrecord_key found = True if not found: debug.error( "The requested key could not be found in the hive(s) searched\n" )
def calculate(self): addr_space = utils.load_as(self._config) if not self._config.HIVE_OFFSET: hive_offsets = [(self.hive_name(h), h.obj_offset) for h in hivelist.HiveList.calculate(self)] else: hive_offsets = [("User Specified", self._config.HIVE_OFFSET)] for name, hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error( "Unable to find root key. Is the hive offset correct?") else: if self._config.KEY: yield name, rawreg.open_key(root, self._config.KEY.split('\\')) else: yield name, root
def get_secret_by_name(addr_space, secaddr, name, lsakey): root = rawreg.get_root(secaddr) if not root: return None enc_secret_key = rawreg.open_key(root, ["Policy", "Secrets", name, "CurrVal"]) if not enc_secret_key: return None enc_secret_value = enc_secret_key.ValueList.List.dereference()[0] if not enc_secret_value: return None enc_secret = secaddr.read(enc_secret_value.Data, enc_secret_value.DataLength) if not enc_secret: return None if addr_space.profile.metadata.get('major', 0) == 5: secret = enc_secret[0xC:] else: secret = enc_secret return decrypt_secret(secret, lsakey)
def get_registry_keys(self): addr_space = utils.load_as(self._config) hl = hivelist.HiveList(self._config) if not self._config.HIVE_OFFSET: hive_offsets = [h.obj_offset for h in hl.calculate()] else: hive_offsets = [self._config.HIVE_OFFSET] for hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) name = obj.Object("_CMHIVE", vm = addr_space, offset = hoff).get_name() root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: self.console_print("Unable to find root key. Is the hive offset correct?") else: if self._config.KEY: yield name, rawreg.open_key(root, self._config.KEY.split('\\')) else: yield name, root
def get_lsa_key(addr_space, secaddr, bootkey): if not bootkey: return None root = rawreg.get_root(secaddr) if not root: return None volmag = obj.VolMagic(addr_space) enc_reg_key = rawreg.open_key(root, ["Policy", volmag.PolicyKey.v()]) if not enc_reg_key: return None enc_reg_value = enc_reg_key.ValueList.List.dereference()[0] if not enc_reg_value: return None obf_lsa_key = secaddr.read(enc_reg_value.Data, enc_reg_value.DataLength) if not obf_lsa_key: return None if addr_space.profile.metadata.get('major', 0) == 5: md5 = MD5.new() md5.update(bootkey) for _i in range(1000): md5.update(obf_lsa_key[60:76]) rc4key = md5.digest() rc4 = ARC4.new(rc4key) lsa_key = rc4.decrypt(obf_lsa_key[12:60]) lsa_key = lsa_key[0x10:0x20] else: lsa_key = decrypt_aes(obf_lsa_key, bootkey) lsa_key = lsa_key[68:100] return lsa_key
def calculate(self): addr_space = utils.load_as(self._config) regapi = registryapi.RegistryApi(self._config) user_hive = "ntuser.dat" trustrecords = {"Software\\Microsoft\\Office\\14.0\\Word\\Security\\Trusted Documents\\TrustRecords", "Software\\Microsoft\\Office\\14.0\\Excel\\Security\\Trusted Documents\\TrustRecords", "Software\\Microsoft\\Office\\14.0\\PowerPoint\\Security\\Trusted Documents\\TrustRecords", "Software\\Microsoft\\Office\\14.0\\Access\\Security\\Trusted Documents\\TrustRecords", } hive_offsets = {} if not self._config.HIVE_OFFSET: for h in hivelist.HiveList.calculate(self): hive_name = self.hive_name(h) if user_hive in hive_name.lower(): hive_offsets[h.obj_offset] = hive_name else: hive_offsets = [("User Specified", self._config.HIVE_OFFSET)] found = False for hoff, name in hive_offsets.iteritems(): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) root = rawreg.get_root(h) if not root: if self._config.HIVE_OFFSET: debug.error("Unable to find root key. Is the hive offset correct?") else: for r in trustrecords: trustrecord_key = rawreg.open_key(root, r.split('\\')) if trustrecord_key: yield name, r, trustrecord_key found = True if not found: debug.error("The requested key could not be found in the hive(s) searched\n")
def get_secrets(addr_space, sysaddr, secaddr): root = rawreg.get_root(secaddr) if not root: return None bootkey = hashdump.get_bootkey(sysaddr) lsakey = get_lsa_key(addr_space, secaddr, bootkey) if not bootkey or not lsakey: return None secrets_key = rawreg.open_key(root, ["Policy", "Secrets"]) if not secrets_key: return None secrets = {} for key in rawreg.subkeys(secrets_key): sec_val_key = rawreg.open_key(key, ["CurrVal"]) if not sec_val_key: continue enc_secret_value = sec_val_key.ValueList.List.dereference()[0] if not enc_secret_value: continue enc_secret = secaddr.read(enc_secret_value.Data, enc_secret_value.DataLength) if not enc_secret: continue if addr_space.profile.metadata.get('major', 0) == 5: secret = enc_secret[0xC:] else: secret = enc_secret secrets[key.Name] = secret return secrets
def calculate(self): addr_space = utils.load_as(self._config) regapi = registryapi.RegistryApi(self._config) hiveset = set() if not self._config.HIVE_OFFSET: hive_offsets = [ h.obj_offset for h in hivelist.HiveList.calculate(self) ] else: hive_offsets = [self._config.HIVE_OFFSET] for hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, self._config, hoff) name = obj.Object("_CMHIVE", vm=addr_space, offset=hoff).get_name() print "[debug]", name root = rawreg.get_root(h) hive = name.split("\\")[-1] hiveset.add(hive) print hiveset for hive in hiveset: print "\n========================", hive for regtime, keyname in regapi.reg_get_last_modified(hive, count=5): print "\n", regtime, keyname regapi.set_current(hive_name=hive) k = keyname.split('\\')[1:] k = '\\'.join(k) print k + "\n" for value, tp, data in self.reg_yield_values_type( regapi, hive_name=hive, key=k): yield value, tp, data regapi.reset_current()
def calculate(self): addr_space = utils.load_as(self._config) config = self._config # Determine OS # myos = config.PROFILE[:5] profile = addr_space.profile if profile.metadata.get('os', 0) == 'windows': if profile.metadata.get('major', 0) == 5 and \ profile.metadata.get('minor', 0) == 1: myos = "WinXP" elif profile.metadata.get('major', 0) == 6 and \ profile.metadata.get('minor', 0) == 1: myos = "Win7" else: debug.error("OS not supported") assert myos in regchk_by_os # Determine which checks to do if not config.CHK: checklist = [] # Default action: Do everything if not config.HIVE_NAME: myhives = regchk_by_os[myos].keys() else: # User has specified a specific hive to process htmp = ''.join(config.HIVE_NAME).lower() if not htmp in regchk_by_os[ myos ]: debug.error("Invalid Hive Name specified.") else: myhives = [ htmp ] # Specific check asked for else: check = ''.join(config.CHK).lower() if not check in chk_defn: debug.error("Invalid check specified.") # Only 1 check to do checklist = [ check ] # determine which hive this check refers to (to avoid wasting time on the other hives) for htmp1, chktmp in regchk_by_os[ myos ].iteritems(): if check in chktmp: htmp = htmp1 myhives = [ htmp ] config.remove_option("HIVE-NAME") # If user hasn't given a specific hive offset, then default is to try to process all the hives if not config.HIVE_OFFSET: hive_offsets = [(self.hive_name(h), h.obj_offset) for h in hivelist.HiveList.calculate(self)] else: hive_offsets = [("User Specified", config.HIVE_OFFSET)] # Try to process each hive in turn for hname, hoff in set(hive_offsets): h = hivemod.HiveAddressSpace(addr_space, config, hoff) root = rawreg.get_root(h) if not root: if config.HIVE_OFFSET: debug.error("Unable to find root key. Is the hive offset correct?") # Find out which hive this is hive_last_name = hname.lower().split("\\")[-1] # see if the current hive is on the list of hives the user wants to process for myhive in myhives: if not hive_last_name in (myhive, "[no name]", "user specified"): continue # Determine current controlset (if the key actually exists in this hive) ccs_key = rawreg.open_key(root, [ "CurrentControlSet" ] ) if ccs_key: ccs_v = rawreg.values(ccs_key)[ 0 ] ccs_tp, ccs_dat = rawreg.value_data(ccs_v) ccs = ccs_dat.encode("ascii", 'backslashreplace').split("\\")[-1] + "\\" # Sanity check if not ccs.lower().startswith("controlset00"): debug.error("CurrentControlSet key found but has invalid value.") else: ccs = "" # Set checklist to run the checks for this hive # If the user just wants to do 1 check then checklist has already been # set. if not config.CHK: checklist = regchk_by_os[ myos ][ myhive ] for check in checklist: chk_ccsflag, chk_key_lst, chk_msg, chk_action_list = chk_defn[check] for chk_key in chk_key_lst: if chk_ccsflag: chk_key = ccs + chk_key if check == "bho": # Do specific processing for Browser Helper Objects key = rawreg.open_key(root, chk_key.split('\\')) if key: # Pull out the class reg key for each GUID for s in rawreg.subkeys(key): # pull out the clsid for the BHO clsid = str(s.Name) if clsid == None: pass # Next read the classid reg key clsid = "Classes\\CLSID\\" + clsid yield hname, \ rawreg.open_key(root, clsid.split('\\')), \ check, \ clsid elif check == "assoc": # Do specific processing for file associations key = rawreg.open_key(root, chk_key.split('\\')) if key: # Pull out the file association values assoc_cache = {} for s in rawreg.subkeys(key): s_name = str(s.Name) # First look for an association key if s_name.startswith(r"."): # Next find the filename value for this association for v in rawreg.values(s): # force conversion to string from String object v_name = str(v.Name) if not v_name == "": continue # Have found the default value key. Now read the datafile value tp, dat = rawreg.value_data( v ) assert tp == "REG_SZ" fname = dat.encode("ascii", 'backslashreplace').rstrip("\0") # Check for cache hit if not fname in assoc_cache: # Find the filename key (which has the actual cmd shell value) cmd_shell_key = "Classes\\" + fname + "\\shell\\open\\command" assoc_cache[fname] = [ rawreg.open_key(root, cmd_shell_key.split('\\')), "{0}, File extension: {1}".format(cmd_shell_key, s_name) ] yield hname, assoc_cache[fname][0], check, assoc_cache[fname][1] break else: yield hname, \ rawreg.open_key(root, chk_key.split('\\')), \ check, \ chk_key