NTLM 认证的过程, Client 需发送或接受三种讯息: Negotiation, Challenge, Authentication, 其过程如下:
1. Client 发送 Negotiation 给 Server, 告知 Server 通讯的信息, 内容含有 NTLM 的表头及 NTLM 标志位, 我们称为 Type 1 Message.
2. Server 在收到 Negotiation 后会随机产生一组长度为 8 bytes 的 NONCE, 并伴随者 Negotiation 所含内容及 Data Block 返回 Client, 这讯息称之为 Type 2 Message.
3. Client 在收到 Challenge 后会以 PASSWORD 当作 KEY 并对 NONCE 进行加密产生两组回应段 - LMRESP 及 NTRESP, 并伴随者 DOMAIN, USER 讯息, 当作身份认证讯息发送给 Server. 这个身份认证的讯息,我们称之为 Type 3 Message.
不管是 Type 1 或 Type 2 或是 Type 3 都是 "NTLM" + Base64 String, 所以如果要还原它们的话, 要先做解码的动作, 在 Perl 上很容易实现这个 Parsing 的动作, 以下为 Perl 的实现代码: decode.pl
#!/usr/bin/perl -w use MIME::Base64; $string = shift; print decode_base64($string);
接着我们实际来看看真实的 Type 1 Message 及其解析出来的内容:
0x08 - 0x0b: Type[4] 是表示 Type 标志 (Type 1: 0x01, Type 2: 0x02, Type 3: 0x03)
0x0c - 0x0f: NTLM_FLAG[4] 是 NTLM 的标志, 在上例中, 其值为 0x0202 是表示 Negotiate NTLM(0x00000200)|Negotiate OEM(0x00000002)
0x10 - 0x11: DOMAIN_LENGTH[2] = ((DOMAIN LENGTH && 0xff), (DOMAIN LENGTH >> 8)), DOMAIN LENGTH = 0, 故其值为 (0, 0)
0x12 - 0x13: DOMAIN_SPACE[2] = DOMAIN_LENGTH[2]
0x14 - 0x15: DOMAIN_OFFSET[2] 是 DOMAIN OFFSET, DOMAIN OFFSET 为 HOST OFFSET + HOST LENGTH, 因 HOST LENGTH = 0 而 HOST OFFSET 固定为 0x20, 所以 DOMAIN OFFSET = 0x20
0x18 - 0x19: HOST_LENGTH[2] = 0
0x1a - 0x1b: HOST_SPACE[2] = HOST_LENGTH[2]
0x1c - 0x1d: HOST_OFFSET[2] = 0x20, 这是固定的值.
当 Server 收到上例由 Client 发送出的讯息时, 会返回 Type 2 Message 给 Client, 以下是截取到的 Type 2 Message:
解析出来可得到下面的内容:
0x08 - 0x0b: Type[4] 是表示 Type 标志 (Type 1: 0x01, Type 2: 0x02, Type 3: 0x03)
0x0c - 0x0d: Target Name Security Buffer Length[2] = 0
0x0e - 0x0f: Target Name Security Buffer Space[2] = 0
0x10 - 0x13: Target Name Security Buffer OFFSET[4] = 0x38, 在 Type 3 中 Data 开始的位置
0x14 - 0x17: NTLM_FLAG[4], NTLM 标示位
0x18 - 0x1f: NONCE[8] Server 产生的 64 bits 乱数
0x20 - 0x27: CONTEXT[8] = 0
0x28 - 0x29: Target Information Security Buffer Length[2] = 0
0x2a - 0x2b: Target Information Security Buffer Space[2] = 0
0x2c - 0x2f: Target Information Security Buffer OFFSET[4] = 0x38
0x30 - 0x37: Data Block[8]
Client 在收到 Challenge 后, 传送含有身分资料的认证包给 Server:
解析后可得内容如下:
0x08 - 0x0b: Type[4] 是表示 Type 标志 (Type 1: 0x01, Type 2: 0x02, Type 3: 0x03)
0x0c - 0x0d: Lan Manager Response Length[2] = 0x18
0x0e - 0x0f: Lan Manager Response Space[2] = 0x18
0x10 - 0x11: Lan Manager Response OFFSET[2] = HOST OFFSET + HOST LENGTH = USER OFFSET + USER LENGTH + HOST LENGTH = DOMAIN OFFSET + DOMAIN LENGTH + USER LENGTH + HOST LENGTH = 0x40 + 0x08 + 0x08 = 0x50
0x14 - 0x15: NT Response Length[2] = 0x18
0x16 - 0x17: NT Response Space[2] = 0x18
0x18 - 0x19: NT Response OFFSET[2] = Lan Manager Response OFFSET + Lan Manager Response Length = 0x50 + 0x18 = 0x68
0x1c - 0x1d: DOMAIN LENGTH[2] = 0x08
0x1e - 0x1f: DOMAIN SPACE[2] = 0x08
0x20 - 0x21: DOMAIN OFFSET[2] = 0x40
0x24 - 0x25: USER LENGTH[2] = 0x08
0x26 - 0x27: USER SPACE[2] = 0x08
0x28 - 0x29: USER OFFSET[2] = DOMAIN OFFSET + DOMAIN LENGTH = 0x40 + 0x08 = 0x48
0x2c - 0x2d: HOST LENGTH[2] = 0
0x2e - 0x2f: HOST SPACE[2] = 0
0x30 - 0x31: HOST OFFSET[2] = USER OFFSET + USER LENGTH = 0x48 + 0x08 = 0x50
0x38 - 0x39: Message Length[2] 整个 Type 3 Message 的长度为 0x80
0x3c - 0x3d: NTLM FLAG[2] = 0x8201, 存放为 0x01 0x82
0x40 - 0x47: DOMAIN[8], 例中 DOMAIN='quantacn'
0x48 - 0x4f: USER[8], 例中 USER='95083101'
0x50 - 0x67: LMRESP[24], LM Response, 这是以 PASSWORD 的形变为 KEY, 再对 Type 2 Message 中的 NONCE 进行加密
0x68 - 0x7f: NTRESP[24], NT Response, 这是将 PASSWORD 进行 MD4 并以此为 KEY, 再对 NONCE 进行加密
至于如何求得 LM Response 及 NT Response 将在下一章节介绍.