Refer to http://davenport.sourceforge.net/ntlm.html and wget source code
NTLM 认证流程:
Connecting to 172.20.168.88:80... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Creating a type-1 NTLM message.
TYPE1_MSG=NTLM TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA=
Reusing existing connection to 172.20.168.88:80.
HTTP request sent, awaiting response... 401 Unauthorized
TYPE2_MSG=TlRMTVNTUAACAAAAAAAAADgAAAACAgACjjnPlWOz9zgAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=
Creating a type-3 NTLM message.
TYPE3_MSG=NTLM TlRMTVNTUAADAAAAGAAYAFAAAAAYABgAaAAAAAgACABAAAAACAAIAEgAAAAAAAAAUAAAAAAAAACAAAAAAYIAAHF1Y
W50YWNuOTUwODMxMDHnTb3gPjCDB/OLXKSIjBeGL0AIsN4D/TWMw9CSzo44hAsR7M+zrOLPRTQcOUsafeI=
Reusing existing connection to 172.20.168.88:80.
HTTP request sent, awaiting response... 302 Object moved
Location: http://172.20.168.53 [following]
--2011-10-13 12:42:36-- http://172.20.168.53/
Connecting to 172.20.168.53:80... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Creating a type-1 NTLM message.
TYPE1_MSG=NTLM TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA=
Reusing existing connection to 172.20.168.53:80.
HTTP request sent, awaiting response... 401 Unauthorized
TYPE2_MSG=TlRMTVNTUAACAAAACAAIADgAAAAGAoECkSVpVi+DIRgAAAAAAAAAAJoAmgBAAAAABgGwHQAAAA9SU1FVQU5UQQIAEABSAFM
AUQBVAEEATgBUAEEAAQAOAFEAUwBNAEMASABSADIABAAYAFIAUwBRAHUAYQBuAHQAYQAuAGMAbwBtAAMAKABxAHMAbQBjAGgAcgAyAC4A
UgBTAFEAdQBhAG4AdABhAC4AYwBvAG0ABQAYAFIAUwBRAHUAYQBuAHQAYQAuAGMAbwBtAAcACABpFEqgYonMAQAAAAA=
Creating a type-3 NTLM message.
TYPE3_MSG=NTLM TlRMTVNTUAADAAAAGAAYAFAAAAAYABgAaAAAAAgACABAAAAACAAIAEgAAAAAAAAAUAAAAAAAAACAAAAAAYIAAHF1YW50YWNuOTUwODMx
MDHDmh1xv/Uoz9B6TWUTOBCxIOjUpN7/8iejYOfw40MUOlXE7hY6iQbd8wENqrnDLnY=
Reusing existing connection to 172.20.168.53:80.
HTTP request sent, awaiting response... 302 Object moved
Location: http://qsmchr5/hrui/webui/ [following]
--2011-10-13 12:42:36-- http://qsmchr5/hrui/webui/
Resolving qsmchr5 (qsmchr5)... 172.20.168.88
Connecting to qsmchr5 (qsmchr5)|172.20.168.88|:80... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Creating a type-1 NTLM message.
TYPE1_MSG=NTLM TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA=
Reusing existing connection to qsmchr5:80.
HTTP request sent, awaiting response... 401 Unauthorized
TYPE2_MSG=TlRMTVNTUAACAAAAAAAAADgAAAACAgACdZNyW+yWh0oAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=
Creating a type-3 NTLM message.
TYPE3_MSG=NTLM TlRMTVNTUAADAAAAGAAYAFAAAAAYABgAaAAAAAgACABAAAAACAAIAEgAAAAAAAAAUAAAAAAAAACAAAAAAYIAAHF1YW50YWNuOTUwODMxM
DER6h6SH+Dq3dFaDlrvwP+Ukeqq8wCx5uHDUXpv0oOrvBcq/HFWJx0F0HBVXZvu6t8=
Reusing existing connection to qsmchr5:80.
HTTP request sent, awaiting response... 200 OK
NTLM 编码规则:
TYPE1 -
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
domain length = SHORTPAIR(domain length)
host offset = 32
domain offset = hostoff + hostlen
[0x00 - 0x07] 0x4e 0x54 0x4c 0x4d 0x53 0x53 0x50 0x00 # NTLMSSP\0
[0x08 - 0x0f] 0x01 0x00 0x00 0x00 0x02 0x02 0x00 0x00 # 32 bit type = 1, 32 bit NTLM flag field:
# Negotiate NTLM (0x00000200)| Negotiate OEM (0x00000002)
[0x10 - 0x17] 0x00 0x00 0x00 0x00 0x20 0x00 0x00 0x00 # domain length[2], domain space[2],
# domain offset[2], zero[2]
[0x18 - 0x1f] 0x00 0x00 0x00 0x00 0x20 0x00 0x00 0x00 # host length[2], host space[2], host offset[2], zero[2]
00000000 4e 54 4c 4d 53 53 50 00 01 00 00 00 02 02 00 00 |NTLMSSP.........|
00000010 00 00 00 00 20 00 00 00 00 00 00 00 20 00 00 00 |.... ....... ...|
BASE64_STRING: TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA=
======================
TYPE2 -
[0x00 - 0x07] 0x4e 0x54 0x4c 0x4d 0x53 0x53 0x50 0x00 # NTLMSSP\0
[0x08 - 0x0b] 0x02 0x00 0x00 0x00 # 32 bit type = 2
[0x0c - 0x13] 0x00 0x00 0x00 0x00 0x38 0x00 0x00 0x00 # Target Name Security Buffer
# (length[2]=0, space[2]=0, offset[4]=0x38)
[0x14 - 0x17] 0x02 0x02 0x00 0x02 # 32 bit NTLM flag field
[0x18 - 0x1f] 0x8e 0x39 0xcf 0x95 0x63 0xb3 0xf7 0x38 # The nonce randomly generated
[0x20 - 0x27] 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # Context
[0x28 - 0x2f] 0x00 0x00 0x00 0x00 0x38 0x00 0x00 0x00 # Target Information Security Buffer
# (length[2]=0, space[2]=0, offset[4]=0x38)
[0x30 - 0x37] 0x05 0x02 0xce 0x0e 0x00 0x00 0x00 0x0f # start of data block
00000000 4e 54 4c 4d 53 53 50 00 02 00 00 00 00 00 00 00 |NTLMSSP.........|
00000010 38 00 00 00 02 02 00 02 8e 39 cf 95 63 b3 f7 38 |8........9..c..8|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 38 00 00 00 |............8...|
00000030 05 02 ce 0e 00 00 00 0f |........|
BASE64_STRING: TlRMTVNTUAACAAAAAAAAADgAAAACAgACjjnPlWOz9zgAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=
=======================
TYPE3 -
domoff = 64
useroff = domoff + domlen = 64 + 8 (以下例为例) = 72
hostoff = useroff + userlen = 72 + 8 (以下例为例) = 80
lmrespoff = hostoff + hostlen = 80 + 0 = 80
ntrespoff = lmrespoff + 0x18 = 80 + 24 = 104
计算 hash 过的 password: 以 password 为 key, magic 为 message, 加密计算, 过程如下:
setup_des_key: 1qaz2ws => 1QAZ2WS
origin keys= (第一组)
pw1[0] = 31
pw1[1] = 51
pw1[2] = 41
pw1[3] = 5a
pw1[4] = 32
pw1[5] = 57
pw1[6] = 53
pw1[7] = 58
*经过转换 -
(
key[0] = key_56[0];
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
key[7] = (key_56[6] << 1) & 0xFF;
)
KEY1[0] = 31
KEY1[1] = a8
KEY1[2] = 50
KEY1[3] = 2b
KEY1[4] = a3
KEY1[5] = 92
KEY1[6] = 5d
KEY1[7] = a6
*DES_set_odd_parity
@odd_parity=(
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254);
KEY1[0] = 31
KEY1[1] = a8
KEY1[2] = 51
KEY1[3] = 2a
KEY1[4] = a2
KEY1[5] = 92
KEY1[6] = 5d
KEY1[7] = a7
MAG1[0] = 4b
MAG1[1] = 47
MAG1[2] = 53
MAG1[3] = 21
MAG1[4] = 40
MAG1[5] = 23
MAG1[6] = 24
MAG1[7] = 25
*DES 编码 -
LMBUFF1[0] = 77
LMBUFF1[1] = 11
LMBUFF1[2] = 04
LMBUFF1[3] = 12
LMBUFF1[4] = e3
LMBUFF1[5] = 54
LMBUFF1[6] = 4d
LMBUFF1[7] = 2f
(origin key) 第二组
pw2[0] = 58
pw2[1] = 33
pw2[2] = 57
pw2[3] = 53
pw2[4] = 58
pw2[5] = 00
pw2[6] = 00
pw2[7] = 00
* 转换
KEY[0] = 58
KEY[1] = 19
KEY[2] = d5
KEY[3] = ea
KEY[4] = 35
KEY[5] = c0
KEY[6] = 00
KEY[7] = 00
*set_des_odd_parity
KEY[0] = 58
KEY[1] = 19
KEY[2] = d5
KEY[3] = ea
KEY[4] = 34
KEY[5] = c1
KEY[6] = 01
KEY[7] = 01
MAG2[0] = 4b
MAG2[1] = 47
MAG2[2] = 53
MAG2[3] = 21
MAG2[4] = 40
MAG2[5] = 23
MAG2[6] = 24
MAG2[7] = 25
*DES 编码
LMBUFF2[0] = 08
LMBUFF2[1] = 3b
LMBUFF2[2] = 70
LMBUFF2[3] = 34
LMBUFF2[4] = aa
LMBUFF2[5] = fc
LMBUFF2[6] = db
LMBUFF2[7] = ff
组合LMBUFF1, LMBUFF2 成 LMBUFF
LMBUFF[0] = 77
LMBUFF[1] = 11
LMBUFF[2] = 04
LMBUFF[3] = 12
LMBUFF[4] = e3
LMBUFF[5] = 54
LMBUFF[6] = 4d
LMBUFF[7] = 2f
LMBUFF[8] = 08
LMBUFF[9] = 3b
LMBUFF[10] = 70
LMBUFF[11] = 34
LMBUFF[12] = aa
LMBUFF[13] = fc
LMBUFF[14] = db
LMBUFF[15] = ff
LMBUFF[16] = 00
LMBUFF[17] = 00
LMBUFF[18] = 00
LMBUFF[19] = 00
LMBUFF[20] = 00
(End of hash password)
===================================
加密 NONCE
NONCE = \x6b \x4b \xa4 \x59 \xbe \xed \xb7 \x68
KEY[0] = 77
KEY[1] = 11
KEY[2] = 04
KEY[3] = 12
KEY[4] = e3
KEY[5] = 54
KEY[6] = 4d
KEY[7] = 2f
*经过转换 -
(
key[0] = key_56[0];
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
key[7] = (key_56[6] << 1) & 0xFF;
)
KEY2[0] = 77
KEY2[1] = 88
KEY2[2] = 41
KEY2[3] = 82
KEY2[4] = 2e
KEY2[5] = 1a
KEY2[6] = 51
KEY2[7] = 9a
*DES_set_odd_parity
@odd_parity=(
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254);
KEY3[0] = 76
KEY3[1] = 89
KEY3[2] = 40
KEY3[3] = 83
KEY3[4] = 2f
KEY3[5] = 1a
KEY3[6] = 51
KEY3[7] = 9b
*DES 编码 -
RESULT1[0] = 6a
RESULT1[1] = eb
RESULT1[2] = 44
RESULT1[3] = 3d
RESULT1[4] = a7
RESULT1[5] = d6
RESULT1[6] = 24
RESULT1[7] = 3c
(第二组: k2= k1+7)
KEY2[0] = 2f
KEY2[1] = 08
KEY2[2] = 3b
KEY2[3] = 70
KEY2[4] = 34
KEY2[5] = aa
KEY2[6] = fc
KEY2[7] = db
*转换
*set_des_odd_parity
*DES 编码
RESULT2[0] = 78
RESULT2[1] = 1b
RESULT2[2] = 33
RESULT2[3] = ca
RESULT2[4] = 6e
RESULT2[5] = fa
RESULT2[6] = ff
RESULT2[7] = 4a
(第三组 k3 = k1+14)
KEY2[0] = db
KEY2[1] = ff
KEY2[2] = 00
KEY2[3] = 00
KEY2[4] = 00
KEY2[5] = 00
KEY2[6] = 00
KEY2[7] = 00
*转换
*set_des_odd_parity
*DES 编码
RESULT[0] = 20
RESULT[1] = 8d
RESULT[2] = 2e
RESULT[3] = 7d
RESULT[4] = ea
RESULT[5] = 6f
RESULT[6] = 48
RESULT[7] = 1a
lmresp=
0x6a 0xeb 0x44 0x3d 0xa7 0xd6 0x24 0x3c
0x78 0x1b 0x33 0xca 0x6e 0xfa 0xff 0x4a
0x20 0x8d 0x2e 0x7d 0xea 0x6f 0x48 0x1a
[0x00 - 0x07] 0x4e 0x54 0x4c 0x4d 0x53 0x53 0x50 0x00 # NTLMSSP\0
[0x08 - 0x0b] 0x03 0x00 0x00 0x00 # 32 bit type = 3
[0x0c - 0x0f] 0x18 0x00 0x18 0x00 # LanManager response length=SHORTPAIR(0x18), twice
[0x10 - 0x13] 0x50 0x00 0x00 0x00 # LanManager response offset[2]=SHORTPAIR(lmrespoff), zero[2]
[0x14 - 0x17] 0x18 0x00 0x18 0x00 # NT response length=SHORTPAIR(0x18), twice
[0x18 - 0x1b] 0x68 0x00 0x00 0x00 # NT response offset[2]=SHORTPAIR(ntrespoff), zero[2]
[0x1c - 0x1f] 0x08 0x00 0x08 0x00 # domain length, domain space = SHORTPAIR(domlen)
[0x20 - 0x23] 0x40 0x00 0x00 0x00 # domain offset[2]=SHORTPAIR(domoff), zero[2]
[0x24 - 0x27] 0x08 0x00 0x08 0x00 # user length, user space = SHORTPAIR(usrlen)
[0x28 - 0x2b] 0x48 0x00 0x00 0x00 # user offset[2] = SHORTPAIR(useroff), zero[2]
[0x2c - 0x2f] 0x00 0x00 0x00 0x00 # host length, host space = SHORTPAIR(hostlen)
[0x30 - 0x33] 0x50 0x00 0x00 0x00 # host offset[2] = SHORTPAIR(hostoff), zero[2]
[0x34 - 0x37] 0x00 0x00 0x00 0x00 # zero[4]
[0x38 - 0x3b] 0xff 0xff 0x00 0x00 # message length, zero[2]
[0x3c - 0x3f] 0x01 0x82 0x00 0x00 # flags, zero[2]
[0x40 - 0x47] 0x71 0x75 0x61 0x6e 0x74 0x61 0x63 0x6e # domain(quantacn)
[0x48 - 0x4f] 0x39 0x35 0x30 0x38 0x33 0x31 0x30 0x31 # user (95083101)
[0x50 - 0x57] 0xe7 0x4d 0xbd 0xe0 0x3e 0x30 0x83 0x07 # lmresp[00-07]
[0x58 - 0x5f] 0xf3 0x8b 0x5c 0xa4 0x88 0x8c 0x17 0x86 # lmresp[08-15]
[0x60 - 0x67] 0x2f 0x40 0x08 0xb0 0xde 0x03 0xfd 0x35 # lmresp[16-23]
[0x68 - 0x6f] 0x8c 0xc3 0xd0 0x92 0xce 0x8e 0x38 0x84 # ntresp[00-07]
[0x70 - 0x77] 0x0b 0x11 0xec 0xcf 0xb3 0xac 0xe2 0xcf # ntresp[08-15]
[0x78 - 0x7f] 0x45 0x34 0x1c 0x39 0x4b 0x1a 0x7d 0xe2 # ntresp[16-23]
ntlmbuf[0x38] = size & 0xff = 0x80
ntlmbuf[0x39] = size >> 8 = 0x00
00000000 4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00 |NTLMSSP.........|
00000010 50 00 00 00 18 00 18 00 68 00 00 00 08 00 08 00 |P.......h.......|
00000020 40 00 00 00 08 00 08 00 48 00 00 00 00 00 00 00 |@.......H.......|
00000030 50 00 00 00 00 00 00 00 80 00 00 00 01 82 00 00 |P...............|
00000040 71 75 61 6e 74 61 63 6e 39 35 30 38 33 31 30 31 |quantacn95083101|
00000050 e7 4d bd e0 3e 30 83 07 f3 8b 5c a4 88 8c 17 86 |.M..>0....\.....|
00000060 2f 40 08 b0 de 03 fd 35 8c c3 d0 92 ce 8e 38 84 |/@.....5......8.|
00000070 0b 11 ec cf b3 ac e2 cf 45 34 1c 39 4b 1a 7d e2 |........E4.9K.}.|
BASE64_STRING: TlRMTVNTUAADAAAAGAAYAFAAAAAYABgAaAAAAAgACABAAAAACAAIAEgAAAAAAAAAUAAAAAAAAACAAAAAAYIAAHF1YW50YWNuOTU
wODMxMDHnTb3gPjCDB/OLXKSIjBeGL0AIsN4D/TWMw9CSzo44hAsR7M+zrOLPRTQcOUsafeI=