NTLM协议(二)——无连接认证

上次我们介绍了NTLM协议面向连接认证过程,这次我们将分享NTLM协议无连接认证的过程。

在NTLM无连接认证中:

◆ NTLM不使用NTLM实现中维护的内部序列号(sequence number),而是使用调用NTLM的应用协议传入的序列号。

◆ 在客户端初始化的时候会话安全(Session security)的密钥就生成了。密钥生成之后,会话安全就能够被使用。而面向连接认证的密钥是在认证之后才生成的。

◆ 不需要发送NEGOTIATE消息。

下图是典型的NTLM协议无连接认证的调用流程(call flow)。

咋一看,好像是服务器启动的申请,其实该申请是客户端在应用协议消息中启动的。

  1. Application message(s):表示客户端和服务器之间发送的应用协议消息。
  2. Application message [NTLM_CHALLENGE]:当应用程序程序需要建立认证会话的时候,NTLM协议就会被调用。服务会发送NTLM CHALLENGE_MESSAGE消息到客户端。该消息包括服务器期望的安全特性和服务器产生的随机数(Challenge)。
  3. Application message [NTLM_AUTHENTICATE]:客户端向服务器发送NTLM AUTHENTICATE_MESSAGE消息。该消息包含用户名和Response。这个Response可以证实客户端知道用户的密码。服务器接下来会验证这个Response。假如该用户是本地账户,服务器可以根据本地账户数据库中的信息验证Response。假如该用户是域账户,服务器会将用户认证信息(用户名,服务器发送给客户端的Challenge,客户端发送给服务器的Response)发送给域控制器,由域控制器验证该Response。这时候NTLM协议认证过程完成。
  4. Application message(s):如果Challenge和Response证明客户端知道用户密码,那么认证成功。假如认证失败,服务器可能会以某种方式发送认证失败的状态给应用协议,或者单纯的结束连接。

可能前面讲的都比较抽象,接下来,我们通过一个实例更为详细的解释NTLM无连接认证的整个过程吧。

在Windows集群服务(Cluster)通过数据报文(Datagram)进行的远程调用(RPC)中普遍用到NTLM协议无连接认证。在Windows Server 2003中,该远程调用只会使用NTLM无连接认证,而不会使用Kerberos认证。

下图是Windows集群服务远程调用通信中,NTLM协议无连接认证的流程。


步骤一、客户端(一个集群结点)发送RPC数据包CsRpcGetJoinVersionData给服务器(另一个集群结点)的JoinVersion RPC接口。

备注:没有NTLM NEGOTIATE MESSAGE消息但是有NTLM MESSAGE SIGNATURE消息。因为认证还没有发生,所以这个时候服务器无法验证这个签名。

步骤二、服务器返回RPC数据包ConvWhoAreYouAuth给客户端。这个数据包包含NTLM CHALLENGE_MESSAGE消息。这个消息包含8字节的随机数,即所谓的Challenge。

备注:服务器同时发送详细的认证协议和sign/seal协议。

以下是网络包的一部分,从这个网络包我们可以很清晰的看出这是ConvWhoAreYouAuth数据包,指明了消息类型NTLM CHALLENGE MESSAGE,同时还可以看到具体的Challenge值。

- Conv: ConvWhoAreYouAuth Request, Actuid={EA73110D-4D8B-49BE-AF8A- 92F23777D74C}

  + actuid: {EA73110D-4D8B-49BE-AF8A-92F23777D74C}

    BootTime: 1246080274 (0x4A45AD12)

  - InData:

   + Size: 258 Elements

   - NLMP: NTLM CHALLENGE MESSAGE

      Signature: NTLMSSP

      MessageType: Challenge Message (0x00000002)

    + TargetName: Length: 0, Offset: 56

    + ChallengeFlags: 0xE29882F3 (NTLM v2 128-bit encryption, Always Sign & Seal)

    + Challenge: 43231D3F450C4E02

步骤三、客户端获得Challenge,返回NTLM AUTHENTICATE_MESSAGE消息(同样嵌入在ConvWhoAreYouAuth应答数据包中)。

备注:客户端根据本地配置和服务器提供的信息选择认证协议和sign/seal协议,用密码的哈希值给session key加密,然后附加到NTLM AUTHENTICATE_MESSAGE消息的SessionKeyString字段上。

以下的网络包指明了消息类型,采取的认证协议,以及返回的Response,还有SessionKeyString。

- NLMP: NTLM AUTHENTICATE MESSAGE, Domain: CITMS, User: clussvr1, Workstation: CITM1DX

      Signature: NTLMSSP

      MessageType: Authenticate Message (0x00000003)

    + LmChallengeResponse: Length: 24, Offset: 112

    + NtChallengeResponse: Length: 24, Offset: 136

    + DomainName: Length: 10, Offset: 72

    + UserName: Length: 16, Offset: 82

    + Workstation: Length: 14, Offset: 98

    + SessionKey: Length: 16, Offset: 160

    + AuthenticateFlags: 0x428082D5 (NTLM v1 No encryption, Always Sign)

    + Version: Windows 5.2 Build 52750 NLMPv15

      DomainNameString: CITMS

      UserNameString: clussvr1

      WorkstationString: CITM1DX

    +LmChallengeResponseString: E3F5EE8E771D115AE0B938F8A334B36F6D412B746CF757A3

    +NTLMV1ChallengeResponse: 99E8566B7D6270548579A6FEAFDD5D7CD967C8F043CB8868

    + SessionKeyString: C321EE73BD41BA8DF068FEA9F72AD2C7

步骤四、服务器向客户端发送RPC数据包Acknowledge,让客户端知道服务器已经接收到ConvWhoAreYouAuth应答数据包。

步骤五、服务器使用用户密码的哈希值解密SessionKeyString字段中的session key,然后对步骤一中从客户端发送过来的CsRpcGetJoinVersionData数据包中的数据进行签名。如果两个签名一样,则服务器会对CsRpcGetJoinVersionData数据包进行应答,客户端收到应答之后也会向服务器发送RPC数据包Acknowledge。如果两个签名不一样,服务器会返回错误给客户端。

通过这个例子,您肯定对NTLM无连接认证也有了更深入的理解了吧。好了,今天就分享到这里了,期待下次再见。

谢谢,

屈贝伟 | 企业平台支持部AD技术工程师 | 微软亚太区全球技术支持中心

 

本博文仅供参考,微软公司对其内容不作任何责任担保或权利赋予。