目录
攻击者总是在寻找新的方法,既要在主机上投放并执行恶意软件,还要避开安全检测。一些新型技术能在基于虚拟化的安全性 (VBS) 飞地中运行恶意软件,同时避开常见的安全防护手段,我们对此作了相关研究。2025 年 8 月 8 日,我在拉斯维加斯举办的 DEF CON 33 极客大会上做了一场演讲,探讨了这类攻击面。
VBS 是 Microsoft 的一项安全功能,它能创造虚拟环境,专用于隔离关键的操作系统组件。VBS 飞地可以隔离进程的某个区域,使其他进程、该进程本身甚至内核都无法访问该区域。
虽然 VBS 飞地可以提升安全性,但这项技术也让攻击者看到了诱人的机会。因为恶意软件一旦在 VBS 飞地中运行,常规的基于内存的安全检测和取证将无法检测到相关行为。我们探讨了这一想法,发现了不少滥用 VBS 飞地的可行方法。
了解 VTL 和 VBS 飞地
虚拟信任级别 (VTL) 是 VBS 飞地的底层架构基础,因此了解 VTL 的概念十分重要。每个信任级别为在该级别下运行的实体分别授予物理内存访问权限,级别不同,则权限不同。低 VTL 中的运行实体无法访问高 VTL 的内存。
Windows 目前主要使用两种信任级别:VTL0 用于运行传统的操作系统组件,包括内核和用户模式应用程序;VTL1 比 VTL0 具有更高的权限,可创建两种新的执行模式:安全内核模式和隔离用户模式。
- 安全内核模式用于运行安全内核,即在 VTL1 中运行的内核,因此比常规内核具有更高的权限。安全内核可以对常规内核实施策略,并限制常规内核对敏感内存区域的访问。由于安全内核的功能非常精简,不支持任何第三方驱动程序,因此大大减少了攻击面。
- 隔离用户模式用于执行安全进程,这是一种使用 VTL1 内存隔离功能的特殊类型用户模式进程。任何 VTL0 代码(包括常规内核)都无法访问隔离用户模式的内存。
VTL0 和 VTL1 总共能创建四种执行模式:
- Ring0 VTL0 — 常规内核模式
- Ring0 VTL1 — 安全内核模式
- Ring3 VTL0 — 常规用户模式
- Ring3 VTL1 — 隔离用户模式
VBS 飞地为 VTL1 的用户模式进程创建了一块内存区域,我们可以向其中加载称为“飞地模块”的 DLL。飞地就变成了“受信任执行环境”,在 VTL0 中运行的任何程序都无法访问飞地中的数据和代码。这项机制有利于将能够入侵系统的攻击者与敏感操作相互隔离。
由于对 VTL1 的访问受限,因此向飞地中加载 DLL 需要使用 Microsoft 颁发的特殊证书对其进行正确签名。如果没有此类签名,任何加载模块的尝试都将失败。尽管只有受信任的第三方可以对飞地模块进行签名,但是对于可以加载这些模块的用户却没有任何限制,只要经过签名,任何进程都可以向飞地中加载任意模块。
调查攻击策略
VBS 飞地之所以对攻击者有吸引力,主要有以下几个原因。首先,在 VTL0 中运行的所有程序,包括端点检测和响应 (EDR) 和分析工具,都无法访问飞地的地址空间。其次,EDR 无法监测飞地内部进行的 API 调用。
认识到这一点以后,我们详细研究了攻击者可能在飞地中执行恶意代码的方式。此外,我们还探讨了恶意代码运行时,攻击者可能使用哪些技术。本博文将介绍我们的研究发现。
滥用可调试飞地模块
VBS 飞地模块可配置为可调试状态。由于飞地模块在 VTL1 中运行,通常无法对其进行调试,因为调试器无法访问飞地内存以检索数据或设置断点。然而,我们发现,当一个可调试的飞地模块被执行时,它仍然会被加载到 VTL1 中。
为了启用调试,安全内核实施了一些异常情况,应用于可调试的飞地模块。VTL0 进程也可以修改可调试飞地模块的内存权限。可调试模块处理的数据很容易被泄露。
这会很大程度破坏飞地模块的核心用途,即隔离 VTL0 与一部分内存。基于这个原因,Microsoft 强烈呼吁开发人员不要发布可调试的飞地模块。
但是,请稍等,还有其他内容!
如果攻击者获得任何可调试的已签名飞地模块,他们便可以执行一些步骤来实现 VTL1 代码执行,具体步骤我已经在 DEF CON 极客大会上阐述。攻击者也会因此面临风险:正如攻击者可以访问飞地内存一样,EDR 也可以访问。然而,这种攻击可以避开 API 监控,使 EDR 解决方案很难检测到攻击。
这种方法可用于创建隐蔽的“半 VTL1”植入程序,充分利用在飞地中运行的一些优势。
自带漏洞飞地攻击 (BYOVE)
我们探讨了攻击者能否利用某个版本的存在漏洞的自带驱动程序 (BYOVD) 技术,在 VBS 飞地中运行恶意软件。我们需要找到自带漏洞的已签名飞地模块。
因此我们想到了 CVE-2023-36880,这是 Microsoft Edge 使用的 VBS 飞地模块中的一个漏洞。该漏洞由 Chrome Platform Security Team 的 Alex Gough 发现,攻击者利用该漏洞可以在飞地模块中读写任意数据。
我们尝试利用读取/写入基元,用返回导向编程 (ROP) 链覆盖飞地栈,最终在飞地中执行 shellcode。然而,我们发现,飞地使用任意代码防护 (ACG) 阻止了未签名的代码执行。ACG 是一种安全缓解措施,旨在阻止动态生成代码的执行(见图)。
我们还没有找到在飞地中绕过 ACG 并将未签名代码加载到其中的方法,尽管从理论上而言,完整 ROP 攻击是可行的。
然而,有趣的是,我们发现了利用 CVE-2023-36880 漏洞的另一种方式,也就是利用飞地模块导出的 SealSettings 和 UnsealSettings 函数的漏洞。这两个函数不会验证目标地址或源缓冲区地址,因此可以指向进程中的任何地址,包括飞地内部的地址。
攻击者可以调用 SealSettings 来加密任意数据,然后调用 UnsealSettings 指向飞地中的目标地址,将原始数据写入飞地内存。
或者,攻击者可以调用 SealSettings,同时提供飞地中的地址作为源缓冲区指针。这将导致飞地加密来自飞地内存的数据并将其写入攻击者控制的位置。然后,攻击者可以调用 UnsealSettings 来解密这些数据,从而能够读取飞地中的任意数据。
Mirage:基于 VTL1 的内存规避
我们探讨了名为“Mirage”的内存扫描规避技术,该技术的灵感来自 Gargoyle,这是一种规避技术,可用于创建在良性状态和武器化状态之间不断切换的有效负载。
Mirage 通过在 VTL1 和 VTL0 内存之间进行切换来实现规避。它将 shellcode 存储在 VTL1 飞地内存中,定期使用漏洞将其传输回 VTL0,执行该代码,然后迅速将其从 VTL0 内存中删除。
由于有效负载大部分时间都隐藏在 VTL1 中,因此可抵御内存扫描和转储。在休眠阶段,有效负载不仅“隐蔽”,而且无法访问。同样,飞地将 shellcode 写入 VTL0,超出了 EDR 工具的监测范围,因此很难依靠监测手段检测到有效负载。
反调试
飞地恶意软件另一个值得关注的应用是反调试。由于 VTL0 应用程序(包括调试程序)无法访问在飞地中运行的代码,这为恶意软件提供了显著的优势。
我们探讨了很多手段。依赖飞地对进程的 VTL0 地址空间的访问权限,支持程序手动读取进程 PEB 并检查“BeingDebugged”标志的值。如果检测到调试程序,飞地可以终止该进程。
我们还考虑了基于时间的反调试技术,它采用处理器时钟周期数来测量不同飞地调用之间的时间间隔,并在检测到显著延迟时终止调试进程。
我们将代码的关键部分与反调试检查一起放进飞地运行,可以制作出几乎完全不受动态分析影响的恶意软件。如果实施得当,这种方法只能通过调试 Hyper-V 或安全内核才能破解。
保护您的环境
截至目前,只有极少数应用程序使用飞地。这为飞地使用/滥用异常的检测提供了极好的契机。为有效利用这一契机,防御者可以专注于以下方面:
- 建立已知的、合法的 VBS 飞地使用基线,并对任何偏离该基线的情况进行标记
- 监测飞地 API 的异常
- 监测飞地 DLL 的加载,出现加载即表示有新的进程
- 利用其他用于隔离关键系统和应用程序的安全技术,例如微分段技术
尽管 VBS 飞地供了保护应用程序敏感部分的绝佳工具,但是,攻击者也可以用飞地来“保护”自己的恶意软件。我在 DEF CON 极客大会上曾介绍过,飞地攻击策略目前主要停留在理论层面。然而,我们可以确信,高水平攻击者也在想方设法寻找能够利用 VBS 飞地的漏洞,达成恶意目的。
面对这类正在发展的威胁,充分了解和掌握飞地在贵企业环境中的应用,是提前做好应对准备的第一步。
了解更多
阅读我的上一篇博文《滥用 VBS 飞地创建规避型恶意软件》,全面了解相关技术讲解。
标签