Skip to main content

Credential Guard 凭据保护

Windows Defender Credential Guard 凭据保护 是一种虚拟化安全技术以防止 NTLM 哈希、Kerberos 票据、应用程序所存储的凭证的窃取进而组织。开启了凭据保护的主机,会分别有 Lsass.exe 进程以及 LsaIso.exe 进程。

凭据保护使用基于虚拟化的安全性 (VBS) 来隔离机密。VBS 利用硬件虚拟化功能创建一个安全的内存区域,该区域与普通操作系统分开。要了解攻击者在处理凭据保护时面临的挑战,可以参考在一个虚拟机内运行的正常操作系统和在另一个具有单独内核的虚拟机内运行的安全进程。这些 VM 由 Hypervisor 管理。

image.png

即使攻击者在操作系统中获得内核级的代码执行,他们仍然需要通过攻击 Hypervisor 或安全虚拟机来实现逃逸,这就是基于虚拟化技术的安全性相关的话题了。

小节开始说了,开启凭据保护的主机会有 2 个进程。LSAIso 进程将在安全虚拟机中运行,而 LSASS 和 LSAIso 可以通过高级本地过程调用 (ALPC) 进行通信。当 LSASS 进程想要保护一个秘密时,它可以调用 LSAIso 来加密它,然后将加密的秘密返回过来。理想情况下,只有 LSAIso 应该能够解密。一旦 NTLM 哈希受到保护,LSASS 进程仅持有一个隔离后的密文 (加密的 blob)。

image.png

如上图所示,LSAIso 进程具有 NTLM 支持。 当 LSASS 进程想要对加密的机密执行 NTLM 操作时,它可以调用 LSAIso 进程中的各种方法来执行操作。值得一提的是,LSAIso 没有网络访问权限。因此,即使 LSAIso 可以执行 NTLM 操作,LSASS 进程仍然负责执行操作前后的任何行为。例如,虽然 LSAIso 可以计算 NTLM 质询响应对,但 LSASS 负责接收和发送该对随机数。

对于开启了凭据保护的主机,使用 mimikatz 读取的凭证是这样的:

image.png

在 2020 年,有个很有意思的绕过技巧。 WDigest 模块,即 wdigest.dll,具有 2 个全局变量分别是 g_IsCredGuardEnabledg_fParameter_UseLogonCredential。这 2 个变量的名字就很直观,凭据保护是否启用,以及明文凭证是否应该存储在内存之中。通过将这两个变量的值进行修改,我们可以让 WDigest 误以为凭据保护未被启用,并且保存明文密码于内存之中。因此,在补丁 WDigest 之后的认证都会在内存中留下明文凭证。所以,我们需要做的是找到这 2 个变量的位置。我们可以在 https://gist.github.com/N4kedTurtle/8238f64d18932c7184faa2d0af2f1240 找到一个 PoC,但是变量的偏移是硬编码的。至于如何动态地找到变量偏移,属于更加高深的内容范围,不在此展开。

 

image.png

以上方法的局限是,之后新认证的用户的凭证可以提取了,但之前的还是无法捕获。而工具 PassTheChallenge (https://github.com/ly4k/PassTheChallenge) 通过利用 LSAIso 进程的功能以及加密后的 NTLM 哈希来还原出 NTLM 哈希。背后的密码学或算法原理较为复杂,不详细展开。