Mimikatz 由 Benjamin Delpy (@gentilkiwi) 开发,是一款广受好评的后渗透工具,允许攻击者从内存中提取明文密码、NTLM 哈希和 Kerberos 票据,并执行诸如传递哈希、传递票据或构建黄金票据等攻击。可以说,Mimikatz 的主要用途是从 LSASS 进程内存中检索用户凭据,以便在后渗透横向移动中使用。
最近,微软在 Windows 10 企业版和 Windows Server 2016 中引入了 Credential Guard,它使用基于虚拟化的安全机制来隔离机密,并且能非常有效地阻止 Mimikatz 直接从内存中检索哈希。 此外,Mimikatz 已成为大多数端点保护解决方案的首要目标,它们在其检测和阻止方面的努力非常激进。尽管这些努力注定会失败,但它们正日益成为一种麻烦。
NetNTLM 是 Windows 的挑战-响应协议,主要在不支持 Kerberos 的情况下使用。在 NetNTLM 中,服务器向客户端发送一个随机的 8 字节 nonce 作为挑战,客户端计算一个响应,该响应使用 NTLM 哈希作为密钥处理挑战,而 NTLM 哈希是用户密码的 MD4 哈希。NetNTLM 认证协议有两个版本,两者都容易受到某些攻击。自然地,版本 1 比版本 2 弱得多,因此从 Windows Vista/2008 开始,NetNTLM 版本 1 默认被禁用。
由于 NTLM 哈希是计算响应的密钥,攻击者不一定需要获取受害者的明文密码来进行身份验证,因此使用 Mimikatz 从 LSASS 内存中检索哈希几乎等同于窃取明文密码。 Chris Hummel 在 2009 年发表了一篇文章描述了这种技术,并将其命名为“传递哈希” [https://www.sans.org/reading-room/whitepapers/testing/crack-pass-hash-33219]。
在 2012 年 Defcon 大会上,Moxie Marlinspike 和 David Hulton 提出了一种针对 NetNTLMv1 的“分而治之”攻击 [https://www.youtube.com/watch?v=sIidzPntdCM]。在 NetNTLMv1 中,客户端收到 8 字节挑战后,通过使用 NTLM 哈希的不同部分作为密钥,对挑战进行三次 DES 加密来计算响应。DES 的有效密钥长度是 56 位,即 7 字节,而 NTLM 哈希是 16 字节。NetNTLMv1 首先使用 NTLM 哈希的前 7 个字节作为密钥加密挑战,然后使用接下来的 7 个字节作为密钥加密挑战,最后使用 NTLM 哈希的最后 2 个字节(用空字节填充)作为密钥加密挑战。实际上,这意味着给定一个 NetNTLMv1 挑战和响应,攻击者必须破解两个 56 位的 DES 密钥,这比破解单个 128 位密钥要容易指数级。 Moxie 和 Hulton 为此开发了定制硬件,能够在不到 24 小时内暴力破解整个 DES 密钥空间,从而保证在合理时间内成功检索 NTLM 哈希。 请注意,与针对密码的字典攻击或暴力攻击(可能不会成功)不同,这种攻击保证成功检索 NTLM 哈希。
正如 ToorCon 在 https://crack.sh 所展示的,为所有可能的 NetNTLMv1 响应(针对选定的挑战,如 0x1122334455667788)创建完整的彩虹表是可行的,这允许在几分钟内破解给定响应的 NTLM 哈希。其含义是,捕获针对选定挑战的 NetNTLMv1 响应几乎可以立即转换为相应的 NTLM 哈希,由于传递哈希的存在,这几乎等同于获取密码。
Mimikatz 通常在攻击者获得目标主机的提升权限后执行。此时,攻击者还可以更改注册表项,例如 LMCompatibilityLevel,它指定主机应协商 NetNTLMv1 还是 NetNTLMv2。攻击者可以将值更改为 0、1 或 2,从而启用客户端端的 NetNTLMv1,然后尝试向一个伪造的 SMB 服务器进行身份验证,该服务器将捕获客户端的响应,如 Optiv 的博客文章所述 [https://www.optiv.com/blog/post-exploitation-using-netntlm-downgrade-attacks]。
另外两个设置可能会阻止受害者协商 NetNTLMv1 响应:
在不应执行 Mimikatz 的安全环境中,攻击者可以执行 Internal Monologue Attack,其中他们通过 SSPI 从用户模式应用程序向 NTLM 认证包(MSV1_0)发起本地过程调用,以在执行扩展的 NetNTLM 降级后,在已登录用户的上下文中计算 NetNTLM 响应。
Internal Monologue Attack 的流程如下:
我最近在启用了 Credential Guard 的环境中重新测试了 Internal Monologue,结果并不理想。我不确定是在初始测试期间我的测试环境中的 Credential Guard 没有正常工作,还是自那以后发生了变化。 我更新了实现,以动态获取来自 AcceptSecurityContext 的服务器令牌,并对其进行篡改,以避免本地认证陷阱,这样如果 NetNTLMv1(无扩展会话安全性)失败,至少可以捕获 NetNTLMv2 挑战-响应。
Internal Monologue Attack 可以说比运行 Mimikatz 更隐蔽,因为无需注入代码或从受保护进程转储内存。 由于通过在本地与 NTLM SSP 交互来诱发 NetNTLMv1 响应,因此不会产生网络流量,并且选定的挑战也不容易可见。 日志中不会记录成功的 NTLM 身份验证事件。 NetNTLM 降级以及窃取令牌/模拟其他用户的注册表更改可能会触发某些指示器。
此工具是一个概念验证,用 C# 实现了 Internal Monologue Attack。将代码移植到 PowerShell 可能会用其他事件日志替换审计追踪中的某些事件日志。 PoC 代码远非完美。欢迎积极的贡献和改进。
Elad Shamir,来自 The Missing Link Security