def get_user_hashes(user_key, hbootkey): samaddr = user_key.obj_vm rid = int(str(user_key.Name), 16) V = None for v in rawreg.values(user_key): if v.Name == 'V': V = samaddr.read(v.Data, v.DataLength) if not V: return None lm_offset = unpack("<L", V[0x9c:0xa0])[0] + 0xCC + 4 lm_len = unpack("<L", V[0xa0:0xa4])[0] - 4 nt_offset = unpack("<L", V[0xa8:0xac])[0] + 0xCC + 4 nt_len = unpack("<L", V[0xac:0xb0])[0] - 4 if lm_len: enc_lm_hash = V[lm_offset:lm_offset + 0x10] else: enc_lm_hash = "" if nt_len: enc_nt_hash = V[nt_offset:nt_offset + 0x10] else: enc_nt_hash = "" return decrypt_hashes(rid, enc_lm_hash, enc_nt_hash, hbootkey)
def render_text(self, outfd, data): outfd.write("Legend: (S) = Stable (V) = Volatile\n\n") keyfound = False for reg, path, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key path: {0}\n".format(path)) outfd.write("Key name: {0} {1:3s}\n".format( key.Name, self.voltext(key))) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Values:\n") for s in rawreg.values(key): tp, dat = rawreg.value_data(s) if tp == 'REG_BINARY' or tp == 'REG_NONE': time = struct.unpack("<q", dat[0:8])[0] seconds, msec = divmod(time, 10000000) days, seconds = divmod(seconds, 86400) if days > 160000 or days < 140000: days = 0 seconds = 0 msec = 0 open_date = datetime.datetime(1601, 1, 1) + datetime.timedelta( days, seconds, msec) outfd.write(str(open_date) + "\t" + s.Name + "\n")
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 render_text(self, outfd, data): for reg, key in data: if not key: if not self._config.BRUTE_FORCE: outfd.write("Unable to find requested key\n") continue outfd.write("Legend: (S) = Stable (V) = Volatile\n\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key name: {0} {1:3s}\n".format(key.Name, self.voltext(key))) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Subkeys:\n") for s in rawreg.subkeys(key): if s.Name == None: outfd.write(" Unknown subkey: " + s.Name.reason + "\n") else: outfd.write(" {1:3s} {0}\n".format(s.Name, self.voltext(s))) outfd.write("\n") outfd.write("Values:\n") for v in rawreg.values(key): tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY': dat = "\n" + hd(dat, length = 16) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') outfd.write("{0:13} {1:15} : {3:3s} {2}\n".format(tp, v.Name, dat, self.voltext(v)))
def render_text(self, outfd, data): outfd.write("Legend: (S) = Stable (V) = Volatile\n\n") keyfound = False for reg, path, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key path: {0}\n".format(path)) outfd.write("Key name: {0} {1:3s}\n".format(key.Name, self.voltext(key))) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Values:\n") for s in rawreg.values(key): tp, dat = rawreg.value_data(s) if tp == 'REG_BINARY' or tp == 'REG_NONE': time = struct.unpack("<q", dat[0:8])[0] seconds, msec= divmod(time, 10000000) days, seconds = divmod(seconds, 86400) if days > 160000 or days < 140000: days = 0 seconds = 0 msec = 0 open_date = datetime.datetime(1601, 1, 1) + datetime.timedelta(days, seconds, msec) outfd.write(str(open_date) + "\t" + s.Name + "\n")
def reg_get_value(self, hive_name, key, value, strcmp=None, given_root=None): ''' This function returns the requested value of a registry key ''' if key and value: h = given_root if given_root != None else self.reg_get_key( hive_name, key) if h != None: for v in rawreg.values(h): if value == v.Name: tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or strcmp == None: # We want raw data return dat else: # This is a string comparison dat = str(dat) dat = dat.strip() dat = ''.join([ x for x in dat if ord(x) != 0 ]) #get rid of funky nulls for string comparison if strcmp == dat: return dat return None
def render_text(self, outfd, data): outfd.write("Legend: (S) = Stable (V) = Volatile\n\n") keyfound = False for reg, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key name: {0} {1:3s}\n".format(key.Name, self.voltext(key))) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Subkeys:\n") for s in rawreg.subkeys(key): if s.Name == None: outfd.write(" Unknown subkey: " + s.Name.reason + "\n") else: outfd.write(" {1:3s} {0}\n".format(s.Name, self.voltext(s))) outfd.write("\n") outfd.write("Values:\n") for v in rawreg.values(key): tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': dat = "\n" + "\n".join(["{0:#010x} {1:<48} {2}".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(dat)]) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') outfd.write("{0:13} {1:15} : {3:3s} {2}\n".format(tp, v.Name, dat, self.voltext(v))) if not keyfound: outfd.write("The requested key could not be found in the hive(s) searched\n")
def render_text(self, outfd, data): for subkey in data: outfd.write("\n{0:<20}: {1}\n".format("Missing service", subkey.Name)) for value in rawreg.values(subkey): value_type, value_data = rawreg.value_data(value) outfd.write("{0:<20}: ({1}) {2}\n".format( value.Name, value_type, value_data))
def generator(self, data): for reg, key in data: if key: subkeys = list(rawreg.subkeys(key)) values = list(rawreg.values(key)) yield (0, [ str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), "-", "-", "-", "-", "-", "-" ]) if subkeys: for s in subkeys: if s.Name == None: yield (0, [ str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), str("Unknown subkey: {0}".format( s.Name.reason)), "-", "-", "-", "-", "-" ]) else: yield (0, [ str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), str("{0}".format(s.Name)), str("{0:3s}".format(self.voltext(s))), "-", "-", "-", "-" ]) if values: for v in values: tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': dat = Bytes(dat) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') yield (0, [ str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), "-", "-", str(tp), str("{0}".format(v.Name)), str("{0:3s}".format(self.voltext(v))), str(dat) ])
def render_text(self, outfd, data): print_values = { 5: 'InstallSource', 6: 'InstallLocation', 3: 'Publisher', 1: 'DisplayName', 2: 'DisplayVersion', 4: 'InstallDate' } outfd.write("Legend: (S) = Stable (V) = Volatile\n\n") keyfound = False for reg, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key name: {0} {1:3s}\n".format( key.Name, self.voltext(key))) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Subkeys:\n") for s in rawreg.subkeys(key): key_info = {} if s.Name == None: outfd.write(" Unknown subkey: " + s.Name.reason + "\n") else: key_info['Name'] = s.Name key_info['LastUpdated'] = s.LastWriteTime for v in rawreg.values(s): if v.Name not in print_values.values(): continue tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': dat = "\n" + "\n".join([ "{0:#010x} {1:<48} {2}".format( o, h, ''.join(c)) for o, h, c in utils.Hexdump(dat) ]) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode( "ascii", 'backslashreplace') key_info[str(v.Name)] = dat outfd.write("Subkey: {0}\n".format(key_info.get( 'Name', ''))) outfd.write(" LastUpdated : {0}\n".format( key_info.get('LastUpdated', ''))) for k, v in sorted(print_values.items()): val = key_info.get(v, '') if val != '': outfd.write(" {0:16}: {1}\n".format(v, val)) outfd.write("\n")
def reg_yield_values(self, hive_name, key, thetype = None, given_root = None): ''' This function yields all values for a requested registry key ''' if key: h = given_root if given_root != None else self.reg_get_key(hive_name, key) if h != None: for v in rawreg.values(h): tp, dat = rawreg.value_data(v) if thetype == None or tp == thetype: yield v.Name, dat
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 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 filter_key(self, key, value): ret = [] if key: for v in rawreg.values(key): if not value or (value and self.get_value_name(v) in value): tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': reason = self.is_bin_suspicious(dat) ret += [{'key': key, 'value': v, 'reason': reason}] elif tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: reason = self.is_string_suspicious(dat) ret += [{'key': key, 'value': v, 'reason': reason}] return ret
def get_user_desc(user_key): samaddr = user_key.obj_vm V = None for v in rawreg.values(user_key): if v.Name == 'V': V = samaddr.read(v.Data, v.DataLength) if not V: return None desc_offset = unpack("<L", V[0x24:0x28])[0] + 0xCC desc_length = unpack("<L", V[0x28:0x2c])[0] desc = V[desc_offset:desc_offset + desc_length].decode('utf-16-le') return desc
def get_user_name(user_key): samaddr = user_key.obj_vm V = None for v in rawreg.values(user_key): if v.Name == 'V': V = samaddr.read(v.Data, v.DataLength) if not V: return None name_offset = unpack("<L", V[0x0c:0x10])[0] + 0xCC name_length = unpack("<L", V[0x10:0x14])[0] username = V[name_offset:name_offset + name_length].decode('utf-16-le') return username
def render_text(self, outfd, data): keyfound = False for win7, reg, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key name: {0}\n".format(key.Name)) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Subkeys:\n") for s in rawreg.subkeys(key): if s.Name == None: outfd.write(" Unknown subkey: " + s.Name.reason + "\n") else: outfd.write(" {0}\n".format(s.Name)) outfd.write("\n") outfd.write("Values:\n") for v in rawreg.values(key): tp, dat = rawreg.value_data(v) subname = v.Name if tp == 'REG_BINARY': dat_raw = dat dat = "\n" + printkey.hd(dat, length=16) try: subname = subname.encode('rot_13') except: pass if win7: guid = subname.split("\\")[0] if guid in folder_guids: subname = subname.replace( guid, folder_guids[guid]) d = self.parse_data(dat_raw) if d != None: dat = d + dat #these types shouldn't be encountered, but are just left here in case: if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') outfd.write("{0:13} {1:15} : {2:3s}\n".format( tp, subname, dat)) if not keyfound: outfd.write( "The requested key could not be found in the hive(s) searched\n" )
def dict_for_key(self, key): # Inspired from the Volatility printkey plugin valdict = {} for v in rawreg.values(key): tp, data = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': data = "\n" + "\n".join(["{0:#010x} {1:<48} {2}".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(data)]) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: data = data.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(data)): data[i] = data[i].encode("ascii", 'backslashreplace') valdict[str(v.Name)] = str(data) return valdict
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 render_text(self, outfd, data): keyfound = False for win7, reg, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key name: {0}\n".format(key.Name)) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Subkeys:\n") for s in rawreg.subkeys(key): if s.Name == None: outfd.write(" Unknown subkey: " + s.Name.reason + "\n") else: outfd.write(" {0}\n".format(s.Name)) outfd.write("\n") outfd.write("Values:\n") for v in rawreg.values(key): tp, dat = rawreg.value_data(v) subname = v.Name if tp == 'REG_BINARY': dat_raw = dat dat = "\n".join(["{0:#010x} {1:<48} {2}".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(dat)]) try: subname = subname.encode('rot_13') except UnicodeDecodeError: pass if win7: guid = subname.split("\\")[0] if guid in folder_guids: subname = subname.replace(guid, folder_guids[guid]) d = self.parse_data(dat_raw) if d != None: dat = d + dat else: dat = "\n" + dat #these types shouldn't be encountered, but are just left here in case: if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') outfd.write("\n{0:13} {1:15} : {2}\n".format(tp, subname, dat)) if not keyfound: outfd.write("The requested key could not be found in the hive(s) searched\n")
def compare(reg_list, mem_list): """Compare the services found in the registry with those in memory""" ## the names of all services in only the registry list missing = set(reg_list.keys()) - set(mem_list.keys()) for service in missing: ## the SCM only loads services with an ImagePath value so make ## sure to skip those entries, as they will not end up in memory has_imagepath = False for value in rawreg.values(reg_list[service]): if str(value.Name) == "ImagePath": has_imagepath = True break if has_imagepath: yield reg_list[service]
def search_key(self, key, prefix): prefix += '\t' for subkey in rawreg.subkeys(key): if not rawreg.values(subkey): if not rawreg.subkeys(subkey): print "[-]", subkey.Name continue else: pass if subkey.Name == None: pass else: print prefix, subkey.Name self.search_key(subkey, prefix) """
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 dict_for_key(self, key): # Inspired from the Volatility printkey plugin valdict = {} for v in rawreg.values(key): tp, data = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': data = "\n" + "\n".join([ "{0:#010x} {1:<48} {2}".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(data) ]) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: data = data.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(data)): data[i] = data[i].encode("ascii", 'backslashreplace') valdict[str(v.Name)] = str(data) return valdict
def reg_yield_values_type(self, regapi, hive_name, key, thetype=None, given_root=None, raw=False): if key or given_root: h = given_root if given_root != None else regapi.reg_get_key( hive_name, key) if h != None: for v in rawreg.values(h): tp, dat = rawreg.value_data(v) if thetype == None or tp == thetype: if raw: yield v, tp, dat else: yield v.Name, tp, dat
def reg_yield_values(self, hive_name, key, thetype=None, given_root=None, raw=False): """ This function yields all values for a requested registry key """ if key or given_root: h = (given_root if given_root != None else self.reg_get_key( hive_name, key)) if h != None: for v in rawreg.values(h): tp, dat = rawreg.value_data(v) if thetype == None or tp == thetype: if raw: yield v, dat else: yield v.Name, dat
def reg_get_value(self, hive_name, key, value, strcmp = None, given_root = None): ''' This function returns the requested value of a registry key ''' if key and value: h = given_root if given_root != None else self.reg_get_key(hive_name, key) if h != None: for v in rawreg.values(h): if value == v.Name: tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or strcmp == None: # We want raw data return dat else: # This is a string comparison dat = str(dat) dat = dat.strip() dat = ''.join([x for x in dat if ord(x) != 0]) #get rid of funky nulls for string comparison if strcmp == dat: return dat return None
def render_text(self, outfd, data): print_values = {5:'InstallSource', 6:'InstallLocation', 3:'Publisher', 1:'DisplayName', 2:'DisplayVersion', 4:'InstallDate'} outfd.write("Legend: (S) = Stable (V) = Volatile\n\n") keyfound = False for reg, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write("Registry: {0}\n".format(reg)) outfd.write("Key name: {0} {1:3s}\n".format(key.Name, self.voltext(key))) outfd.write("Last updated: {0}\n".format(key.LastWriteTime)) outfd.write("\n") outfd.write("Subkeys:\n") for s in rawreg.subkeys(key): key_info = {} if s.Name == None: outfd.write(" Unknown subkey: " + s.Name.reason + "\n") else: key_info['Name'] = s.Name key_info['LastUpdated'] = s.LastWriteTime for v in rawreg.values(s): if v.Name not in print_values.values(): continue tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': dat = "\n" + "\n".join(["{0:#010x} {1:<48} {2}".format(o, h, ''.join(c)) for o, h, c in utils.Hexdump(dat)]) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') key_info[str(v.Name)] = dat outfd.write("Subkey: {0}\n".format(key_info.get('Name',''))) outfd.write(" LastUpdated : {0}\n".format(key_info.get('LastUpdated',''))) for k, v in sorted(print_values.items()): val = key_info.get(v, '') if val != '': outfd.write(" {0:16}: {1}\n".format(v, val)) outfd.write("\n")
def getregistrykeyobject(self,reg,key,regObjList): regKeyObject = regObjList.RegistryKey.add(resultitemtype=19) regKeyObject.Name=utils._utf8_encode(key.Name) path = reg lastSlash = reg.rfind("/") if lastSlash >= 0: path = "\\" + reg[:lastSlash].replace("/", "\\") regKeyObject.Path=utils._utf8_encode(path) regKeyObject.Volatile=self.voltext(key) regvalues = rawreg.values(key) if regvalues is not None and len(regvalues) > 0: values = regKeyObject.Values values.Count=len(regvalues) for value in regvalues: regKeyValue = values.RegistryValue.add(resultitemtype=21) regKeyValue.Name=utils._utf8_encode(value.Name) regKeyValue.Type=value.Type.v() or 0 try: regKeyValue.Value = self._get_raw_registry_data2(value) except Exception as e: regKeyValue.Value = "EXCEPTION: " + str(e) return regKeyObject
def reg_get_value(self, hive_name, key, value, data = None): ''' This function returns the requested value of a registry key ''' addr_space = utils.load_as(self._config) if key and value: h = self.reg_get_key(hive_name, key) if h != None: for v in rawreg.values(h): if value == v.Name: tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY': return dat else: dat = str(dat) dat = dat.strip() temp = '' dat = temp.join([x for x in dat if ord(x) != 0]) #get rid of funky nulls for string comparison if data != None and data == dat: return dat elif data == None: return dat return None
def getregistrykeyobject(self, reg, key, regObjList): regKeyObject = regObjList.RegistryKey.add(resultitemtype=19) regKeyObject.Name = utils._utf8_encode(key.Name) path = reg lastSlash = reg.rfind("/") if lastSlash >= 0: path = "\\" + reg[:lastSlash].replace("/", "\\") regKeyObject.Path = utils._utf8_encode(path) regKeyObject.Volatile = self.voltext(key) regvalues = rawreg.values(key) if regvalues is not None and len(regvalues) > 0: values = regKeyObject.Values values.Count = len(regvalues) for value in regvalues: regKeyValue = values.RegistryValue.add(resultitemtype=21) regKeyValue.Name = utils._utf8_encode(value.Name) regKeyValue.Type = value.Type.v() or 0 try: regKeyValue.Value = self._get_raw_registry_data2(value) except Exception as e: regKeyValue.Value = "EXCEPTION: " + str(e) return regKeyObject
def render_text(self, outfd, data): outfd.write("Legend: (S) = Stable (V) = Volatile\n\n") keyfound = False for reg, key in data: if key: keyfound = True outfd.write("----------------------------\n") outfd.write(f"Registry: {reg}\n") outfd.write(f"Key name: {key.Name} {self.voltext(key):3s}\n") outfd.write(f"Last updated: {key.LastWriteTime}\n") outfd.write("\n") outfd.write("Subkeys:\n") for s in rawreg.subkeys(key): if s.Name == None: outfd.write(f" Unknown subkey at {s.obj_offset:#x}\n") else: outfd.write(f" {self.voltext(s):3s} {s.Name}\n") outfd.write("\n") outfd.write("Values:\n") for v in rawreg.values(key): tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': dat = "\n" + "\n".join([ f"{o:#010x} {h:<48} {''.join(c)}" for o, h, c in utils.Hexdump(dat) ]) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') outfd.write( f"{tp:13} {v.Name:15} : {self.voltext(v):3s} {dat}\n") if not keyfound: outfd.write( "The requested key could not be found in the hive(s) searched\n" )
def render_key(self, outfd, key, actions): if len(actions) > 0: action = actions[0] else: return if action == PRT_VALUE: valname = actions[1] for v in rawreg.values(key): # force conversion to string from String object v_name = str(v.Name) # Determine whether to print this value if valname[0] == "all": pass # include specified values elif valname[0] == "+": if not v_name in valname: continue # exclude specified values elif valname[0] == "-": if v_name in valname: continue else: debug.error("Pgm Error - Invalid valname render_key PRT_VALUE") self.prt_val(outfd, v) actions = actions[2:] elif action == LIST_SUBKEYS: subkey_1st = True valname = actions[1] for s in rawreg.subkeys(key): s_name = str(s.Name) # Determine whether to list this subkey if valname[0] == "all": pass # include specified keys elif valname[0] == "+": if not s_name in valname: continue # exclude specified keys elif valname[0] == "-": if s_name in valname: continue # include subkey if starts with specified value elif valname[0] == "s": if not s_name.startswith( valname[1] ): continue else: debug.error("Pgm Error - Invalid valname render_key LIST_SUBKEYS") if subkey_1st: outfd.write(" Subkeys:\n") subkey_1st = False if s_name == None: outfd.write(" Unknown subkey: " + s_name.reason + "\n") else: outfd.write(" {1:3s} {0}\n".format(s_name, self.voltext(s))) # If there is a recursive action specified for each subkey, then do it if actions[2]: self.render_key(outfd, s, actions[2]) outfd.write("\n") actions = actions[3:] # Print Windows Services elif action == PRT_SRVC: for s in rawreg.subkeys(key): v_type, v_start, v_display, v_path = ('','','','') for v in rawreg.values(s): v_name = str(v.Name) if v_name in ["Type", "DisplayName", "ImagePath", "Start" ]: tp, dat = rawreg.value_data(v) if v_name == "Type": if dat in serv_types: v_type = serv_types[dat] elif v_name == "Start": if dat in serv_starts: v_start = serv_starts[dat] elif v_name == "ImagePath": v_path = dat else: v_display = dat outfd.write("\n {0:s} {1} {2:10s} {3}".format(s.Name, v_display, self.voltext(s), s.LastWriteTime)) outfd.write("\n {0} Start= {1}, Type= {2}\n".format( v_path, v_start, v_type)) actions = actions[1:] # Data field is a Windows TimeStamp elif action == PRT_WINTIME: valname = actions[1] for v in rawreg.values(key): v_name = v.Name if v_name in valname: v_ts = obj.Object("WinTimeStamp", v.Data.v(), v.obj_vm) outfd.write(" {0} {1} \n".format(v_name, v_ts)) actions = actions[2:] # Data field is MountedDevices key value elif action == PRT_DEV: for v in rawreg.values(key): tp, dat = rawreg.value_data(v) assert tp == 'REG_BINARY' if v.DataLength == 12: hexa = ' '.join(["{0:02X}".format(ord(k)) for k in dat[:4]]) outfd.write("\n {0:15} : {1:3s}\n Drive Signature: {2}\n".format(v.Name, self.voltext(v), hexa)) elif v.DataLength > 12: dat = dat.encode("ascii", 'backslashreplace') outfd.write("\n {0:15} : {1:3s}\n {2}\n".format(v.Name, self.voltext(v), dat)) actions = actions[1:] # Access and print "shell\\open\\command" subkey value # Print value which is null-terminated Unicode string elif action == PRT_UNI: for v in rawreg.values(key): v_name = str(v.Name) if v_name.startswith("MRUList"): continue tp, dat = rawreg.value_data( v ) assert( tp == "REG_BINARY") # grab up to (but not including) the first null byte xx = dat.decode('utf-16-le', "ignore").split("\0")[0] # convert unicode to ascii yy = xx.encode("ascii", 'backslashreplace') outfd.write(" {0} {1}\n".format(v_name, yy)) actions = actions[1:] # Print Explorer UserAssist Active Desktop key elif action == PRT_USRAS: for v in rawreg.values(key): v_name = str(v.Name) if v_name.startswith("HRZR"): # Python decodes rot13 to unicode so need to convert to ascii ad_ent = v_name.decode('rot13', "ignore").encode("ascii", 'backslashreplace') outfd.write(" {0}\n".format(ad_ent)) actions = actions[1:] # Print a binary timestamp stored as low value / high value # Assumes that low value key field is specified first, followed by high value elif action == PRT_BINTIME: valname = actions[1] v_ts_lo = 0 v_ts_hi = 0 for v in rawreg.values(key): v_name = v.Name if v_name == valname[0]: tp, v_ts_lo = rawreg.value_data( v ) assert tp == "REG_DWORD" elif v_name == valname[1]: tp, v_ts_hi = rawreg.value_data( v ) assert tp == "REG_DWORD" if not v_ts_lo == 0: # Format the time for display windows_ts = (v_ts_hi << 32) | v_ts_lo if(windows_ts == 0): unix_time =0 else: unix_time = windows_ts / 10000000 # nano-sec since 16 unix_time = unix_time - 11644473600 if unix_time < 0: unix_time = 0 try: utc_display = strftime("%a %b %d %H:%M:%S %Y UTC", gmtime( unix_time )) except ValueError, e: utc_display = "Datetime conversion failure: " + str(e) outfd.write(" {0} : {1} \n".format(valname, utc_display)) actions = actions[2:]
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
def calculate(self): if (self._config.HIVE or self._config.USER) and "Registry" not in self._config.TYPE: debug.error( "You must use --registry in conjuction with -H/--hive and/or -U/--user" ) if self._config.TYPE != None: for t in self._config.TYPE.split(","): if t.strip() not in self.types and t.strip() != "Registry": debug.error( "You have entered an incorrect type: {0}".format(t)) addr_space = utils.load_as(self._config) version = ( addr_space.profile.metadata.get('major', 0), addr_space.profile.metadata.get('minor', 0), ) pids = {} # dictionary of process IDs/ImageFileName body = False if self._config.OUTPUT == "body": body = True if self._config.MACHINE != "": self._config.update("MACHINE", "{0} ".format(self._config.MACHINE)) if "ImageDate" in self._config.TYPE: im = imageinfo.ImageInfo(self._config).get_image_time(addr_space) yield self.getoutput( "[{0}LIVE RESPONSE]{1} (System time){1}".format( self._config.MACHINE, "" if body else "|"), im['ImageDatetime'], body=body, ) if version <= (6, 1) and "IEHistory" in self._config.TYPE: self._config.update("LEAK", True) data = iehistory.IEHistory(self._config).calculate() for process, record in data: ## Extended fields are available for these records if record.obj_name == "_URL_RECORD": line = "[{6}IEHISTORY]{0} {1}->{5}{0} PID: {2}/Cache type \"{3}\" at {4:#x}".format( "" if body else "|", process.ImageFileName, process.UniqueProcessId, record.Signature, record.obj_offset, record.Url, self._config.MACHINE, ) yield self.getoutput( line, record.LastModified, end=record.LastAccessed, body=body, ) self._config.remove_option("REDR") self._config.remove_option("LEAK") psx = [] if ("Process" in self._config.Type or "TimeDateStamp" in self._config.Type or "LoadTime" in self._config.Type or "_CM_KEY_BODY" in self._config.Type): psx = psxview.PsXview(self._config).calculate() for offset, eprocess, ps_sources in psx: pids[eprocess.UniqueProcessId.v()] = eprocess.ImageFileName if "Process" in self._config.TYPE: line = "[{5}PROCESS]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput(line, eprocess.CreateTime, end=eprocess.ExitTime, body=body) if not hasattr(eprocess.obj_vm, "vtop"): eprocess = taskmods.DllList( self._config).virtual_process_from_physical_offset( addr_space, eprocess.obj_offset) if eprocess == None: continue else: ps_ad = eprocess.get_process_address_space() if ps_ad == None: continue if version[0] == 5 and "Process" in self._config.TYPE: line = "[{5}PROCESS LastTrimTime]{0} {1}{0} PID: {2}/PPID: {3}/POffset: 0x{4:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput(line, eprocess.Vm.LastTrimTime, body=body) if (eprocess.ObjectTable.HandleTableList and "_CM_KEY_BODY" in self._config.TYPE): for handle in eprocess.ObjectTable.handles(): if not handle.is_valid(): continue name = "" object_type = handle.get_object_type() if object_type == "Key": key_obj = handle.dereference_as("_CM_KEY_BODY") name = key_obj.full_key_name() line = "[{6}Handle (Key)]{0} {1}{0} {2} PID: {3}/PPID: {4}/POffset: 0x{5:08x}".format( "" if body else "|", name, eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, offset, self._config.MACHINE, ) yield self.getoutput( line, key_obj.KeyControlBlock.KcbLastWriteTime, body=body, ) if eprocess.Peb == None or eprocess.Peb.ImageBaseAddress == None: continue # Get DLL PE timestamps for Wow64 processes (excluding 64-bit ones) if eprocess.IsWow64 and "TimeDateStamp" in self._config.TYPE: for vad, address_space in eprocess.get_vads( vad_filter=eprocess._mapped_file_filter): if vad.FileObject.FileName: name = str(vad.FileObject.FileName).lower() basename = ntpath.basename(name) if not basename.endswith("dll") or basename in [ "wow64cpu.dll", "ntdll.dll", "wow64.dll", "wow64win.dll", ]: continue data = ps_ad.zread(vad.Start, vad.Length) bufferas = addrspace.BufferAddressSpace(self._config, data=data) try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset=0, vm=bufferas) header = pe_file.get_nt_header() except ValueError as ve: continue line = "[{7}PE HEADER 32-bit (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, vad.Start, self._config.MACHINE, ) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body) # get DLL PE timestamps mods = dict() if ("TimeDateStamp" in self._config.TYPE or "LoadTime" in self._config.TYPE): mods = dict((mod.DllBase.v(), mod) for mod in eprocess.get_load_modules()) for mod in list(mods.values()): basename = str(mod.BaseDllName or "") if basename == str(eprocess.ImageFileName): line = "[{7}PE HEADER (exe)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) else: line = "[{7}PE HEADER (dll)]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) if "TimeDateStamp" in self._config.TYPE: yield self.getoutput(line, mod.TimeDateStamp, body=body) line2 = "[{7}PE DEBUG]{0} {4}{0} Process: {1}/PID: {2}/PPID: {3}/Process POffset: 0x{5:08x}/DLL Base: 0x{6:08x}".format( "" if body else "|", eprocess.ImageFileName, eprocess.UniqueProcessId, eprocess.InheritedFromUniqueProcessId, basename, offset, mod.DllBase.v(), self._config.MACHINE, ) yield self.getoutput( line2, mod.get_debug_directory().TimeDateStamp, body=body, ) if (hasattr(mod, "LoadTime") and "LoadTime" in self._config.TYPE): temp = line.replace( "[{0}PE HEADER ".format(self._config.MACHINE), "[{0}DLL LOADTIME ".format(self._config.MACHINE), ) yield self.getoutput(temp, mod.LoadTime, body=body) # Get Sockets and Evtlogs XP/2k3 only if version[0] == 5: # socks = sockets.Sockets(self._config).calculate() socks = [] if "Socket" in self._config.TYPE: socks = sockscan.SockScan(self._config).calculate( ) # you can use sockscan instead if you uncomment for sock in socks: la = "{0}:{1}".format(sock.LocalIpAddress, sock.LocalPort) line = "[{6}SOCKET]{0} LocalIP: {2}/Protocol: {3}({4}){0} PID: {1}/POffset: 0x{5:#010x}".format( "" if body else "|", sock.Pid, la, sock.Protocol, protos.protos.get(sock.Protocol.v(), "-"), sock.obj_offset, self._config.MACHINE, ) yield self.getoutput(line, sock.CreateTime, body=body) stuff = [] if "EvtLog" in self._config.TYPE: evt = evtlogs.EvtLogs(self._config) stuff = evt.calculate() for name, buf in stuff: for fields in evt.parse_evt_info(name, buf, rawtime=True): line = "[{8}EVT LOG]{0} {1}{0} {2}/{3}/{4}/{5}/{6}/{7}".format( "" if body else "|", fields[1], fields[2], fields[3], fields[4], fields[5], fields[6], fields[7], self._config.MACHINE, ) yield self.getoutput(line, fields[0], body=body) elif version <= (6, 1): # Vista+ nets = [] if "Socket" in self._config.TYPE: nets = netscan.Netscan(self._config).calculate() for net_object, proto, laddr, lport, raddr, rport, state in nets: if net_object.CreateTime.v() == 0: continue if raddr == "*" and rport == "*": conn = "{0}:{1}".format(laddr, lport) socket_type = "SOCKET" else: conn = "{0}:{1} -> {2}:{3}".format(laddr, lport, raddr, rport) socket_TYPE = "CONNECTION" line = ( "[{6}NETWORK {7}]{0} {2}{0} {1}/{3}/{4}/{5:<#10x}".format( "" if body else "|", net_object.Owner.UniqueProcessId, conn, proto, state, net_object.obj_offset, self._config.MACHINE, socket_type, )) yield self.getoutput(line, net_object.CreateTime, body=body) # Get threads threads = [] if "Thread" in self._config.TYPE: threads = modscan.ThrdScan(self._config).calculate() for thread in threads: image = pids.get(thread.Cid.UniqueProcess.v(), "UNKNOWN") line = "[{4}THREAD]{0} {1}{0} PID: {2}/TID: {3}".format( "" if body else "|", image, thread.Cid.UniqueProcess, thread.Cid.UniqueThread, self._config.MACHINE, ) yield self.getoutput(line, thread.CreateTime, end=thread.ExitTime, body=body) data = [] if "Symlink" in self._config.TYPE: data = filescan.SymLinkScan(self._config).calculate() for link in data: objct = link.get_object_header() line = "[{6}SYMLINK]{0} {1}->{2}{0} POffset: {3}/Ptr: {4}/Hnd: {5}".format( "" if body else "|", str(objct.NameInfo.Name or ''), str(link.LinkTarget or ''), link.obj_offset, objct.PointerCount, objct.HandleCount, self._config.MACHINE, ) yield self.getoutput(line, link.CreationTime, body=body) data = [] if "TimeDateStamp" in self._config.TYPE: data = moddump.ModDump(self._config).calculate() for aspace, procs, mod_base, mod_name in data: mod_name = str(mod_name or '') space = tasks.find_space(aspace, procs, mod_base) if space != None: try: pe_file = obj.Object("_IMAGE_DOS_HEADER", offset=mod_base, vm=space) header = pe_file.get_nt_header() except ValueError as ve: continue line = ( "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format( "" if body else "|", mod_name, mod_base, self._config.MACHINE, )) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body) uastuff = [] if "Userassist" in self._config.TYPE: uastuff = userassist.UserAssist(self._config).calculate() for win7, reg, key in uastuff: ts = "{0}".format(key.LastWriteTime) for v in rawreg.values(key): tp, dat = rawreg.value_data(v) subname = v.Name if tp == 'REG_BINARY': dat_raw = dat try: subname = codecs.encode(subname, 'rot_13') except UnicodeDecodeError: pass if win7: guid = subname.split("\\")[0] if guid in userassist.folder_guids: subname = subname.replace( guid, userassist.folder_guids[guid]) bufferas = addrspace.BufferAddressSpace(self._config, data=dat_raw) uadata = obj.Object("_VOLUSER_ASSIST_TYPES", offset=0, vm=bufferas) ID = "N/A" count = "N/A" fc = "N/A" tf = "N/A" lw = "N/A" if (len(dat_raw) < bufferas.profile.get_obj_size( '_VOLUSER_ASSIST_TYPES') or uadata == None): continue else: if hasattr(uadata, "ID"): ID = "{0}".format(uadata.ID) if hasattr(uadata, "Count"): count = "{0}".format(uadata.Count) else: count = "{0}".format( uadata.CountStartingAtFive if uadata.CountStartingAtFive < 5 else uadata.CountStartingAtFive - 5) if hasattr(uadata, "FocusCount"): seconds = (uadata.FocusTime + 500) / 1000.0 time = (datetime.timedelta(seconds=seconds) if seconds > 0 else uadata.FocusTime) fc = "{0}".format(uadata.FocusCount) tf = "{0}".format(time) lw = "{0}".format(uadata.LastUpdated) subname = subname.replace("|", "%7c") line = "[{7}USER ASSIST]{0} {2}{0} Registry: {1}/ID: {3}/Count: {4}/FocusCount: {5}/TimeFocused: {6}".format( "" if body else "|", reg, subname, ID, count, fc, tf, self._config.MACHINE, ) yield self.getoutput(line, uadata.LastUpdated, body=body) shimdata = [] if "Shimcache" in self._config.TYPE: shimdata = shimcache.ShimCache(self._config).calculate() for path, lm, lu in shimdata: line = "[{2}SHIMCACHE]{0} {1}{0} ".format("" if body else "|", path, self._config.MACHINE) if lu: yield self.getoutput(line, lm, end=lu, body=body) else: yield self.getoutput(line, lm, body=body) if ("_HBASE_BLOCK" in self._config.TYPE or "_CMHIVE" in self._config.TYPE or "Registry" in self._config.TYPE): regapi = registryapi.RegistryApi(self._config) for o in regapi.all_offsets: if "_HBASE_BLOCK" in self._config.TYPE: line = "[{2}_HBASE_BLOCK TimeStamp]{0} {1}{0} ".format( "" if body else "|", regapi.all_offsets[o], self._config.MACHINE, ) h = obj.Object("_HHIVE", o, addr_space) yield self.getoutput(line, h.BaseBlock.TimeStamp, body=body) if ("_CMHIVE" in self._config.TYPE and version[0] == 6 and addr_space.profile.metadata.get('build', 0) >= 7601): line = ( line) = "[{2}_CMHIVE LastWriteTime]{0} {1}{0} ".format( "" if body else "|", regapi.all_offsets[o], self._config.MACHINE, ) cmhive = obj.Object("_CMHIVE", o, addr_space) yield self.getoutput(line, cmhive.LastWriteTime, body=body) if "Registry" in self._config.TYPE: regapi.reset_current() regdata = regapi.reg_get_all_keys(self._config.HIVE, self._config.USER, reg=True, rawtime=True) for lwtime, reg, item in regdata: item = item.replace("|", "%7c") line = "[{3}REGISTRY]{0} {2}{0} Registry: {1}".format( "" if body else "|", reg, item, self._config.MACHINE) yield self.getoutput(line, lwtime, body=body) if "Timer" in self._config.TYPE: volmagic = obj.VolMagic(addr_space) KUSER_SHARED_DATA = obj.Object( "_KUSER_SHARED_DATA", offset=volmagic.KUSER_SHARED_DATA.v(), vm=addr_space, ) interrupt = (KUSER_SHARED_DATA.InterruptTime.High1Time << 32) | KUSER_SHARED_DATA.InterruptTime.LowPart now = KUSER_SHARED_DATA.SystemTime.as_windows_timestamp() data = timers.Timers(self._config).calculate() for timer, module in data: signaled = "-" if timer.Header.SignalState.v(): signaled = "Yes" module_name = "UNKNOWN" if module: module_name = str(module.BaseDllName or '') try: # human readable time taken from http://computer.forensikblog.de/en/2011/10/timers-and-times.html bufferas = addrspace.BufferAddressSpace( self._config, data=struct.pack( '<Q', timer.DueTime.QuadPart - interrupt + now), ) due_time = obj.Object("WinTimeStamp", is_utc=True, offset=0, vm=bufferas) except TypeError: due_time = 0 line = "[{6}TIMER]{0} {1}{0} Signaled: {2}/Routine: 0x{3:x}/Period(ms): {4}/Offset: 0x{5:x}".format( "" if body else "|", module_name, signaled, timer.Dpc.DeferredRoutine, timer.Period, timer.obj_offset, self._config.MACHINE, ) yield self.getoutput(line, due_time, body=body)
def render_text(self, outfd, data): for subkey in data: outfd.write("\n{0:<20}: {1}\n".format("Missing service", subkey.Name)) for value in rawreg.values(subkey): value_type, value_data = rawreg.value_data(value) outfd.write("{0:<20}: ({1}) {2}\n".format(value.Name, value_type, value_data))
def do_action(self): ########################### # Memory analysis CACHE ########################### self.console_print("Calculating memory hash: "+self.filepath) hresult = self.sha256hash(self.filepath) self.console_print("SHA256: " + hresult) cache = False # WE CHECK IF THIS MEMORY HAS CACHE cache_process = hresult+"_"+"process" if os.path.exists(cache_process): with open (cache_process, 'r') as outfile: vprocess = json.load(outfile) cache = True outfile.close() cache_threads = hresult+"_"+"threads" if os.path.exists(cache_threads): with open (cache_threads, 'r') as outfile: vthreads = json.load(outfile) #cache = True outfile.close() cache_vads = hresult+"_"+"vads" if os.path.exists(cache_vads): with open (cache_vads, 'r') as outfile: vvads = json.load(outfile) #cache = True outfile.close() cache_tokens = hresult+"_"+"tokens" if os.path.exists(cache_tokens): with open (cache_tokens, 'r') as outfile: vtokens = json.load(outfile) #cache = True outfile.close() if cache: self.console_print("Using process cache file: "+cache_process) self.console_print("Using threads cache file: "+cache_threads) self.console_print("Using vads cache file: "+cache_vads) self.console_print("Using tokens cache file: "+cache_tokens) self.send_message(vprocess) self.send_message(vthreads) self.send_message(vvads) self.send_message(vtokens) self.terminate() ########################### # Get MachineGUID ########################### if self._running: self._config.KEY = 'Microsoft\\Cryptography' for reg,key in self.get_registry_keys(): if key: for v in rawreg.values(key): tp, dat = rawreg.value_data(v) if (v.Name == "MachineGuid"): self.machineguid = dat if self.machineguid == "": self.machineguid = "ffffffff-2cf2-4c6d-919d-686204658ab6" mg_vector = self.machineguid.split("-") computerid = mg_vector[0] self.console_print("MACHINEGUID detected: " + str(computerid)) ########################### # Plugin psxview volatility ########################### if self._running: proc = psxv.PsXview(self._config) pslist1 = {} vprocess = [] vthreads = [] vvads = [] vtokens = [] ## ## PRINCIPAL LOOP TO GET THE PROCESSES ## for offset, process, ps_sources in proc.calculate(): # Check if PEB structure is ready (psxview is a pool tag plugin) PEB = str(process.Peb) peb_empty = False if PEB == "": peb_empty = True # PEB pslist1['CommandLine'] = str(process.Peb.ProcessParameters.CommandLine).replace('\"','') pslist1['CurrentDirectory'] = str(process.Peb.ProcessParameters.CurrentDirectory.DosPath) pslist1['Image'] = str(process.Peb.ProcessParameters.ImagePathName) pslist1['BeingDebugged'] = str(process.Peb.BeingDebugged) pslist1['DllPath'] = str(process.Peb.ProcessParameters.DllPath) # EPROCESS pslist1['UtcTime'] = self.normalize_utc_time(str(process.CreateTime)) pslist1['ProcessId'] = str(int(process.UniqueProcessId)) pslist1['ParentProcessId'] = str(int(process.InheritedFromUniqueProcessId)) pslist1['TerminalSessionId'] = str(int(process.SessionId)) pslist1['ExitTime'] = str(process.ExitTime) pslist1['IsWow64'] = str(process.IsWow64) pslist1['NumHandles'] = str(int(process.ObjectTable.HandleCount)) pslist1['NumThreads'] = str(int(process.ActiveThreads)) pslist1['computer'] = computerid pslist1['Source'] = "Memory" pslist1['LogonGuid'] = "{" + computerid + "-0000-0000-0000-000000000000}" pslist1['idEvent'] = 1 pslist1['IntegrityLevel'] = "" # por calcular pslist1['User'] = "" # por calcular pslist1['ParentImage'] = "" pslist1['ParentCommandLine'] = "" pslist1['ParentProcessGuid'] = "" pslist1["UnknownThreads"] = "False" pslist1['PsList'] = str(offset in ps_sources["pslist"]) pslist1['PsScan'] = str(offset in ps_sources["psscan"]) pslist1['ThreadProc'] = str(offset in ps_sources["thrdproc"]) pslist1['PsPcid'] = str(offset in ps_sources["pspcid"]) pslist1['Csrss'] = str(offset in ps_sources["csrss"]) pslist1['Session'] = str(offset in ps_sources["session"]) pslist1['DeskThrd'] = str(offset in ps_sources["deskthrd"]) self.console_print("Extraction information of process with PID: "+str(pslist1['ProcessId'])) # Exception (I) If we don't find smss.exe in PEB structure, we get ImageFileName from EPROCESS. if pslist1['Image'] == "": pslist1['Image'] = str(process.ImageFileName) if pslist1['Image'] == "smss.exe": pslist1['CommandLine'] = "C:\\Windows\\System32\\smss.exe" pslist1['Image'] = "C:\\Windows\\System32\\smss.exe" pslist1['TerminalSessionId'] = "0" # Exception (II) Exception with terminated process if pslist1['ExitTime'] != "1970-01-01 00:00:00 UTC+0000": pslist1['Image'] = str(process.ImageFileName) pslist1['CommandLine'] = str(process.ImageFileName) # Exception (III) with kernel if pslist1['ProcessId'] == '4' and pslist1['TerminalSessionId'] == "-1": pslist1['Image'] = "system" pslist1['CommandLine'] = "system" pslist1['TerminalSessionId'] = "0" pslist1['IntegrityLevel'] = "System" pslist1['User'] = "******" # Exception (IV) with smss.exe if pslist1['Image'] == "\\SystemRoot\\System32\\smss.exe" and pslist1['TerminalSessionId'] == "-1": pslist1['CommandLine'] = "C:\\Windows\\System32\\smss.exe" pslist1['Image'] = "C:\\Windows\\System32\\smss.exe" pslist1['CurrentDirectory'] = "C:\\Windows\\System32\\" pslist1['TerminalSessionId'] = "0" # We build the "PROCESSGUID" to MERGE this event ID with Sysmon ################################################################ date_time_obj = datetime.datetime.strptime(pslist1["UtcTime"], '%Y-%m-%d %H:%M:%S.%f') epoch = datetime.datetime.utcfromtimestamp(0) t = (date_time_obj-epoch).total_seconds() hex_string = '{:02x}'.format(int(t)) firstpart, secondpart = hex_string[:len(hex_string)/2], hex_string[len(hex_string)/2:] if pslist1['Image'] != "" and pslist1['ProcessId'] != "": result2 = hashlib.md5(pslist1['computer']+"-"+secondpart+"-"+firstpart+"-"+pslist1['ProcessId']+pslist1['Image'].lower()) else: result2 = hashlib.md5(pslist1['computer']+"-"+secondpart+"-"+firstpart+"-"+"666666"+"C:\syspce\dummy.exe") syspceid_datetime = date_time_obj.strftime('%Y-%m-%d %H:%M:%S') result = hashlib.md5(pslist1["ProcessId"]+pslist1["ParentProcessId"]+pslist1["computer"]+syspceid_datetime) pslist1['ProcessGuid'] = result2.hexdigest() pslist1['SyspceId'] = result.hexdigest() ########### # Privileges ########### if self._running: privileges = process.get_token().privileges() for value, present, enabled, default in privileges: try: name, desc = privm.PRIVILEGE_INFO[int(value)] #print name except KeyError: continue privileges_logged = ["SeImpersonatePrivilege","SeAssignPrimaryPrivilege","SeTcbPrivilege","SeBackupPrivilege","SeRestorePrivilege", "SeCreateTokenPrivilege","SeLoadDriverPrivilege","SeTakeOwnershipPrivilege","SeDebugPrivilege"] if str(name) in privileges_logged: #print str(name+"Present") #print str(name+"Enabled") pslist1[str(name)+"Present"] = "False" pslist1[str(name)+"Enabled"] = "False" if present: pslist1[name+"Present"] = "True" if enabled or default: pslist1[name+"Enabled"] = "True" else: sys.exit() ########### # Process Integrity Level and User ########### if self._running: tokenprocess = process.get_token() user_sids = self.lookup_user_sids(self._config) if tokenprocess.is_valid(): cont = 0 for sid_string in tokenprocess.get_sids(): if sid_string in well_known_sids: sid_name = well_known_sids[sid_string] elif sid_string in getservicesids.servicesids: sid_name = getservicesids.servicesids[sid_string] elif sid_string in user_sids: sid_name = user_sids[sid_string] else: sid_name_re = self.find_sid_re(sid_string, well_known_sid_re) if sid_name_re: sid_name = sid_name_re else: sid_name = "" if cont == 0: pslist1["User"] = str(sid_name) cont = cont + 1 if sid_string == "S-1-16-8192": pslist1["IntegrityLevel"] = "Medium" elif sid_string == "S-1-16-8448": pslist1["IntegrityLevel"] = "MediumPlus" elif sid_string == "S-1-16-4096": pslist1["IntegrityLevel"] = "Low" elif sid_string == "S-1-16-12288": pslist1["IntegrityLevel"] = "High" elif sid_string == "S-1-16-16384": pslist1["IntegrityLevel"] = "System" else: sys.exit() ################################# ## HANDLES TOKENS OPENS IN OTHER PROCESS ################################# token1 = {} if self._running: #user_sids = self.lookup_user_sids(self._config) for handle in process.ObjectTable.handles(): token = handle.dereference_as("_TOKEN") if token.is_valid(): token1["idEvent"] = 103 token1["ProcessId"] = pslist1["ProcessId"] token1["ProcessGuid"] = pslist1["ProcessGuid"] token1["SyspceId"] = pslist1["SyspceId"] token1["Image"] = pslist1["Image"] token1["Source"] = "Memory" token1['computer'] = pslist1['computer'] token1["TokenOffset"] = "" token1["TokenHandleValue"] = "" token1["TokenGrantAccess"] = "" token1["User"] = "" token1["UserSid"] = "" token1["IntegrityToken"] = "" token1["IntegritySid"] = "" token_with_sid = 0 list_tokens = token.get_sids() cont = 0 for sid_string in list_tokens: if sid_string in well_known_sids: sid_name = well_known_sids[sid_string] elif sid_string in getservicesids.servicesids: sid_name = getservicesids.servicesids[sid_string] elif sid_string in user_sids: sid_name = user_sids[sid_string] else: sid_name_re = self.find_sid_re(sid_string, well_known_sid_re) if sid_name_re: sid_name = sid_name_re else: sid_name = "" if cont == 0: token1["UserSid"] = str(sid_string) token1["User"] = str(sid_name) cont = cont + 1 token_with_sid = 1 #TOKEN INTEGRITY LEVEL if sid_string == "S-1-16-8192": token1["IntegrityToken"] = "Medium" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-8448": token1["IntegrityToken"] = "MediumPlus" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-4096": token1["IntegrityToken"] = "Low" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-12288": token1["IntegrityToken"] = "High" token1["IntegritySid"] = str(sid_string) elif sid_string == "S-1-16-16384": token1["IntegrityToken"] = "System" token1["IntegritySid"] = str(sid_string) if token_with_sid: token1["TokenOffset"] = str(handle.Body.obj_offset) token1["TokenHandleValue"] = str(handle.HandleValue) token1["TokenGrantAccess"] = str(handle.GrantedAccess) token_with_sid = 0 vtokens.append(token1) token1 = {} else: sys.exit() ## MODULES ########### modules = "" if self._running: for module in process.get_load_modules(): if module is not None: modules = modules + "," + str(module.FullDllName) pslist1['Modules'] = modules else: sys.exit() ## VADS ######## """ This looks for private allocations that are committed, memory-resident, non-empty (not all zeros) and with an original protection that includes write and execute. """ vad1 = {} if self._running: pslist1["RwxPage"] = "False" vads = process.get_vads(vad_filter=process._injection_filter) #vads = process.get_vads() for vad, address_space in vads: if self.is_vad_empty(vad, address_space): vad1["VadEmpty"] = "True" else: vad1["VadEmpty"] = "False" protect_flags = str(vadinfo.PROTECT_FLAGS.get(vad.VadFlags.Protection.v(), "")) # Process fields necessaries to a new idEvent vad1["idEvent"] = 102 vad1["ProcessId"] = pslist1["ProcessId"] vad1["ProcessGuid"] = pslist1["ProcessGuid"] vad1["SyspceId"] = pslist1["SyspceId"] vad1["Image"] = pslist1["Image"] vad1["Source"] = "Memory" vad1['computer'] = pslist1['computer'] # Fields VADs vad1["VadNode"] = str(vad.obj_offset) vad1["VadProtection"] = str(protect_flags) vad1["VadStart"] = str(vad.Start) vad1["VadEnd"] = str(vad.End) vvads.append(vad1) vad1 = {} pslist1["RwxPage"] = "True" else: sys.exit() ## THREADS ########### if self._running: self.get_threads(process,vthreads,pslist1) else: sys.exit() vprocess.append(pslist1) pslist1 = {} ## POST-EXTRACTION TASKS ## 1) FILL PARENT INFORMATION computer_alerts = 0 for p in vprocess: for x in vprocess: if p['ParentProcessId'] == x['ProcessId']: p['ParentImage'] = x['Image'] p['ParentCommandLine'] = x['CommandLine'] p['ParentProcessGuid'] = x['ProcessGuid'] p['RealParent'] = x['Image'] # Exception (VII) with lsass.exe if p["Image"].find("lsass.exe") != -1 and p["ParentImage"].find("wininit.exe")!= -1 and p['TerminalSessionId'] == "0": p['CommandLine'] = "C:\\Windows\\System32\\lsass.exe" p['CurrentDirectory'] = "C:\\Windows\\System32\\" # Exception (V) with svchost.exe if p["Image"].find("svchost.exe") != -1 and (p['TerminalSessionId'] == "0" or p['TerminalSessionId'] == "-1") and p["ParentImage"].find("services.exe") != -1: p['CommandLine'] = "C:\\Windows\\System32\\svchost.exe" p['Image'] = "C:\\Windows\\System32\\svchost.exe" p['CurrentDirectory'] = "C:\\Windows\\System32\\" p['TerminalSessionId'] = "0" # Exception (VI) with sppsvc.exe if p["Image"].find("sppsvc.exe") != -1 and p['TerminalSessionId'] == "-1" and p["ParentImage"].find("services.exe") != -1: p['CommandLine'] = "C:\\Windows\\System32\\sppsvc.exe" p['Image'] = "C:\\Windows\\System32\\sppsvc.exe" p['CurrentDirectory'] = "C:\\Windows\\System32\\" p['TerminalSessionId'] = "0" # Check computer self.check_fields(p) if p['computer'] == 'ffffffff' and computer_alerts == 0: print "[SYSPCE] Warning computer is ffffffff, problems while we try to read registry key" computer_alerts = 1 winlogon_fake_father = False winlogon_csrss_father = False wininit_fake_father = False wininit_csrss_father = False winlogon_father_pid = -1 wininit_father_pid = -1 ## POST-EXTRACTION TASKS ## 2) FIX PROBLEMS WITH MEMORY EXTRACTION for p in vprocess: ## WINLOGON problems with hierarchy in memory dumps (SMSS.exe die then it's possible collisions by pid) if p['Image'].find('winlogon') != -1: for x in vprocess: if p['ParentProcessId'] == x['ParentProcessId']: if p['Image'].find('smss.exe') == -1: winlogon_fake_father = True winlogon_father_pid = p['ParentProcessId'] break for z in vprocess: if z['Image'].find('csrss') != -1: if z['ParentProcessId'] == winlogon_father_pid: winlogon_csrss_father = True z['ParentImage'] = "smss.exe" z['ParentCommandLine'] = 'smss.exe' z['RealParent'] = "smss.exe" z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' for z in vprocess: if z['Image'].find('winlogon') != -1: if z['ParentProcessId'] == winlogon_father_pid: z['ParentImage'] = 'smss.exe' z['ParentCommandLine'] = 'smss.exe' z['RealParent'] = 'smss.exe' z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' ## WININIT problems with hierarchy in memory dumps (SMSS.exe die then it's possible collisions by pid) if p['Image'].find('wininit') != -1: for x in vprocess: if p['ParentProcessId'] == x['ParentProcessId']: if p['Image'].find('smss.exe') == -1: wininit_fake_father = True wininit_father_pid = p['ParentProcessId'] break for z in vprocess: if z['Image'].find('csrss.exe') != -1: if z['ParentProcessId'] == wininit_father_pid: wininit_csrss_father = True z['ParentImage'] = "smss.exe" z['ParentCommandLine'] = 'smss.exe' z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' for z in vprocess: if z['Image'].find('wininit') != -1: if z['ParentProcessId'] == wininit_father_pid: z['ParentImage'] = 'smss.exe' z['ParentCommandLine'] = 'smss.exe' z['ParentProcessId'] = '' z['ParentProcessGuid'] = '' ########################### # Plugin privs volatility ########################### #if self._running: # priv = privm.Privs(self._config) # privs_1 = {} # privs_2 = {} # priv_vector = [] # for privs in priv.calculate(): # privileges = privs.get_token().privileges() # for value, present, enabled, default in privileges: # try: # name, desc = privm.PRIVILEGE_INFO[int(value)] # except KeyError: # continue # privs_1 = {} # privs_1['ProcessId'] = str(int(privs.UniqueProcessId)) # privs_1['Name'] = name # # privileges_logged = ["SeImpersonatePrivilege","SeAssignPrimaryPrivilege","SeTcbPrivilege","SeBackupPrivilege","SeRestorePrivilege", # "SeCreateTokenPrivilege","SeLoadDriverPrivilege","SeTakeOwnershipPrivilege","SeDebugPrivilege"] # privs_1['Present'] = "False" # privs_1['Enabled'] = "False" # if str(name) in privileges_logged: # if present: # privs_1['Present'] = "True" # if enabled or default: # privs_1["Enabled"] = "True" # priv_vector.append(privs_1) # # for p in vprocess: # for x in priv_vector: # if p['ProcessId'] == x['ProcessId']: # pvp = x['Name'] + "Present" # p[pvp] = x['Present'] # pve = x['Name'] + "Enabled" # p[pve] = x['Enabled'] # To Send to the CORE ############################ if self._running: events_list = vprocess self.send_message(events_list) thread_list = vthreads self.send_message(thread_list) vads_list = vvads self.send_message(vads_list) token_list = vtokens self.send_message(token_list) # WE BUILD MEMORY CACHE (PROCESS, THREADS AND VADS) cache_process = hresult+"_"+"process" if not os.path.exists(cache_process): with open (cache_process, 'w') as outfile: json.dump(vprocess,outfile) outfile.close() cache_threads = hresult+"_"+"threads" if not os.path.exists(cache_threads): with open (cache_threads, 'w') as outfile: json.dump(vthreads,outfile) outfile.close() cache_vads = hresult+"_"+"vads" if not os.path.exists(cache_vads): with open (cache_vads, 'w') as outfile: json.dump(vvads,outfile) outfile.close() cache_tokens = hresult+"_"+"tokens" if not os.path.exists(cache_tokens): with open (cache_tokens, 'w') as outfile: json.dump(vtokens,outfile) outfile.close()
def generator(self, data): for reg, key in data: if key: subkeys = list(rawreg.subkeys(key)) values = list(rawreg.values(key)) yield ( 0, [ f"{reg}", f"{key.Name}", f"{self.voltext(key):3s}", f"{key.LastWriteTime}", "-", "-", "-", "-", "-", "-", ], ) if subkeys: for s in subkeys: if s.Name == None: yield ( 0, [ f"{reg}", f"{key.Name}", f"{self.voltext(key):3s}", f"{key.LastWriteTime}", f"Unknown subkey: {s.Name.reason}", "-", "-", "-", "-", "-", ], ) else: yield ( 0, [ f"{reg}", f"{key.Name}", f"{self.voltext(key):3s}", f"{key.LastWriteTime}", f"{s.Name}", f"{self.voltext(s):3s}", "-", "-", "-", "-", ], ) if values: for v in values: tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': dat = Bytes(dat) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') yield ( 0, [ f"{reg}", f"{key.Name}", f"{self.voltext(key):3s}", f"{key.LastWriteTime}", "-", "-", f"{tp}", f"{v.Name}", f"{self.voltext(v):3s}", f"{dat}", ], )
line = "{0}|{1}|{2}|{3}|{4}|{5}|EPROCESS Offset: 0x{6:08x}|DLL Base: {7:8x}||\n".format( "-1", "[PE Timestamp (dll)]", task.ImageFileName, task.UniqueProcessId, task.InheritedFromUniqueProcessId, mod_name, o, mod_base) yield line self.reset_current() uastuff = userassist.UserAssist.calculate(self) for win7, reg, key in uastuff: ts = "{0}".format(key.LastWriteTime) for v in rawreg.values(key): tp, dat = rawreg.value_data(v) subname = v.Name if tp == 'REG_BINARY': dat_raw = dat try: subname = subname.encode('rot_13') except: pass if win7: guid = subname.split("\\")[0] if guid in userassist.folder_guids: subname = subname.replace(guid, userassist.folder_guids[guid]) bufferas = addrspace.BufferAddressSpace(self._config, data = dat_raw) uadata = obj.Object("_VOLUSER_ASSIST_TYPES", offset = 0, vm = bufferas) ID = "N/A"
header = pe_file.get_nt_header() except ValueError, ve: continue line = "[{3}PE HEADER (module)]{0} {1}{0} Base: {2:#010x}".format( "" if body else "|", mod_name, mod_base, self._config.MACHINE) yield self.getoutput(line, header.FileHeader.TimeDateStamp, body=body) uastuff = [] if "Userassist" in self._config.TYPE: uastuff = userassist.UserAssist(self._config).calculate() for win7, reg, key in uastuff: ts = "{0}".format(key.LastWriteTime) for v in rawreg.values(key): tp, dat = rawreg.value_data(v) subname = v.Name if tp == 'REG_BINARY': dat_raw = dat try: subname = subname.encode('rot_13') except UnicodeDecodeError: pass if win7: guid = subname.split("\\")[0] if guid in userassist.folder_guids: subname = subname.replace( guid, userassist.folder_guids[guid]) bufferas = addrspace.BufferAddressSpace(self._config, data=dat_raw)
def generator(self, data): for reg, key in data: if key: subkeys = list(rawreg.subkeys(key)) values = list(rawreg.values(key)) yield (0, [str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), "-", "-", "-", "-", "-", "-"]) if subkeys: for s in subkeys: if s.Name == None: yield (0, [str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), str("Unknown subkey: {0}".format(s.Name.reason)), "-", "-", "-", "-", "-"]) else: yield (0, [str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), str("{0}".format(s.Name)), str("{0:3s}".format(self.voltext(s))), "-", "-", "-", "-"]) if values: for v in values: tp, dat = rawreg.value_data(v) if tp == 'REG_BINARY' or tp == 'REG_NONE': dat = Bytes(dat) if tp in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_LINK']: dat = dat.encode("ascii", 'backslashreplace') if tp == 'REG_MULTI_SZ': for i in range(len(dat)): dat[i] = dat[i].encode("ascii", 'backslashreplace') yield (0, [str("{0}".format(reg)), str("{0}".format(key.Name)), str("{0:3s}".format(self.voltext(key))), str("{0}".format(key.LastWriteTime)), "-", "-", str(tp), str("{0}".format(v.Name)), str("{0:3s}".format(self.voltext(v))), str(dat)])