public 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; }
public void KrbErrorBadIntegrity() { 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, 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(); // Modify ciphertext of TGT byte originalFirstByte = (byte)client.Context.Ticket.Ticket.enc_part.cipher.ByteArrayValue.GetValue(0); client.Context.Ticket.Ticket.enc_part.cipher.ByteArrayValue.SetValue((byte)(originalFirstByte + 1), 0); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options); krbError = client.ExpectKrbError(); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve Kerberos error."); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_BAD_INTEGRITY, krbError.ErrorCode, "If decrypting the authenticator using the session key shows that it has been modified, " + "the KRB_AP_ERR_BAD_INTEGRITY error is returned"); }
/// <summary> /// Parse raw PA_DATA type to IPaData object. /// </summary> /// <param name="data">Raw PA_DATA</param> /// <returns>Reference to IPaData object</returns> public static IPaData ParseReqPaData(PA_DATA data) { switch (data.padata_type.Value) { case (long)PaDataType.PA_FX_FAST: return(PaFxFastReq.Parse(data)); case (long)PaDataType.PA_PAC_REQUEST: return(PaPacRequest.Parse(data)); case (long)PaDataType.PA_TGS_REQ: return(PaTgsReq.Parse(data)); case (long)PaDataType.PA_ETYPE_INFO2: return(PaETypeInfo2.Parse(data)); } return(PaRawData.Parse(data)); }
public void Protected_Users_Network_Logon_Computer_A2A2_Succeed() { base.Logging(); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal 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); 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.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[16].Username, this.testConfig.LocalRealm.User[16].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, krbError2.ErrorCode, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data, paPacRequest.Data, paPacOptions.Data}); client.SendAsRequestWithFast(options, seqOfPaData3, null, subkey, fastOptions, apOptions); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", userKrbAsRep.EncPart.GetType().Name)); // verify the PA-DATA of AS_REP: asResponse.EncPart.pa_datas as PA_SUPPORTED_ENCTYPES bool isExistPaSupportedEncTypes = false; bool isExistPadataValue = false; var padataCount = userKrbAsRep.EncPart.pa_datas.Elements.Length; for (int i = 0; i < padataCount; i++) { var padata = PaDataParser.ParseRepPaData(userKrbAsRep.EncPart.pa_datas.Elements[i]); if ((PaDataType)padata.Data.padata_type.Value == PaDataType.PA_SUPPORTED_ENCTYPES) { isExistPaSupportedEncTypes = true; for (int j = 0; j < padata.Data.padata_value.Value.Length; j++) { if (padata.Data.padata_value.Value[j] == 0x1F) { isExistPadataValue = true; } } } } BaseTestSite.Assert.IsTrue(isExistPaSupportedEncTypes, "If domainControllerFunctionality returns a value >= 3:" + "the KDC SHOULD, in the encrypted pre-auth data part ([Referrals-11], Appendix A) of the AS-REP message, " + "include PA-DATA with the padata-type set to PA-SUPPORTED-ENCTYPES (165)."); BaseTestSite.Assert.IsTrue(isExistPadataValue, "If domainControllerFunctionality returns a value >= 3: " + "the KDC SHOULD, in the encrypted pre-auth data part ([Referrals-11], Appendix A) of the AS-REP message, " + "include PA-DATA with the padata-type set to PA-SUPPORTED-ENCTYPES (165), and the padata-value set to 0x1F (section 2.2.6)."); if (testConfig.IsClaimSupported) { PaSupportedEncTypes paSupportedEncTypes = null; // userKrbAsRep.EncPart.pa_datas.GetType foreach (var padata in userKrbAsRep.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."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), "Claims is supported."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.FAST_Supported), "FAST is supported."); } // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request."); client.SendTgsRequestWithFast(testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options, null, null, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve TGS response."); KerberosTgsResponse userKrbTgsRep = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.Response, "The Response pare of TGS-REP is not null."); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.Response.padata, "The Padata of TGS-REP is not null."); EncryptionKey strengthenKey = null; foreach (PA_DATA paData in userKrbTgsRep.Response.padata.Elements) { var parsedPaData = PaDataParser.ParseRepPaData(paData); if (parsedPaData is PaFxFastRep) { var armoredRep = ((PaFxFastRep)parsedPaData).GetArmoredRep(); var kerbRep = ((PaFxFastRep)parsedPaData).GetKerberosFastRep(client.Context.FastArmorkey); strengthenKey = kerbRep.FastResponse.strengthen_key; } } BaseTestSite.Assert.IsNotNull(strengthenKey, "Strengthen key field must be set in TGS-REP."); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.EncPart, "The encrypted part of TGS-REP is decrypted."); }
public void StrengthenKey() { base.Logging(); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve preauthentication required error."); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncTimeStamp."); string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp( timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve AS response."); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Assert.IsNotNull(asResponse.EncPart, "The encrypted part of AS response is decrypted."); BaseTestSite.Assert.IsNotNull(asResponse.EncPart.key, "AS response should contain a session key."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Switch to user principal."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("Construct Kerberos client using user account: {0}.", this.testConfig.LocalRealm.User[1].Username)); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, this.testConfig.LocalRealm.User[1].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored AS request with no pre-authentication padata."); var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { new PA_DATA(new KerbInt32((long)PaDataType.PA_FX_FAST), null) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncryptedChallenge."); var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); PaPacRequest paPacRequest = new PaPacRequest(true); Asn1SequenceOf<PA_DATA> outerSeqPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data }); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, outerSeqPaData, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve AS response."); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Assert.IsNotNull(userKrbAsRep.EncPart, "The encrypted part of AS response is decrypted."); BaseTestSite.Assert.IsNotNull(userKrbAsRep.EncPart.key, "AS response should contain a session key."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", userKrbAsRep.EncPart.GetType().Name)); // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request."); client.SendTgsRequestWithFast(testConfig.LocalRealm.ClientComputer.DefaultServiceName, options, null, null, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve TGS response."); KerberosTgsResponse userKrbTgsRep = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.Response, "The Response pare of TGS-REP is not null."); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.Response.padata, "The Padata of TGS-REP is not null."); EncryptionKey strengthenKey = null; foreach (PA_DATA paData in userKrbTgsRep.Response.padata.Elements) { var parsedPaData = PaDataParser.ParseRepPaData(paData); if (parsedPaData is PaFxFastRep) { var armoredRep = ((PaFxFastRep)parsedPaData).GetArmoredRep(); var kerbRep = ((PaFxFastRep)parsedPaData).GetKerberosFastRep(client.Context.FastArmorkey); strengthenKey = kerbRep.FastResponse.strengthen_key; } } BaseTestSite.Assert.IsNotNull(strengthenKey, "Strengthen key field must be set in TGS-REP."); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.EncPart, "The encrypted part of TGS-REP is decrypted."); }
public void ChangePasswordError() { base.Logging(); if (!this.testConfig.UseProxy) { BaseTestSite.Assert.Inconclusive("This case is only applicable when Kerberos Proxy Service is in use."); } #region KRB5_KPASSWD_SOFTERROR //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 for password change"); 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 for password change"); 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; } //Specify a new password which doesn't meet the complexity requirements string newPwd = "123"; //Create and send Kpassword request 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_SOFTERROR, (KpasswdError)kpassClient.GetResultCode(kpassResponse), "The result code should be KRB5_KPASSWD_SOFTERROR when the new password doesn't meet the complexity requirements."); #endregion KRB5_KPASSWD_SOFTERROR #region KRB5_KPASSWD_MALFORMED newPwd = this.testConfig.LocalRealm.User[22].Password; //Create and send Kpassword request BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends KpasswordRequest"); kpassClient.SendMalformedKpasswordRequest(newPwd); BaseTestSite.Log.Add(LogEntryKind.TestStep, "KDC returns KpasswordResponse"); kpassResponse = kpassClient.ExpectKpasswordResponse(); //Verify the result code BaseTestSite.Assert.AreEqual(KpasswdError.KRB5_KPASSWD_MALFORMED, (KpasswdError)kpassClient.GetResultCode(kpassResponse), "The result code should be KRB5_KPASSWD_MALFORMED when the request is malformed."); #endregion KRB5_KPASSWD_MALFORMED #region KRB5_KPASSWD_AUTHERROR //Create and send Kpassword request BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends KpasswordRequest"); kpassClient.SendAuthErrorKpasswordRequest(newPwd); BaseTestSite.Log.Add(LogEntryKind.TestStep, "KDC returns KpasswordResponse"); kpassResponse = kpassClient.ExpectKpasswordResponse(); //Verify the result code BaseTestSite.Assert.AreEqual(KpasswdError.KRB5_KPASSWD_AUTHERROR, (KpasswdError)kpassClient.GetResultCode(kpassResponse), "The result code should be KRB5_KPASSWD_AUTHERROR when the request fails due to an error in authentication processing."); #endregion KRB5_KPASSWD_AUTHERROR #region KRB5_KPASSWD_ACCESSDENIED //Create kerberos test client and connect //Use the user who can't change the password 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; } options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends AS_REQ without Pre-Authentication data for password change"); client.SendAsRequestForPwdChange(options, null); //Recieve preauthentication required error BaseTestSite.Log.Add(LogEntryKind.TestStep, "KDC returns KRB_ERROR: KDC_ERR_PREAUTH_REQUIRED"); 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 for password change"); timeStamp = KerberosUtility.CurrentKerberosTime.Value; paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, this.client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); paPacRequest = new PaPacRequest(true); 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"); asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create kpassword test client and connect 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; } newPwd = this.testConfig.LocalRealm.User[1].Password; //Create and send Kpassword request BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends KpasswordRequest"); kpassClient.SendKpasswordRequest(newPwd); BaseTestSite.Log.Add(LogEntryKind.TestStep, "KDC returns KpasswordResponse"); kpassResponse = kpassClient.ExpectKpasswordResponse(); //Verify the result code BaseTestSite.Assert.AreEqual(KpasswdError.KRB5_KPASSWD_ACCESSDENIED, (KpasswdError)kpassClient.GetResultCode(kpassResponse), "The result code should be KRB5_KPASSWD_ACCESSDENIED when the user has no access to change the password."); #endregion KRB5_KPASSWD_ACCESSDENIED }
public void APDS_KERBEROS_PAC_VALIDATION() { base.Logging(); BaseTestSite.Log.Add(LogEntryKind.Comment, "Construct Kerberos client for testing."); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); 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}); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PA data."); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request."); client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); if (this.testConfig.IsKileImplemented) { //Get Server and KDC Signatures PacServerSignature pacServerSignature = null; PacKdcSignature pacKdcSignature = null; 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 (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is PacServerSignature) { pacServerSignature = buf as PacServerSignature; } if (buf is PacKdcSignature) { pacKdcSignature = buf as PacKdcSignature; } } BaseTestSite.Log.Add(LogEntryKind.Comment, "Establish Secure Channel."); NrpcClient nrpcClient = NrpcClient.CreateNrpcClient(this.testConfig.LocalRealm.RealmName); ushort[] endPointList = NrpcUtility.QueryNrpcTcpEndpoint(testConfig.LocalRealm.KDC[0].FQDN); ushort endPoint = endPointList[0]; MachineAccountCredential machineCredential = new MachineAccountCredential( this.testConfig.LocalRealm.RealmName, testConfig.LocalRealm.ClientComputer.FQDN.Split('.')[0], testConfig.LocalRealm.ClientComputer.Password); nrpcClient.Context.NegotiateFlags = NrpcNegotiateFlags.SupportsAESAndSHA2 | NrpcNegotiateFlags.SupportsConcurrentRpcCalls | NrpcNegotiateFlags.SupportsCrossForestTrusts | NrpcNegotiateFlags.SupportsGenericPassThroughAuthentication | NrpcNegotiateFlags.SupportsNetrLogonGetDomainInfo | NrpcNegotiateFlags.SupportsNetrLogonSendToSam | NrpcNegotiateFlags.SupportsNetrServerPasswordSet2 | NrpcNegotiateFlags.SupportsRC4 | NrpcNegotiateFlags.SupportsRefusePasswordChange | NrpcNegotiateFlags.SupportsRodcPassThroughToDifferentDomains | NrpcNegotiateFlags.SupportsSecureRpc | NrpcNegotiateFlags.SupportsStrongKeys | NrpcNegotiateFlags.SupportsTransitiveTrusts; NrpcClientSecurityContext securityContext = new NrpcClientSecurityContext( this.testConfig.LocalRealm.RealmName, testConfig.LocalRealm.KDC[0].FQDN.Split('.')[0], machineCredential, true, nrpcClient.Context.NegotiateFlags); nrpcClient.BindOverTcp(testConfig.LocalRealm.KDC[0].FQDN, endPoint, securityContext, TimeSpan.FromMilliseconds(600000)); _NETLOGON_LOGON_INFO_CLASS logonLevel = _NETLOGON_LOGON_INFO_CLASS.NetlogonGenericInformation; _NETLOGON_VALIDATION_INFO_CLASS validationLevel = _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationGenericInfo2; _NETLOGON_VALIDATION? validationInfomation; byte? authoritative; NrpcNetrLogonSamLogonExtraFlags? extraFlags = NrpcNetrLogonSamLogonExtraFlags.None; BaseTestSite.Log.Add(LogEntryKind.Comment, "Create valid KERB_VERIFY_PAC_REQUEST."); KERB_VERIFY_PAC_REQUEST kerberosReq = ApdsUtility.CreateKerbVerifyPacRequest(pacServerSignature.NativePacSignatureData, pacKdcSignature.NativePacSignatureData); //Create Kerberos Validation Logon Info _NETLOGON_LEVEL netlogonLevel = ApdsUtility.CreatePacLogonInfo( NrpcParameterControlFlags.AllowLogonWithComputerAccount, this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.Admin.Username, testConfig.LocalRealm.KDC[0].FQDN.Split('.')[0], kerberosReq); _NETLOGON_LEVEL encryptedLogonLevel = nrpcClient.EncryptNetlogonLevel( (_NETLOGON_LOGON_INFO_CLASS)logonLevel, netlogonLevel); BaseTestSite.Log.Add(LogEntryKind.Comment, "Call NetrLogonSamLogonEx for Kerberos pac validation."); NtStatus result = nrpcClient.NetrLogonSamLogonEx( nrpcClient.Handle, testConfig.LocalRealm.KDC[0].FQDN.Split('.')[0], testConfig.LocalRealm.ClientComputer.FQDN.Split('.')[0], logonLevel, encryptedLogonLevel, validationLevel, out validationInfomation, out authoritative, ref extraFlags); BaseTestSite.Assert.AreEqual(NtStatus.STATUS_SUCCESS, result, "[MS-APDS]3.2.5.2 If the checksum is verified, the DC MUST return STATUS_SUCCESS."); BaseTestSite.Assert.IsNull(validationInfomation.Value.ValidationGeneric2[0].ValidationData, "[MS-APDS]3.2.5.2 There is no return message."); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create invalid KERB_VERIFY_PAC_REQUEST."); kerberosReq = ApdsUtility.CreateKerbVerifyPacRequest(pacKdcSignature.NativePacSignatureData, pacKdcSignature.NativePacSignatureData); //Create Kerberos Validation Logon Info netlogonLevel = ApdsUtility.CreatePacLogonInfo( NrpcParameterControlFlags.AllowLogonWithComputerAccount, this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.Admin.Username, testConfig.LocalRealm.KDC[0].FQDN.Split('.')[0], kerberosReq); encryptedLogonLevel = nrpcClient.EncryptNetlogonLevel( (_NETLOGON_LOGON_INFO_CLASS)logonLevel, netlogonLevel); BaseTestSite.Log.Add(LogEntryKind.Comment, "Call NetrLogonSamLogonEx for Kerberos pac validation."); result = nrpcClient.NetrLogonSamLogonEx( nrpcClient.Handle, testConfig.LocalRealm.KDC[0].FQDN.Split('.')[0], testConfig.LocalRealm.ClientComputer.FQDN.Split('.')[0], logonLevel, encryptedLogonLevel, validationLevel, out validationInfomation, out authoritative, ref extraFlags); BaseTestSite.Assert.AreEqual(NtStatus.STATUS_LOGON_FAILURE, result, "[MS-APDS]3.2.5.2 If the checksum verification fails, the DC MUST return an error code, STATUS_LOGON_FAILURE (section 2.2) as the return value to the Netlogon Generic Pass-through method."); } }
public void PacMarkedAdIfRelevant() { base.Logging(); //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); // 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; 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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); //Verify PAC if (this.testConfig.IsKileImplemented) { EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = null; foreach (var element in tgsResponse.TicketEncPart.authorization_data.Elements) { var authData = AuthDataElementParser.ParseAuthDataElement(element); if (authData is AdIfRelevent) { AdIfRelevent adIfRelevent = authData as AdIfRelevent; foreach (var subElement in adIfRelevent.Elements) { if (subElement is AdWin2KPac) { adWin2kPac = subElement as AdWin2KPac; goto pacFound; } } } } pacFound: BaseTestSite.Assert.IsNotNull(adWin2kPac, "AdWin2KPAC is marked as Ad-If-Relevent."); } }
public void UPN_DNS_INFO() { base.Logging(); //Create kerberos test client and connect client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[5].Username, this.testConfig.LocalRealm.User[5].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; 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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[5].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC 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."); UpnDnsInfo upnDnsInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is UpnDnsInfo) { upnDnsInfo = buf as UpnDnsInfo; break; } } BaseTestSite.Assert.IsNotNull(upnDnsInfo, "UPN_DNS_INFO is generated."); BaseTestSite.Assert.AreEqual( upnDnsInfo.Upn.Length * 2, upnDnsInfo.NativeUpnDnsInfo.UpnLength, "The UpnLength field SHOULD be the length of the UPN field, in bytes."); BaseTestSite.Assert.AreEqual( upnDnsInfo.DnsDomain.Length * 2, upnDnsInfo.NativeUpnDnsInfo.DnsDomainNameLength, "The DnsDomainNameLength field SHOULD be the length of the DnsDomainName field, in bytes."); BaseTestSite.Assert.AreEqual( UPN_DNS_INFO_Flags_Values.NoUpnAttribute, upnDnsInfo.NativeUpnDnsInfo.Flags & UPN_DNS_INFO_Flags_Values.NoUpnAttribute, "The Flags field SHOULD set the U bit if the user account object does not have the userPrincipalName attribute ([MS-ADA3] (file://%5bMS-ADA3%5d.pdf) section 2.349) set."); } }
public void DomainLocalGroupMembershipWithDisableResourceSIDCompressionUnset() { base.Logging(); //Create kerberos test client and connect client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, this.testConfig.LocalRealm.User[13].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); BaseTestSite.Log.Add(LogEntryKind.Comment, "Construct Kerberos client for testing."); //Create and send AS request // 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; } Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, cred); } KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.LocalResources[0].DefaultServiceName, options, seqOfPaData); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.LocalResources[0].DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); //EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.LocalResources[0].DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); //tgsResponse.DecryptTicket(key); tgsResponse.DecryptTicket(this.testConfig.LocalRealm.LocalResources[0].Password, this.testConfig.LocalRealm.LocalResources[0].ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[13].Username, KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname), "The client principal name in ticket encrypted part should match expected."); //Verify PAC if (this.testConfig.IsKileImplemented && this.testConfig.LocalRealm.KDC[0].IsWindows) { 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."); KerbValidationInfo kerbValidationInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { kerbValidationInfo = buf as KerbValidationInfo; break; } } BaseTestSite.Assert.IsNotNull(kerbValidationInfo, "KerbValidationInfo is generated."); BaseTestSite.Assert.AreEqual(1, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid.Length, "The number of ResourceGroupDomainSid should be 1 as is configured."); foreach (_RPC_SID element in kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid) { byte[] expectedIdentifierAuthority = new byte[6] { 0, 0, 0, 0, 0, 5 }; BaseTestSite.Assert.AreEqual(expectedIdentifierAuthority.Length, element.IdentifierAuthority.Value.Length, "IdentifierAuthority 000005 stands for S-1-5"); BaseTestSite.Assert.IsTrue(element.IdentifierAuthority.Value.SequenceEqual(expectedIdentifierAuthority), "IdentifierAuthority elements should match expected."); uint[] expectedSubAuthority = commonUserFields.domainSid; BaseTestSite.Assert.AreEqual(expectedSubAuthority.Length, element.SubAuthorityCount, "SubAuthorityCount should match expected."); BaseTestSite.Assert.IsTrue(element.SubAuthority.SequenceEqual(expectedSubAuthority), "SubAuthorityCount elements should match expected."); } uint resourceGroupCount = this.testConfig.LocalRealm.ResourceGroups.GroupCount; BaseTestSite.Assert.AreEqual((uint)resourceGroupCount, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupCount, "The ResourceGroupCount field contains the number of groups in the ResourceGroupIds field."); Adapter.Group[] resourceGroups = this.testConfig.LocalRealm.ResourceGroups.Groups; NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); uint[] expectedResourceGroupIds = Adapter.PacHelper.GetResourceGroupIds(this.testConfig.LocalRealm.RealmName, cred, resourceGroupCount, resourceGroups); for (int i = 0; i < resourceGroupCount; i++) { BaseTestSite.Assert.AreEqual(Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled | Attributes_Values.Resource, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds[i].Attributes, "The Attributes have the A, B, C and E bits set to 1, and all other bits set to zero."); } BaseTestSite.Assert.IsTrue(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds.Select(id => id.RelativeId).OrderBy(id => id).SequenceEqual(expectedResourceGroupIds.OrderBy(id => id)), "RelativeId contains the RID of the value pmsgOut.ppDsNames.Sid."); } }
/// <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); }
public void PAC_DEVICE_INFO() { base.Logging(); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); // Switch to user principal client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; PaFxFastReq paFxFastReq = new PaFxFastReq(null); Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { (paFxFastReq.Data) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, krbError2.ErrorCode, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); PaPacRequest paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data, paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, null, subkey, fastOptions, apOptions); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); if (testConfig.IsClaimSupported) { PaSupportedEncTypes paSupportedEncTypes = null; BaseTestSite.Assert.IsNotNull(userKrbAsRep.EncPart.pa_datas, "The encrypted padata of AS-REP is not null."); foreach (var padata in userKrbAsRep.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."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), "Claims is supported."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.FAST_Supported), "FAST is supported."); } // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); client.Context.ArmorSessionKey = client.Context.Ticket.SessionKey; client.Context.ArmorTicket = client.Context.Ticket; client.SendTgsRequestWithExplicitFast(testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options, null, null, subkey, fastOptions, apOptions); KerberosTgsResponse userKrbTgsRep = client. ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); if (testConfig.IsClaimSupported) { 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."); foreach (var padata in userKrbTgsRep.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."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.CompoundIdentity_Supported), "Compound identity is supported."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.FileServer[0].Smb2ServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); userKrbTgsRep.DecryptTicket(key); //userKrbTgsRep.DecryptTicket(testConfig.LocalRealm.FileServer[0].Password, testConfig.LocalRealm.FileServer[0].ServiceSalt); //Verify PAC BaseTestSite.Assert.IsNotNull(userKrbTgsRep.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData<AdWin2KPac>(userKrbTgsRep.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); PacDeviceInfo pacDeviceInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is PacDeviceInfo) { pacDeviceInfo = buf as PacDeviceInfo; break; } } BaseTestSite.Assert.IsNotNull(pacDeviceInfo, "PAC_DEVICE_INFO is generated."); } }
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; }
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(); }
public void NetworkLogonCompoundIdentitySmb2() { base.Logging(); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); // Switch to user principal client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; string timeStamp2 = KerberosUtility.CurrentKerberosTime.Value; PaFxFastReq paFxFastReq = new PaFxFastReq(null); //PaEncTimeStamp paEncTimeStamp2 = new PaEncTimeStamp(timeStamp2, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { (paFxFastReq.Data) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data }); PaPacRequest paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf<PA_DATA> outerSeqPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, outerSeqPaData, subkey, fastOptions, apOptions); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); PaSupportedEncTypes paSupportedEncTypes = null; if (this.testConfig.IsKileImplemented) { foreach (var padata in userKrbAsRep.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 (testConfig.IsClaimSupported) { BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), "Claims is supported."); } BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.FAST_Supported), "FAST is supported."); } // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); client.Context.ArmorSessionKey = client.Context.Ticket.SessionKey; client.Context.ArmorTicket = client.Context.Ticket; client.SendTgsRequestWithExplicitFast(testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options, null, null, subkey, fastOptions, apOptions); KerberosTgsResponse userKrbTgsRep = client. ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); 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 userKrbTgsRep.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.CompoundIdentity_Supported), "Compound identity is supported."); } } AuthorizationData data = null; subkey = KerberosUtility.GenerateKey(client.Context.SessionKey); byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired, data, subkey, ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG); KerberosApResponse apRep = client.GetApResponseFromToken(SendAndRecieveSmb2Ap(this.testConfig.LocalRealm.FileServer[0], token)); ; }
public void NetworkLogonClaimsSmb2() { 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); // 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; 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}.", 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."); //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."); } // ***The SupportedEncryptionTypes.Claims_Supported bit is not set. May be a bug or a TDI.*** // //BaseTestSite.Assert.IsTrue( // paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), // "Claims is supported."); 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); KerberosApResponse apRep = client.GetApResponseFromToken(SendAndRecieveSmb2Ap(this.testConfig.LocalRealm.FileServer[0], token)); ; }
public void CrossRealmGetReferralTGT() { 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(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(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options); } else if (this.testConfig.TrustType == Adapter.TrustType.Realm) { client.SendTgsRequest(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, options); } KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); EncryptionKey key = testConfig.QueryKey( this.testConfig.TrustedRealm.KDC[0].DefaultServiceName + "@" + this.testConfig.LocalRealm.RealmName, client.Context.Realm.ToString(), client.Context.SelectedEType); tgsResponse.DecryptTicket(key); 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."); //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 referral 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."); //verify referral info PaSvrReferralInfo paSvrReferralInfo = null; foreach (PA_DATA item in tgsResponse.EncPart.pa_datas.Elements) { if (item.padata_type.Value == (long)PaDataType.PA_SVR_REFERRAL_INFO) { paSvrReferralInfo = PaSvrReferralInfo.Parse(item); break; } } BaseTestSite.Assert.IsNotNull(paSvrReferralInfo, "Tgs response should include PaSvrReferralInfo in encrypted part."); BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.RealmName.ToLower(), paSvrReferralInfo.PaSvrReferralData.referred_realm.Value.ToLower(), "Realm name in PaSvrReferralInfo should match expect trusted realm name."); //decrypt ticket in the TGS response key = testConfig.QueryKey(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType); refTgsResponse.DecryptTicket(key); //verify the unencrypted part 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[1].Username.ToLower(), KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(), "User name in service ticket encrypted part should match expected."); //Verify PAC 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 (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { KerbValidationInfo kerbValidationInfo =null ; kerbValidationInfo=buf as KerbValidationInfo; uint userId = kerbValidationInfo.NativeKerbValidationInfo.UserId; Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, cred); } BaseTestSite.Assert.AreEqual(commonUserFields.userId, userId, "The UserID field SHOULD match local realm client user sid."); } if (buf is PacClientInfo) { PacClientInfo pacClientInfo = null; pacClientInfo = buf as PacClientInfo; BaseTestSite.Assert.IsNotNull(pacClientInfo, "PAC_CLIENT_INFO is generated."); var authTimeInPac = DtypUtility.ToDateTime(pacClientInfo.NativePacClientInfo.ClientId).ToString("yyyyMMddHHmmss") + "Z"; var c = asResponse.EncPart.authtime; BaseTestSite.Assert.AreEqual( asResponse.EncPart.authtime.ToString(), authTimeInPac, "ClientId field is a FILETIME structure in little-endian format that contains the Kerberos initial TGT auth time."); string clientName = new string(pacClientInfo.NativePacClientInfo.Name); BaseTestSite.Assert.AreEqual( pacClientInfo.NativePacClientInfo.Name.Length * sizeof(char), pacClientInfo.NativePacClientInfo.NameLength, "The User NameLength field should match the client user account name length."); BaseTestSite.Assert.AreEqual( this.testConfig.LocalRealm.User[1].Username.ToLower(), clientName.ToLower(), "The User Name field should match the client user account name."); } if (buf is UpnDnsInfo) { UpnDnsInfo upnDnsInfo = null; upnDnsInfo = buf as UpnDnsInfo; BaseTestSite.Assert.IsNotNull(buf, "UPN_DNS_INFO is generated."); BaseTestSite.Assert.AreEqual(upnDnsInfo.Upn.Length * 2, upnDnsInfo.NativeUpnDnsInfo.UpnLength, "The UpnLength field SHOULD be the length of the UPN field, in bytes."); //upnDnsInfo.NativeUpnDnsInfo.UpnOffset; BaseTestSite.Assert.AreEqual(upnDnsInfo.DnsDomain.Length * 2, upnDnsInfo.NativeUpnDnsInfo.DnsDomainNameLength, "The DnsDomainNameLength field SHOULD be the length of the DnsDomainName field, in bytes."); //upnDnsInfo.NativeUpnDnsInfo.DnsDomainNameOffset; BaseTestSite.Assert.AreEqual(upnDnsInfo.Upn.ToLower(), this.testConfig.LocalRealm.User[1].Username.ToLower() + "@" + this.testConfig.LocalRealm.RealmName.ToLower(), "The UPN field should be the user principal name in local realm "); BaseTestSite.Assert.AreEqual(upnDnsInfo.DnsDomain.ToLower(), this.testConfig.LocalRealm.RealmName.ToLower(), "The dnsDomain field should be the local realm name"); } if (buf is PacServerSignature) { PacServerSignature serverSignature = null; serverSignature = buf as PacServerSignature; BaseTestSite.Assert.IsNotNull(serverSignature, "Server Signature is generated."); } if(buf is PacKdcSignature) { PacKdcSignature kdcSignature = null; kdcSignature = buf as PacKdcSignature; BaseTestSite.Assert.IsNotNull(kdcSignature, "KDC Signature is generated."); } } } }
public void ServerSignature() { base.Logging(); //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); // 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; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC 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."); PacServerSignature serverSignature = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is PacServerSignature) { serverSignature = buf as PacServerSignature; break; } } BaseTestSite.Assert.IsNotNull(serverSignature, "Server Signature is generated."); var serverKey = KeyGenerator.MakeKey( (EncryptionType)tgsResponse.Response.ticket.enc_part.etype.Value, this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); //cannot make a kdc key var kdcKey = KeyGenerator.MakeKey( EncryptionType.AES256_CTS_HMAC_SHA1_96, this.testConfig.LocalRealm.KDC[0].Password, this.testConfig.LocalRealm.RealmName.ToUpper() + "krbtgt" ); bool isServerSignValidate = false; bool isKdcSignValidate = false; adWin2kPac.Pac.ValidateSign(serverKey, kdcKey, out isServerSignValidate, out isKdcSignValidate); BaseTestSite.Assert.IsTrue(isServerSignValidate, "Server signature should be valid."); if ((EncryptionType)tgsResponse.Response.ticket.enc_part.etype.Value == EncryptionType.RC4_HMAC || (EncryptionType)tgsResponse.Response.ticket.enc_part.etype.Value == EncryptionType.DES_CBC_MD5) { BaseTestSite.Assert.AreEqual( PAC_SIGNATURE_DATA_SignatureType_Values.KERB_CHECKSUM_HMAC_MD5, serverSignature.NativePacSignatureData.SignatureType, "The server signature type is KERB_CHECKSUM_HMAC_MD5."); } else if ((EncryptionType)tgsResponse.Response.ticket.enc_part.etype.Value == EncryptionType.AES256_CTS_HMAC_SHA1_96) { BaseTestSite.Assert.AreEqual( PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES256, serverSignature.NativePacSignatureData.SignatureType, "The server signature type is HMAC_SHA1_96_AES256."); } else if ((EncryptionType)tgsResponse.Response.ticket.enc_part.etype.Value == EncryptionType.AES128_CTS_HMAC_SHA1_96) { BaseTestSite.Assert.AreEqual(PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES128, serverSignature.NativePacSignatureData.SignatureType, "The server signature type is HMAC_SHA1_96_AES128."); } else { throw new Exception("The cryptographic system is none. The checksum operation will fail."); } } }
public void Protected_Users_DES_PreAuthentication_Fail() { base.Logging(); //Section 3.3.5.6: PROTECTED_USERS is not supported by Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs. if (int.Parse(this.testConfig.LocalRealm.DomainControllerFunctionality) < 6) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Section 3.3.5.6: PROTECTED_USERS is not supported in Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs."); BaseTestSite.Log.Add(LogEntryKind.Comment, "Will exit the case immediately."); return; } //Create kerberos test client and connect client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[15].Username, this.testConfig.LocalRealm.User[15].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; } //Send AS request KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); KerberosKrbError krbError; //Recieve preauthentication required error METHOD_DATA methodData; krbError = client.ExpectPreauthRequiredError(out methodData); //Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; //pre-authentication use DES PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, EncryptionType.DES_CBC_MD5, 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 with DES as pre-authentication client.SendAsRequest(options, seqOfPaData); //PROTECTED_USERS is not supported in Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs. //Receive KDC_ERR_ETYPE_NOTSUPP error from KDC krbError = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KDC_ERR_ETYPE_NOTSUPP, krbError.ErrorCode, "Section 3.3.5.6 AS Exchange:" + "If domainControllerFunctionality returns a value >= 6 ([MS-ADTS] section 3.1.1.3.2.25), the KDC MUST check whether the account is a member of PROTECTED_USERS ([MS-DTYP] section 2.4.2.4). " + "If it is a member of PROTECTED_USERS, then:<50>" + "If pre-authentication used DES or RC4, the KDC MUST return KDC_ERR_ETYPE_NOTSUPP."); }
public void DomainLocalGroupMembershipWithDisableResourceSIDCompressionSet() { base.Logging(); //Create kerberos test client and connect client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, this.testConfig.LocalRealm.User[13].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); BaseTestSite.Log.Add(LogEntryKind.Comment, "Construct Kerberos client for testing."); //Create and send AS request // 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; } Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, cred); } KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.LocalResources[1].DefaultServiceName, options, seqOfPaData); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.LocalResources[1].DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); tgsResponse.DecryptTicket(this.testConfig.LocalRealm.LocalResources[1].Password, this.testConfig.LocalRealm.LocalResources[1].ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[13].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC if (this.testConfig.IsKileImplemented && this.testConfig.LocalRealm.KDC[0].IsWindows) { 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."); KerbValidationInfo kerbValidationInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { kerbValidationInfo = buf as KerbValidationInfo; break; } } BaseTestSite.Assert.IsNotNull(kerbValidationInfo, "KerbValidationInfo is generated."); //sidcount =2 because, one for AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID and one for CLAIMS_VALID SID uint resourceGroupCount = this.testConfig.LocalRealm.ResourceGroups.GroupCount; uint expectedSidCount = 2 + resourceGroupCount; BaseTestSite.Assert.AreEqual(expectedSidCount, kerbValidationInfo.NativeKerbValidationInfo.SidCount, "The SidCount includes the number of one AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY, one CLAIMS_VALID and the number of localResourceGroup SIDs."); //BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ExtraSids, "."); KERB_SID_AND_ATTRIBUTES[] expectedDefaultExtraSids = new KERB_SID_AND_ATTRIBUTES[2]; //The CLAIMS_VALID SID is "S-1-5-21-0-0-0-497" _RPC_SID CLAIMS_VALID = new _RPC_SID(); CLAIMS_VALID.Revision = 0x01; CLAIMS_VALID.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); CLAIMS_VALID.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 }; CLAIMS_VALID.SubAuthorityCount = 5; CLAIMS_VALID.SubAuthority = new uint[] { 21, 0, 0, 0, 497 }; expectedDefaultExtraSids[0] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[0].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[0].SID = new _RPC_SID[1]; expectedDefaultExtraSids[0].SID[0] = CLAIMS_VALID; //The AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID is "S-1-18-1" _RPC_SID AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = new _RPC_SID(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.Revision = 0x01; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 18 }; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthorityCount = 1; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthority = new uint[] { 1 }; expectedDefaultExtraSids[1] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[1].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[1].SID = new _RPC_SID[1]; expectedDefaultExtraSids[1].SID[0] = AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY; Adapter.Group[] resourceGroups = this.testConfig.LocalRealm.ResourceGroups.Groups; NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); KERB_SID_AND_ATTRIBUTES[] expectedResourceGroupExtraSids = Adapter.PacHelper.GetResourceGroupExtraSids(this.testConfig.LocalRealm.RealmName, cred, resourceGroupCount, resourceGroups); var expectedExtraSids = expectedDefaultExtraSids.Concat(expectedResourceGroupExtraSids).ToArray(); var res = expectedSidCount; for (int i = 0; i < expectedSidCount; i++) { for (int j = 0; j < expectedSidCount; j++) { if(Adapter.PacHelper.ExtraSidsAreEqual(expectedExtraSids[i], kerbValidationInfo.NativeKerbValidationInfo.ExtraSids[j])) { res--; } } } BaseTestSite.Assert.AreEqual((uint)0, res, "The ExtraSids field contains the pointer to a list which is the list copied from the PAC in the TGT plus a list constructed from the domain local groups..."); } }
public void Protected_Users_Interactive_Logon_User_A2AF_Fail() { base.Logging(); //Section 3.3.5.6: Authentication Policies are not supported by Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs. if (int.Parse(this.testConfig.LocalRealm.DomainControllerFunctionality) < 6) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Section 3.3.5.6: Authentication Policies are not supported by Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs."); BaseTestSite.Log.Add(LogEntryKind.Comment, "Will exit the case immediately."); return; } //TODO: Consider to udpate Client computer's department attribute and then interactive log on to client computer client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.FileServer[0].NetBiosName, this.testConfig.LocalRealm.FileServer[0].Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.FileServer[0].AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal 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); 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.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[16].Username, this.testConfig.LocalRealm.User[16].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); // Access check with User's A2AF failed, KDC will return the KDC_ERR_POLICY error. BaseTestSite.Assert.AreEqual( KRB_ERROR_CODE.KDC_ERR_POLICY, krbError2.ErrorCode, "Section 3.3.5.6 As Exchange " + "If AllowedToAuthenticateFrom is not NULL, the PAC of the armor TGT MUST be used to perform an access check for the ACTRL_DS_CONTROL_ACCESS right with additional rights GUID against the AllowedToAuthenticateFrom. " + "If the access check fails, the KDC MUST return KDC_ERR_POLICY." ); }
public void KdcSignature() { base.Logging(); //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); // 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; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC 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."); PacKdcSignature kdcSignature = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is PacKdcSignature) { kdcSignature = buf as PacKdcSignature; break; } } BaseTestSite.Assert.IsNotNull(kdcSignature, "KDC Signature is generated."); //cannot make a kdc key //kdcSignature untestable } }
public void Protected_Users_Interactive_Logon_User_A2AF_Succeed() { base.Logging(); //Section 3.3.5.6: Authentication Policies are not supported by Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs. if (int.Parse(this.testConfig.LocalRealm.DomainControllerFunctionality) < 6) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Section 3.3.5.6: Authentication Policies are not supported by Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs."); BaseTestSite.Log.Add(LogEntryKind.Comment, "Will exit the case immediately."); return; } client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } //AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal 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); 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.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[16].Username, this.testConfig.LocalRealm.User[16].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, krbError2.ErrorCode, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data, paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, null, subkey, fastOptions, apOptions); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", userKrbAsRep.EncPart.GetType().Name)); //verify flags in as reponse int flags = KerberosUtility.ConvertFlags2Int(asResponse.EncPart.flags.ByteArrayValue); BaseTestSite.Assert.AreEqual((EncTicketFlags)0, EncTicketFlags.FORWARDABLE & EncTicketFlags.PROXIABLE & (EncTicketFlags)flags, "Section 3.3.5.1: " + "If DelegationNotAllowed is set to TRUE on the principal, " + "(or if domainControllerFunctionality returns a value >= 6 ([MS-ADTS] section 3.1.1.3.2.25) and the principal is a member of PROTECTED_USERS ([MS-DTYP] section 2.4.2.4)), " + "the KILE KDC MUST NOT set the PROXIABLE or FORWARDABLE ticket flags ([RFC4120] sections 2.5 and 2.6)." ); //Get user linked authentication policy attribute string attributeDN = this.sutController.getAccountAttributeDN( this.testConfig.LocalRealm.RealmName.ToLower().Substring(0, this.testConfig.LocalRealm.RealmName.Length - 4), this.testConfig.LocalRealm.User[16].Username, "Users", "msDS-AssignedAuthNPolicy", this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password ); //Get authentication policy TGT lifetime // if policy not config the TGT life time, use the default value 4 hours for protected users. // if not a protected user, use the default value 10 hours by DC group policy defined. double? policyTGTLifetime4User = 4 * 36000000000; if (attributeDN != null) { char seperator = ','; string userLinkedPolicyName = attributeDN.Substring(3, attributeDN.IndexOf(seperator) - 3); //Get Authentication Policy User's TGT lifetime policyTGTLifetime4User = this.sutController.getAuthPolicyTGTLifeTime( this.testConfig.LocalRealm.RealmName.ToLower().Substring(0, this.testConfig.LocalRealm.RealmName.Length - 4), userLinkedPolicyName, "msds-UserTGTLifetime", this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password ); if (policyTGTLifetime4User == null) { // if policy not config the TGT life time, use the default value 4 hours for protected users. // if not a protected user, use the default value 10 hours by DC group policy defined. policyTGTLifetime4User = 4 * 36000000000; } } // if policy not config the TGT life time, use the default value 4 hours for protected users. // if not a protected user, use the default value 10 hours by DC group policy defined. double? policyTGTLifetime4Computer = 4 * 36000000000; attributeDN = this.sutController.getAccountAttributeDN( this.testConfig.LocalRealm.RealmName.ToLower().Substring(0, this.testConfig.LocalRealm.RealmName.Length - 4), this.testConfig.LocalRealm.ClientComputer.NetBiosName.Substring(0, this.testConfig.LocalRealm.ClientComputer.NetBiosName.Length - 1), "Computers", "msDS-AssignedAuthNPolicy", this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password ); if (attributeDN != null) { char seperator = ','; string userLinkedPolicyName = attributeDN.Substring(3, attributeDN.IndexOf(seperator) - 3); //Get Authentication Policy Computer's TGT lifetime policyTGTLifetime4Computer = this.sutController.getAuthPolicyTGTLifeTime( this.testConfig.LocalRealm.RealmName.ToLower().Substring(0, this.testConfig.LocalRealm.RealmName.Length - 4), userLinkedPolicyName, "msds-ComputerTGTLifetime", this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password ); if (policyTGTLifetime4Computer == null) { policyTGTLifetime4Computer = 4 * 36000000000; } } //Get TGTlifetime from ticket received DateTime startTime = DateTime.ParseExact( asResponse.EncPart.starttime.ToString(), "yyyyMMddHHmmssZ", System.Globalization.CultureInfo.InvariantCulture ); DateTime endTime = DateTime.ParseExact( asResponse.EncPart.endtime.ToString(), "yyyyMMddHHmmssZ", System.Globalization.CultureInfo.InvariantCulture ); DateTime renewTime = DateTime.ParseExact( asResponse.EncPart.renew_till.ToString(), "yyyyMMddHHmmssZ", System.Globalization.CultureInfo.InvariantCulture ); //get timespan TimeSpan maxTGTlife = endTime - startTime; TimeSpan maxRenewTime = renewTime - startTime; double? maxTGTlifeTimeSpan = maxTGTlife.Ticks; double? maxRenewTimeSpan = maxRenewTime.Ticks; //verify MaxRenewAge and MaxTicketAge for the TGT BaseTestSite.Assert.AreEqual( policyTGTLifetime4Computer, // as response is encrypted by computer's key maxTGTlifeTimeSpan, "Section 3.3.5.6 MaxTicketAge (section 3.3.1) for the TGT is 4 hours unless specified by policy. " + "If TGTLifetime is not 0: MaxTicketAge for the TGT is TGTLifetime." ); BaseTestSite.Assert.AreEqual( policyTGTLifetime4Computer, maxRenewTimeSpan, "Section 3.3.5.6 MaxRenewAge (section 3.3.1) for the TGT is 4 hours unless specified by policy. " + "If TGTLifetime is not 0: MaxRenewAge for the TGT is TGTLifetime." ); // verify the PA-DATA of AS_REP: asResponse.EncPart.pa_datas as PA_SUPPORTED_ENCTYPES bool isExistPaSupportedEncTypes = false; bool isExistPadataValue = false; var padataCount = userKrbAsRep.EncPart.pa_datas.Elements.Length; for (int i = 0; i < padataCount; i++) { var padata = PaDataParser.ParseRepPaData(userKrbAsRep.EncPart.pa_datas.Elements[i]); if ((PaDataType)padata.Data.padata_type.Value == PaDataType.PA_SUPPORTED_ENCTYPES) { isExistPaSupportedEncTypes = true; for (int j = 0; j < padata.Data.padata_value.Value.Length; j++) { if (padata.Data.padata_value.Value[j]==0x1F) { isExistPadataValue = true; } } } } BaseTestSite.Assert.IsTrue(isExistPaSupportedEncTypes, "If domainControllerFunctionality returns a value >= 3:" + "the KDC SHOULD, in the encrypted pre-auth data part ([Referrals-11], Appendix A) of the AS-REP message, " + "include PA-DATA with the padata-type set to PA-SUPPORTED-ENCTYPES (165)."); BaseTestSite.Assert.IsTrue(isExistPadataValue, "If domainControllerFunctionality returns a value >= 3: " + "the KDC SHOULD, in the encrypted pre-auth data part ([Referrals-11], Appendix A) of the AS-REP message, " + "include PA-DATA with the padata-type set to PA-SUPPORTED-ENCTYPES (165), and the padata-value set to 0x1F (section 2.2.6)."); if (testConfig.IsClaimSupported) { PaSupportedEncTypes paSupportedEncTypes = null; // userKrbAsRep.EncPart.pa_datas.GetType foreach (var padata in userKrbAsRep.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."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), "Claims is supported."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.FAST_Supported), "FAST is supported."); } // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request."); client.SendTgsRequestWithFast(testConfig.LocalRealm.ClientComputer.DefaultServiceName, options, null, null, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve TGS response."); KerberosTgsResponse userKrbTgsRep = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.Response, "The Response pare of TGS-REP is not null."); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.Response.padata, "The Padata of TGS-REP is not null."); EncryptionKey strengthenKey = null; foreach (PA_DATA paData in userKrbTgsRep.Response.padata.Elements) { var parsedPaData = PaDataParser.ParseRepPaData(paData); if (parsedPaData is PaFxFastRep) { var armoredRep = ((PaFxFastRep)parsedPaData).GetArmoredRep(); var kerbRep = ((PaFxFastRep)parsedPaData).GetKerberosFastRep(client.Context.FastArmorkey); strengthenKey = kerbRep.FastResponse.strengthen_key; } } BaseTestSite.Assert.IsNotNull(strengthenKey, "Strengthen key field must be set in TGS-REP."); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.EncPart, "The encrypted part of TGS-REP is decrypted."); }
public void KERB_VALIDATION_INFO() { base.Logging(); //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); BaseTestSite.Log.Add(LogEntryKind.Comment, "Construct Kerberos client for testing."); //Create and send AS request // 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; } Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, cred); } KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC 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."); KerbValidationInfo kerbValidationInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { kerbValidationInfo = buf as KerbValidationInfo; break; } } BaseTestSite.Assert.IsNotNull(kerbValidationInfo, "KerbValidationInfo is generated."); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { var flogonTime = (long)kerbValidationInfo.NativeKerbValidationInfo.LogonTime.dwHighDateTime << 32 | (long)kerbValidationInfo.NativeKerbValidationInfo.LogonTime.dwLowDateTime; if (flogonTime != 0x7FFFFFFFFFFFFFFF) { System.DateTime logonTime = System.DateTime.FromFileTime(flogonTime); } BaseTestSite.Assert.AreEqual(commonUserFields.LogonTime, flogonTime, "LogonTime in KERB_VALIDATION_INFO structure should be equal to that in AD."); long fPasswordLastSet = (long)kerbValidationInfo.NativeKerbValidationInfo.PasswordLastSet.dwHighDateTime << 32 | (long)kerbValidationInfo.NativeKerbValidationInfo.PasswordLastSet.dwLowDateTime; if (fPasswordLastSet != 0x7FFFFFFFFFFFFFFF) { System.DateTime passwordLastSet = System.DateTime.FromFileTime(fPasswordLastSet); } BaseTestSite.Assert.AreEqual(commonUserFields.PasswordLastSet, fPasswordLastSet, "PasswordLastSet in KERB_VALIDATION_INFO structure should be equal to that in AD."); var effectiveName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.EffectiveName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), effectiveName.ToLower(), "The EffectiveName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserName field of the SamrQueryInformationUser2 response message."); string fullName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.FullName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), fullName.ToLower(), "The FullName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.FullName field of the SamrQueryInformationUser2 response message."); string logonScript = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonScript.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ScriptPath, logonScript, "The LogonScript field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ScriptPath field of the SamrQueryInformationUser2 response message."); string profilePath = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.ProfilePath.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ProfilePath, profilePath, "The ProfilePath field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ProfilePath field of the SamrQueryInformationUser2 response message."); string homeDirectory = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectory.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDirectory, homeDirectory, "The HomeDirectory field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectory field of the SamrQueryInformationUser2 response message."); string homeDirectoryDrive = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectoryDrive.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDrive, homeDirectoryDrive, "The HomeDirectoryDrive field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectoryDrive field of the SamrQueryInformationUser2 response message."); ushort logonCount = kerbValidationInfo.NativeKerbValidationInfo.LogonCount; BaseTestSite.Assert.AreEqual(commonUserFields.LogonCount, logonCount, "The LogonCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.LogonCount field of the SamrQueryInformationUser2 response message."); ushort badPasswordCount = kerbValidationInfo.NativeKerbValidationInfo.BadPasswordCount; BaseTestSite.Assert.AreEqual(commonUserFields.BadPwdCount, badPasswordCount, "The BadPasswordCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.BadPasswordCount field of the SamrQueryInformationUser2 response message."); uint userId = kerbValidationInfo.NativeKerbValidationInfo.UserId; BaseTestSite.Assert.AreEqual(commonUserFields.userId, userId, "The UserID field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserId field of the SamrQueryInformationUser2 response message."); uint primaryGroupId = kerbValidationInfo.NativeKerbValidationInfo.PrimaryGroupId; BaseTestSite.Assert.AreEqual(commonUserFields.primaryGroupId, primaryGroupId, "The PrimaryGroupId field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.PrimaryGroupId field of the SamrQueryInformationUser2 response message."); var userAccountControl = kerbValidationInfo.NativeKerbValidationInfo.UserAccountControl; //not the same with what is in the Active Directory //BaseTestSite.Assert.AreEqual(commonUserFields.userAccountControl, userAccountControl, "The BadPasswordCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.BadPasswordCount field of the SamrQueryInformationUser2 response message."); //read only, need SUT adapter uint groupCount = kerbValidationInfo.NativeKerbValidationInfo.GroupCount; BaseTestSite.Assert.AreEqual(commonUserFields.groupCount, groupCount, "The GroupCount field SHOULD be set to the Groups.MembershipCount field of the SamrGetGroupsForUser response message."); //read only, need SUT adapter Microsoft.Protocols.TestTools.StackSdk.Security.Pac._GROUP_MEMBERSHIP[] groupIds = kerbValidationInfo.NativeKerbValidationInfo.GroupIds; BaseTestSite.Assert.AreEqual(commonUserFields.groupIds.Length, groupIds.Length, "The GroupIds field SHOULD be set to the Groups.Group field of the SamrGetGroupsForUser response message."); BaseTestSite.Assert.IsTrue(groupIds.Select(id => id.RelativeId).OrderBy(id => id).SequenceEqual(commonUserFields.groupIds.OrderBy(id => id)), "The GroupIds field SHOULD be set to the Groups.Group field of the SamrGetGroupsForUser response message."); UserFlags_Values userFlags = kerbValidationInfo.NativeKerbValidationInfo.UserFlags; BaseTestSite.Assert.AreEqual(UserFlags_Values.ExtraSids, UserFlags_Values.ExtraSids & userFlags, "The D bit SHOULD be set in the UserFlags field if the ExtraSids field is populated and contains additional SIDs and all other bits MUST be set to zero."); byte[] userSessionKey = kerbValidationInfo.NativeKerbValidationInfo.UserSessionKey; byte[] allZero = userSessionKey; Array.Clear(allZero, 0, allZero.Length); BaseTestSite.Assert.AreEqual(allZero, userSessionKey, "The UserSessionKey field MUST be set to zero."); string logonServer = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonServer.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.KDC[0].NetBiosName.Remove(this.testConfig.LocalRealm.KDC[0].NetBiosName.IndexOf("$")), logonServer, "The LogonServer SHOULD be set to NetbiosServerName."); string logonDomainName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonDomainName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.Remove(this.testConfig.LocalRealm.RealmName.IndexOf(".")).ToLower(), logonDomainName.ToLower(), "The LogonDomainName SHOULD be set to NetbiosDomainName."); BaseTestSite.Assert.AreEqual(1, kerbValidationInfo.NativeKerbValidationInfo.LogonDomainId.Length, "The number of LogonDomainId should always be 1."); foreach (_RPC_SID element in kerbValidationInfo.NativeKerbValidationInfo.LogonDomainId) { byte[] expectedIdentifierAuthority = new byte[6] { 0, 0, 0, 0, 0, 5 }; BaseTestSite.Assert.AreEqual(expectedIdentifierAuthority.Length, element.IdentifierAuthority.Value.Length, "IdentifierAuthority 000005 stands for S-1-5"); for (int i = 0; i < expectedIdentifierAuthority.Length; i++) { BaseTestSite.Assert.AreEqual(expectedIdentifierAuthority[i], element.IdentifierAuthority.Value[i], "IdentifierAuthority element {0} should match expected.", i); } uint[] expectedSubAuthority = commonUserFields.domainSid; BaseTestSite.Assert.AreEqual(expectedSubAuthority.Length, element.SubAuthorityCount, "SubAuthorityCount should match expected."); for (int i = 0; i < expectedSubAuthority.Length; i++) { BaseTestSite.Assert.AreEqual(commonUserFields.domainSid[i], element.SubAuthority[i], "SubAuthorityCount element {0} should match expected."); } } KERB_VALIDATION_INFO_Reserved1_Values[] reserved1 = kerbValidationInfo.NativeKerbValidationInfo.Reserved1; BaseTestSite.Assert.AreEqual(2, reserved1.Length, "The Reserved1 field MUST be set to a two-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved1_Values element in reserved1) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved1_Values.V1, element, "Each element of the array MUST be zero."); } KERB_VALIDATION_INFO_Reserved3_Values[] reserved3 = kerbValidationInfo.NativeKerbValidationInfo.Reserved3; BaseTestSite.Assert.AreEqual(7, reserved3.Length, "The Reserved1 field MUST be set to a seven-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved3_Values element in reserved3) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved3_Values.V1, element, "Each element of the array MUST be zero."); } //sidcount =2 because, one for AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID and one for CLAIMS_VALID SID uint expectedSidCount = 2; BaseTestSite.Assert.AreEqual(expectedSidCount, kerbValidationInfo.NativeKerbValidationInfo.SidCount, "The SidCount includes the number of one AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY, one CLAIMS_VALID."); KERB_SID_AND_ATTRIBUTES[] expectedDefaultExtraSids = new KERB_SID_AND_ATTRIBUTES[expectedSidCount]; //The CLAIMS_VALID SID is "S-1-5-21-0-0-0-497" _RPC_SID CLAIMS_VALID = new _RPC_SID(); CLAIMS_VALID.Revision = 0x01; CLAIMS_VALID.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); CLAIMS_VALID.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 }; CLAIMS_VALID.SubAuthorityCount = 5; CLAIMS_VALID.SubAuthority = new uint[] { 21, 0, 0, 0, 497 }; expectedDefaultExtraSids[0] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[0].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[0].SID = new _RPC_SID[1]; expectedDefaultExtraSids[0].SID[0] = CLAIMS_VALID; //The AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID is "S-1-18-1" _RPC_SID AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = new _RPC_SID(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.Revision = 0x01; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 18 }; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthorityCount = 1; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthority = new uint[] { 1 }; expectedDefaultExtraSids[1] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[1].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[1].SID = new _RPC_SID[1]; expectedDefaultExtraSids[1].SID[0] = AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY; var expectedExtraSids = expectedDefaultExtraSids; uint res = expectedSidCount; for (int i = 0; i < expectedSidCount; i++) { for (int j = 0; j < expectedSidCount; j++) { if (Adapter.PacHelper.ExtraSidsAreEqual(expectedExtraSids[i], kerbValidationInfo.NativeKerbValidationInfo.ExtraSids[j])) { res--; } } } BaseTestSite.Assert.AreEqual((uint)0, res, "The ExtraSids field contains the pointer to a list which is the list copied from the PAC in the TGT plus a list constructed from the domain local groups, notice domain local groups is equal to 0 in this test case."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid, "The ResourceGroupDomainSid field MUST be set to zero."); BaseTestSite.Assert.AreEqual((uint)0, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupCount, "The ResourceGroupCount field MUST be set to zero."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds, "The ResourceGroupIds field MUST be set to zero."); } else { string effectiveName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.EffectiveName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), effectiveName.ToLower(), "The EffectiveName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserName field of the SamrQueryInformationUser2 response message."); string fullName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.FullName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), fullName.ToLower(), "The FullName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.FullName field of the SamrQueryInformationUser2 response message."); string logonScript = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonScript.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ScriptPath, logonScript, "The LogonScript field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ScriptPath field of the SamrQueryInformationUser2 response message."); string profilePath = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.ProfilePath.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ProfilePath, profilePath, "The ProfilePath field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ProfilePath field of the SamrQueryInformationUser2 response message."); string homeDirectory = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectory.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDirectory, homeDirectory, "The HomeDirectory field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectory field of the SamrQueryInformationUser2 response message."); string homeDirectoryDrive = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectoryDrive.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDrive, homeDirectoryDrive, "The HomeDirectoryDrive field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectoryDrive field of the SamrQueryInformationUser2 response message."); uint userId = kerbValidationInfo.NativeKerbValidationInfo.UserId; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.UserID, userId, "The UserID field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserId field of the SamrQueryInformationUser2 response message."); uint primaryGroupId = kerbValidationInfo.NativeKerbValidationInfo.PrimaryGroupId; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.PrimaryGroupId, primaryGroupId, "The PrimaryGroupId field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.PrimaryGroupId field of the SamrQueryInformationUser2 response message."); uint userAccountControl = kerbValidationInfo.NativeKerbValidationInfo.UserAccountControl; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.UserAccountControl, userAccountControl, "The BadPasswordCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.BadPasswordCount field of the SamrQueryInformationUser2 response message."); uint groupCount = kerbValidationInfo.NativeKerbValidationInfo.GroupCount; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.GroupCount, groupCount, "The GroupCount field SHOULD be set to the Groups.MembershipCount field of the SamrGetGroupsForUser response message."); UserFlags_Values userFlags = kerbValidationInfo.NativeKerbValidationInfo.UserFlags; BaseTestSite.Assert.AreEqual(UserFlags_Values.ExtraSids, UserFlags_Values.ExtraSids & userFlags, "The D bit SHOULD be set in the UserFlags field if the ExtraSids field is populated and contains additional SIDs and all other bits MUST be set to zero."); byte[] userSessionKey = kerbValidationInfo.NativeKerbValidationInfo.UserSessionKey; byte[] allZero = userSessionKey; Array.Clear(allZero, 0, allZero.Length); BaseTestSite.Assert.AreEqual(allZero, userSessionKey, "The UserSessionKey field MUST be set to zero."); string logonServer = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonServer.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.KDC[0].NetBiosName.Remove(this.testConfig.LocalRealm.KDC[0].NetBiosName.IndexOf("$")), logonServer, "The LogonServer SHOULD be set to NetbiosServerName."); string logonDomainName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonDomainName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.Remove(this.testConfig.LocalRealm.RealmName.IndexOf(".")).ToLower(), logonDomainName.ToLower(), "The LogonDomainName SHOULD be set to NetbiosDomainName."); KERB_VALIDATION_INFO_Reserved1_Values[] reserved1 = kerbValidationInfo.NativeKerbValidationInfo.Reserved1; BaseTestSite.Assert.AreEqual(2, reserved1.Length, "The Reserved1 field MUST be set to a two-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved1_Values element in reserved1) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved1_Values.V1, element, "Each element of the array MUST be zero."); } KERB_VALIDATION_INFO_Reserved3_Values[] reserved3 = kerbValidationInfo.NativeKerbValidationInfo.Reserved3; BaseTestSite.Assert.AreEqual(7, reserved3.Length, "The Reserved1 field MUST be set to a seven-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved3_Values element in reserved3) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved3_Values.V1, element, "Each element of the array MUST be zero."); } //sidcount =2 because, one for AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID and one for CLAIMS_VALID SID uint expectedSidCount = 2; BaseTestSite.Assert.AreEqual(expectedSidCount, kerbValidationInfo.NativeKerbValidationInfo.SidCount, "The SidCount includes the number of one AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY, one CLAIMS_VALID."); KERB_SID_AND_ATTRIBUTES[] expectedDefaultExtraSids = new KERB_SID_AND_ATTRIBUTES[expectedSidCount]; //The CLAIMS_VALID SID is "S-1-5-21-0-0-0-497" _RPC_SID CLAIMS_VALID = new _RPC_SID(); CLAIMS_VALID.Revision = 0x01; CLAIMS_VALID.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); CLAIMS_VALID.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 }; CLAIMS_VALID.SubAuthorityCount = 5; CLAIMS_VALID.SubAuthority = new uint[] { 21, 0, 0, 0, 497 }; expectedDefaultExtraSids[0] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[0].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[0].SID = new _RPC_SID[1]; expectedDefaultExtraSids[0].SID[0] = CLAIMS_VALID; //The AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID is "S-1-18-1" _RPC_SID AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = new _RPC_SID(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.Revision = 0x01; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 18 }; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthorityCount = 1; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthority = new uint[] { 1 }; expectedDefaultExtraSids[1] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[1].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[1].SID = new _RPC_SID[1]; expectedDefaultExtraSids[1].SID[0] = AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY; var expectedExtraSids = expectedDefaultExtraSids; uint res = expectedSidCount; for (int i = 0; i < expectedSidCount; i++) { for (int j = 0; j < expectedSidCount; j++) { if (Adapter.PacHelper.ExtraSidsAreEqual(expectedExtraSids[i], kerbValidationInfo.NativeKerbValidationInfo.ExtraSids[j])) { res--; } } } BaseTestSite.Assert.AreEqual((uint)0, res, "The ExtraSids field contains the pointer to a list which is the list copied from the PAC in the TGT plus a list constructed from the domain local groups, notice domain local groups is equal to 0 in this test case."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid, "The ResourceGroupDomainSid field MUST be set to zero."); BaseTestSite.Assert.AreEqual((uint)kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds.Length, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupCount, "The ResourceGroupCount field MUST be set to zero."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds, "The ResourceGroupIds field MUST be set to zero."); } } }
public void Protected_Users_Network_Logon_Computer_A2A2_Fail() { base.Logging(); //Section 3.3.5.6: Authentication Policies are not supported by Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs. if (int.Parse(this.testConfig.LocalRealm.DomainControllerFunctionality) < 6) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Section 3.3.5.6: Authentication Policies are not supported by Windows 2000, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, or Windows Server 2012 KDCs."); BaseTestSite.Log.Add(LogEntryKind.Comment, "Will exit the case immediately."); return; } client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal 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); 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.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[17].Username, this.testConfig.LocalRealm.User[17].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, krbError.ErrorCode, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data, paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, null, subkey, fastOptions, apOptions); //receive as response KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", userKrbAsRep.EncPart.GetType().Name)); // verify the PA-DATA of AS_REP: asResponse.EncPart.pa_datas as PA_SUPPORTED_ENCTYPES bool isExistPaSupportedEncTypes = false; bool isExistPadataValue = false; var padataCount = userKrbAsRep.EncPart.pa_datas.Elements.Length; for (int i = 0; i < padataCount; i++) { var padata = PaDataParser.ParseRepPaData(userKrbAsRep.EncPart.pa_datas.Elements[i]); if ((PaDataType)padata.Data.padata_type.Value == PaDataType.PA_SUPPORTED_ENCTYPES) { isExistPaSupportedEncTypes = true; for (int j = 0; j < padata.Data.padata_value.Value.Length; j++) { if (padata.Data.padata_value.Value[j] == 0x1F) { isExistPadataValue = true; } } } } BaseTestSite.Assert.IsTrue(isExistPaSupportedEncTypes, "If domainControllerFunctionality returns a value >= 3:" + "the KDC SHOULD, in the encrypted pre-auth data part ([Referrals-11], Appendix A) of the AS-REP message, " + "include PA-DATA with the padata-type set to PA-SUPPORTED-ENCTYPES (165)."); BaseTestSite.Assert.IsTrue(isExistPadataValue, "If domainControllerFunctionality returns a value >= 3: " + "the KDC SHOULD, in the encrypted pre-auth data part ([Referrals-11], Appendix A) of the AS-REP message, " + "include PA-DATA with the padata-type set to PA-SUPPORTED-ENCTYPES (165), and the padata-value set to 0x1F (section 2.2.6)."); if (testConfig.IsClaimSupported) { PaSupportedEncTypes paSupportedEncTypes = null; // userKrbAsRep.EncPart.pa_datas.GetType foreach (var padata in userKrbAsRep.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."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), "Claims is supported."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.FAST_Supported), "FAST is supported."); } // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request."); client.SendTgsRequestWithFast(testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options, null, null, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve TGS response."); krbError = client.ExpectKrbError(); // Access check with Computer's A2A2 failed, KDC will return the KDC_ERR_POLICY error. BaseTestSite.Assert.AreEqual( KRB_ERROR_CODE.KDC_ERR_POLICY, krbError.ErrorCode, "Section 3.3.5.7 TGS Exchange: " + "If AllowedToAuthenticateFrom is not NULL, the PAC of the armor TGT MUST be used to perform an access check for the ACTRL_DS_CONTROL_ACCESS right with additional rights GUID against the AllowedToAuthenticateFrom." + "If the access check fails, the KDC MUST return KDC_ERR_POLICY." ); }
public void FastKrb_Error() { base.Logging(); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve preauthentication required error."); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncTimeStamp."); string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp( timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve AS response."); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Assert.IsNotNull(asResponse.EncPart, "The encrypted part of AS response is decrypted."); BaseTestSite.Assert.IsNotNull(asResponse.EncPart.key, "AS response should contain a session key."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Switch to user principal."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("Construct Kerberos client using user account: {0}.", this.testConfig.LocalRealm.User[1].Username)); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, this.testConfig.LocalRealm.User[1].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored AS request with no pre-authentication padata."); var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { new PA_DATA(new KerbInt32((long)PaDataType.PA_FX_FAST), null) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncryptedChallenge."); var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); var invalidKey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Invalid", "this is a salt"); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.ToString(), 0, invalidKey, userKey); PaPacRequest paPacRequest = new PaPacRequest(true); Asn1SequenceOf<PA_DATA> outerSeqPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data }); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, outerSeqPaData, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve AS response."); KerberosKrbError error = client.ExpectKrbError(); BaseTestSite.Assert.IsNotNull(error.KrbError.e_data, "E_data is not null"); Asn1SequenceOf<PA_DATA> seqOfPadata = new Asn1SequenceOf<PA_DATA>(); seqOfPadata.BerDecode(new Asn1DecodingBuffer(error.KrbError.e_data.ByteArrayValue)); var padataCount = seqOfPadata.Elements.Length; PaFxFastRep paFxFastRep = null; for (int i = 0; i < padataCount; i++) { var padata = PaDataParser.ParseRepPaData(seqOfPadata.Elements[i]); //Fix me: PaETypeInfo is also possible if (padata is PaFxFastRep) { paFxFastRep = padata as PaFxFastRep; } } BaseTestSite.Assert.IsNotNull(paFxFastRep , "KDC must reply a PA-FX-Fast response."); PaFxError paFxError = null; var armoredRep = paFxFastRep.GetKerberosFastRep(client.Context.FastArmorkey); foreach (var padata in armoredRep.PaData) { if (padata is PaFxError) { paFxError = padata as PaFxError; break; } } BaseTestSite.Assert.IsNotNull(paFxError , "KDC must include a PA-FX-ERROR padata."); BaseTestSite.Assert.IsNull(paFxError.KrbError.KrbError.e_data, "E_data is null."); }
public void RC4_InteractiveLogonUseFast() { base.Logging(); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); EncryptionType[] rc4HmacType = new EncryptionType[] { EncryptionType.RC4_HMAC }; // Define device principal client supported encryption type BaseTestSite.Log.Add(LogEntryKind.Comment, "Set device principal client supported encryption type as RC4_HMAC."); client.SetSupportedEType(rc4HmacType); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); // AS_REQ and AS_REP using device principal string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp( timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Assert.IsNotNull(asResponse.EncPart, "The encrypted part of AS response is decrypted."); BaseTestSite.Assert.IsNotNull(asResponse.EncPart.key, "AS response should contain a session key."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Switch to user principal."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("Construct Kerberos client using user account: {0}.", this.testConfig.LocalRealm.User[1].Username)); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, this.testConfig.LocalRealm.User[1].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // Define user principal client supported encryption type BaseTestSite.Log.Add(LogEntryKind.Comment, "Set user principal client supported encryption type as RC4_HMAC."); client.SetSupportedEType(rc4HmacType); // 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; } // FAST armored AS_REQ and KRB-ERROR using user principal // Create a "random" key. BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored AS request with no pre-authentication padata."); var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { new PA_DATA(new KerbInt32((long)PaDataType.PA_FX_FAST), null) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, krbError2.ErrorCode, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncryptedChallenge."); var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); PaPacRequest paPacRequest = new PaPacRequest(true); Asn1SequenceOf<PA_DATA> outerSeqPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data }); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, outerSeqPaData, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve AS response."); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.ticket, "AS response should contain a TGT."); BaseTestSite.Assert.IsNotNull(userKrbAsRep.EncPart, "The encrypted part of AS response is decrypted."); BaseTestSite.Assert.IsNotNull(userKrbAsRep.EncPart.key, "AS response should contain a session key."); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", userKrbAsRep.EncPart.GetType().Name)); // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request."); client.SendTgsRequestWithFast(testConfig.LocalRealm.ClientComputer.DefaultServiceName, options, null, null, subkey, fastOptions, apOptions); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve TGS response."); KerberosTgsResponse userKrbTgsRep = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.EncPart, "The encrypted part of TGS-REP is decrypted."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), userKrbTgsRep.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, KerberosUtility.PrincipalName2String(userKrbTgsRep.Response.ticket.sname), "The Service principal name in ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); userKrbTgsRep.DecryptTicket(key); //userKrbTgsRep.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), userKrbTgsRep.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), KerberosUtility.PrincipalName2String(userKrbTgsRep.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); }
public void UnsupportedFastArmorType() { base.Logging(); client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); // Switch to user principal client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; string timeStamp2 = KerberosUtility.CurrentKerberosTime.Value; PaFxFastReq paFxReq = new PaFxFastReq(null); Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { (paFxReq.Data) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data }); PaPacRequest paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf<PA_DATA> outerSeqPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, outerSeqPaData, subkey, fastOptions, apOptions, 0); KerberosKrbError krbError3 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError3.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_FAILED, "Pre-authentication failed."); }
public void RC4_CrossRealm_PAC_DEVICE_CLAIMS_INFO() { base.Logging(); // Clear trust realm encryption type IClientControlAdapter adapter = BaseTestSite.GetAdapter<IClientControlAdapter>(); adapter.ClearTrustRealmEncType(); try { client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); EncryptionType[] rc4HmacType = new EncryptionType[] { EncryptionType.RC4_HMAC }; // Define device principal client supported encryption type BaseTestSite.Log.Add(LogEntryKind.Comment, "Set device principal client supported encryption type as RC4_HMAC."); client.SetSupportedEType(rc4HmacType); // 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; client.SendAsRequest(options, null); //Recieve preauthentication required error METHOD_DATA methodData; KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); //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(); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); //Create and send TGS request client.SendTgsRequest(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); KerberosTicket referralComputerTicket = client.Context.Ticket; EncryptionKey referralComputerSessionKey = client.Context.Ticket.SessionKey; //start client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // Define device principal client supported encryption type BaseTestSite.Log.Add(LogEntryKind.Comment, "Set device principal client supported encryption type as RC4_HMAC."); client.SetSupportedEType(rc4HmacType); // 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; } // AS_REQ and KRB-ERROR using device principal options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); // AS_REQ and AS_REP using device principal timeStamp = KerberosUtility.CurrentKerberosTime.Value; paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); // Switch to user principal client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // Define user principal client supported encryption type BaseTestSite.Log.Add(LogEntryKind.Comment, "Set user principal client supported encryption type as RC4_HMAC."); client.SetSupportedEType(rc4HmacType); // 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; string timeStamp2 = KerberosUtility.CurrentKerberosTime.Value; PaFxFastReq paFxFastReq = new PaFxFastReq(null); Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { (paFxFastReq.Data) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required."); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data }); paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf<PA_DATA> outerSeqPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, outerSeqPaData, subkey, fastOptions, apOptions); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); if (testConfig.IsClaimSupported) { PaSupportedEncTypes paSupportedEncTypes = null; foreach (var padata in userKrbAsRep.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."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), "Claims is supported."); BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.FAST_Supported), "FAST is supported."); } // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); client.Context.ArmorSessionKey = client.Context.Ticket.SessionKey; client.Context.ArmorTicket = client.Context.Ticket; if (this.testConfig.TrustType == Adapter.TrustType.Forest) { client.SendTgsRequestWithExplicitFast(testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options, null, null, subkey, fastOptions, apOptions); } else if (this.testConfig.TrustType == Adapter.TrustType.Realm) { client.SendTgsRequestWithExplicitFast(testConfig.TrustedRealm.KDC[0].DefaultServiceName, options, null, null, subkey, fastOptions, apOptions); } KerberosTgsResponse userKrbTgsRep = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); client.ChangeRealm(this.testConfig.TrustedRealm.RealmName, this.testConfig.TrustedRealm.KDC[0].IPAddress, this.testConfig.TrustedRealm.KDC[0].Port, this.testConfig.TransportType); //Create and send referral TGS request client.Context.ArmorTicket = referralComputerTicket; client.Context.ArmorSessionKey = referralComputerTicket.SessionKey; client.SendTgsRequestWithExplicitFast(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options, null, null, subkey, fastOptions, apOptions); KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); EncryptionKey key = testConfig.QueryKey(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType); refTgsResponse.DecryptTicket(key); //Verify PAC if (testConfig.IsKileImplemented && testConfig.IsClaimSupported) { BaseTestSite.Assert.IsNotNull(refTgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData<AdWin2KPac>(refTgsResponse.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); DeviceClaimsInfo deviceClaimsInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is DeviceClaimsInfo) { deviceClaimsInfo = buf as DeviceClaimsInfo; break; } } BaseTestSite.Assert.IsNotNull(deviceClaimsInfo, "PAC_DEVICE_CLAIM_INFO should be generated."); } } finally { adapter.SetTrustRealmEncTypeAsAes(); } }
/// <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; } }
public void RC4_UsingFAST_Smb2() { base.Logging(); client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); EncryptionType[] rc4HmacType = new EncryptionType[] { EncryptionType.RC4_HMAC }; // Define device principal client supported encryption type BaseTestSite.Log.Add(LogEntryKind.Comment, "Set device principal client supported encryption type as RC4_HMAC."); client.SetSupportedEType(rc4HmacType); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); // AS_REQ and AS_REP using device principal string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); // Switch to user principal client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // Define user principal client supported encryption type BaseTestSite.Log.Add(LogEntryKind.Comment, "Set user principal client supported encryption type as RC4_HMAC."); client.SetSupportedEType(rc4HmacType); // 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; string timeStamp2 = KerberosUtility.CurrentKerberosTime.Value; PaFxFastReq paFxReq = new PaFxFastReq(null); Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { (paFxReq.Data) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); PaPacRequest paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data, paPacRequest.Data, paPacOptions.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, null, subkey, fastOptions, apOptions); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); client.SendTgsRequestWithFast(testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options, null, null, subkey, fastOptions, apOptions); KerberosTgsResponse userKrbTgsRep = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.AreEqual(EncryptionType.RC4_HMAC, client.Context.SelectedEType, "Client selected encryption type should be RC4_HMAC."); AuthorizationData data = null; subkey = KerberosUtility.GenerateKey(client.Context.SessionKey); byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired, data, subkey, ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG); KerberosApResponse apRep = client.GetApResponseFromToken(SendAndRecieveSmb2Ap(this.testConfig.LocalRealm.FileServer[0], token)); }
public void NetworkLogonLdapWithClaim_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(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims); 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(); 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); }
public void PAC_CLIENT_INFO() { base.Logging(); //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); // 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; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC 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."); PacClientInfo pacClientInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is PacClientInfo) { pacClientInfo = buf as PacClientInfo; break; } } BaseTestSite.Assert.IsNotNull(pacClientInfo, "PAC_CLIENT_INFO is generated."); var authTimeInPac = DtypUtility.ToDateTime(pacClientInfo.NativePacClientInfo.ClientId).ToString("yyyyMMddHHmmss") + "Z"; var c = asResponse.EncPart.authtime; BaseTestSite.Assert.AreEqual( asResponse.EncPart.authtime.ToString(), authTimeInPac, "ClientId field is a FILETIME structure in little-endian format that contains the Kerberos initial TGT auth time."); string clientName = new string(pacClientInfo.NativePacClientInfo.Name); BaseTestSite.Assert.AreEqual( pacClientInfo.NativePacClientInfo.Name.Length * sizeof(char), pacClientInfo.NativePacClientInfo.NameLength, "The NameLength field is an unsigned 16-bit integer in little-endian format that specifies the length, in bytes, of the Name field."); BaseTestSite.Assert.AreEqual( this.testConfig.LocalRealm.User[1].Username.ToLower(), clientName.ToLower(), "The Name field is an array of 16-bit Unicode characters in little-endian format that contains the client's account name."); } }