利用NTLM哈希作为密码字典:跨域密码重用的高效攻击技术

本文详细介绍了“哈希剥离”技术,即利用已获取的NTLM哈希作为密码字典,快速验证密码在多个系统或域之间的重用情况,从而实现高效的横向移动和权限提升,而无需恢复明文密码。

信任安全 | 天啊!将NTLM哈希武器化为密码字典

文章正文

密码重用现象在Active Directory (AD) 环境中十分普遍。从攻击者的角度来看,这是实现横向移动或权限提升的一条可靠路径。尽管大多数IT团队都意识到了这种风险,但更长的密码和密码管理器的使用,让人们常常误以为重用长密码是安全的。一旦密码长度达到很高的字符数,对于许多哈希类型而言,恢复它们通常是不切实际的,而这种重用行为往往就因此被忽视了。

这就引入了“哈希剥离”技术。我们不再尝试从Kerberos票据或缓存凭据等较慢的算法中恢复明文密码,而是可以将NTLM(NT)哈希作为密码字典,在Hashcat的NT模式下使用。这让我们能够快速验证密码在NTLMv1和NTLMv2质询-响应、Kerberos 5 etype 23票据以及DCC/DCC2哈希之间的重用情况。如果找到匹配项,我们就可以更有效地利用时间,从NT哈希中恢复明文,或者直接使用哈希传递(Pass-the-Hash, PtH)。在本文中,我将描述哈希剥离技术及其与AD的相关性,概述涉及的关键Hashcat模式,通过两个示例演示该技术,并以限制哈希剥离机会的实用缓解措施作为结尾。

什么是哈希剥离?

假设一家公司运营着两个站点。站点A被入侵,暴露了未加盐的MD5哈希:

1
md5(password)

后来,站点B通过用bcrypt包装现有密码来升级密码存储。它同样被入侵,暴露了:

1
bcrypt(md5(password))

利用站点A泄露的MD5哈希和站点B泄露的、经过bcrypt包装的MD5哈希,你可以直接将站点A泄露中的MD5值提供给bcrypt函数:

1
bcrypt(md5hash)

如果bcrypt校验匹配,我们就确认了密码被重用,而无需恢复明文。这就是哈希剥离:外部层(bcrypt)被剥离,你可以以更高的速度针对内部哈希(MD5)运行密码恢复攻击。我推荐查阅Sam Croley的《这算什么剥离?分层哈希剥离》以获取更详细的解释。

这与AD有何关联?

AD中的密码以NTLM哈希的形式存储在域控制器上。NT哈希是通过对密码的UTF-16LE编码进行MD4运算得出的。

1
MD4(UTF-16LE(password))

Kerberos支持多种加密类型。当允许使用RC4-HMAC(etype 23)时,可以请求使用目标账户NT哈希派生的密钥加密的TGS票据。使用任何域用户,你可以为具有SPN的账户请求TGS,捕获生成的TGS-REP,提取基于RC4的TGS-REP哈希,并将其离线进行密码恢复。

1
RC4-HMAC(MD4(UTF-16LE(password)))

如果提供的NT哈希作为候选者验证了TGS-REP哈希,你就证明了使用了相同的密码。从那里,你可以剥离外部层,然后从NT哈希中恢复明文,或者跳过恢复步骤直接使用哈希传递。

这种剥离方法同样适用于任何以NT哈希为基础密钥的场景。这包括:

  • NTLM质询-响应:NTLMv1和NTLMv2
  • Kerberos 5, etype 23票据:AS-REQ预认证、TGS-REP和AS-REP
  • 缓存凭据:DCC和DCC2

注意:在撰写本文时,Hashcat中尚未为Kerberos 5, etype 23 AS-REQ预认证提供NT候选模式。

剥离还是不剥离?

当AD环境中存在密码重用时,哈希剥离可以节省大量时间。你无需在慢速哈希格式上消耗计算资源,而是可以通过测试NT哈希作为候选者来快速确认多个目标之间的重用情况。这些NT候选者最好来自同一AD环境。最丰富的来源是域控制器的NTDS提取,这通常能产生数千个哈希。Windows终端上的SAM/SECURITY注册表配置单元提取也可用,但由于LAPS(本地管理员密码解决方案)和本地账户使用不频繁,其价值通常较低。该技术在多域或信任场景中尤其有价值:如果你控制了一个域并获得了其NT哈希,并且能够在另一个域中捕获基于NT的哈希,剥离技术可以让你快速验证重用情况,并优先处理高价值的横向移动目标。

当你拥有NT哈希和基于NT的目标时,都应该尝试剥离。即使是一个原本无法破解的60字符密码短语,如果你有相应的NT哈希,也可以验证其重用情况。然后,你可以从NT哈希离线恢复明文,或者直接使用NT哈希通过哈希传递进行身份验证。

攻击NT哈希要快得多。在Apple M3 Max上,Hashcat的NTLM(模式1000)运行速度约为每秒300亿次哈希运算(30,000 MH/s),而TGS-REP(模式13100)的运行速度约为每秒3亿次哈希运算(300 MH/s),速度优势大约为100倍。虽然这个差距没有计入测试重用所花费的时间,但针对基于NT的捕获运行Hashcat的NT哈希模式只会增加极少的额外运行时间。

图1 - Hashcat NTLM(1000)基准测试 图2 - Hashcat TGS-REP(13100)基准测试

但所有这些剥离的乐趣也有其限制。Kerberos 5 etype 17和18不是从NT哈希派生而来的,因此基于NT的剥离不适用于它们。如果AD域强制使用AES,并且你无法请求RC4/etype 23,则必须回退到正常的密码恢复,并使用Hashcat中的AES Kerberos模式,例如etype 17(AES128)的模式19600和etype 18(AES256)的模式19700。

归根结底,当NT哈希来自你正在测试的同一环境时,哈希剥离的效果最好。你也可以使用大型数据泄露列表中的哈希,有可能找到匹配项,但这种方法耗时且成功率较低。Hashcat的NT剥离模式并不比普通的密码模式快,而且因为你输入的是固定的32位十六进制NT哈希,应用密码字典规则会破坏这些哈希,使其不再代表原始密码。

Hashcat剥离模式

为便于快速参考,下表列出了Hashcat密码模式及其对应的基于NT的剥离模式。

哈希类型 模式(密码) 模式(NT)
域缓存凭据(DCC) 1100 31500
域缓存凭据2(DCC2) 2100 31600
NetNTLMv1 / NetNTLMv1+ESS 5500 27000
NetNTLMv2 5600 27100
Kerberos 5, etype 23, AS-REQ预认证 7500
Kerberos 5, etype 23, TGS-REP 13100 35300
Kerberos 5, etype 23, AS-REP 18200 35400

演示时间

在这些演示中,假设SMOKE.LOCAL域已被入侵,并通过使用Impacket的secretsdump.py执行DCSync攻击获取了NT哈希:

1
secretsdump.py <domain>/<user>@<ip> -history -user-status -outputfile <output.txt>

图3 - 对SMOKE.LOCAL执行DCSync攻击

当你执行DCSync攻击时,应该同时针对密码历史记录。使用secretsdump.py时,可以通过-history标志实现。微软建议在历史记录中保留最多24个先前密码以减少重用,但从攻击者的角度来看,这显著增加了获取的NT哈希数量。用户不总是拥有完整的历史记录,但即使每个账户只有几个历史密码,也能极大地扩展恢复的密码数量以及用于剥离的NT哈希密码字典。同样的逻辑也适用于使用Mimikatz或类似工具在Windows终端上转储SAM时:历史哈希为你提供了更多用于剥离的候选哈希,并揭示了可用于预测当前可能密码的密码更改模式。

图4 - 带有密码历史记录的扩展NT哈希密码字典

最后,请确保你使用的是最新版本的Hashcat,因为以下演示中使用的基于NT的剥离模式需要较新的版本。

演示 1:Kerberoast场景

在此演示中,使用一个低权限用户对CHOKE.LOCAL执行Kerberoast攻击。使用Impacket的GetUserSPNs.py为CHOKE.LOCAL\roastable账户请求服务票据,返回一个Kerberos 5 etype 23 TGS-REP哈希。该哈希被保存到roastable_TGS文件中,$krb5tgs$23$格式表明它是基于RC4的。

1
GetUserSPNs.py -dc-ip <dc_ip> -request <domain>/<user>

图5 - 从Kerberoast攻击中获取TGS哈希

接下来,使用Hashcat的NT候选模式35300,利用从CHOKE.LOCAL获取的TGS哈希和从SMOKE.LOCAL获得的NT哈希密码字典。Hashcat能够将TGS-REP与密码字典中的某个NT哈希匹配,表明CHOKE.LOCAL\roastable账户重用了密码。

1
hashcat -m 35300 <hash_file> <nt_wordlist>

图6 - 将TGS-REP剥离至NT哈希

然后,通过NetExec使用该NT哈希,以CHOKE.LOCAL\roastable的身份通过SMB认证到CHOKE.LOCAL域控制器,在实践中演示了跨域密码重用。

1
nxc smb <dc_ip> -u <user> -H <NT_hash>

图7 - 使用NT哈希认证到CHOKE.LOCAL

演示 2:域缓存凭据场景

在此演示中,使用本地管理员账户localadmin,对CHOKE.LOCAL域中一台已加入域的 workstation 执行LSA机密提取。使用NetExec提取LSA机密,其中包括CHOKE.LOCAL\highpriv账户的DCC2哈希。然后将该DCC2哈希复制到名为DCC2_hash的文件中以供离线测试。

1
nxc smb <ip> -u <user> -p <password> --local-auth --lsa

图8 - 从LSA机密中提取DCC2哈希

然后使用Hashcat的NT候选模式31600,将DCC2哈希作为目标,并使用从SMOKE.LOCAL获得的NT哈希密码字典。

1
Hashcat -m 31600 <hash_file> <nt_wordlist>

图9 - 使用NT哈希认证到CHOKE.LOCAL

利用该NT哈希,NetExec以CHOKE.LOCAL\highpriv的身份通过SMB认证到CHOKE.LOCAL域控制器,再次在实践中演示了跨域密码重用。

1
nxc smb <dc_ip> -u <user> -H <NT_hash>

图10 - 使用NT哈希认证到CHOKE.LOCAL

缓解措施

密码重用是使得哈希剥离成为可能的核心问题。用户账户和服务账户不应跨域、林或权限层级共享密码。服务账户应使用gMSA或其他托管凭据,而不是静态密码。在多个账户之间重用相同的秘密,实际上消除了这些账户旨在提供的权限分离。

Kerberos配置是一个主要的控制点。环境应优先选择AES etype 17和18,并尽可能逐步淘汰域账户和服务账户的RC4/etype 23。在收紧允许的类型之后,应轮换密码,以便派生新的AES密钥,并使任何现有的基于RC4的票据失效。

需要控制本地管理员重用和特权登录。终端上的本地管理员密码应使用LAPS、Windows LAPS或类似的控制措施进行管理,以便每个主机都有唯一的、可轮换的本地管理员凭据。域管理员和其他第0层账户应限制在普通工作站上进行交互式登录,这样它们的缓存凭据就无法轻易通过本地管理员访问被提取。

结论

如两个演示所示,哈希剥离使得检测和利用密码重用成为可能,而无需恢复底层密码。Kerberoast示例使用了NT哈希1269258dd36b6ed22bdd1f7774954fa6,它来自密码:

1
Trustedsec**!!TrustedsecTrustedsec@#$&*WOOOOH12345IsAnyoneActuallyReadingThis??

这种字符串在正常的渗透测试任务中实际上是无法破解的,然而剥离技术仍然可以让你证明重用并实现横向移动。DCC2示例使用了520adba9cd842298ea83c576a2a1de02,这是一个更现实的、可以通过标准密码字典和规则恢复的密码。我把这个留给读者作为练习。

虽然哈希剥离将NT哈希变成了用于其他NT派生格式的高价值密码字典,但它并不能完全替代密码恢复。然而,在攻击性任务中,它可以通过证明重用和实现访问权限(即使底层密码实际上无法恢复)来提供快速的胜利。

致谢

  • Sam Croley - 原始的哈希剥离研究
  • Hashcat团队 - 构建和维护Hashcat
  • Justin Bollinger - 博客审阅
  • Hans Lakhan - 术语和概念的合理性检查

其他参考资料

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计