NTLM 认证 HTTP
NTLM是NT LAN Manager的缩写。NTLM是Windows NT早期版本的标准安全协议。该协议有时也称为NT challenge/response(NTCR)协议。
这里有一点要注意该scheme不是一个http认证scheme,而是一个connection认证scheme,虽然它使用http状态码和http头。
NTLM的握手过程:
当一个客户端需要使用NTLM scheme向一个Proxy或server进行认证时,会进行如下握手:
1. C ---> S GET...
2. C <--- S 401 Unauthorized
WWW-Authenticate: NTLM
3. C ---> S GET...
Authorization: NTLM <base64-encoded type-1-message>
4. C <--- S 401 Unauthorized
WWW-Authenticate: NTLM<base64-encoded type-2-message>
5. C ---> S GET...
Authorization: NTLM <base64-encoded type-3-message>
6. C <--- S 200 Ok
在握手过程中,发送的messages均为二进制结构.
Type-1-Message:
结构如下:
struct {
byte protocol[8]; // 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
byte type; // 0x01
byte zero[3];
short flags; // 0xb203
byte zero[2];
short dom_len; // domain string length
short dom_len; // domain string length
short dom_off; // domain string offset
byte zero[2];
short host_len; // host string length
short host_len; // host string length
short host_off; // host string offset (always 0x20)
byte zero[2];
byte host[*]; // host string (ASCII)
byte dom[*]; // domain string (ASCII)
} type-1-message
内存布局:
0 1 2 3
+-------+-------+-------+-------+
0: | 'N' | 'T' | 'L' | 'M' |
+-------+-------+-------+-------+
4: | 'S' | 'S' | 'P' | 0 |
+-------+-------+-------+-------+
8: | 1 | 0 | 0 | 0 |
+-------+-------+-------+-------+
12: | 0x03 | 0xb2 | 0 | 0 |
+-------+-------+-------+-------+
16: | domain length | domain length |
+-------+-------+-------+-------+
20: | domain offset | 0 | 0 |
+-------+-------+-------+-------+
24: | host length | host length |
+-------+-------+-------+-------+
28: | host offset | 0 | 0 |
+-------+-------+-------+-------+
32: | host string | //主机名和域名是ascII,大写,非null结尾。
+ +
. .
. .
+ +-----------------+
| | domain string |
+-------------+ +
. .
. .
+-------+-------+-------+-------+
Type-2-Message:
结构如下:
struct {
byte protocol[8]; // 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
byte type; // 0x02
byte zero[7];
short msg_len; // 0x28
byte zero[2];
short flags; // 0x8201
byte zero[2];
byte nonce[8]; // nonce
byte zero[8];
} type-2-message
内存布局:
0 1 2 3
+-------+-------+-------+-------+
0: | 'N' | 'T' | 'L' | 'M' |
+-------+-------+-------+-------+
4: | 'S' | 'S' | 'P' | 0 |
+-------+-------+-------+-------+
8: | 2 | 0 | 0 | 0 |
+-------+-------+-------+-------+
12: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
16: | message len | 0 | 0 | //这里的message len指完整message的长度,一般为40
+-------+-------+-------+-------+
20: | 0x01 | 0x82 | 0 | 0 |
+-------+-------+-------+-------+
24: | |
+ server nonce | //这里的nonce用来在客户端生成LanManager和NT responses。
28: | |
+-------+-------+-------+-------+
32: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
36: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
Type-3-Message:
结构如下:
struct {
byte protocol[8]; // 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
byte type; // 0x03
byte zero[3];
short lm_resp_len; // LanManager response length (always 0x18)
short lm_resp_len; // LanManager response length (always 0x18)
short lm_resp_off; // LanManager response offset
byte zero[2];
short nt_resp_len; // NT response length (always 0x18)
short nt_resp_len; // NT response length (always 0x18)
short nt_resp_off; // NT response offset
byte zero[2];
short dom_len; // domain string length
short dom_len; // domain string length
short dom_off; // domain string offset (always 0x40)
byte zero[2];
short user_len; // username string length
short user_len; // username string length
short user_off; // username string offset
byte zero[2];
short host_len; // host string length
short host_len; // host string length
short host_off; // host string offset
byte zero[6];
short msg_len; // message length
byte zero[2];
short flags; // 0x8201
byte zero[2];
byte dom[*]; // domain string (unicode UTF-16LE)
byte user[*]; // username string (unicode UTF-16LE)
byte host[*]; // host string (unicode UTF-16LE)
byte lm_resp[*]; // LanManager response
byte nt_resp[*]; // NT response
} type-3-message
内存布局:
0 1 2 3
+-------+-------+-------+-------+
0: | 'N' | 'T' | 'L' | 'M' |
+-------+-------+-------+-------+
4: | 'S' | 'S' | 'P' | 0 |
+-------+-------+-------+-------+
8: | 3 | 0 | 0 | 0 |
+-------+-------+-------+-------+
12: | LM-resp len | LM-Resp len |
+-------+-------+-------+-------+
16: | LM-resp off | 0 | 0 |
+-------+-------+-------+-------+
20: | NT-resp len | NT-Resp len |
+-------+-------+-------+-------+
24: | NT-resp off | 0 | 0 |
+-------+-------+-------+-------+
28: | domain length | domain length |
+-------+-------+-------+-------+
32: | domain offset | 0 | 0 |
+-------+-------+-------+-------+
36: | user length | user length |
+-------+-------+-------+-------+
40: | user offset | 0 | 0 |
+-------+-------+-------+-------+
44: | host length | host length |
+-------+-------+-------+-------+
48: | host offset | 0 | 0 |
+-------+-------+-------+-------+
52: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
56: | message len | 0 | 0 |
+-------+-------+-------+-------+
60: | 0x01 | 0x82 | 0 | 0 |
+-------+-------+-------+-------+
64: | domain string |
+ + //主机,域名和用户名字符串为Unicode(UTF-16 LE)
. .
. .
+ +-------------------+
| | user string |
+-----------+ +
. .
. .
+ +-------------+
| | host string |
+-----------------+ +
. .
. .
+ +---------------------------+
| | LanManager-response |
+---+ + //response的长度为24
. .
. .
+ +------------------+
| | NT-response |
+------------+ +
. .
. .
+-------+-------+-------+-------+
下面举个例子:
主机名为LightCity,NT域名为Ursa-Minor,用户为Zaphod,密码为Beeblebrox,服务器发回nonce为SrvNonce:
C -> S GET ...
S -> C 401 Unauthorized
WWW-Authenticate: NTLM
C -> S GET ...
Authorization: NTLM TlRMTVNTUAABAAAAA7IAAAoACgApAAAACQAJACAAAABMSUdIVENJVFlVUlNBLU1JTk9S
S -> C 401 Unauthorized
WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAACgAAAABggAAU3J2Tm9uY2UAAAAAAAAAAA==
C -> S GET ...
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAHIAAAAYABgAigAAABQAFABAAAAADAAMAFQAAAASABIAYAAAAAAAAACiAAAAAYIAAFUAUgBTAEEALQBNAEkATgBPAFIAWgBhAHAAaABvAGQATABJAEcASABUAEMASQBUAFkArYfKbe/jRoW5xDxHeoxC1gBmfWiS5+iX4OAN4xBKG/IFPwfH3agtPEia6YnhsADT
S -> C 200 Ok
对应的message如下:
Type-1 Message:
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
0: 4e 54 4c 4d 53 53 50 00 01 00 00 00 03 b2 00 00 "NTLMSSP........."
10: 0a 00 0a 00 29 00 00 00 09 00 09 00 20 00 00 00 "....)....... ..."
20: 4c 49 47 48 54 43 49 54 59 55 52 53 41 2d 4d 49 "LIGHTCITYURSA-MI"
30: 4e 4f 52 "NOR"
Type-2 Message:
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
0: 4e 54 4c 4d 53 53 50 00 02 00 00 00 00 00 00 00 "NTLMSSP........."
10: 28 00 00 00 01 82 00 00 53 72 76 4e 6f 6e 63 65 "(.......SrvNonce"
20: 00 00 00 00 00 00 00 00 "........"
Type-3 Message:
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
0: 4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00 "NTLMSSP........."
10: 72 00 00 00 18 00 18 00 8a 00 00 00 14 00 14 00 "r..............."
20: 40 00 00 00 0c 00 0c 00 54 00 00 00 12 00 12 00 "@.......T......."
30: 60 00 00 00 00 00 00 00 a2 00 00 00 01 82 00 00 "`..............."
40: 55 00 52 00 53 00 41 00 2d 00 4d 00 49 00 4e 00 "U.R.S.A.-.M.I.N."
50: 4f 00 52 00 5a 00 61 00 70 00 68 00 6f 00 64 00 "O.R.Z.a.p.h.o.d."
60: 4c 00 49 00 47 00 48 00 54 00 43 00 49 00 54 00 "L.I.G.H.T.C.I.T."
70: 59 00 ad 87 ca 6d ef e3 46 85 b9 c4 3c 47 7a 8c "Y....m..F...<Gz."
80: 42 d6 00 66 7d 68 92 e7 e8 97 e0 e0 0d e3 10 4a "B..f}h.........J"
90: 1b f2 05 3f 07 c7 dd a8 2d 3c 48 9a e9 89 e1 b0 "...?....-<H....."
a0: 00 d3 ".."