/// <summary> /// The NetrServerPasswordSet method sets a new one-way /// function (OWF) of a password for an account used by /// the domain controller (as detailed in section) for /// setting up the secure channel from the client. Opnum /// : 6 /// </summary> /// <param name="PrimaryName"> /// The custom RPC binding handle, as specified in section /// . /// </param> /// <param name="AccountName"> /// The null-terminated Unicode string that contains the /// name of the account whose password is being changed. In /// windows, all machine account names are the name of /// the machine with a $ (dollar sign) appended. /// </param> /// <param name="SecureChannelType"> /// An enumerated value (specified in section) that indicates /// the type of secure channel used by the client. /// </param> /// <param name="ComputerName"> /// A null-terminated Unicode string that contains the NetBIOS /// name of the client computer calling this method. /// </param> /// <param name="Authenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, as /// specified in section , that contains the client authenticator. /// </param> /// <param name="ReturnAuthenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, as /// specified in section , that contains the server return /// authenticator. /// </param> /// <param name="UasNewPassword"> /// A pointer to an ENCRYPTED_LM_OWF_PASSWORD structure, /// as specified in section and encrypted by the algorithm /// specified in section. /// </param> public NtStatus NetrServerPasswordSet( string PrimaryName, string AccountName, _NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType, string ComputerName, _NETLOGON_AUTHENTICATOR? Authenticator, out _NETLOGON_AUTHENTICATOR? ReturnAuthenticator, _LM_OWF_PASSWORD? UasNewPassword) { const ushort opnum = 6; byte[] requestStub; byte[] responseStub; Int3264[] paramList; int retVal; SafeIntPtr pPrimaryName = Marshal.StringToHGlobalUni(PrimaryName); SafeIntPtr pAccountName = Marshal.StringToHGlobalUni(AccountName); SafeIntPtr pComputerName = Marshal.StringToHGlobalUni(ComputerName); SafeIntPtr pAuthenticator = TypeMarshal.ToIntPtr(Authenticator); SafeIntPtr pUasNewPassword = TypeMarshal.ToIntPtr(UasNewPassword); paramList = new Int3264[] { pPrimaryName, pAccountName, (uint)SecureChannelType, pComputerName, pAuthenticator, IntPtr.Zero, pUasNewPassword, 0 // retVal }; requestStub = RpceStubEncoder.ToBytes( RpceStubHelper.GetPlatform(), NrpcRpcStubFormatString.TypeFormatString, new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) }, NrpcRpcStubFormatString.ProcFormatString, NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum], true, paramList); rpceClientTransport.Call(opnum, requestStub, rpceTimeout, out responseStub); using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList( RpceStubHelper.GetPlatform(), NrpcRpcStubFormatString.TypeFormatString, new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) }, NrpcRpcStubFormatString.ProcFormatString, NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum], true, responseStub, paramList)) { IntPtr pReturnAuthenticator = outParamList[5]; ReturnAuthenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(pReturnAuthenticator); retVal = outParamList[7].ToInt32(); } pPrimaryName.Dispose(); pAccountName.Dispose(); pComputerName.Dispose(); pAuthenticator.Dispose(); pUasNewPassword.Dispose(); return (NtStatus)retVal; }
/// <summary> /// The NetrServerPasswordSet method sets a new one-way /// function (OWF) of a password for an account used by /// the domain controller for /// setting up the secure channel from the client. Opnum: 6 /// </summary> /// <param name="primaryName"> /// The custom RPC binding handle. /// </param> /// <param name="accountName"> /// The null-terminated Unicode string that contains the /// name of the account whose password is being changed. In /// windows, all machine account names are the name of /// the machine with a $ (dollar sign) appended. /// </param> /// <param name="secureChannelType"> /// An enumerated value that indicates /// the type of secure channel used by the client. /// </param> /// <param name="computerName"> /// A null-terminated Unicode string that contains the NetBIOS /// name of the client computer calling this method. /// </param> /// <param name="authenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, /// that contains the client authenticator. /// </param> /// <param name="returnAuthenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, /// that contains the server return /// authenticator. /// </param> /// <param name="uasNewPassword"> /// A pointer to an ENCRYPTED_LM_OWF_PASSWORD structure, /// and encrypted. /// </param> /// <returns> /// The method returns 0x00000000 on success; /// otherwise, it returns a nonzero error code. /// </returns> public NtStatus NetrServerPasswordSet( string primaryName, string accountName, _NETLOGON_SECURE_CHANNEL_TYPE secureChannelType, string computerName, _NETLOGON_AUTHENTICATOR? authenticator, out _NETLOGON_AUTHENTICATOR? returnAuthenticator, _LM_OWF_PASSWORD? uasNewPassword) { NtStatus status = rpc.NetrServerPasswordSet( primaryName, accountName, secureChannelType, computerName, authenticator, out returnAuthenticator, uasNewPassword); context.ConnectionStatus = status; return status; }
/// <summary> /// Encrypt LM_OWF_PASSWORD and NT_OWF_PASSWORD by RC4 and session key. /// </summary> /// <param name="lmOwfPassword">LM_OWF_PASSWORD</param> /// <param name="ntOwfPassword">NT_OWF_PASSWORD</param> /// <exception cref="InvalidOperationException"> /// Thrown when the method is called before establishing a NRPC secure channel.<para/> /// Thrown when neither AES nore RC4 is negotiated. /// </exception> private void EncryptLmAndNtOwfPassword( ref _LM_OWF_PASSWORD lmOwfPassword, ref _NT_OWF_PASSWORD ntOwfPassword) { if (lmOwfPassword.data == null || lmOwfPassword.data.Length != 2) { throw new ArgumentException("lmOwfPassword is invalid", "lmOwfPassword"); } if (ntOwfPassword.data == null || ntOwfPassword.data.Length != 2) { throw new ArgumentException("ntOwfPassword is invalid", "ntOwfPassword"); } ValidateSecureChannelExists(); //For all versions of Windows except Windows NT 3.1, //encrypt by using RC4 and the session key. byte[] lmOwf = ArrayUtility.ConcatenateArrays( lmOwfPassword.data[0].data, lmOwfPassword.data[1].data); byte[] ntOwf = ArrayUtility.ConcatenateArrays( ntOwfPassword.data[0].data, ntOwfPassword.data[1].data); bool isAesNegotiated = IsAesOrRc4Negotiated(); lmOwf = NrpcUtility.EncryptBuffer(isAesNegotiated, context.SessionKey, lmOwf); ntOwf = NrpcUtility.EncryptBuffer(isAesNegotiated, context.SessionKey, ntOwf); lmOwfPassword.data = NrpcUtility.CreateCypherBlocks(lmOwf); ntOwfPassword.data = NrpcUtility.CreateCypherBlocks(ntOwf); }
/// <summary> /// Encrypt password before calling NetrServerPasswordSet. /// </summary> /// <param name="password"> /// The password to be encrypted. /// </param> /// <returns> /// A LM_OWF_PASSWORD struct with encrypted password. /// </returns> /// <exception cref="ArgumentNullException"> /// Thrown when password is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when SAMR failed to encrypt password. /// Thrown when the method is called before establishing a NRPC secure channel. /// </exception> public _LM_OWF_PASSWORD EncryptUasNewPassword(string password) { if (password == null) { throw new ArgumentNullException("password"); } ValidateSecureChannelExists(); //Compute the NTOWFv1 ([MS-NLMP] section 3.3.1) of the new password. byte[] ntOwfV1 = NlmpUtility.NtOWF(NlmpVersion.v1, null, null, password); //Encrypt ([MS-SAMR] section 2.2.11.1.1) the result of step 1 using //the Session-Key for the secure channel as the Specified Key. _ENCRYPTED_LM_OWF_PASSWORD samrEncryptedLmOwfPassword = SamrCryptography.EncryptBlockWithKey(ntOwfV1, context.SessionKey); if (samrEncryptedLmOwfPassword.data == null && samrEncryptedLmOwfPassword.data.Length != NrpcUtility.OWF_PASSWORD_LENGTH) { throw new InvalidOperationException("SAMR failed to encrypt LM_OWF_PASSWORD."); } _LM_OWF_PASSWORD encryptedLmOwfPassword = new _LM_OWF_PASSWORD(); encryptedLmOwfPassword.data = NrpcUtility.CreateCypherBlocks(samrEncryptedLmOwfPassword.data); return encryptedLmOwfPassword; }