1 NTLM 协议
1.1 简介
NTLM 协议是一个在微软环境中使用的认证协议。该协议允许用户向服务器证明其身份,以便使用该服务器提供的服务。
有两种认证的场景:
- 工作组环境
- 用户使用服务器本地帐户的密钥。由于服务器在其本地数据库中拥有用户的密钥,能够对用户进行身份验证;
- 域环境
- 在 Active Directory 环境中,用户在身份验证期间使用域帐户,在这种情况下,服务器将向域控发送用户的认证信息。
在这两种情况下,NTLM 认证始于客户和服务器之间的「挑战/响应」机制。
1.2 挑战 - 响应认证机制
挑战/响应机制的目的是为了让服务器验证用户的身份,且不通过网络传输用户密码。整个认证过程有三步。
协商 - Negotiation - type1
- 客户端向服务端发送认证请求( NEGOTIATE_MESSAGE )
挑战 - Challenge - type2
- 服务端向客户端发送 64 位的随机值( CHALLENGE_MESSAGE )
响应 - Response - type3
- 客户端使用其用户的 NT Hash 值对 Challenge 进行加密,并将结果返回给服务端
下图为 1 次 NTLM 认证过程:
为了完成身份验证,服务器只需要检查客户端发送的响应的有效性。
1.3 认证
NT Hash 的计算:
- 先将用户密码转换为十六进制格式。
- 将十六进制格式的密码进行 Unicode 编码。
- 使用 MD4 摘要算法对 Unicode 编码数据进行 Hash 计算
python2 -c 'import hashlib,binascii; print binascii.hexlify(hashlib.new("md4", "p@Assword!123".encode("utf-16le")).digest())'
如前文所述,NTLM 认证有两种不同的场景。
1.3.1 本地账户
在使用本地帐户完成身份验证的场景下,服务器使用用户的密钥或用户密钥的 MD4 散列(NT Hash) 对其发送给客户端的 Challenge 进行加密。 然后它会检查它的操作结果是否等于客户端的响应,证明用户身份。
服务器需要存储本地用户及其密码的哈希值。 此数据库的名称是 SAM(安全帐户管理器)。 SAM 可以在注册表中找到,可以使用 psexec 以 SYSTEM 身份打开它:
psexec.exe -i -s regedit.exe
在 C:\Windows\System32\SAM
下也有一份拷贝。
总结下工作组下的认证流程:
服务器发送一个 Challenge (1) 并且客户端使用其密钥的哈希值加密该质询,然后使用其用户对应的 NT Hash 加密 Challenge 并将其发送回服务器 (2) 。服务器将在其 SAM 中查找用户密码的哈希值 (3) , 并加密之前用这个散列发送的 Challenge (4) ,并将其结果与用户返回的结果进行比较。 如果相同 (5) 则用户已通过身份验证,否则,认证失败。
1.3.2 域账户
当用域帐户进行认证时,用户的 NT Hash 不再存储在服务器上,而是存储在域控制器上。用户要认证的服务器会收到客户端对 Challenge 加密的响应报文,但它不能检查该响应是否有效,因此,服务端需要把验证身份的任务委托给域控制器。
为此,在服务端与域控进行通信时,使用了 Netlogon
服务,该服务能够与域控制器建立安全会话,被称为安全通道( Secure Channel
)。由于服务器知道自己的密钥,而域控制器知道服务器密钥的哈希,服务端与域控之间可以交换会话密钥并安全地通信。
客户端向域控发送 NETLOGON_NETWORK_INFO ,其中主要包括:
typedef struct _NETLOGON_NETWORK_INFO {
NETLOGON_LOGON_IDENTITY_INFO Identity;
LM_CHALLENGE LmChallenge;
STRING NtChallengeResponse;
STRING LmChallengeResponse;
} NETLOGON_NETWORK_INFO,
*PNETLOGON_NETWORK_INFO;
- 客户端用户名 (Identity)
- 服务端向客户端发送的 Challenge (LmChallenge)
- 客户端向服务端发送的 Response (NtChallengeResponse)
域控将在其数据库中查找对应用户的 NT Hash。对于域控制器,用户的数据被存储在 NTDS.DIT
的文件中。一旦检索到 NT Hash,计算 Challenge 的加密值,并将此结果与客户端的响应进行比较。
总结下域环境下的认证流程:
和之前的情况类似,服务器发送一个挑战 (1) ,客户端 jsnow 用 NT Hash 加密,并将它连同它的用户名和域名 (2) 一起发送回服务器。服务器将使用 Netlogon 服务 (3) 将此信息发送到安全通道中的域控制器。域控制器在其 NTDS.DIT 数据库 (4) 中找到用户散列来加密 Challenge,然后将两个结果进行比较。如果是相同的 (5) ,则用户已通过身份验证。 否则认证失败。在这两种情况下,域控制器都会将信息传输到服务器 (6) 。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论