专栏首页信安之路轻松理解 NTLM 协议工作流程

轻松理解 NTLM 协议工作流程

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 函数:

def str_to_hex(s):
  return ' '.join([hex(ord(c)).replace('0x', '') for c in s])

转双字节函数:

def hex_to_unicode(hex_str):
  hex_str_ = hex_str.replace(" ","00")+"00"
  return hex_str_

md4 hash 函数:

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 函数:

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 这个协议的工作流程,也没有涉及某某字段的意思,想要深入理解的可以自己去找相关资料深入研究。

本文分享自微信公众号 - 信安之路(xazlsec),作者:myh0st

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 新手指南:Bwapp之XSS –stored

    XSS 全称:跨站脚本( Cross Site Scripting ),为了不和层叠样式表( Cascading Style Sheets )的缩写 CSS 混...

    信安之路
  • python的反反暴力破解

    本文适合刚刚学完 python,光听别人说强大,但是自己没有直观感受过的人。介绍两种防暴力破解的方法,以及用 py 的绕过方法。(暂不考虑 sql 注入,不谈机...

    信安之路
  • php 弱类型问题

    php 是一门简单而强大的语言,提供了很多 Web 适用的语言特性,其中就包括了变量弱类型,在弱类型机制下,你能够给一个变量赋任意类型的值。

    信安之路
  • 安装python3.7编译器后如何正确安装opnecv的方法详解

    记住不要在python环境下输入pip命令,否则出现如下情况,以免对后续安装opencv走弯路。

    砸漏
  • 欲求不满之 Redis Lua 脚本的执行原理

    Redis 提供了非常丰富的指令集,但是用户依然不满足,希望可以自定义扩充若干指令来完成一些特定领域的问题。Redis 为这样的用户场景提供了 lua 脚本支持...

    老钱
  • 视频 | Web安全漏洞系列之直接对象引用漏洞IDOR

    PwnFunction是当前Youtube中受欢迎的安全课程,它结合了Hacker101 和 LiveOverflow两个频道特点,对Web应用技术相关的各种典...

    FB客服
  • [享学Netflix] 十二、Archaius动态属性DynamicProperty原理详解(重要)

    上篇文章了解到了Netflix Archaius它提供的两个支持类:配置管理器ConfigurationManager和动态属性支持DynamicPropert...

    YourBatman
  • Springboot 系列(二)Spring Boot 配置文件

    不管是通过官方提供的方式获取 Spring Boot 项目,还是通过 IDEA 快速的创建 Spring Boot 项目,我们都会发现在 resource 有一...

    未读代码
  • GAN用于无监督表征学习,效果依然惊人……

    近年来,GAN 在图像合成领域取得了惊人的成果,例如先前 DeepMind 提出的 BigGAN。近日,DeepMind 提出全新的 BigBiGAN,引起了社...

    机器之心
  • 前端代码乱糟糟?是时候引入代码质量检查工具了

    为了统一团队的代码规范,除了一纸规范说明之外,还需要引入工具进行限制。虽说工具并不能完全实现规范中的规则,但至少能够在一定程度上缓解代码不统一的局面。

    书童小二

扫码关注云+社区

领取腾讯云代金券