NTLM协议(二)——无连接认证
上次我们介绍了NTLM协议面向连接认证过程,这次我们将分享NTLM协议无连接认证的过程。
在NTLM无连接认证中:
◆ NTLM不使用NTLM实现中维护的内部序列号(sequence number),而是使用调用NTLM的应用协议传入的序列号。
◆ 在客户端初始化的时候会话安全(Session security)的密钥就生成了。密钥生成之后,会话安全就能够被使用。而面向连接认证的密钥是在认证之后才生成的。
◆ 不需要发送NEGOTIATE消息。
下图是典型的NTLM协议无连接认证的调用流程(call flow)。
咋一看,好像是服务器启动的申请,其实该申请是客户端在应用协议消息中启动的。
- Application message(s):表示客户端和服务器之间发送的应用协议消息。
- Application message [NTLM_CHALLENGE]:当应用程序程序需要建立认证会话的时候,NTLM协议就会被调用。服务会发送NTLM CHALLENGE_MESSAGE消息到客户端。该消息包括服务器期望的安全特性和服务器产生的随机数(Challenge)。
- Application message [NTLM_AUTHENTICATE]:客户端向服务器发送NTLM AUTHENTICATE_MESSAGE消息。该消息包含用户名和Response。这个Response可以证实客户端知道用户的密码。服务器接下来会验证这个Response。假如该用户是本地账户,服务器可以根据本地账户数据库中的信息验证Response。假如该用户是域账户,服务器会将用户认证信息(用户名,服务器发送给客户端的Challenge,客户端发送给服务器的Response)发送给域控制器,由域控制器验证该Response。这时候NTLM协议认证过程完成。
- 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技术工程师 | 微软亚太区全球技术支持中心
本博文仅供参考,微软公司对其内容不作任何责任担保或权利赋予。