コード例 #1
0
        private void SendTgsRequest(string sName, KdcOptions kdcOptions, Asn1SequenceOf <PA_DATA> seqPadata = null, AuthorizationData dataInAuthentiator = null, AuthorizationData dataInEncAuthData = null, MsgType msgType = MsgType.KRB_TGS_REQ)
        {
            if (string.IsNullOrEmpty(sName))
            {
                throw new ArgumentNullException("sName");
            }
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY          kdcReqBody = this.CreateKdcRequestBody(kdcOptions, sname, dataInEncAuthData); // almost same as AS request
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();

            kdcReqBody.BerEncode(bodyBuffer);

            ChecksumType checksumType = KerberosUtility.GetChecksumType(this.Context.SelectedEType);
            PA_DATA      paTgsReq     = CreatePaTgsReqest(checksumType, bodyBuffer.Data, dataInAuthentiator); // use AS session key encrypt authenticator.

            Asn1SequenceOf <PA_DATA> tempPaData = null;

            if (seqPadata == null || seqPadata.Elements == null || seqPadata.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paTgsReq });
            }
            else
            {
                PA_DATA[] paDatas = new PA_DATA[seqPadata.Elements.Length + 1];
                Array.Copy(seqPadata.Elements, paDatas, seqPadata.Elements.Length);
                paDatas[seqPadata.Elements.Length] = paTgsReq;
                tempPaData = new Asn1SequenceOf <PA_DATA>(paDatas);
            }

            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, tempPaData, Context.TransportType);

            tgsRequest.Request.msg_type.Value = (long)msgType;
            this.client.SendPdu(tgsRequest);
        }
コード例 #2
0
        private KDC_REQ_BODY CreateKdcRequestBody(KdcOptions kdcOptions, PrincipalName sName, AuthorizationData authData = null)
        {
            KDC_REQ_BODY kdcReqBody = this.CreateKdcRequestBody(kdcOptions, sName);

            if (authData == null)
            {
                return(kdcReqBody);
            }

            Asn1BerEncodingBuffer asnEncBuffer = new Asn1BerEncodingBuffer();

            authData.BerEncode(asnEncBuffer, true);

            EncryptedData encryptData = new EncryptedData();

            encryptData.etype = new KerbInt32(0);
            byte[] encryptAsnEncoded = asnEncBuffer.Data;
            if (this.Context.SessionKey != null && this.Context.SessionKey.keytype != null && this.Context.SessionKey.keyvalue != null && this.Context.SessionKey.keyvalue.Value != null)
            {
                encryptAsnEncoded = KerberosUtility.Encrypt(
                    (EncryptionType)this.Context.SessionKey.keytype.Value,
                    this.Context.SessionKey.keyvalue.ByteArrayValue,
                    encryptAsnEncoded,
                    (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData
                    );

                encryptData.etype = new KerbInt32(this.Context.SessionKey.keytype.Value);
            }
            encryptData.cipher = new Asn1OctetString(encryptAsnEncoded);
            kdcReqBody.enc_authorization_data = encryptData;

            return(kdcReqBody);
        }
コード例 #3
0
        protected void TypicalASExchange(KerberosTestClient client, KdcOptions options)
        {
            //Create and send AS request
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            PaPacOptions             paPacOptions = new PaPacOptions(PacOptions.Claims);
            Asn1SequenceOf <PA_DATA> paData       = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data });

            client.SendAsRequest(options, paData);

            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create pa-enc-timestamp
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               this.client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);

            paData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });
            //Create and send AS request
            client.SendAsRequest(options, paData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();
        }
コード例 #4
0
        public void KPSInvalidTargetDomain()
        {
            base.Logging();

            if (!this.testConfig.UseProxy)
            {
                BaseTestSite.Assert.Inconclusive("This case is only applicable when Kerberos Proxy Service is in use.");
            }
            //Create kerberos test client and connect
            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                                            this.testConfig.LocalRealm.User[1].Username,
                                            this.testConfig.LocalRealm.User[1].Password,
                                            KerberosAccountType.User,
                                            testConfig.LocalRealm.KDC[0].IPAddress,
                                            testConfig.LocalRealm.KDC[0].Port,
                                            testConfig.TransportType,
                                            testConfig.SupportedOid);

            KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);

            //Set the TargetDomain to an invalid value;
            proxyClient.TargetDomain = "InvalidDomain";
            client.UseProxy          = true;
            client.ProxyClient       = proxyClient;

            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends Proxy Message with invalid Target Domain.");
            client.SendAsRequest(options, null);

            BaseTestSite.Assert.AreEqual(KKDCPError.STATUS_NO_LOGON_SERVERS, client.ProxyClient.Error, "Server should drop the connection.");
        }
コード例 #5
0
        private CLAIMS_SET?GetADUserClaims_SingleRealm(string realm, string user, string userPwd, string server, string servicePwd, string serviceSpn)
        {
            base.Logging();

            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                                            this.testConfig.LocalRealm.User[2].Username,
                                            this.testConfig.LocalRealm.User[2].Password,
                                            KerberosAccountType.User,
                                            testConfig.LocalRealm.KDC[0].IPAddress,
                                            testConfig.LocalRealm.KDC[0].Port,
                                            testConfig.TransportType,
                                            testConfig.SupportedOid);

            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncTimeStamp, PaPacRequest and paPacOptions.");
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               client.Context.SelectedEType,
                                                               client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            PaPacOptions             paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });

            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request: {0}.", this.testConfig.LocalRealm.FileServer[0].Smb2ServiceName);
            Asn1SequenceOf <PA_DATA> seqOfPaData2 = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data });

            client.SendTgsRequest(this.testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options, seqOfPaData2);
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();
            EncryptionKey       key         = testConfig.QueryKey(this.testConfig.LocalRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            tgsResponse.DecryptTicket(key);
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted.");

            if (this.testConfig.IsKileImplemented)
            {
                BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data.");
                AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
                BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac.");

                foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers)
                {
                    if (buf.GetType() == typeof(ClientClaimsInfo))
                    {
                        return(((ClientClaimsInfo)buf).NativeClaimSet);
                    }
                }
            }
            return(null);
        }
コード例 #6
0
ファイル: KrbTgsReq.cs プロジェクト: mdavis332/Kerberos.NET
        public static KrbTgsReq CreateTgsReq(
            string spn,
            KrbEncryptionKey tgtSessionKey,
            KrbKdcRep kdcRep,
            KdcOptions options,
            KrbTicket user2UserTicket = null
            )
        {
            var tgtApReq = CreateApReq(kdcRep, tgtSessionKey);

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

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

            var tgt = kdcRep.Ticket;

            var sname = spn.Split('/', '@');

            var tgs = new KrbTgsReq
            {
                PaData = paData.ToArray(),
                Body   = new KrbKdcReqBody
                {
                    EType      = KerberosConstants.ETypes.ToArray(),
                    KdcOptions = options,
                    Nonce      = KerberosConstants.GetNonce(),
                    Realm      = tgt.Realm,
                    SName      = new KrbPrincipalName()
                    {
                        Type = PrincipalNameType.NT_SRV_HST,
                        Name = sname
                    },
                    Till = KerberosConstants.EndOfTime
                },
            };

            if (options.HasFlag(KdcOptions.EncTktInSkey) && user2UserTicket != null)
            {
                tgs.Body.AdditionalTickets = new[] {
                    user2UserTicket
                };
            }

            return(tgs);
        }
コード例 #7
0
        private KerberosAsRequest SendAsRequest(KdcOptions kdcOptions, Asn1SequenceOf <PA_DATA> seqPaData)
        {
            string        sName  = KerberosConstValue.KERBEROS_SNAME;
            string        domain = this.Context.Realm.Value;
            PrincipalName sname  =
                new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain));

            KDC_REQ_BODY      kdcReqBody = CreateKdcRequestBody(kdcOptions, sname);
            KerberosAsRequest asRequest  = this.CreateAsRequest(kdcReqBody, seqPaData);

            this.client.SendPdu(asRequest);
            return(asRequest);
        }
コード例 #8
0
        /// <summary>
        /// Generate a GCC AP token for the given account and SPN.
        /// </summary>
        /// <param name="kdcIpAddr">KDC IP address</param>
        /// <param name="account">Account Name.</param>
        /// <param name="pwd">Password of the account.</param>
        /// <param name="domain">Domain name.</param>
        /// <param name="spn">SPN</param>
        /// <param name="aType">Account type</param>
        /// <returns>Token</returns>
        public static byte[] GenerateGssApToken(string kdcIpAddr, string account, string pwd, string domain, string spn, KerberosAccountType aType)
        {
            KerberosTestClient client = new KerberosTestClient(
                domain,
                account,
                pwd,
                KerberosAccountType.User,
                kdcIpAddr,
                88,
                Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.TransportType.TCP,
                (KerberosConstValue.OidPkt)Enum.Parse(typeof(KerberosConstValue.OidPkt), "MSKerberosToken"));

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE | KdcOptions.OK_AS_DELEGATE;

            client.SendAsRequest(options, null);

            //Recieve preauthentication required error
            Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.METHOD_DATA methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string timeStamp = KerberosUtility.CurrentKerberosTime.Value;

            Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.PaEncTimeStamp paEncTimeStamp = new Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt);
            Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.PaPacRequest   paPacRequest   = new Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.PaPacRequest(true);
            Microsoft.Protocols.TestTools.StackSdk.Asn1.Asn1SequenceOf <PA_DATA>       seqOfPaData    = new Microsoft.Protocols.TestTools.StackSdk.Asn1.Asn1SequenceOf <PA_DATA>(new Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });
            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            //Create and send TGS request
            client.SendTgsRequest(spn, options);
            KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse();


            // client.ChangeRealm(childDomain, childDcIp, 88, Microsoft.Protocols.TestTools.StackSdk.Security.Kerberos.TransportType.TCP);
            // client.SendTgsRequest(spn, options);
            // KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.AuthorizationData data   = null;
            Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.EncryptionKey     subkey = Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.KerberosUtility.GenerateKey(client.Context.SessionKey);
            byte[] token = client.CreateGssApiToken(Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.ApOptions.None,
                                                    data,
                                                    subkey,
                                                    Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.ChecksumFlags.None,
                                                    KerberosConstValue.GSSToken.GSSAPI
                                                    );

            return(token);
        }
コード例 #9
0
        private EncTicketPart RetrieveAndDecryptServiceTicket(KerberosFunctionalClient kerberosClient, out EncryptionKey serviceKey)
        {
            //Create and send AS request
            const KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            kerberosClient.SendAsRequest(options, null);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects Kerberos Error from KDC");
            //Receive preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = kerberosClient.ExpectPreauthRequiredError(out methodData);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends AS request with PA-DATA set");
            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               kerberosClient.Context.SelectedEType,
                                                               kerberosClient.Context.CName.Password,
                                                               kerberosClient.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send AS request
            kerberosClient.SendAsRequest(options, seqOfPaData);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects AS response from KDC");
            KerberosAsResponse asResponse = kerberosClient.ExpectAsResponse();

            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create and send TGS request
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends TGS request to KDC");
            kerberosClient.SendTgsRequest(servicePrincipalName, options);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects TGS response from KDC");
            KerberosTgsResponse tgsResponse = kerberosClient.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(servicePrincipalName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "Service principal name in service ticket should match expected.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Decrypt SMB2 Service Ticket");
            serviceKey = keyManager.QueryKey(servicePrincipalName, TestConfig.DomainName, kerberosClient.Context.SelectedEType);
            tgsResponse.DecryptTicket(serviceKey);

            return(tgsResponse.TicketEncPart);
        }
コード例 #10
0
ファイル: KrbAsReq.cs プロジェクト: dotnet/Kerberos.NET
        private static DateTimeOffset?CalculateRenewTime(KdcOptions kdcOptions, Krb5Config config)
        {
            if (!kdcOptions.HasFlag(KdcOptions.Renewable))
            {
                return(null);
            }

            if (config.Defaults.RenewLifetime > TimeSpan.Zero)
            {
                return(DateTimeOffset.UtcNow.Add(config.Defaults.RenewLifetime));
            }
            else
            {
                return(EndOfTime);
            }
        }
コード例 #11
0
        private KDC_REQ_BODY CreateKdcRequestBody(KdcOptions kdcOptions, PrincipalName sName)
        {
            KerbUInt32    nonce     = new KerbUInt32((uint)Math.Abs((int)DateTime.Now.Ticks));
            KerberosTime  till      = new KerberosTime(KerberosConstValue.TGT_TILL_TIME);
            KerberosTime  rtime     = new KerberosTime(KerberosConstValue.TGT_RTIME);
            HostAddresses addresses =
                new HostAddresses(new HostAddress[1] {
                new HostAddress(new KerbInt32((int)AddressType.NetBios),
                                new Asn1OctetString(Encoding.ASCII.GetBytes(System.Net.Dns.GetHostName())))
            });

            KDCOptions options = new KDCOptions(KerberosUtility.ConvertInt2Flags((int)kdcOptions));

            KDC_REQ_BODY kdcReqBody = new KDC_REQ_BODY(options, Context.CName.Name, Context.Realm, sName, null, till, rtime, nonce, Context.SupportedEType, addresses, null, null);

            return(kdcReqBody);
        }
コード例 #12
0
        private void DAC_Smb2_AccessFile(string RealmName, User user, Computer kdc, TransportType transportType, FileServer fileserver, string filePath, string fileName, bool expectAccessDeny)
        {
            base.Logging();

            client = new KerberosTestClient(RealmName,
                                            user.Username,
                                            user.Password,
                                            KerberosAccountType.User,
                                            kdc.IPAddress,
                                            kdc.Port,
                                            transportType,
                                            testConfig.SupportedOid);

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create and send TGS request
            client.SendTgsRequest(fileserver.Smb2ServiceName, options);
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(fileserver.Smb2ServiceName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "Service principal name in service ticket should match expected.");
            EncryptionKey key = testConfig.QueryKey(fileserver.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            tgsResponse.DecryptTicket(key);

            BaseTestSite.Assert.AreEqual(RealmName.ToLower(),
                                         tgsResponse.TicketEncPart.crealm.Value.ToLower(),
                                         "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(user.Username.ToLower(),
                                         KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(),
                                         "User name in service ticket encrypted part should match expected.");

            //Assert authorization data
            if (this.testConfig.IsKileImplemented)
            {
                BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data.");
                AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
                BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac.");
            }

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);

            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                                                    data,
                                                    subkey,
                                                    ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File.");
            AccessFile(filePath, fileName, fileserver, token, tgsResponse.EncPart.key, expectAccessDeny);
        }
コード例 #13
0
        private void claimsTest_Kerberos_CrossRealm_ADSource_User_Only(bool ctaFromConfig)
        {
            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                                            this.testConfig.LocalRealm.User[2].Username,
                                            this.testConfig.LocalRealm.User[2].Password,
                                            KerberosAccountType.User,
                                            testConfig.LocalRealm.KDC[0].IPAddress,
                                            testConfig.LocalRealm.KDC[0].Port,
                                            testConfig.TransportType,
                                            testConfig.SupportedOid);

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               this.client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            PaPacOptions             paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });

            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse       asResponse   = client.ExpectAsResponse();
            Asn1SequenceOf <PA_DATA> seqOfPaData2 = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send TGS request
            client.SendTgsRequest(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, options, seqOfPaData2);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request");
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive a referral TGS response.");

            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "The service principal name in referral ticket should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(),
                                         tgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in referral ticket should match expected.");

            EncryptionKey key = testConfig.QueryKey(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName + "@" + this.testConfig.LocalRealm.RealmName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            tgsResponse.DecryptTicket(key);

            CLAIMS_SET claims      = new CLAIMS_SET();
            AdWin2KPac adWin2kPac  = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
            bool       foundClaims = false;

            foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers)
            {
                if (buf.GetType() == typeof(ClientClaimsInfo))
                {
                    claims      = ((ClientClaimsInfo)buf).NativeClaimSet;
                    foundClaims = true;
                }
            }
            BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in referral TGS Ticket");
            foundClaims = false;

            #region genertaed transformed claims
            Dictionary <string, string> expectedClaims = new Dictionary <string, string>();
            if (!ctaFromConfig)
            {
                ClaimTransformer    transformer = new ClaimTransformer(this.testConfig.TrustedRealm.KDC[0].IPAddress, this.testConfig.TrustedRealm.RealmName, this.testConfig.TrustedRealm.Admin.Username, this.testConfig.TrustedRealm.Admin.Password);
                List <CLAIMS_ARRAY> transformed = null;
                BaseTestSite.Assert.AreEqual <Win32ErrorCode_32>(Win32ErrorCode_32.ERROR_SUCCESS, transformer.TransformClaimsOnTrustTraversal(claims.ClaimsArrays, this.testConfig.LocalRealm.RealmName, true, out transformed), "should successfully transform claims");
                foreach (CLAIMS_ARRAY array in transformed)
                {
                    foreach (CLAIM_ENTRY entry in array.ClaimEntries)
                    {
                        string id    = entry.Id;
                        string value = null;
                        switch (entry.Type)
                        {
                        case CLAIM_TYPE.CLAIM_TYPE_BOOLEAN:
                            value = entry.Values.Struct4.BooleanValues[0].ToString();
                            break;

                        case CLAIM_TYPE.CLAIM_TYPE_INT64:
                            value = entry.Values.Struct1.Int64Values[0].ToString();
                            break;

                        case CLAIM_TYPE.CLAIM_TYPE_STRING:
                            value = entry.Values.Struct3.StringValues[0].ToString();
                            break;

                        case CLAIM_TYPE.CLAIM_TYPE_UINT64:
                            value = entry.Values.Struct2.Uint64Values[0].ToString();
                            break;

                        default:
                            BaseTestSite.Assert.Fail("Found invalid claim type during transform, value:" + (int)entry.Type);
                            break;
                        }
                        expectedClaims.Add(id.ToLower(), value.ToLower());
                    }
                }
            }
            else
            {
                string[] tmp = this.testConfig.LocalRealm.User[2].TransformedClaims.ToLower().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                BaseTestSite.Assert.IsTrue(tmp != null && tmp.Length % 2 == 0, "Claim.Crossforest.TransformedClaims in PTFConfig should be valid and not empty");
                for (int i = 0; i < tmp.Length; i += 2)
                {
                    expectedClaims.Add(tmp[i], tmp[i + 1]);
                }
            }
            #endregion
            //Change realm
            client.ChangeRealm(this.testConfig.TrustedRealm.RealmName,
                               this.testConfig.TrustedRealm.KDC[0].IPAddress,
                               this.testConfig.TrustedRealm.KDC[0].Port,
                               this.testConfig.TransportType);

            //Create and send referal TGS request
            client.SendTgsRequest(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options);
            KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName,
                                         KerberosUtility.PrincipalName2String(refTgsResponse.Response.ticket.sname),
                                         "The service principal name in service ticket should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.RealmName.ToLower(),
                                         refTgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in service ticket should match expected.");

            key = testConfig.QueryKey(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);
            refTgsResponse.DecryptTicket(key);

            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(),
                                         refTgsResponse.TicketEncPart.crealm.Value.ToLower(),
                                         "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[2].Username,
                                         KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(),
                                         "User name in service ticket encrypted part should match expected.");

            adWin2kPac = FindOneInAuthData <AdWin2KPac>(refTgsResponse.TicketEncPart.authorization_data.Elements);
            foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers)
            {
                if (buf.GetType() == typeof(ClientClaimsInfo))
                {
                    foundClaims = true;
                    claims      = ((ClientClaimsInfo)buf).NativeClaimSet;
                }
            }

            int errors = 0;
            BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in reference TGS Ticket");
            for (int i = 0; i < claims.ClaimsArrays[0].ClaimEntries.Length; i++)
            {
                string claimvalue = null;
                if (!expectedClaims.TryGetValue(claims.ClaimsArrays[0].ClaimEntries[i].Id.ToLower(), out claimvalue))
                {
                    errors++;
                    BaseTestSite.Log.Add(LogEntryKind.CheckFailed, "Found unexpected claim with id: " + claims.ClaimsArrays[0].ClaimEntries[i].Id + " after transform");
                }
                else
                {
                    if (claimvalue != claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0].ToLower())
                    {
                        errors++;
                        BaseTestSite.Log.Add(
                            LogEntryKind.CheckFailed,
                            "Value of claim \"" + claims.ClaimsArrays[0].ClaimEntries[i].Id + "\" is not expected, expected: " + claimvalue + " ,actual: " + claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0]);
                    }
                    expectedClaims.Remove(claims.ClaimsArrays[0].ClaimEntries[i].Id);
                }
            }

            BaseTestSite.Assert.AreEqual(expectedClaims.Count, claims.ClaimsArrays[0].ClaimEntries.Count(), "Claims count should be equal.");
            BaseTestSite.Assert.AreEqual <int>(0, errors, "Expect no error should be found when compare claims from reference TGS ticket");
        }
        private KDC_REQ_BODY CreateKdcRequestBody(
            KdcOptions kdcOptions,
            PrincipalName sName,
            KerberosTime from,
            KerberosTime till
            )
        {
            KerbUInt32 nonce = new KerbUInt32((uint)Math.Abs((int)DateTime.Now.Ticks));
            KerberosTime rtime = new KerberosTime(KerberosConstValue.TGT_RTIME);
            HostAddresses addresses =
                new HostAddresses(new HostAddress[1] { new HostAddress(new KerbInt32((int)AddressType.NetBios),
                    new Asn1OctetString(Encoding.ASCII.GetBytes(System.Net.Dns.GetHostName()))) });

            KDCOptions options = new KDCOptions(KerberosUtility.ConvertInt2Flags((int)kdcOptions));

            KDC_REQ_BODY kdcReqBody = new KDC_REQ_BODY(options, Context.CName.Name, Context.Realm, sName, from, till, rtime, nonce, Context.SupportedEType, addresses, null, null);
            return kdcReqBody;
        }
        /// <summary>
        /// Create and send AS request
        /// </summary>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="seqPaData">A sequence of preauthentication data</param>
        public void SendAsRequest(KdcOptions kdcOptions, Asn1SequenceOf<PA_DATA> seqPaData, KerberosTime from, KerberosTime till)
        {
            string sName = KerberosConstValue.KERBEROS_SNAME;
            string domain = this.Context.Realm.Value;
            PrincipalName sname =
                new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, from, till);
            KerberosAsRequest asRequest = this.CreateAsRequest(kdcReqBody, seqPaData);
            this.SendPdu(asRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send AS Request.");
        }
コード例 #16
0
        /// <summary>
        /// Initialize the context from a token.
        /// </summary>
        /// <param name="inToken">The token used to initialize.</param>
        /// <exception cref="System.NotSupportedException">Thrown when the ContextAttribute contains a flag that not be
        /// supported.</exception>
        /// <exception cref="System.InvalidOperationException">Thrown when an error is returned.</exception>
        public override void Initialize(byte[] inToken)
        {
            if (inToken == null || inToken.Length == 0)
            {
                KilePdu       response = null;
                string        sname    = ConstValue.KERBEROS_SNAME;
                KileAsRequest asRequest;
                EncryptionKey subkey = null;

                // Create and send AS request for pre-authentication
                KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.RENEWABLE
                                     | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLEOK;
                KDCOptions flags = new KDCOptions(KerberosUtility.ConvertInt2Flags((int)options));

                // Create and send AS request for pre-authentication
                asRequest = client.CreateAsRequest(sname, flags, null, this.GetClientSupportedEtype());
                client.SendPdu(asRequest);
                response = client.ExpectPdu(ConstValue.TIMEOUT_DEFAULT);
                KileKrbError preAuthError = response as KileKrbError;
                if ((preAuthError == null) || (!preAuthError.ErrorCode.Equals(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED)))
                {
                    throw new InvalidOperationException("The Error code should be KDC_ERR_PREAUTH_REQUIRED");
                }

                // Create and send AS request for TGT
                var                      defualtEncryptType = (client.ClientContext.TgsSessionKey == null) ? EncryptionType.RC4_HMAC : (EncryptionType)client.ClientContext.TgsSessionKey.keytype.Value;
                PaEncTimeStamp           timestamp          = client.ConstructPaEncTimeStamp(defualtEncryptType);
                PaPacRequest             pacRequest         = client.ConstructPaPacRequest(true);
                Asn1SequenceOf <PA_DATA> paData             = client.ConstructPaData(timestamp, pacRequest);

                if ((contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
                {
                    asRequest = client.CreateAsRequest(sname, flags, paData, this.GetClientSupportedEtype());
                    //subkey = new EncryptionKey((int)EncryptionType.AES256_CTS_HMAC_SHA1_96,
                    //    KileUtility.GenerateRandomBytes(ConstValue.AES_KEY_LENGTH));

                    var key = KeyGenerator.MakeKey(EncryptionType.AES256_CTS_HMAC_SHA1_96, client.ClientContext.Password, client.ClientContext.Salt);
                    subkey = new EncryptionKey(new KerbInt32((long)EncryptionType.AES256_CTS_HMAC_SHA1_96), new Asn1OctetString(key));
                }
                else
                {
                    asRequest = client.CreateAsRequest(sname, flags, paData, this.GetClientSupportedEtype());
                }
                client.SendPdu(asRequest);
                response = client.ExpectPdu(ConstValue.TIMEOUT_DEFAULT);

                if (response.GetType() == typeof(KileKrbError))
                {
                    throw new InvalidOperationException("Received Kerberos Error response: " + ((KileKrbError)response).ErrorCode);
                }
                KileAsResponse asResponse = (KileAsResponse)response;

                // Create and send TGS request

                // for example: "KERB.COMldapsut02.kerb.com"
                client.ClientContext.Salt = domain.ToUpper();
                string[] nameList = userLogonName.Split('/');
                foreach (string name in nameList)
                {
                    client.ClientContext.Salt += name;
                }
                KileTgsRequest tgsRequest = client.CreateTgsRequest(this.serverName,
                                                                    flags,
                                                                    null,
                                                                    ChecksumType.hmac_md5_string,
                                                                    null,
                                                                    null);
                client.SendPdu(tgsRequest);
                response = client.ExpectPdu(ConstValue.TIMEOUT_DEFAULT);

                if (response.GetType() == typeof(KileKrbError))
                {
                    throw new InvalidOperationException("Received Kerberos Error response: " + ((KileKrbError)response).ErrorCode);
                }

                KileTgsResponse tgsResponse = (KileTgsResponse)response;

                ApOptions     apOption;
                ChecksumFlags checksumFlag;
                GetFlagsByContextAttribute(out apOption, out checksumFlag);

                KerbAuthDataTokenRestrictions adRestriction =
                    client.ConstructKerbAuthDataTokenRestrictions(0,
                                                                  (uint)LSAP_TOKEN_INFO_INTEGRITY_Flags.FULL_TOKEN,
                                                                  (uint)LSAP_TOKEN_INFO_INTEGRITY_TokenIL.Medium,
                                                                  new Guid().ToString());
                AdAuthDataApOptions adApOptions = client.ConstructAdAuthDataApOptions(ConstValue.KERB_AP_OPTIONS_CBT);
                AuthorizationData   authData    = client.ConstructAuthorizationData(adRestriction, adApOptions);
                KileApRequest       apRequest   = client.CreateApRequest(apOption,
                                                                         ChecksumType.ap_authenticator_8003,
                                                                         ConstValue.SEQUENCE_NUMBER_DEFAULT,
                                                                         checksumFlag,
                                                                         subkey,
                                                                         authData);
                token = apRequest.ToBytes();

                bool isMutualAuth = (contextAttribute & ClientSecurityContextAttribute.MutualAuth)
                                    == ClientSecurityContextAttribute.MutualAuth;
                bool isDceStyle = (contextAttribute & ClientSecurityContextAttribute.DceStyle)
                                  == ClientSecurityContextAttribute.DceStyle;

                if (isMutualAuth || isDceStyle)
                {
                    continueProcess = true;   // SEC_I_CONTINUE_NEEDED;
                }
                else
                {
                    continueProcess = false;  // SEC_E_OK;
                }
            }
            else  // mutual authentication
            {
                KileApResponse apResponse = client.ParseApResponse(inToken);
                token = null;

                if ((contextAttribute & ClientSecurityContextAttribute.DceStyle)
                    == ClientSecurityContextAttribute.DceStyle)
                {
                    KileApResponse apResponseSend = client.CreateApResponse(null);
                    token = apResponseSend.ToBytes();
                }

                this.continueProcess = false;      // SEC_E_OK;
            }
        }
コード例 #17
0
ファイル: S4U.cs プロジェクト: zhouzu/KerberosRun
        //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);
            }
        }
        /// <summary>
        /// Create and send FAST TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
        /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
        /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
        /// <param name="fastOptions">FAST options</param>
        /// <param name="apOptions">AP options in FAST armor field</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequestWithFastHideCName(
            string sName,
            PrincipalName cName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> innerSeqPaData,
            Asn1SequenceOf<PA_DATA> outerSeqPaData,
            EncryptionKey subKey,
            ApOptions apOptions,
            AuthorizationData data = null)
        {
            var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(
                KerberosUtility.ConvertInt2Flags((int)FastOptionFlags.Hide_Client_Names));
            Context.Subkey = subKey;
            Context.ReplyKey = subKey;
            string domain = this.Context.Realm.Value;
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data);
            kdcReqBody.cname = cName;
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            KerberosApRequest apRequest = CreateApRequest(
                option,
                Context.Ticket,
                subKey,
                data,
                KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator,
                checksumType,
                bodyBuffer.Data);

            PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data });
            }
            else
            {
                tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length);
                tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data;
            }
            var armorKey = GetArmorKey(Context.SessionKey, subKey);
            var pafxfast = CreateTgsPaFxFast(armorKey, Context.Ticket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue);
            Context.FastArmorkey = armorKey;
            PA_DATA[] elements;
            if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
            {
                elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
                elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
                elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data;
            }
            else
            {
                elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data };
            }
            Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType);

            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request.");
        }
        /// <summary>
        /// Create and send FAST TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
        /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
        /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
        /// <param name="fastOptions">FAST options</param>
        /// <param name="apOptions">AP options in FAST armor field</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequestWithExplicitFast(
            string sName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> innerSeqPaData,
            Asn1SequenceOf<PA_DATA> outerSeqPaData,
            EncryptionKey subKey,
            FastOptions fastOptions,
            ApOptions apOptions,
            AuthorizationData data = null)
        {
            Context.Subkey = subKey;
            Context.ReplyKey = subKey;
            string domain = this.Context.Realm.Value;
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data);
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            //Create PA-TGS-REQ
            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            KerberosApRequest apRequest = CreateApRequest(
                option,
                Context.Ticket,
                subKey,
                data,
                KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator,
                checksumType,
                bodyBuffer.Data);

            PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data });
            }
            else
            {
                tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length);
                tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data;
            }
            //Create explicit FAST armor
            EncryptionKey explicitSubkey = KerberosUtility.MakeKey(
                Context.SelectedEType,
                "Password04!",
                "This is a salt");
            Authenticator plaintextAuthenticator = CreateAuthenticator(Context.ArmorTicket, null, explicitSubkey);
            KerberosApRequest apReq = new KerberosApRequest(Context.Pvno,
                new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions)),
                Context.ArmorTicket,
                plaintextAuthenticator,
                KeyUsageNumber.AP_REQ_Authenticator);
            FastArmorApRequest explicitArmor = new FastArmorApRequest(apReq.Request);

            //Create armor key
            var armorKey = GetArmorKey(Context.ArmorSessionKey, subKey, explicitSubkey);
            Context.FastArmorkey = armorKey;

            //Create PA-FX-FAST
            var pafxfast = CreateTgsPaFxFast(armorKey, Context.ArmorTicket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue, explicitArmor);

            PA_DATA[] elements;
            if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
            {
                elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
                elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
                elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data;
            }
            else
            {
                elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data };
            }
            Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType);

            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request.");
        }
        /// <summary>
        /// Create and send TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="seqPadata">A sequence of preauthentication data</param>
        /// <param name="checksumType">Checksum type of PA-TGS-REQ</param>
        /// <param name="additionalTicket">Additional ticket</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequest(string sName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> seqPadata = null,
            Ticket additionalTicket = null,
            AuthorizationData dataInAuthenticator = null,
            AuthorizationData dataInEncAuthData = null)
        {
            if (sName == null)
            {
                throw new ArgumentNullException("sName");
            }
            PrincipalName sname = new PrincipalName(
                new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, dataInEncAuthData);
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            PA_DATA paTgsReq = CreatePaTgsReq(checksumType, bodyBuffer.Data, dataInAuthenticator);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (seqPadata == null || seqPadata.Elements == null || seqPadata.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq });
            }
            else
            {
                PA_DATA[] paDatas = new PA_DATA[seqPadata.Elements.Length + 1];
                Array.Copy(seqPadata.Elements, paDatas, seqPadata.Elements.Length);
                paDatas[seqPadata.Elements.Length] = paTgsReq;
                tempPaData = new Asn1SequenceOf<PA_DATA>(paDatas);
            }

            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, tempPaData, Context.TransportType);
            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send TGS request.");
        }
 /// <summary>
 /// Create and send FAST AS request
 /// </summary>
 /// <param name="kdcOptions">KDC options</param>
 /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
 /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
 /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
 /// <param name="fastOptions">FAST options</param>
 /// <param name="apOptions">AP options in FAST armor field</param>
 public void SendAsRequestWithFastHideCName(
     KdcOptions kdcOptions,
     string cName,
     Asn1SequenceOf<PA_DATA> innerSeqPaData,
     Asn1SequenceOf<PA_DATA> outerSeqPaData,
     EncryptionKey subKey,
     ApOptions apOptions)
 {
     var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(
         KerberosUtility.ConvertInt2Flags((int)FastOptionFlags.Hide_Client_Names));
     Context.Subkey = subKey;
     string sName = KerberosConstValue.KERBEROS_SNAME;
     string domain = this.Context.Realm.Value;
     PrincipalName sname =
         new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain));
     KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname);
     kdcReqBody.cname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_PRINCIPAL), KerberosUtility.String2SeqKerbString(cName));
     var pafxfast = CreateAsPaFxFast(subKey, fastOptions, apOptions, innerSeqPaData, sName, kdcReqBody);
     PA_DATA[] elements;
     if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
     {
         elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
         Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
         elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
     }
     else
     {
         elements = new PA_DATA[] { pafxfast.Data };
     }
     Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
     KerberosAsRequest asRequest = this.CreateAsRequest(kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements));
     this.SendPdu(asRequest);
     this.testSite.Log.Add(LogEntryKind.Debug, "Send AS Request with FAST PA-DATA.");
 }
 /// <summary>
 /// Create and send FAST AS request with an unknown armor type
 /// </summary>
 /// <param name="kdcOptions">KDC options</param>
 /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
 /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
 /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
 /// <param name="fastOptions">FAST options</param>
 /// <param name="apOptions">AP options in FAST armor field</param>
 /// <param name="armorType">armorType</param>
 public void SendAsRequestWithFast(
     KdcOptions kdcOptions,
     Asn1SequenceOf<PA_DATA> innerSeqPaData,
     Asn1SequenceOf<PA_DATA> outerSeqPaData,
     EncryptionKey subKey,
     FastOptions fastOptions,
     ApOptions apOptions,
     KrbFastArmorType armorType
     )
 {
     Context.Subkey = subKey;
     string sName = KerberosConstValue.KERBEROS_SNAME;
     string domain = this.Context.Realm.Value;
     PrincipalName sname =
         new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain));
     KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname);
     var pafxfast = CreateAsPaFxFast(subKey, fastOptions, apOptions, innerSeqPaData, sName, kdcReqBody, armorType);
     PA_DATA[] elements;
     if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
     {
         elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
         Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
         elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
     }
     else
     {
         elements = new PA_DATA[] { pafxfast.Data };
     }
     Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
     KerberosAsRequest asRequest = this.CreateAsRequest(kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements));
     this.SendPdu(asRequest);
     this.testSite.Log.Add(LogEntryKind.Debug, "Send AS Request with FAST PA-DATA.");
 }
コード例 #23
0
        private void CBAC_Smb2_AccessFile(string RealmName, User user, Computer kdc, TransportType transportType, FileServer fileserver, string filePath, string fileName, bool expectAccessDeny)
        {
            base.Logging();

            client = new KerberosTestClient(RealmName,
                                            user.Username,
                                            user.Password,
                                            KerberosAccountType.User,
                                            kdc.IPAddress,
                                            kdc.Port,
                                            transportType,
                                            testConfig.SupportedOid);

            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncTimeStamp, PaPacRequest and paPacOptions.");
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               client.Context.SelectedEType,
                                                               client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            PaPacOptions             paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });

            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            //Verify encrypted padata
            PaSupportedEncTypes paSupportedEncTypes = null;

            BaseTestSite.Assert.IsNotNull(asResponse.EncPart, "The encrypted part of AS-REP is decrypted.");
            BaseTestSite.Assert.IsNotNull(asResponse.EncPart.pa_datas, "The encrypted padata is not null.");
            if (this.testConfig.IsKileImplemented)
            {
                foreach (var padata in asResponse.EncPart.pa_datas.Elements)
                {
                    var parsedPadata = PaDataParser.ParseRepPaData(padata);
                    if (parsedPadata is PaSupportedEncTypes)
                    {
                        paSupportedEncTypes = parsedPadata as PaSupportedEncTypes;
                    }
                }
                BaseTestSite.Assert.IsNotNull(paSupportedEncTypes, "The encrypted padata of AS-REP contains PA_SUPPORTED_ENCTYPES.");
                if (this.testConfig.IsClaimSupported)
                {
                    BaseTestSite.Assert.IsTrue(
                        paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported),
                        "Claims is supported.");
                }
            }
            //TGS exchange
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request: {0}.", fileserver.Smb2ServiceName);
            Asn1SequenceOf <PA_DATA> seqOfPaData2 = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data });

            client.SendTgsRequest(fileserver.Smb2ServiceName, options, seqOfPaData2);
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();
            EncryptionKey       key         = testConfig.QueryKey(fileserver.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            tgsResponse.DecryptTicket(key);
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted.");

            //Verify TGS encryped padata
            paSupportedEncTypes = null;
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted.");
            BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart.pa_datas, "The encrypted padata of TGS-REP is not null.");
            if (this.testConfig.IsKileImplemented)
            {
                foreach (var padata in tgsResponse.EncPart.pa_datas.Elements)
                {
                    var parsedPadata = PaDataParser.ParseRepPaData(padata);
                    if (parsedPadata is PaSupportedEncTypes)
                    {
                        paSupportedEncTypes = parsedPadata as PaSupportedEncTypes;
                    }
                }
                BaseTestSite.Assert.IsNotNull(paSupportedEncTypes, "The encrypted padata of TGS-REP contains PA_SUPPORTED_ENCTYPES.");
            }

            if (this.testConfig.IsKileImplemented)
            {
                BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data.");
                AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
                BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac.");
            }

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);

            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                                                    data,
                                                    subkey,
                                                    ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File.");
            AccessFile(filePath, fileName, fileserver, token, tgsResponse.EncPart.key, expectAccessDeny);
        }
コード例 #24
0
        private void CrossRealm_Smb2_AccessFile(string localRealmName, string trustuedRealmName, User localUser, Computer localKDC, Computer trustedKDC, TransportType transportType, FileServer fileserverInTrustedRealm, string filePath, string fileName, bool expectAccessDeny)
        {
            base.Logging();

            client = new KerberosTestClient(localRealmName,
                                            localUser.Username,
                                            localUser.Password,
                                            KerberosAccountType.User,
                                            localKDC.IPAddress,
                                            localKDC.Port,
                                            transportType,
                                            testConfig.SupportedOid);

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               this.client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            //Create and send TGS request
            if (this.testConfig.TrustType == Adapter.TrustType.Forest)
            {
                client.SendTgsRequest(fileserverInTrustedRealm.Smb2ServiceName, options);
            }
            else if (this.testConfig.TrustType == Adapter.TrustType.Realm)
            {
                client.SendTgsRequest(trustedKDC.DefaultServiceName, options);
            }
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request");
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive a referral TGS response.");

            BaseTestSite.Assert.AreEqual(trustedKDC.DefaultServiceName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "The service principal name in referral ticket should match expected.");
            BaseTestSite.Assert.AreEqual(localRealmName.ToLower(),
                                         tgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in referral ticket should match expected.");

            //Change realm
            client.ChangeRealm(trustuedRealmName,
                               trustedKDC.IPAddress,
                               trustedKDC.Port,
                               this.testConfig.TransportType);

            //Create and send referral TGS request
            client.SendTgsRequest(fileserverInTrustedRealm.Smb2ServiceName, options);
            KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(fileserverInTrustedRealm.Smb2ServiceName,
                                         KerberosUtility.PrincipalName2String(refTgsResponse.Response.ticket.sname),
                                         "The service principal name in service ticket should match expected.");
            BaseTestSite.Assert.AreEqual(trustuedRealmName.ToLower(),
                                         refTgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in service ticket should match expected.");

            EncryptionKey key = testConfig.QueryKey(fileserverInTrustedRealm.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            refTgsResponse.DecryptTicket(key);

            BaseTestSite.Assert.AreEqual(localRealmName.ToLower(),
                                         refTgsResponse.TicketEncPart.crealm.Value.ToLower(),
                                         "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(localUser.Username.ToLower(),
                                         KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(),
                                         "User name in service ticket encrypted part should match expected.");

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);

            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                                                    data,
                                                    subkey,
                                                    ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File.");
            AccessFile(filePath, fileName, fileserverInTrustedRealm, token, refTgsResponse.EncPart.key, expectAccessDeny);
        }
コード例 #25
0
 /// <summary>
 /// Create and send TGS request
 /// </summary>
 /// <param name="sName">Service principal name</param>
 /// <param name="kdcOptions">KDC options</param>
 /// <param name="msgType">Message Type</param>
 public void SendTgsRequest(string sName,
     KdcOptions kdcOptions,
     MsgType msgType)
 {
     SendTgsRequest(sName, kdcOptions, null, null, null, null, msgType);
 }
コード例 #26
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);
        }
コード例 #27
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);

            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            writer.WriteBitString(KdcOptions.AsReadOnlySpan());
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

            if (Asn1Extension.HasValue(CName))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
                CName?.Encode(writer);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
            }
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
            writer.WriteCharacterString(UniversalTagNumber.GeneralString, Realm);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 2));

            if (Asn1Extension.HasValue(SName))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
                SName?.Encode(writer);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            }

            if (Asn1Extension.HasValue(From))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
                writer.WriteGeneralizedTime(From.Value);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
            }
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 5));
            writer.WriteGeneralizedTime(Till);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 5));

            if (Asn1Extension.HasValue(RTime))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 6));
                writer.WriteGeneralizedTime(RTime.Value);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 6));
            }
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 7));
            writer.WriteInteger(Nonce);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 7));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 8));
            writer.PushSequence();

            for (int i = 0; i < EType.Length; i++)
            {
                writer.WriteInteger((long)EType[i]);
            }

            writer.PopSequence();

            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 8));

            if (Asn1Extension.HasValue(Addresses))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 9));
                writer.PushSequence();

                for (int i = 0; i < Addresses.Length; i++)
                {
                    Addresses[i]?.Encode(writer);
                }

                writer.PopSequence();

                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 9));
            }


            if (Asn1Extension.HasValue(EncAuthorizationData))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 10));
                EncAuthorizationData?.Encode(writer);
                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 10));
            }

            if (Asn1Extension.HasValue(AdditionalTickets))
            {
                writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 11));
                writer.PushSequence();

                for (int i = 0; i < AdditionalTickets.Length; i++)
                {
                    AdditionalTickets[i]?.Encode(writer);
                }

                writer.PopSequence();

                writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 11));
            }

            writer.PopSequence(tag);
        }
コード例 #28
0
        /// <summary>
        /// Kerberos Client Initialize without server token
        /// </summary>
        private void ClientInitialize()
        {
            this.ApRequestAuthenticator = null;
            // Create and send AS request for pre-authentication
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            KerberosTicket ticket = this.GetTGTCachedToken(this.credential, this.serverName);

            if (ticket == null)
            {
                this.SendAsRequest(options, null);

                // Expect recieve preauthentication required error
                METHOD_DATA methodData;
                this.ExpectPreauthRequiredError(out methodData);

                // Create sequence of PA data
                string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
                PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                                   0,
                                                                   this.Context.SelectedEType,
                                                                   this.Context.CName.Password,
                                                                   this.Context.CName.Salt);
                PaPacRequest             paPacRequest   = new PaPacRequest(true);
                PaPacOptions             paPacOptions   = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc);
                Asn1SequenceOf <PA_DATA> seqOfPaData_AS = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });
                // Create and send AS request for TGT
                KerberosAsRequest asRequest = this.SendAsRequest(options, seqOfPaData_AS);

                // Expect TGT(AS) Response from KDC
                KerberosAsResponse asResponse = this.ExpectAsResponse();

                // Create and send TGS request
                Asn1SequenceOf <PA_DATA> seqOfPaData_TGS = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data });
                this.SendTgsRequest(this.serverName, options, seqOfPaData_TGS);

                // Expect TGS Response from KDC
                KerberosTgsResponse tgsResponse = this.ExpectTgsResponse();
                this.UpdateTGTCachedToken(this.Context.Ticket);
            }
            else
            {
                // Restore SessionKey and Ticket from cache
                this.Context.SessionKey    = ticket.SessionKey;
                this.Context.ApSessionKey  = ticket.SessionKey;
                this.Context.Ticket        = ticket;
                this.Context.SelectedEType = (EncryptionType)Context.Ticket.Ticket.enc_part.etype.Value;
            }

            // cache this.Context.Ticket;
            ApOptions apOption;

            GetFlagsByContextAttribute(out apOption);

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(this.client.Context.ContextKey);

            this.token = this.CreateGssApiToken(apOption,
                                                data,
                                                subkey,
                                                this.Context.ChecksumFlag,
                                                KerberosConstValue.GSSToken.GSSAPI);

            bool isMutualAuth = (contextAttribute & ClientSecurityContextAttribute.MutualAuth)
                                == ClientSecurityContextAttribute.MutualAuth;
            bool isDceStyle = (contextAttribute & ClientSecurityContextAttribute.DceStyle)
                              == ClientSecurityContextAttribute.DceStyle;

            if (isMutualAuth || isDceStyle)
            {
                this.needContinueProcessing = true;
            }
            else
            {
                this.needContinueProcessing = false;
            }
        }
コード例 #29
0
        public void KerbAuth_Replay()
        {
            #region Get Service Ticket
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize Kerberos Functional Client");
            KerberosFunctionalClient kerberosClient = new KerberosFunctionalClient(
                TestConfig.DomainName,
                TestConfig.UserName,
                TestConfig.UserPassword,
                KerberosAccountType.User,
                KDCIP,
                KDCPort,
                TransportType.TCP,
                OidPkt,
                BaseTestSite);

            //Create and send AS request
            const KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;
            kerberosClient.SendAsRequest(options, null);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects Kerberos Error from KDC");
            //Receive preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = kerberosClient.ExpectPreauthRequiredError(out methodData);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends AS request with PA-DATA set");
            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               kerberosClient.Context.SelectedEType,
                                                               kerberosClient.Context.CName.Password,
                                                               kerberosClient.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new[] { paEncTimeStamp.Data, paPacRequest.Data });
            //Create and send AS request
            kerberosClient.SendAsRequest(options, seqOfPaData);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects AS response from KDC");
            KerberosAsResponse asResponse = kerberosClient.ExpectAsResponse();
            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create and send TGS request
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends TGS request to KDC");
            kerberosClient.SendTgsRequest(servicePrincipalName, options);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects TGS response from KDC");
            KerberosTgsResponse tgsResponse = kerberosClient.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(servicePrincipalName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "Service principal name in service ticket should match expected.");
            #endregion

            #region Create AP request
            Ticket        serviceTicket = kerberosClient.Context.Ticket.Ticket;
            Realm         crealm        = serviceTicket.realm;
            EncryptionKey subkey        = KerberosUtility.GenerateKey(kerberosClient.Context.SessionKey);
            PrincipalName cname         = kerberosClient.Context.CName.Name;
            Authenticator authenticator = CreateAuthenticator(cname, crealm, subkey);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create AP Request");
            KerberosApRequest request = new KerberosApRequest(
                kerberosClient.Context.Pvno,
                new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.MutualRequired)),
                kerberosClient.Context.Ticket,
                authenticator,
                KeyUsageNumber.AP_REQ_Authenticator
                );
            #endregion

            #region Create GSS token and send session setup request
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create GSS Token");
            byte[] token = KerberosUtility.AddGssApiTokenHeader(request, OidPkt, GssToken);

            Smb2FunctionalClientForKerbAuth smb2Client = new Smb2FunctionalClientForKerbAuth(TestConfig.Timeout, TestConfig, BaseTestSite);
            smb2Client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            byte[] repToken;
            uint   status = DoSessionSetupWithGssToken(smb2Client, token, out repToken);

            KerberosApResponse apRep = kerberosClient.GetApResponseFromToken(repToken, GssToken);
            // Get subkey from AP response, which used for signing in smb2
            apRep.Decrypt(kerberosClient.Context.Ticket.SessionKey.keyvalue.ByteArrayValue);
            smb2Client.SetSessionSigningAndEncryption(true, false, apRep.ApEncPart.subkey.keyvalue.ByteArrayValue);
            #endregion

            #region Second client
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Replay the request from another client");
            Smb2FunctionalClientForKerbAuth smb2Client2 = new Smb2FunctionalClientForKerbAuth(TestConfig.Timeout, TestConfig, BaseTestSite);
            smb2Client2.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = DoSessionSetupWithGssToken(smb2Client2, token, out repToken);

            BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status,
                                            "Session Setup should fail because it uses a Replay of KRB_AP_REQ");

            if (TestConfig.IsWindowsPlatform)
            {
                krbError = kerberosClient.GetKrbErrorFromToken(repToken);
                BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_REPEAT, krbError.ErrorCode,
                                             "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_REPEAT);
            }
            smb2Client2.Disconnect();
            #endregion

            string path = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            AccessFile(smb2Client, path);

            smb2Client.LogOff();
            smb2Client.Disconnect();
        }
コード例 #30
0
        /// <summary>
        /// Create and send AS request for Password change
        /// </summary>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="seqPaData">A sequence of preauthentication data</param>
        public void SendAsRequestForPwdChange(KdcOptions kdcOptions, Asn1SequenceOf<PA_DATA> seqPaData)
        {
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(KerberosConstValue.KERBEROS_KADMIN_SNAME.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname);
            KerberosAsRequest asRequest = this.CreateAsRequest(kdcReqBody, seqPaData);
            this.SendPdu(asRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send AS Request for password change.");
        }
        private KDC_REQ_BODY CreateKdcRequestBody(
            KdcOptions kdcOptions,
            PrincipalName sName,
            AuthorizationData data = null
            )
        {
            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sName);

            if (data == null)
                return kdcReqBody;

            Asn1BerEncodingBuffer asnBuffer = new Asn1BerEncodingBuffer();
            // Fix me: NullReferenceException if data is null.
            if (data != null) data.BerEncode(asnBuffer, true);

            EncryptedData eData = new EncryptedData();
            eData.etype = new KerbInt32(0);
            byte[] encAsnEncoded = asnBuffer.Data;
            if (Context.SessionKey != null && Context.SessionKey.keytype != null
                && Context.SessionKey.keyvalue != null && Context.SessionKey.keyvalue.Value != null)
            {
                encAsnEncoded = KerberosUtility.Encrypt((EncryptionType)Context.SessionKey.keytype.Value,
                                                    Context.SessionKey.keyvalue.ByteArrayValue,
                                                    asnBuffer.Data,
                                                    (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData);
                eData.etype = new KerbInt32(Context.SessionKey.keytype.Value);
            }
            eData.cipher = new Asn1OctetString(encAsnEncoded);
            kdcReqBody.enc_authorization_data = eData;

            return kdcReqBody;
        }
コード例 #32
0
        public void ChangePasswordSuccess()
        {
            base.Logging();

            if (!this.testConfig.UseProxy)
            {
                BaseTestSite.Assert.Inconclusive("This case is only applicable when Kerberos Proxy Service is in use.");
            }

            //Create kerberos test client and connect
            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                                            this.testConfig.LocalRealm.User[22].Username,
                                            this.testConfig.LocalRealm.User[22].Password,
                                            KerberosAccountType.User,
                                            testConfig.LocalRealm.KDC[0].IPAddress,
                                            testConfig.LocalRealm.KDC[0].Port,
                                            testConfig.TransportType,
                                            testConfig.SupportedOid);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                client.UseProxy          = true;
                client.ProxyClient       = proxyClient;
            }

            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends AS_REQ without Pre-Authentication data");
            client.SendAsRequestForPwdChange(options, null);
            //Recieve preauthentication required error
            METHOD_DATA methodData;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "KDC returns KRB_ERROR: KDC_ERR_PREAUTH_REQUIRED");
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends AS_REQ with PA-ENC-TIMESTAMP and PA-PAC-REQUEST");
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               this.client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);

            PaPacRequest             paPacRequest = new PaPacRequest(true);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send AS request
            client.SendAsRequestForPwdChange(options, seqOfPaData);
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "KDC returns AS_REP");
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create kpassword test client and connect
            KpasswdTestClient kpassClient = new KpasswdTestClient(
                testConfig.LocalRealm.KDC[0].IPAddress,
                KerberosConstValue.KPASSWORD_PORT,
                testConfig.TransportType,
                client.Context.Ticket);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                kpassClient.UseProxy     = true;
                kpassClient.ProxyClient  = proxyClient;
            }

            //Create and send Kpassword request
            string newPwd = this.testConfig.LocalRealm.User[22].Password;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends KpasswordRequest");
            kpassClient.SendKpasswordRequest(newPwd);
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "KDC returns KpasswordResponse");
            KpasswordResponse kpassResponse = kpassClient.ExpectKpasswordResponse();

            //Verify the result code
            BaseTestSite.Assert.AreEqual(KpasswdError.KRB5_KPASSWD_SUCCESS, (KpasswdError)kpassClient.GetResultCode(kpassResponse), "The result code should be KRB5_KPASSWD_SUCCESS.");
        }
コード例 #33
0
        public void NetworkLogonLdapWithoutPac_Ldap()
        {
            base.Logging();

            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                                            this.testConfig.LocalRealm.User[1].Username,
                                            this.testConfig.LocalRealm.User[1].Password,
                                            KerberosAccountType.User,
                                            testConfig.LocalRealm.KDC[0].IPAddress,
                                            testConfig.LocalRealm.KDC[0].Port,
                                            testConfig.TransportType,
                                            testConfig.SupportedOid);

            // Kerberos Proxy Service is used
            if (this.testConfig.UseProxy)
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client .");
                KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig);
                proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName;
                client.UseProxy          = true;
                client.ProxyClient       = proxyClient;
            }

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);

            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               this.client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(false);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();

            BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT.");

            //Create and send TGS request
            client.SendTgsRequest(this.testConfig.LocalRealm.LdapServer[0].LdapServiceName, options);
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            AuthorizationData data   = null;
            EncryptionKey     subkey = KerberosUtility.GenerateKey(client.Context.SessionKey);

            byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired,
                                                    data,
                                                    subkey,
                                                    ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG,
                                                    this.testConfig.LocalRealm.LdapServer[0].GssToken);

            //AP exchange part
            byte[]             repToken   = this.SendAndRecieveLdapAp(this.testConfig.LocalRealm.LdapServer[0], token, this.testConfig.TrustedRealm.LdapServer[0].GssToken);
            KerberosApResponse apResponse = client.GetApResponseFromToken(repToken, this.testConfig.LocalRealm.LdapServer[0].GssToken);
        }