Exemplo n.º 1
0
        /// <summary>
        /// Import a krb-cred structure containing one or more tickets into the current user ticket cache.
        /// </summary>
        /// <param name="krbCred">The krb-cred to import into the cache.</param>
        /// <param name="luid">The Logon Id of the user owning the ticket cache. The default of 0 represents the currently logged on user.</param>
        public unsafe void ImportCredential(KrbCred krbCred, long luid = 0)
        {
            if (krbCred is null)
            {
                throw new ArgumentNullException(nameof(krbCred));
            }

            var krbCredBytes = krbCred.EncodeApplication();

            var ticketRequest = new KERB_SUBMIT_TKT_REQUEST
            {
                MessageType    = KERB_PROTOCOL_MESSAGE_TYPE.KerbSubmitTicketMessage,
                KerbCredSize   = krbCredBytes.Length,
                KerbCredOffset = Marshal.SizeOf(typeof(KERB_SUBMIT_TKT_REQUEST)),
                LogonId        = luid
            };

            var bufferSize = ticketRequest.KerbCredOffset + krbCredBytes.Length;

            using (var pool = CryptoPool.Rent <byte>(bufferSize))
            {
                var buffer = pool.Memory.Slice(0, bufferSize);

                fixed(void *pBuffer = &MemoryMarshal.GetReference(buffer.Span))
                {
                    Marshal.StructureToPtr(ticketRequest, (IntPtr)pBuffer, false);
                    krbCredBytes.Span.CopyTo(buffer.Span.Slice(ticketRequest.KerbCredOffset));

                    this.LsaCallAuthenticationPackage(pBuffer, bufferSize);
                }
            }
        }
Exemplo n.º 2
0
        public override bool Add(TicketCacheEntry entry)
        {
            if (entry.Value is KerberosClientCacheEntry cacheEntry)
            {
                var cred = KrbCred.WrapTicket(
                    cacheEntry.KdcResponse.Ticket,
                    new KrbCredInfo
                {
                    Key       = cacheEntry.SessionKey,
                    AuthTime  = cacheEntry.AuthTime,
                    EndTime   = cacheEntry.EndTime,
                    Flags     = cacheEntry.Flags,
                    PName     = cacheEntry.KdcResponse.CName,
                    Realm     = cacheEntry.KdcResponse.CRealm,
                    RenewTill = cacheEntry.RenewTill,
                    SName     = cacheEntry.KdcResponse.Ticket.SName,
                    SRealm    = cacheEntry.KdcResponse.Ticket.Realm,
                    StartTime = cacheEntry.StartTime
                }
                    );

                lsa.ImportCredential(cred);
            }

            return(true);
        }
Exemplo n.º 3
0
        public void CreateKrbCredSucceeds()
        {
            KrbCred krbCred = CreateKrbCredential();

            Assert.IsNotNull(krbCred);
            Assert.AreEqual(EncryptionType.NULL, krbCred.EncryptedPart.EType);
            Assert.AreEqual("host/test.com", krbCred.Tickets[0].SName.FullyQualifiedName);
        }
        /// <summary>
        /// Shows the Kerberos Ticket included in an authentication token with KrbCred format
        /// which is used to transfer Kerberos credentials between applications.
        /// Reference:
        ///     The Unencrypted Form of Kerberos 5 KRB-CRED Message
        ///     https://tools.ietf.org/html/rfc6448
        /// </summary>
        /// <param name="message"></param>
        internal void ShowKrbCredTicket(string message)
        {
            var krbAsRepBytes = Convert.FromBase64String(message);
            var krbCred       = KrbCred.DecodeApplication(krbAsRepBytes);

            Assert.IsNotNull(krbCred);

            var credPart = krbCred.Validate();

            Assert.IsNotNull(credPart);

            AADKerberosLogger.PrintLines(2);
            AADKerberosLogger.Save("KRB-CRED Supplemental Ticket -----------------------------");
            AADKerberosLogger.Save("  ProtocolVersionNumber: " + krbCred.ProtocolVersionNumber);
            AADKerberosLogger.Save("  Message Type: " + krbCred.MessageType);
            AADKerberosLogger.Save("  # of Tickets: " + krbCred.Tickets.Length);

            for (int i = 0; i < krbCred.Tickets.Length; i++)
            {
                var ticket     = krbCred.Tickets[i];
                var ticketInfo = credPart.TicketInfo[i];

                var key = new byte[ticketInfo.Key.KeyValue.Length];
                ticketInfo.Key.KeyValue.CopyTo(key);

                AADKerberosLogger.Save("  Number: " + ticket.TicketNumber);
                AADKerberosLogger.Save("  Realm: " + ticket.Realm);
                AADKerberosLogger.Save("  SName: " + ticket.SName.FullyQualifiedName);
                ShowEncryptedDataPart("EncryptedPart", ticket.EncryptedPart);

                AADKerberosLogger.Save("  Ticket.Flags: " + ticketInfo.Flags);
                AADKerberosLogger.Save("  Ticket.Realm: " + ticketInfo.Realm);
                AADKerberosLogger.Save("  Ticket.PName: " + ticketInfo.PName.FullyQualifiedName);
                AADKerberosLogger.Save("  Ticket.SRealm: " + ticketInfo.SRealm);
                AADKerberosLogger.Save("  Ticket.SName: " + ticketInfo.SName.FullyQualifiedName);
                AADKerberosLogger.Save("  Ticket.AuthTime: " + ticketInfo.AuthTime);
                AADKerberosLogger.Save("  Ticket.StartTime: " + ticketInfo.StartTime);
                AADKerberosLogger.Save("  Ticket.EndTime: " + ticketInfo.EndTime);
                AADKerberosLogger.Save("  Ticket.RenewTill: " + ticketInfo.RenewTill);
                ShowEncrytionKey("Ticket.Key", ticketInfo.Key);

                if (ticketInfo.AuthorizationData == null)
                {
                    AADKerberosLogger.Save("  Ticket.AuthorizationData:");
                }
                else
                {
                    for (int j = 0; j < ticketInfo.AuthorizationData.Length; j++)
                    {
                        ShowAuthorizationData("Ticket.AuthorizationData", ticketInfo.AuthorizationData[j]);
                    }
                }
                AADKerberosLogger.Save("");
            }
        }
        /// <summary>
        /// Create KRB_CRED. This PDU should be sent after AP exchange successfully.
        /// </summary>
        /// <returns>The created KRB_CRED.</returns>
        public KrbCred CreateKrbCredRequest()
        {
            KrbCred cred = new KrbCred(context);

            cred.KerberosCred.msg_type = new Asn1Integer((int)MsgType.KRB_CRED);
            cred.KerberosCred.pvno     = new Asn1Integer(ConstValue.KERBEROSV5);

            Ticket[] ticket = new Ticket[] { context.ApTicket };
            cred.KerberosCred.tickets = new Asn1SequenceOf <Ticket>(ticket);

            EncryptionKey key = context.ContextKey;

            cred.CredEncPart = ConstrutCredEncryptedData(key);

            return(cred);
        }
Exemplo n.º 6
0
        private static KrbCred CreateKrbCredential()
        {
            KrbCred krbCred = KrbKdcRep.GenerateWrappedServiceTicket(new ServiceTicketRequest
            {
                Principal           = new FakeKerberosPrincipal("*****@*****.**"),
                ServicePrincipal    = new FakeKerberosPrincipal(RequestedSpn),
                ServicePrincipalKey = Key,
                IncludePac          = false,
                RealmName           = "test.com",
                Now       = DateTimeOffset.UtcNow,
                StartTime = DateTimeOffset.UtcNow,
                EndTime   = DateTimeOffset.UtcNow.AddHours(5),
                RenewTill = DateTimeOffset.UtcNow.AddDays(3),
                Flags     = TicketFlags.Renewable
            });

            return(krbCred);
        }
Exemplo n.º 7
0
        public async Task KdcTagPeekFailureUnknownHandler()
        {
            var kdc = new KdcServer(new KdcServerOptions {
                DefaultRealm = "domain.com", IsDebug = true
            });

            var krbCred = new KrbCred {
                Tickets = Array.Empty <KrbTicket>()
            };

            var response = await kdc.ProcessMessage(krbCred.EncodeApplication());

            var err = KrbError.DecodeApplication(response);

            Assert.IsNotNull(err);

            Assert.AreEqual(KerberosErrorCode.KRB_ERR_GENERIC, err.ErrorCode);
            Assert.IsTrue(err.EText.Contains("doesn't have a message handler registered"));
        }
Exemplo n.º 8
0
        private static KrbCred CreateKrbCredential()
        {
            var key = new KerberosKey(key: new byte[16], etype: EncryptionType.AES128_CTS_HMAC_SHA1_96);

            KrbCred krbCred = KrbKdcRep.GenerateWrappedServiceTicket(new ServiceTicketRequest
            {
                Principal           = new FakeKerberosPrincipal("*****@*****.**"),
                ServicePrincipal    = new FakeKerberosPrincipal("host/test.com"),
                ServicePrincipalKey = key,
                IncludePac          = false,
                RealmName           = "test.com",
                Now       = DateTimeOffset.UtcNow,
                StartTime = DateTimeOffset.UtcNow,
                EndTime   = DateTimeOffset.UtcNow.AddHours(5),
                RenewTill = DateTimeOffset.UtcNow.AddDays(3),
                Flags     = TicketFlags.Renewable
            });

            return(krbCred);
        }
Exemplo n.º 9
0
        public async Task KdcTagPeekFailureNullBuilder()
        {
            var kdc = new KdcServer(new KdcServerOptions {
                DefaultRealm = "domain.com", IsDebug = true
            });

            kdc.RegisterMessageHandler(MessageType.KRB_CRED, (b, o) => null);

            var krbCred = new KrbCred {
                Tickets = Array.Empty <KrbTicket>()
            };

            var response = await kdc.ProcessMessage(krbCred.EncodeApplication());

            var err = KrbError.DecodeApplication(response);

            Assert.IsNotNull(err);

            Assert.AreEqual(KerberosErrorCode.KRB_ERR_GENERIC, err.ErrorCode);
            Assert.IsTrue(err.EText.Contains("Message handler builder KRB_CRED must not return null"));
        }
Exemplo n.º 10
0
        //FROM TGS_REP
        public static byte[] toKirbi(KrbTgsRep tgsRep, KrbEncTgsRepPart tgsDecryptedRepPart, bool ptt = false)
        {
            //KrbCredInfo::= SEQUENCE {
            //                key[0]                 EncryptionKey,
            //prealm[1]              Realm OPTIONAL,
            //pname[2]               PrincipalName OPTIONAL,
            //flags[3]               TicketFlags OPTIONAL,
            //authtime[4]            KerberosTime OPTIONAL,
            //starttime[5]           KerberosTime OPTIONAL,
            //endtime[6]             KerberosTime OPTIONAL
            //renew - till[7]          KerberosTime OPTIONAL,
            //srealm[8]              Realm OPTIONAL,
            //sname[9]               PrincipalName OPTIONAL,
            //caddr[10]              HostAddresses OPTIONAL
            //}

            var info = new KrbCredInfo()
            {
                Key       = tgsDecryptedRepPart.Key,
                Realm     = tgsDecryptedRepPart.Realm,
                PName     = tgsRep.CName,
                Flags     = tgsDecryptedRepPart.Flags,
                StartTime = tgsDecryptedRepPart.StartTime,
                EndTime   = tgsDecryptedRepPart.EndTime,
                RenewTill = tgsDecryptedRepPart.RenewTill,
                SRealm    = tgsDecryptedRepPart.Realm,
                SName     = tgsDecryptedRepPart.SName
            };



            //EncKrbCredPart   ::= [APPLICATION 29]   SEQUENCE {
            //ticket-info[0]         SEQUENCE OF KrbCredInfo,
            //nonce[1]               INTEGER OPTIONAL,
            //timestamp[2]           KerberosTime OPTIONAL,
            //usec[3]                INTEGER OPTIONAL,
            //s-address[4]           HostAddress OPTIONAL,
            //r-address[5]           HostAddress OPTIONAL
            //}

            KrbCredInfo[] infos = { info };

            var encCredPart = new KrbEncKrbCredPart()
            {
                TicketInfo = infos
            };

            //KRB-CRED         ::= [APPLICATION 22]   SEQUENCE {
            //pvno[0]                INTEGER,
            //msg - type[1]            INTEGER, --KRB_CRED
            //tickets[2]             SEQUENCE OF Ticket,
            //enc - part[3]            EncryptedData
            //}
            var myCred = new KrbCred();

            myCred.ProtocolVersionNumber = 5;
            myCred.MessageType           = MessageType.KRB_CRED;
            KrbTicket[] tickets = { tgsRep.Ticket };
            myCred.Tickets = tickets;


            var encryptedData = new KrbEncryptedData()
            {
                Cipher = encCredPart.EncodeApplication(),
            };

            myCred.EncryptedPart = encryptedData;

            byte[] kirbiBytes = myCred.EncodeApplication().ToArray();


            string kirbiString = Convert.ToBase64String(kirbiBytes);

            if (ptt)
            {
                LSA.ImportTicket(kirbiBytes, new LUID());
            }


            return(kirbiBytes);
        }
Exemplo n.º 11
0
        //FROM TGS
        public static byte[] toKirbi(KrbTicket tgs, string srvName, string srvHash, EncryptionType etype, string service, bool ptt = false, bool verbose = false)
        {
            var kerbCred = new Utils.KerberosHashCreds(srvName, srvHash, etype);

            var ticketDecrypted = tgs.EncryptedPart.Decrypt
                                      (kerbCred.CreateKey(),
                                      KeyUsage.Ticket,
                                      b => KrbEncTicketPart.DecodeApplication(b));


            //KrbCredInfo::= SEQUENCE {
            //                key[0]                 EncryptionKey,
            //prealm[1]              Realm OPTIONAL,
            //pname[2]               PrincipalName OPTIONAL,
            //flags[3]               TicketFlags OPTIONAL,
            //authtime[4]            KerberosTime OPTIONAL,
            //starttime[5]           KerberosTime OPTIONAL,
            //endtime[6]             KerberosTime OPTIONAL
            //renew - till[7]          KerberosTime OPTIONAL,
            //srealm[8]              Realm OPTIONAL,
            //sname[9]               PrincipalName OPTIONAL,
            //caddr[10]              HostAddresses OPTIONAL
            //}

            string srvHost = null;

            if (srvName.Contains("$"))
            {
                srvHost = srvName.Replace("$", string.Empty) + "." + ticketDecrypted.CRealm;
            }
            else
            {
                srvHost = srvName;
            }

            var info = new KrbCredInfo()
            {
                Key       = ticketDecrypted.Key,
                Realm     = ticketDecrypted.CRealm,
                PName     = ticketDecrypted.CName,
                Flags     = ticketDecrypted.Flags,
                StartTime = ticketDecrypted.StartTime,
                EndTime   = ticketDecrypted.EndTime,
                RenewTill = ticketDecrypted.RenewTill,
                SRealm    = ticketDecrypted.CRealm,
                SName     = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = new[] { service, srvHost }
                }
            };



            //EncKrbCredPart   ::= [APPLICATION 29]   SEQUENCE {
            //ticket-info[0]         SEQUENCE OF KrbCredInfo,
            //nonce[1]               INTEGER OPTIONAL,
            //timestamp[2]           KerberosTime OPTIONAL,
            //usec[3]                INTEGER OPTIONAL,
            //s-address[4]           HostAddress OPTIONAL,
            //r-address[5]           HostAddress OPTIONAL
            //}

            KrbCredInfo[] infos = { info };

            var encCredPart = new KrbEncKrbCredPart()
            {
                TicketInfo = infos
            };

            //KRB-CRED         ::= [APPLICATION 22]   SEQUENCE {
            //pvno[0]                INTEGER,
            //msg - type[1]            INTEGER, --KRB_CRED
            //tickets[2]             SEQUENCE OF Ticket,
            //enc - part[3]            EncryptedData
            //}
            var myCred = new KrbCred();

            myCred.ProtocolVersionNumber = 5;
            myCred.MessageType           = MessageType.KRB_CRED;
            KrbTicket[] tickets = { tgs };
            myCred.Tickets = tickets;


            //https://github.com/dirkjanm/krbrelayx/blob/master/lib/utils/kerberos.py#L220
            //No Encryption for KRB-CRED
            var encryptedData = new KrbEncryptedData()
            {
                Cipher = encCredPart.EncodeApplication()
            };

            myCred.EncryptedPart = encryptedData;

            byte[] kirbiBytes = myCred.EncodeApplication().ToArray();


            string kirbiString = Convert.ToBase64String(kirbiBytes);

            if (ptt)
            {
                LSA.ImportTicket(kirbiBytes, new LUID());
            }
            else
            {
                Console.WriteLine("[+] SliverTicket Ticket Kirbi:");
                Console.WriteLine("    - {0}", kirbiString);
            }
            if (verbose)
            {
                Console.WriteLine("[*] Ticket Info:");
                PrintFunc.PrintKirbi(kirbiString);
            }


            return(kirbiBytes);
        }