Gabriel Landau

为了乐趣和利益而沙箱化反恶意软件产品

本文演示了一个漏洞,该漏洞允许攻击者绕过 Windows 安全机制,该机制可以保护反恶意软件产品免受各种形式的攻击。

10 分钟阅读安全研究
Sandboxing Antimalware Products for Fun and Profit

本文演示了一个漏洞,该漏洞允许攻击者绕过 Windows 安全机制,该机制可以保护反恶意软件产品免受各种形式的攻击。 这尤其令人感兴趣,因为我们构建和维护两种受益于此保护的反恶意软件产品。

受保护的反恶意软件服务

Windows 8.1 引入了受保护的反恶意软件服务的概念。 这使得经过特殊签名的程序可以运行,使其免受篡改和终止,即使是管理用户也是如此。 Microsoft 的文档(已存档)将其描述为

在 Windows 8.1 中,引入了受保护服务的新概念,以允许将反恶意软件用户模式服务作为受保护服务启动。 在服务作为受保护服务启动后,Windows 使用代码完整性仅允许将受信任的代码加载到受保护的服务中。 Windows 还保护这些进程免受代码注入以及来自管理员进程的其他攻击。

目的是防止恶意软件立即禁用您的防病毒软件然后横行霸道。 在本文的其余部分中,我们将它们称为受保护的进程精简版 (PPL)。 如需更深入的了解,Alex Ionescu 在其在 2014 年 NoSuchCon 上的演讲中详细介绍了受保护的进程。

为了能够作为 PPL 运行,反恶意软件供应商必须向 Microsoft 申请、证明其身份、签署具有约束力的法律文件、实施早期启动反恶意软件 (ELAM) 驱动程序,通过测试套件运行该驱动程序,然后将其提交给 Microsoft 以获取特殊的 Authenticode 签名。 这不是一个简单的过程。 完成此过程后,供应商可以使用此 ELAM 驱动程序,通过以 PPL 形式运行来让 Windows 保护其反恶意软件服务。

您可以通过在默认 Windows 10 安装中从提升的管理命令提示符运行以下命令来亲自查看 PPL 的运行情况

运行中的受保护进程精简版

C:\WINDOWS\system32>whoami
nt authority\system

C:\WINDOWS\system32>whoami /priv | findstr "Debug"
SeDebugPrivilege                Debug programs                    Enabled

C:\WINDOWS\system32>taskkill /f /im MsMpEng.exe
ERROR: The process "MsMpEng.exe" with PID 2236 could not be terminated.
Reason: Access is denied.

正如您在此处看到的,即使以 SYSTEM 用户身份运行(或具有SeDebugPrivilege的提升管理员)也无法终止 PPL Windows Defender 反恶意软件服务 (MsMpEng.exe)。 这是因为像 taskkill.exe 这样的非 PPL 进程无法使用诸如OpenProcess之类的 API 获取具有 PROCESS_TERMINATE 访问权限的 PPL 进程句柄。

总之,Windows 尝试保护 PPL 进程免受非 PPL 进程的攻击,即使是那些具有管理权限的进程。 这既有文档记录也有实施。 话虽如此,在 PROCESS_TERMINATE 被阻止的情况下,让我们看看是否有其他方法可以干扰它。

Windows 令牌

可以将 Windows 令牌视为安全凭据。 它说明你是谁以及你被允许做什么。 通常,当用户运行进程时,该进程会使用他们的令牌运行,并且可以执行用户可以执行的任何操作。 令牌中最重要的一些数据包括

  • 用户身份
  • 组成员身份(例如,管理员)
  • 特权(例如,SeDebugPrivilege)
  • 完整性级别

令牌是 Windows 授权的关键部分。 只要 Windows 线程访问可保护对象,操作系统就会执行安全检查。 它将线程的有效令牌与正在访问的对象的安全描述符进行比较。 您可以在 Microsoft访问令牌文档和 Elastic 博客文章中了解有关令牌的更多信息,该文章介绍了 Windows 令牌

沙箱令牌

某些应用程序(例如 Web 浏览器)一直是利用的重复目标。 一旦攻击者成功利用浏览器进程,漏洞利用负载就可以执行浏览器进程可以执行的任何操作。 这是因为它共享浏览器的令牌。

为了减轻此类攻击造成的损害,Web 浏览器已将其大部分代码移至较低特权的辅助进程中。 这通常是通过创建称为沙箱的受限安全上下文来完成的。 当沙箱化的辅助进程需要在系统上执行特权操作(例如,保存下载的文件)时,它可以请求非沙箱化的“代理”进程代表其执行操作。 如果利用了沙箱化进程,则目标是将负载对损害的资源访问能力限制为沙箱可访问的资源。

虽然现代沙箱涉及操作系统安全的多个组件,但最重要的组件之一是低特权或受限令牌。 可以使用诸如此类的 API 创建新的沙箱令牌

CreateRestrictedToken。 有时,沙箱化的进程需要在执行一些初始化后锁定自身。 AdjustTokenPrivilegesAdjustTokenGroups API 允许进行此调整。 这些 API 使得可以以这样一种方式“没收”现有进程令牌的特权和组,即在不创建沙箱外部的新令牌的情况下无法恢复它们。

今天常用的一种沙箱是 Google Chrome 的一部分。 甚至一些安全产品也开始在这些天使用沙箱。

访问令牌

Windows 提供 OpenProcessTokenAPI 以启用与进程令牌的交互。 MSDN 表示,必须具有 PROCESS_QUERY_INFORMATION 权限才能使用 OpenProcessToken。 由于非受保护的进程只能获得对 PPL 进程的 PROCESS_QUERY_LIMITED_INFORMATION 访问权限(注意 LIMITED),因此似乎不可能获得 PPL 进程的令牌句柄。 但是,在这种情况下,MSDN 是不正确的。 仅使用 PROCESS_QUERY_LIMITED_INFORMATION,我们可以成功打开受保护进程的令牌。James Forshaw更深入地解释了此文档差异,显示了底层

反编译的内核代码.

令牌本身就是可保护的对象。 因此,仍然会应用常规访问检查。 将尝试访问令牌的线程的有效令牌与被访问令牌的安全描述符进行检查,以确定请求的访问权限(TOKEN_QUERY、TOKEN_WRITE、TOKEN_IMPERSONATE 等)。 有关访问检查的更多详细信息,请参阅 Microsoft 文章“DACL 如何控制对对象的访问。”

攻击

Process Hacker提供了令牌安全描述符的精美可视化效果。 查看 Windows Defender (MsMpEng.exe) 的令牌,我们看到以下任意访问控制列表 (DACL)

请注意,SYSTEM 用户对令牌拥有完全控制权。这意味着,除非有其他机制保护令牌,否则以 SYSTEM 身份运行的线程可以修改令牌。当这种修改成为可能时,它就违反了“PPL 受管理员保护”的预期设计目标。

演示

遗憾的是,没有其他机制保护令牌。使用此技术,攻击者可以强制删除 MsMpEng.exe 令牌的所有权限,并将其从系统完整性级别降至不受信任的完整性。被降级为不受信任的完整性会阻止受害进程访问系统上的大多数安全资源,从而在不终止进程的情况下悄无声息地使其失效。

在此视频中,攻击者本可以进一步限制令牌,但权限和完整性更改足以阻止 MsMpEng.exe 检测和阻止 Mimikatz 的执行。我们认为这说明了一个有效的概念验证。

防御

较新版本的 Windows 包含一个未公开的功能,称为“信任标签”。信任标签是系统访问控制列表 (SACL) 的一部分,它是每个安全描述符的可选组件。信任标签允许 Windows 限制对特定类型受保护进程的特定访问权限。例如,Windows 使用信任标签保护 \KnownDlls 对象目录,使其免受恶意管理员的修改。我们可以使用WinObjEx64 来看到这一点

与 \KnownDlls 一样,令牌是可保护的对象,因此可以保护它们免受恶意管理员的修改。实际上,Elastic Security 就是这样做的,并且通过拒绝具有低于“反恶意软件轻型”信任标签的进程的 TOKEN_WRITE 访问权限,它不受此攻击的影响。但是,由于此保护是在运行时应用的,因此在它可以应用信任标签之前,仍然存在短暂的漏洞窗口。

理想情况下,Windows 会在创建时将此类信任标签应用于每个 PPL 进程的令牌。这将消除竞争条件并修复 PPL 机制中的漏洞。这有先例。通过内核调试器,我们可以看到 Windows 已经在 Windows(如下所示的 21H1)上使用信任标签保护 System 进程的令牌

1: kd> dx -r1 (((nt!_OBJECT_HEADER*)((@$cursession.Processes[0x4]->KernelObject->Token->Object - sizeof(nt!_OBJECT_HEADER))  & ~0xf))->SecurityDescriptor & ~0xf)
(((nt!_OBJECT_HEADER*)((@$cursession.Processes[0x4]->KernelObject->Token->Object - sizeof(nt!_OBJECT_HEADER))  & ~0xf))->SecurityDescriptor & ~0xf) : 0xffffe00649c46c20
1: kd> !sd 0xffffe00649c46c20
->Revision: 0x1
->Sbz1    : 0x0
->Control : 0x8814
            SE_DACL_PRESENT
            SE_SACL_PRESENT
            SE_SACL_AUTO_INHERITED
            SE_SELF_RELATIVE
->Owner   : S-1-5-32-544
->Group   : S-1-5-32-544
->Dacl    :
->Dacl    : ->AclRevision: 0x2
->Dacl    : ->Sbz1       : 0x0
->Dacl    : ->AclSize    : 0x1c
->Dacl    : ->AceCount   : 0x1
->Dacl    : ->Sbz2       : 0x0
->Dacl    : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl    : ->Ace[0]: ->AceFlags: 0x0
->Dacl    : ->Ace[0]: ->AceSize: 0x14
->Dacl    : ->Ace[0]: ->Mask : 0x000f01ff
->Dacl    : ->Ace[0]: ->SID: S-1-5-18

->Sacl    :
->Sacl    : ->AclRevision: 0x2
->Sacl    : ->Sbz1       : 0x0
->Sacl    : ->AclSize    : 0x34
->Sacl    : ->AceCount   : 0x2
->Sacl    : ->Sbz2       : 0x0
->Sacl    : ->Ace[0]: ->AceType: SYSTEM_MANDATORY_LABEL_ACE_TYPE
->Sacl    : ->Ace[0]: ->AceFlags: 0x0
->Sacl    : ->Ace[0]: ->AceSize: 0x14
->Sacl    : ->Ace[0]: ->Mask : 0x00000001
->Sacl    : ->Ace[0]: ->SID: S-1-16-16384

->Sacl    : ->Ace[1]: ->AceType: SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE
->Sacl    : ->Ace[1]: ->AceFlags: 0x0
->Sacl    : ->Ace[1]: ->AceSize: 0x18
->Sacl    : ->Ace[1]: ->Mask : 0x00020018
->Sacl    : ->Ace[1]: ->SID: S-1-19-1024-8192

SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE 访问控制条目限制对 READ_CONTROL、TOKEN_QUERY 和 TOKEN_QUERY_SOURCE (0x00020018) 的访问,除非调用方是 WinTcb 受保护的进程 (SID S-1-19-1024-8192)。该 SID 可以解释如下

缓解

与本文一起,我们正在发布PPLGuard概念验证的更新,该更新可保护所有正在运行的反恶意软件 PPL 进程免受此攻击。它包括反恶意软件产品可以用来保护自身的示例代码。以下是它的实际应用,保护了 Defender

披露

我们在 2022-01-05 向Microsoft 安全响应中心 (MSRC) 披露了此漏洞并提出了修复建议。他们在 2022-01-24 回应称,他们已将其归类为中等严重性,并且不会通过安全更新来解决它。但是,他们可能会在 Windows 的未来版本中解决它。

结论

在本文中,我们披露了 Windows 受保护进程精简版 (PPL) 机制中的一个缺陷。然后,我们演示了恶意软件如何使用此缺陷来使 PPL 反恶意软件产品失效。最后,我们展示了一个简单的 ACL 修复(带有示例代码),反恶意软件产品可以使用它来防御此攻击。Elastic Security 已经整合了此修复,但我们希望 Windows 在不久的将来默认实现它(或类似的东西)。