/// <summary> /// The NetrServerTrustPasswordsGet method Supported in windows_2000_server_sp4, /// windows_xp, and windows_server_2003, windows_vista, /// windows_server_2008, windows_7, and windows_server_7. /// returns the encrypted current and previous passwords /// for an account in the domain. This method is called /// by a client to retrieve the current and previous account /// passwords from a domain controller. The account name /// requested MUST be the name used when the secure channel /// was created, unless the method is called on a PDC by /// a DC, in which case it can be any valid account name. /// Opnum: 42 /// </summary> /// <param name="TrustedDcName"> /// The custom RPC binding handle, as specified in section /// . /// </param> /// <param name="AccountName"> /// The null-terminated Unicode string that contains the /// name of the client account in the domain for which /// the trust password MUST be returned. In windows, all /// machine account names are the name of the machine with /// a $ (dollar sign) appended. /// </param> /// <param name="SecureChannelType"> /// A NETLOGON_SECURE_CHANNEL_TYPE enumerated value, as /// specified in section , that indicates the type of the /// secure channel being established by this call. /// </param> /// <param name="ComputerName"> /// The null-terminated Unicode string that contains the /// NetBIOS name of the client computer. /// </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="EncryptedNewOwfPassword"> /// A pointer to an ENCRYPTED_NT_OWF_PASSWORD structure, /// as specified in section , that contains the NTOWFv1 /// (as specified in NTLM v1 Authentication in [MS-NLMP] /// section) of the current password, encrypted as specified /// in [MS-SAMR] section , Encrypting an NT Hash or LM /// Hash Value with a Specified Key. The session key is /// the specified 16-byte key that is used to derive the /// password's keys. The specified 16-byte key uses the /// 16-byte value process, as specified in [MS-SAMR] section /// . /// </param> /// <param name="EncryptedOldOwfPassword"> /// A pointer to an ENCRYPTED_NT_OWF_PASSWORD structure, /// as specified in section , that contains the NTOWFv1 /// (as specified in NTLM v1 Authentication in [MS-NLMP] /// section) of the previous password, encrypted as specified /// in [MS-SAMR] section , Encrypting an NT Hash or LM /// Hash Value with a Specified Key. The session key is /// the specified 16-byte key that is used to derive the /// password's keys. The specified 16-byte key uses the /// 16-byte value process, as specified in [MS-SAMR] section /// . /// </param> public NtStatus NetrServerTrustPasswordsGet( string TrustedDcName, string AccountName, _NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType, string ComputerName, _NETLOGON_AUTHENTICATOR? Authenticator, out _NETLOGON_AUTHENTICATOR? ReturnAuthenticator, out _NT_OWF_PASSWORD? EncryptedNewOwfPassword, out _NT_OWF_PASSWORD? EncryptedOldOwfPassword) { const ushort opnum = 42; byte[] requestStub; byte[] responseStub; Int3264[] paramList; int retVal; SafeIntPtr pTrustedDcName = Marshal.StringToHGlobalUni(TrustedDcName); SafeIntPtr pAccountName = Marshal.StringToHGlobalUni(AccountName); SafeIntPtr pComputerName = Marshal.StringToHGlobalUni(ComputerName); SafeIntPtr pAuthenticator = TypeMarshal.ToIntPtr(Authenticator); paramList = new Int3264[] { pTrustedDcName, pAccountName, (uint)SecureChannelType, pComputerName, pAuthenticator, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 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); IntPtr pEncryptedNewOwfPassword = outParamList[6]; EncryptedNewOwfPassword = TypeMarshal.ToNullableStruct<_NT_OWF_PASSWORD>(pEncryptedNewOwfPassword); IntPtr pEncryptedOldOwfPassword = outParamList[7]; EncryptedOldOwfPassword = TypeMarshal.ToNullableStruct<_NT_OWF_PASSWORD>(pEncryptedOldOwfPassword); retVal = outParamList[8].ToInt32(); } pTrustedDcName.Dispose(); pAccountName.Dispose(); pComputerName.Dispose(); pAuthenticator.Dispose(); return (NtStatus)retVal; }
/// <summary> /// compute _NT_OWF_PASSWORD that is an ENCRYPTED_NT_OWF_PASSWORD structure, contains the NTOWFv1 (as specified /// in NTLM v1 /// Authentication in [MS-NLMP] section 3.3.1) of the current password, encrypted as specified in /// [MS-SAMR] section 2.2.11.1.1, Encrypting an NT Hash or LM Hash Value with a specified key. /// The session key is the specified 16-byte key that is used to derive the password's keys. The /// specified 16-byte key uses the 16-byte value process, as specified in [MS-SAMR] section 2.2.11.1.4. /// </summary> /// <param name="password">password used to do the compute </param> /// <param name="key">The key used to do encryption, here is sessionkey</param> /// <returns>_NT_OWF_PASSWORD that contains encrypted NTOWFv1 of password </returns> /// <exception cref="ArgumentNullException"> /// Thrown when password is null. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown when key is null. /// </exception> public static _NT_OWF_PASSWORD ComputeEncryptedNtOwfv1Password(string password, byte[] key) { if (password == null) { throw new ArgumentNullException("password"); } if (key == null) { throw new ArgumentNullException("key"); } byte[] ntowfv1Password = NlmpUtility.NtOWF(NlmpVersion.v1, null, null, password); byte[] encryptOwfPassword = EncryptOwfPassword(ntowfv1Password, key); _NT_OWF_PASSWORD ntowfPassword = new _NT_OWF_PASSWORD(); ntowfPassword.data = CreateCypherBlocks(encryptOwfPassword); return ntowfPassword; }
/// <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> /// The NetrServerTrustPasswordsGet method Supported in windows_2000_server_sp4, /// windows_xp, and windows_server_2003, windows_vista, /// windows_server_2008, windows_7, and windows_server_7. /// returns the encrypted current and previous passwords /// for an account in the domain. This method is called /// by a client to retrieve the current and previous account /// passwords from a domain controller. The account name /// requested MUST be the name used when the secure channel /// was created, unless the method is called on a PDC by /// a DC, in which case it can be any valid account name. /// Opnum: 42 /// </summary> /// <param name="trustedDcName"> /// The custom RPC binding handle. /// </param> /// <param name="accountName"> /// The null-terminated Unicode string that contains the /// name of the client account in the domain for which /// the trust password MUST be returned. In windows, all /// machine account names are the name of the machine with /// a $ (dollar sign) appended. /// </param> /// <param name="secureChannelType"> /// A NETLOGON_SECURE_CHANNEL_TYPE enumerated value, /// that indicates the type of the /// secure channel being established by this call. /// </param> /// <param name="computerName"> /// The null-terminated Unicode string that contains the /// NetBIOS name of the client computer. /// </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="encryptedNewOwfPassword"> /// A pointer to an ENCRYPTED_NT_OWF_PASSWORD structure, /// that contains the NTOWFv1 /// (as specified in NTLM v1 Authentication in [MS-NLMP]) /// of the current password, encrypted as specified /// in [MS-SAMR], Encrypting an NT Hash or LM /// Hash Value with a Specified Key. The session key is /// the specified 16-byte key that is used to derive the /// password's keys. The specified 16-byte key uses the /// 16-byte value process, as specified in [MS-SAMR]. /// </param> /// <param name="encryptedOldOwfPassword"> /// A pointer to an ENCRYPTED_NT_OWF_PASSWORD structure, /// that contains the NTOWFv1 /// (as specified in NTLM v1 Authentication in [MS-NLMP]) /// of the previous password, encrypted as specified /// in [MS-SAMR], Encrypting an NT Hash or LM /// Hash Value with a Specified Key. The session key is /// the specified 16-byte key that is used to derive the /// password's keys. The specified 16-byte key uses the /// 16-byte value process, as specified in [MS-SAMR]. /// </param> /// <returns> /// The method returns 0x00000000 on success; /// otherwise, it returns a nonzero error code. /// </returns> public NtStatus NetrServerTrustPasswordsGet( string trustedDcName, string accountName, _NETLOGON_SECURE_CHANNEL_TYPE secureChannelType, string computerName, _NETLOGON_AUTHENTICATOR? authenticator, out _NETLOGON_AUTHENTICATOR? returnAuthenticator, out _NT_OWF_PASSWORD? encryptedNewOwfPassword, out _NT_OWF_PASSWORD? encryptedOldOwfPassword) { NtStatus status = rpc.NetrServerTrustPasswordsGet( trustedDcName, accountName, secureChannelType, computerName, authenticator, out returnAuthenticator, out encryptedNewOwfPassword, out encryptedOldOwfPassword); context.ConnectionStatus = status; return status; }
/// <summary> /// The NetrServerPasswordGet method Supported in windows_2000_server, /// windows_xp, windows_server_2003, windows_vista, windows_server_2008, /// windows_7, and windows_server_7. allows a domain controller /// to get a machine account password from the DC with /// the PDC role in the domain. Opnum: 31 /// </summary> /// <param name="primaryName"> /// The custom RPC binding handle. /// </param> /// <param name="accountName"> /// A null-terminated Unicode string that contains the name /// of the account to retrieve the password for. For machine /// accounts, the account name is the machine name appended /// with a "$" character. /// </param> /// <param name="accountType"> /// A NETLOGON_SECURE_CHANNEL_TYPE enumerated value, /// that describes the secure channel /// to be used for authentication. /// </param> /// <param name="computerName"> /// A null-terminated Unicode string that contains the NetBIOS /// name of the BDC making the call. /// </param> /// <param name="authenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, /// that contains the encrypted /// logon credential and a time stamp. /// </param> /// <param name="returnAuthenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, /// that contains the server return /// authenticator. /// </param> /// <param name="encryptedNtOwfPassword"> /// A pointer to an ENCRYPTED_NT_OWF_PASSWORD structure, /// as specified in [MS-SAMR], that contains the /// OWF password of the account. /// </param> /// <returns> /// The method returns 0x00000000 on success; /// otherwise, it returns a nonzero error code. /// </returns> public NtStatus NetrServerPasswordGet( string primaryName, string accountName, _NETLOGON_SECURE_CHANNEL_TYPE accountType, string computerName, _NETLOGON_AUTHENTICATOR? authenticator, out _NETLOGON_AUTHENTICATOR? returnAuthenticator, out _NT_OWF_PASSWORD? encryptedNtOwfPassword) { NtStatus status = rpc.NetrServerPasswordGet( primaryName, accountName, accountType, computerName, authenticator, out returnAuthenticator, out encryptedNtOwfPassword); context.ConnectionStatus = status; return status; }
/// <summary> /// Decrypt password after calling NetrServerPasswordGet. /// </summary> /// <param name="ntOwfPassword"> /// The password to be decrypted, both input and output. /// </param> /// <exception cref="ArgumentException"> /// Thrown when ntOwfPassword is invalid. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when the method is called before establishing a NRPC secure channel. /// </exception> public void DecryptNtOwfPassword(ref _NT_OWF_PASSWORD ntOwfPassword) { if (ntOwfPassword.data == null || ntOwfPassword.data.Length != 2) { throw new ArgumentException("Invalid NT_OWF_PASSWORD", "ntOwfPassword"); } ValidateSecureChannelExists(); //The client MUST decrypt the EncryptedNtOwfPassword //return parameter using DES in ECB mode [FIPS81] //and the session key established as the decryption key. //TDI 49785, DES key is 8 bytes, but session key is 16 bytes. using (DES des = DES.Create()) { des.Mode = CipherMode.ECB; des.Padding = PaddingMode.None; des.Key = ArrayUtility.SubArray( context.SessionKey, 0, NrpcUtility.NL_CREDENTIAL_LENGTH); ntOwfPassword.data[0].data = des.CreateDecryptor().TransformFinalBlock( ntOwfPassword.data[0].data, 0, ntOwfPassword.data[0].data.Length); } using (DES des = DES.Create()) { des.Mode = CipherMode.ECB; des.Padding = PaddingMode.None; des.Key = ArrayUtility.SubArray( context.SessionKey, NrpcUtility.NL_CREDENTIAL_LENGTH, NrpcUtility.NL_CREDENTIAL_LENGTH); ntOwfPassword.data[1].data = des.CreateDecryptor().TransformFinalBlock( ntOwfPassword.data[1].data, 0, ntOwfPassword.data[1].data.Length); } }