/// <summary> /// RPC bind over TCP/IP, using specified endpoint and authenticate provider. /// </summary> /// <param name="serverName">NRPC server machine name.</param> /// <param name="endpoint">RPC endpoints, it's the port on TCP/IP.</param> /// <param name="securityContext"> /// Security provider for RPC. /// Set the value to null to disable authentication. /// </param> /// <param name="timeout">Timeout for bind and all future requests.</param> /// <exception cref="ArgumentNullException"> /// Thrown when serverName is null. /// </exception> public void BindOverTcp( string serverName, ushort endpoint, ClientSecurityContext securityContext, TimeSpan timeout) { if (serverName == null) { throw new ArgumentNullException("serverName"); } nrpcSecurityContext = securityContext as NrpcClientSecurityContext; if (nrpcSecurityContext != null) { context = nrpcSecurityContext.nrpc.context; } rpc.Bind( RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE, serverName, endpoint.ToString(CultureInfo.InvariantCulture), null, securityContext, securityContext == null ? RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_NONE : (context.SealSecureChannel ? RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_PRIVACY : RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY), timeout); context.PrimaryName = serverName; NrpcRpcAdapter nrpcRpcAdapter = rpc as NrpcRpcAdapter; if (nrpcRpcAdapter != null) { context.rpceTransportContext = nrpcRpcAdapter.rpceClientTransport.Context; } }
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."); } }
/// <summary> /// RPC bind over named pipe, using well-known endpoint "\PIPE\NETLOGON". /// </summary> /// <param name="serverName">NRPC server machine name.</param> /// <param name="transportCredential"> /// If connect by SMB/SMB2, it's the security credential /// used by under layer transport (SMB/SMB2). /// If connect by TCP, this parameter is ignored. /// </param> /// <param name="securityContext"> /// Security provider for RPC. /// Set the value to null to disable authentication. /// </param> /// <param name="timeout">Timeout for bind and all future requests.</param> /// <exception cref="ArgumentNullException"> /// Thrown when serverName is null. /// </exception> public void BindOverNamedPipe( string serverName, AccountCredential transportCredential, ClientSecurityContext securityContext, TimeSpan timeout) { if (serverName == null) { throw new ArgumentNullException("serverName"); } nrpcSecurityContext = securityContext as NrpcClientSecurityContext; if (nrpcSecurityContext != null) { context = nrpcSecurityContext.nrpc.context; } rpc.Bind( RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, serverName, NrpcUtility.NETLOGON_RPC_OVER_NP_WELLKNOWN_ENDPOINT, transportCredential, securityContext, securityContext == null ? RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_NONE : (context.SealSecureChannel ? RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_PRIVACY : RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY), timeout); context.PrimaryName = serverName; NrpcRpcAdapter nrpcRpcAdapter = rpc as NrpcRpcAdapter; if (nrpcRpcAdapter != null) { context.rpceTransportContext = nrpcRpcAdapter.rpceClientTransport.Context; } }