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