David.Turing's blog

 

基于NTLM的Proxy认证

以Matrix的Blog为例,截取其中的认证过程进行分析(注意,本文中使用的cookie值已经被处理过,呵呵,别想干坏事握)

测试环境:
域:mydomain.com
域主机:davidturing.mydomain.com
域用户:davidturing@mydomain.com
代理服务器:proxyserver.mydomain.com

1) 登陆Windows域(mydomain.com),用户名为davidturing
2) 打开IE窗口,URL=http://www.matrix.org.cn/blog/cas/,由于公司使用了ProxyServer,员工必须通过ProxyServer才能上网。
于是,IE Client就向Proxyserver请求访问Matrix Blog。
3) Proxy认证使用了NTLM,对IE Client进行认证。
于是,IE(Client)就和ProxyServer(Server)执行下面的三次握手的认证过程。

1: C --> S GET ...

2: C <-- S 401 Unauthorized
WWW-Authenticate: NTLM

3: C --> S GET ...
Authorization: NTLM

4: C <-- S 401 Unauthorized
WWW-Authenticate: NTLM

5: C --> S GET ...
Authorization: NTLM

6: C <-- S 200 Ok

需要指出,NTLM只是两种Windows认证方式中的一种,Kerberos是另外一种,而且更有名,我会为Kerberos认证再写一篇Blog:)

4) 握手的过程被我Sniffer了下来,如下文所示:
/******************
Client->ProxyServer:
******************/
GET http://www.matrix.org.cn/blog/cas HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: zh-cn,en;q=0.8,zh;q=0.5,zh-tw;q=0.3
Cookie: user=cas%3A%3AAq3HtCAsqNlhY%3A%3A1; matrix_user_cookie=Y2FzfDgzMzM4MURELTk17UStMUU4MS05OTJDLTJERDM4RERGNkUyRg==
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Maxthon; .NET CLR 2.0.50215)
Host: www.matrix.org.cn
Proxy-Connection: Keep-Alive

{分析:注意,这是一个很简单的HTTP GET请求,无非是想请求www.matrix.org.cn /blog/cas这张页面}


/******************
ProxyServer-> Client:
******************/
HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires authorization to fulfill the request. Access to the Web Proxy service is denied. )
Via:1.1 PROXYSERVER
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html
Content-Length: 2372



......返回给客户端的HTTP实体,提示页面内容被省略......


{分析:接着,ProxyServer要求我提供认证信息,注意,HTTP 407代码的含义是类似于401,表示客户必须先经过代理服务器的授权。我们还可以看到,Proxy-Authenticate字段里面包含了NTLM,Kerberos,表明可以通过客户端来Negotiate再决定使用两者中的一种}

/******************
Client->ProxyServer:
******************/
GET http://www.matrix.org.cn/blog/cas HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: zh-cn,en;q=0.8,zh;q=0.5,zh-tw;q=0.3
Cookie: user=cas%3A%3AAq3HtCAsqNlhY%3A%3A1; matrix_user_cookie=Y2FzfDgzMzM4MURELTk17UStMUU4MS05OTJDLTJERDM4RERGNkUyRg==
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Maxthon; .NET CLR 2.0.50215)
Host: www.matrix.org.cn
Proxy-Connection: Keep-Alive
Proxy-Authorization: NTLM TlRMTVNTUAABAAAAB4IAogAAAAAAAAAAAA
AAAAAAAAAFAJMIAAAAD2==

{分析:
这里,客户端将自己的NTLM代码发送给服务器,里面包含了一些自己的域帐号发送给ProxyServer,ProxyServer就可以知道用户是谁,然后去域服务器取出用户的域密码,加密一个随机字符串去Challenge用户(见下文)。

在NTLM中,这是三次握手的"第一手"(Type1 Message),目的是Client告诉Server两样东西:
hoststring:即client的主机名(比如davidturing)
domainstring:即client在域中的名(比如davidturing.mydomain.com)

Proxy-Authorization的信息结构如下
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 |
+ +
. .
. .
+ +-----------------+
| | domain string |
+-------------+ +
. .
. .
[如果数据图显示的太丑,可以参考:
http://www.innovation.ch/java/ntlm.html
]
由于截取的信息经过BASE64处理,所以,你不可能肉眼从Proxy-Authorization值中判断出主机名和主机域名:)
}


/******************
ProxyServer-> Client:
******************/
HTTP/1.1 407 Proxy Authentication Required ( ¾Ü¾ø•ÃÎÊ¡£ )
Via:1.1 PROXYSERVER

Proxy-Authenticate:
NTLM TlRMTVNTUAACAAAAGAAYADgAAAAFgoGikmfj
JzhsTW0AAAAAAAAAAIoAigBQAAAABQCTCAAA
AA9IAE4ASQBTAEkALgBDAE8ATQAuAEMATgAC
ABgASABOAEkAUwBJAC4AQwBPAE0ALgBDAE4A
AQAWAFAAUgBPAFgAWQBTAEUAUgBWAEUAUgA
EABgAaABuAGkAcwBpAC4AYwBvAG0ALgBjAG4A
AwAwAHAAcgBvAHgAeQBzAGUAcgB2AGUAcgAuA
GgAbgBpAHMAaQAuAGMAbwBtAC4AYwBuAAAAA
AA=

Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html
Content-Length: 0


{分析:这个步骤中,ProxyServer回应我的IE一个Proxy-Authorization,其值就是上面那段很长的字符,这是一个authcode,目的是Chanllenge客户端(IE)。Chanllenge是对客户端的一种身份挑战,好比方,你说你是张三,OK,服务器用张三的密码加密一段咚咚,你能告诉服务器这段咚咚是什么,服务器就相信你了。

这条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 |
+-------+-------+-------+-------+
20: | 0x01 | 0x82 | 0 | 0 |
+-------+-------+-------+-------+
24: | |
+ server nonce |
28: | |
+-------+-------+-------+-------+
32: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
36: | 0 | 0 | 0 | 0 |
+-------+-------+-------+-------+
里面包含了server nounce值,这个值就是Challenge了。我们需要
根据这个8字节的随机数构造type-3 message。
}

 

/******************
Client->ProxyServer:
******************/
GET http://www.matrix.org.cn/blog/cas HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: zh-cn,en;q=0.8,zh;q=0.5,zh-tw;q=0.3
Proxy-Authorization:
NTLM TlRMTVNTUAADAAAAGAAYAJIAAAAYABgAqgA
AABgAGABIAAAAGAAYAGAAAAAaABoAeAAAA
AAAAADCAAAABYKAogUAkwgAAAAPaABuAGk
AcwBpAC4AYwBvAG0ALgBjAG4AaAB1AGEAbg
BnAHoAaABhAG8AcQBpAG4ASABVAEEATgBHA
FoASABBAE8AUQBJAE4AMQCGRQ1i+bZleAs2A
kgEXS/CfJ3oOrsi6prctAW2HyADaWwbNqmpO1
Eptq7yJUh4SXd=

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Maxthon; .NET CLR 2.0.50215)
Host: www.matrix.org.cn
Proxy-Connection: Keep-Alive
Cookie: user=cas%3A%3AAq3HtCAsqNlhY%3A%3A1; matrix_user_cookie=Y2FzfDgzMzM4MURELTk17UStMUU4MS05OTJDLTJERDM4RERGNkUyRg==


{分析:OK,这里就是IE客户端响应ProxyServer的Chanllenge,上面的NTLM=TIRMT….就是Challenge回应码,如果这段代码正确,ProxyServer就承认用户的身份,就可以让他到访问外网资源。

分析一下这个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 |
+ +
. .
. .
+ +-------------------+
| | user string |
+-----------+ +
. .
. .
+ +-------------+
| | host string |
+-----------------+ +
. .
. .
+ +---------------------------+
| | LanManager-response |
+---+ +
. .
. .
+ +------------------+
| | NT-response |
+------------+ +
. .
. .
+-------+-------+-------+-------+

domain string: 主机域名(如davidturing.mydomain.com)
user string:用户名(davidturing)
LanManager-response: 类DES的散列处理
NT-response:MD4散列处理
详情可参考:
http://samba.kn.vutbr.cz/samba/docs/man/Samba-Developers-Guide/pwencrypt.html
}

/******************
ProxyServer-> Client:
******************/
HTTP/1.1 301 Moved Permanently
Via: 1.1 PROXYSERVER
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 158
Date: Wed, 21 Sep 2005 03:44:57 GMT
Location: http://www.matrix.org.cn/blog//cas/
Content-Type: text/html
Server: Microsoft-IIS/6.0

Object Moved

This document may be found here

{分析:很明显,ProxyServer已经承认了我的身份,并让我访问Matrix了。这里有一个小插曲,Matrix做了重定向(熟悉HTTP协议的人应该知道HTTP 301表示move permanetly,即客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。)比如,如果我们直接访问http://www.matrix.org.cn/blog//cas/,服务器会IE重定向到http://61.142.81.140:9703/blog/cas/,你在页面上不会察觉到这一点。Chris估计是想做备份吧?Blog这东西经常出问题。}

到此,我们已经通过了Proxy认证了,下面的通讯的Traffic我就不想说了,反正就是先取HTML网页,再取网页的Style.css,有一个先后顺序,大家不必关心了。

/******************
Client->ProxyServer:
******************/
GET http://www.matrix.org.cn/blog//cas/ HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: zh-cn,en;q=0.8,zh;q=0.5,zh-tw;q=0.3
If-Modified-Since: Mon, 19 Sep 2005 03:19:14 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Maxthon; .NET CLR 2.0.50215)
Host: www.matrix.org.cn
Proxy-Connection: Keep-Alive
If-None-Match: "ea7c9ee9c8bcc51:10a4"
Cookie: user=cas%3A%3AAq3HtCAsqNlhY%3A%3A1; matrix_user_cookie=Y2FzfDgzMzM4MURELTk17UStMUU4MS05OTJDLTJERDM4RERGNkUyRg==

/******************
ProxyServer-> Client:
******************/
HTTP/1.1 200 OK
Via: 1.1 PROXYSERVER
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 36149
Date: Wed, 21 Sep 2005 03:44:57 GMT
Content-Location: http://www.matrix.org.cn/blog//cas/index.html
Content-Type: text/html
Server: Microsoft-IIS/6.0
Last-Modified: Tue, 20 Sep 2005 14:29:13 GMT
Accept-Ranges: bytes
ETag: "4a5cbacefbdc51:10ce"



....页面内容被省略.........

/******************
Client->ProxyServer:
******************/
GET http://www.matrix.org.cn/blog/cas/styles-site.css HTTP/1.0
Accept: */*
Referer: http://www.matrix.org.cn/blog//cas/
Accept-Language: zh-cn,en;q=0.8,zh;q=0.5,zh-tw;q=0.3
Proxy-Connection: Keep-Alive
If-Modified-Since: Sat, 13 Aug 2005 13:23:57 GMT
If-None-Match: "3cea6142aa0c51:10a4"
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Maxthon; .NET CLR 2.0.50215)
Host: www.matrix.org.cn
Cookie: user=cas%3A%3AAq3HtCAsqNlhY%3A%3A1; matrix_user_cookie=Y2FzfDgzMzM4MURELTk17UStMUU4MS05OTJDLTJERDM4RERGNkUyRg==


/******************
ProxyServer-> Client:
******************/
HTTP/1.1 200 OK
Via: 1.1 PROXYSERVER
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 5379
Date: Wed, 21 Sep 2005 03:44:57 GMT
Content-Type: text/css
Server: Microsoft-IIS/6.0
Last-Modified: Sat, 13 Aug 2005 13:23:57 GMT
Accept-Ranges: bytes
ETag: "3cea6142aa0c51:10ce"

body {
margin:0px 0px 20px 0px;
background:#FFF;
}
A { color: #003366; text-decoration: underline; }
A:link { color: #003366; text-decoration: underline; }
.....styles-site.css内容被省略 .....
padding-right:15px;
padding-top:5px;
padding-bottom:5px;
}

posted on 2006-04-02 12:03 david.turing 阅读(6118) 评论(3)  编辑  收藏

评论

# re: 基于NTLM的Proxy认证 2007-08-31 00:12 aaa

糖果NTLM认证模块
支持ISA Server NTLM认证的dll模块
NTLM是一种比Basic认证更安全的认证技术,使用本模块可以让你的软件用编程的方是通过NTLM认证。
http://www.languangav.com.cn/soft/product.htm  回复  更多评论   

# re: 基于NTLM的Proxy认证 2008-04-17 14:43 wodeyinlimin

我也一直在研究ntlm认证的问题,我写的是java 程序,试图访问外网。
  回复  更多评论   

# re: 基于NTLM的Proxy认证 2008-11-18 12:41 李先生

你好!
你这个过程,是怎么sniffer下来的,我现在在网络上遇到点麻烦,查不出来什么毛病,需要实现这样的功能进行分析一下。lijs007@126.com  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(110)

我参与的团队

随笔分类(126)

随笔档案(155)

文章分类(9)

文章档案(19)

相册

搜索

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜