NTLM认证过程分析,以及过某些代理后无法认证问题解决方法。

  • A+
所属分类:系统文档

前一阵子遇到了一个NTLM认证的问题,解决问题的同时就顺带了解了一下NTLM的认证过程。

顺便也把我遇到的问题写出来。

 

正常情况下NTLM的认证过程:

1: C –> S GET/POST …

2: C <– S 401 Unauthorized

WWW-Authenticate: NTLM

3: C –> S GET/POST …

Authorization: NTLM

4: C <– S 401 Unauthorized

WWW-Authenticate: NTLM

5: C –> S GET/POST …

Authorization: NTLM

6: C <—S Ok

以下以一台PC直接登陆,且成功登陆为例:

1: C –> S POST …

wps_clip_image-31929

客户端发请求访问

 

2: C <– S 401 Unauthorized

WWW-Authenticate: NTLM

wps_clip_image-7549

服务器拒绝,返回401.2,提示不可匿名访问,需要认证,并声明是NTLM认证

 

3: C –> S POST …

Authorization: NTLM

wps_clip_image-12420

客户端将自己的NTLM代码发给服务器,其中代码中包含加密的用户名和密码

 

4: C <– S 401 Unauthorized

WWW-Authenticate: NTLM

wps_clip_image-11752

服务器返回401.1,发起Chanllenge,使用保存在服务器端的用户名密码生成加密的代码发给客户端,请求客户端解析

 

5: C –> S GET …

Authorization: NTLM

wps_clip_image-3846

客户端使用服务器发起的Chanllenge代码与自己的认证信息进行回应(如果回应正确则认证通过)

 

6: C <– S Ok

wps_clip_image-10687

认证通过,服务器返回302跳转,页面跳转至网站内部,整个认证过程结束。

按照服务器的提示,整个流程为:

1: C –> S POST …

2: C <– S 401.2 Unauthorized

WWW-Authenticate: NTLM

3: C –> S POST…

Authorization: NTLM

4: C <– S 401.1 Unauthorized

WWW-Authenticate: NTLM

5: C –> S POST…

Authorization: NTLM

6: C <—S 302

 

 

我在工作中遇到的问题是,过代理之后无法通过服务器的NTLM认证。

也就是说,我在PC上配置了一个代理,通过代理访问一个需要NTLM认证的网站。

 

 

 

首先,按照正常情况下NTLM的认证过程模板

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 Ok(出错就在这一步)

 

从抓包分析(以下仅分析从代理到服务器的数据包,未分析PC到代理的数据包):

1: C –> S GET …

image002

客户端发请求访问

2: C <– S 401 Unauthorized

WWW-Authenticate: NTLM

image004

服务器拒绝,返回401.2,提示不可匿名访问,需要认证,并声明是NTLM认证

3: C –> S GET …

Authorization: NTLM

image006

客户端将自己的NTLM代码发给服务器,其中代码中包含加密的用户名和密码

4: C <– S 401 Unauthorized

WWW-Authenticate: NTLM

image008

服务器返回401.1,发起Chanllenge,使用保存在服务器端的用户名密码生成加密的代码发给客户端,请求客户端解析

5: C –> S GET …

Authorization: NTLM

image010

客户端使用服务器发起的Chanllenge代码与自己的认证信息进行回应(如果回应正确则认证通过)

6: C <– S

image012

认证失败!

 

整个流程,直通和代理都没有区别。

唯一的几点区别以及NTLM的特性:

1、 网上的资料说,NTLM认证的关键在于“Connection: Keep-Alive”。每次会话生成的认证信息都是不同的。

即:第三步,客户端生成的均为“NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFASgKAAAADw==”,每次都相同

服务器则是:

“TlRMTVNTUAACAAAAEAAQADgAAAAFgomi2NVi54k850UAAAAAAAAAAIoAigBIAAAABQLODgAAAA9DAE4ATwBPAEMARwBBAFMAAgAQAEMATgBPAE8AQwBHAEEAUwABAAwATQBPAFMAUwAtADEABAAYAGMAbgBvAG8AYwBnAGEAcwAuAGMAbwBtAAMAJgBNAE8AUwBTAC0AMQAuAGMAbgBvAG8AYwBnAGEAcwAuAGMAbwBtAAUAGABjAG4AbwBvAGMAZwBhAHMALgBjAG8AbQAAAAAA”

“TlRMTVNTUAACAAAAEAAQADgAAAAFgomiEMrdcmTWLkwAAAAAAAAAAIoAigBIAAAABQLODgAAAA9DAE4ATwBPAEMARwBBAFMAAgAQAEMATgBPAE8AQwBHAEEAUwABAAwATQBPAFMAUwAtADEABAAYAGMAbgBvAG8AYwBnAGEAcwAuAGMAbwBtAAMAJgBNAE8AUwBTAC0AMQAuAGMAbgBvAG8AYwBnAGEAcwAuAGMAbwBtAAUAGABjAG4AbwBvAGMAZwBhAHMALgBjAG8AbQAAAAAA”

“TlRMTVNTUAACAAAAEAAQADgAAAAFgomieRl6vsRLLukAAAAAAAAAAIoAigBIAAAABQLODgAAAA9DAE4ATwBPAEMARwBBAFMAAgAQAEMATgBPAE8AQwBHAEEAUwABAAwATQBPAFMAUwAtADEABAAYAGMAbgBvAG8AYwBnAGEAcwAuAGMAbwBtAAMAJgBNAE8AUwBTAC0AMQAuAGMAbgBvAG8AYwBnAGEAcwAuAGMAbwBtAAUAGABjAG4AbwBvAGMAZwBhAHMALgBjAG8AbQAAAAAA”

每次都不同,也就是说不同的会话有不同的认证信息。(微软的认证系统靠抓包回放是攻不破了

2、 不经过代理的时候,整个认证过程只有一条连接:

image002[4]

这条连接一直持续到整个认证过程结束都没有断。

而经过代理时,整个过程被分成了很多条连接:

image004[4]

每一条连接都仅完成一次POST,即12、34、56。整个流程从正常的一段,被分解成了3段。

虽然我们的请求里都包含“keep-alive”(不过是小写的!),但是每条连接之后都被reset了

image006[4]

 

分析:

首先由于NTLM的认证需要Keep-Alive,所以如果在第4步被reset了,就会导致第四步由服务器生成的WWW-Authenticate失效,这样第五步发出的Authorization就是过期的,进而导致认证失败。

那么,代理的会话被reset就是罪魁祸首,如果代理能和pc直通一样,与服务器保持Keep-Alive,问题就能解决。

 

检查了代理引擎关于NTLM的代码,发现这个代理引擎在访问需要NTLM认证服务器的时候,会自己把链接断开,也就是说上面的分析是正确的。

改写了代码让代理引擎保证Keep-Alive,问题修复。

 

参考资料:http://www.blogjava.net/security/archive/2008/11/18/38717.html

与本文不同的是,资料上都是GET,本文都是POST。不影响分析逻辑。

FROM:

https://blog.catscarlet.com/201305161297.html

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: