前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >轻松理解 NTLM 协议工作流程

轻松理解 NTLM 协议工作流程

作者头像
信安之路
发布2020-06-16 14:48:10
3K0
发布2020-06-16 14:48:10
举报
文章被收录于专栏:信安之路

NTLM 使用在 Windows NT 和 Windows 2000 Server(or later)工作组环境中(Kerberos 用在域模 式下)。

在 AD 域环境中,如果需要认证 Windows NT 系统,也必须采用 NTLM。相比 Kerberos,基于 NTLM 的认证过程要简单很多。NTLM 采用一种质询/应答(Challenge/Response)消息交换模式,下图是 NTLM 的认证过程:

NTLM 认证协议可以使用在各种协议中,比如 HTTP、SMB 等等,下面以 HTTP 来说明其具体认证流 程:

先来找个目标吧,也可以自己搭建一个基于域的 401 认证服务,我这里测试就找个实际的环境来吧,通 常 exchange 的邮件服务器都会有 ews 的接口,我们可以随便找一个做测试。

在 bing 上使用语法搜一下:

/owa/auth/logon.aspx

找一个邮件服务器是用 exchange 搭建的,并且支持 http 的,因为转包查看的话,https 经过加密的包不太好看,我这找了一个:

http://ex.myhosting.com/ews

开启 wireshark,然后访问上面的连接,随便输入账号和密码,点击登录之后,会得到一些 http 的数据包,如图:

验证流程分三步

第一步:获取服务器的一些基本信息,比如:认证的协议、服务器版本,如图:

第二步:获取服务器返回给客户端的 challenge 值,如图:

这个值在后面的数据校验中会使用,这里先不做过多介绍

第三步:根据前面获取的数据,组合之后提交给服务器,在服务器端进行验证

这里的 NTProofStr 是一个用做数据验签的 hash 值,为了保证前面获取的 challenge 和后面的数据是完整的未经过修改的。

我们把上图中 NTLMv2 的 Response 数值复制处理如下:

c9ce34e95466b7e956dd63da0b17e2e801010000000000008351a367173bd601afd3469d61d432470000000002000800430041004500580001000e0045005800430041005300310032000400140063006100650078002e006c006f00630061006c000300240045005800430041005300310032002e0063006100650078002e006c006f00630061006c000500140063006100650078002e006c006f00630061006c00070008008351a367173bd601060004000200000008003000300000000000000001000000002000002cd5deecf08e9ba9b3e2e91b120999526fba9ded3b72687fcae5218d3b4301120a0010000000000000000000000000000000000009002a0048005400540050002f00650078002e006d00790068006f007300740069006e0067002e0063006f006d000000000000000000

最前面的 32 个字符就是验证数据完整性的 hash 值,也就是 NTProofStr 的值,后面的数据中包含了一些服务器的信息,如图:

这些数据是第三步的请求阶段,也就是客户端提交给服务器的数据,服务器会拿这些数据进行验证,判断是否验证通过。

验签 hash 如何产生

从上面我们没有看到账号密码信息在哪里发挥作用,下面我们来看看具体账号密码在哪里被使用,在哪里发挥作用的。

我们在内网渗透的时候,经常会抓本地密码,本地存储的 hash 就是用户密码经过一系列加密后的结果,具体加密方式如下:

NTLM hash = md4(unicode(hex(password)))

函数解释:hex 为将字符串转为 hex 值、unicode 是将字符串转为双字节字符串、md4 为 md4 hash

用 python 为例来编写关键函数的代码如下:

hex 函数:

代码语言:javascript
复制
def str_to_hex(s):
  return ' '.join([hex(ord(c)).replace('0x', '') for c in s])

转双字节函数:

代码语言:javascript
复制
def hex_to_unicode(hex_str):
  hex_str_ = hex_str.replace(" ","00")+"00"
  return hex_str_

md4 hash 函数:

代码语言:javascript
复制
from Crypto.Hash import MD4
def str_to_md4(str_):
  m = MD4.new()
  m.update(str_)
  return m.hexdigest()

只有密码不行,怎么把用户名和域信息给用上呢?这里就涉及了一个 NTLMv2 HASH ,具体算法如下:

NTLMv2 hash = md5(unicode(hex(upper(username+domain))), ntlm)

关键函数:upper 是将字符串都转为大写字母、md5 就是将 ntlm 的 hash 作为 salt,对用户名和域组合的信息进行 md5 hash

md5 hash 函数:

代码语言:javascript
复制
import hmac
import hashlib
def str_to_hmac_md5(passwd_,salt_):
  h_md5 = hmac.new(salt_, passwd_, hashlib.md5).hexdigest()
  return h_md5

从上面的过程来看,最后得到的 NTLMv2 HASH 就包含了账号、密码、域的信息,有一个因素有问题,那么整个验证就不成功,那么这 hash 在后面怎么用?

服务器如何验证客户端提交的信息

最后一步,客户端提交的信息包括:

签名 hash NTProofStr 用来验证数据完整性,数值为:c9ce34e95466b7e956dd63da0b17e2e8

还有一串数据,在上面已经提供,前面的 32 位的字符串就是上面签名的 hash,去掉之后就是服务器相关的数据,提取出来之后如下:

01010000000000008351a367173bd601afd3469d61d432470000000002000800430041004500580001000e0045005800430041005300310032000400140063006100650078002e006c006f00630061006c000300240045005800430041005300310032002e0063006100650078002e006c006f00630061006c000500140063006100650078002e006c006f00630061006c00070008008351a367173bd601060004000200000008003000300000000000000001000000002000002cd5deecf08e9ba9b3e2e91b120999526fba9ded3b72687fcae5218d3b4301120a0010000000000000000000000000000000000009002a0048005400540050002f00650078002e006d00790068006f007300740069006e0067002e0063006f006d000000000000000000

在之前第二步的时候,获得了一个 challenge 的值: e8fd1257ab09ae57

到这里,该有的数据都有了,那么如何这些数据之间又有什么关系?主要是签名的获取算法,公式如下:

签名数据 NTProofStr = md5(challenge + 数据, NTLMv2 HASH)

理解上也简单,就是将第二步的 challenge 的值和服务器的数据连接起来,用包含账号密码域信息的 hash 作为 salt 进行 md5 哈希之后的结果就是签名的值,我们用一个小巧的计算器来计算下:

以上就是 NTLM 协议组成验证数据的过程,最后数据发送到服务器端,服务器根据提交的数据进行类似的加密验证,从而判断用户提交的凭证是否正确,整个过程保证了认证的安全性。

总结

在服务器端,保存的不是用户的明文密码,而是密码经过 NTLM 加密后的字符串,因为是 hash 算法,所以不可逆,对于 NTLM 的哈希只能进行暴力枚举无法进行解密。

如果 401 认证的服务是 http 的协议,我们可以在流量包中截获相关数据包,比如 challenge 的值、NTLMv2 的返回包、用户名、域名,有了这些信息,就可以通过暴力枚举的方式破解用户的密码,如果 https 协议,我们就无法通过数据包来截获明文的数据包了,所以 https 的是多么重要。

这不是一个攻击的文章,旨在理解 NTLM 这个协议的工作流程,也没有涉及某某字段的意思,想要深入理解的可以自己去找相关资料深入研究。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 验证流程分三步
  • 验签 hash 如何产生
  • 服务器如何验证客户端提交的信息
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档