本文演示了一个缺陷,该缺陷允许攻击者绕过 Windows 安全机制,该机制保护反恶意软件产品免受各种形式的攻击。这特别令人关注,因为我们构建并维护了两个受益于此保护的反恶意软件产品。
受保护的反恶意软件服务
Windows 8.1 引入了受保护的反恶意软件服务的概念。这使经过特殊签名的程序能够运行,从而使其免受篡改和终止,即使是管理员用户也无法进行。Microsoft 的文档 (存档) 将其描述为
在 Windows 8.1 中,引入了受保护服务的新概念,以允许反恶意软件用户模式服务作为受保护服务启动。在服务作为受保护服务启动后,Windows 使用代码完整性仅允许受信任的代码加载到受保护的服务中。Windows 还保护这些进程免受代码注入和其他来自管理员进程的攻击。
目的是防止恶意软件立即禁用您的防病毒软件,然后肆意运行。在本文的其余部分,我们将其称为受保护进程轻量级 (PPL)。有关更深入的信息,Alex Ionescu 在其 2014 年 NoSuchCon 演讲中详细介绍了受保护进程。
为了能够作为 PPL 运行,反恶意软件供应商必须向 Microsoft 申请,证明其身份,签署具有约束力的法律文件,实施 早期启动反恶意软件 (ELAM) 驱动程序,将其运行通过测试套件,并将其提交给 Microsoft 以获取特殊的 Authenticode 签名。这不是一个简单的过程。完成此过程后,供应商可以 使用此 ELAM 驱动程序让 Windows 通过将其作为 PPL 运行来保护其反恶意软件服务。
您可以通过在默认 Windows 10 安装上的提升的管理员命令提示符下运行以下命令来查看 PPL 的实际运行情况
受保护进程轻量级 (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 访问令牌文档和介绍 Windows 令牌的 Elastic 博客文章 中阅读有关令牌的更多信息。
沙盒令牌
某些应用程序(例如 Web 浏览器)一直是攻击的反复目标。一旦攻击者成功利用浏览器进程,利用程序负载就可以执行浏览器进程可以执行的任何操作。这是因为它们共享浏览器的令牌。
为了减轻此类攻击造成的损害,Web 浏览器已将其大部分代码移动到较低权限的工作进程中。这通常是通过创建称为沙盒的受限安全上下文来完成的。当沙盒工作进程需要对系统执行特权操作(例如保存下载的文件)时,它可以请求非沙盒“代理”进程代表其执行操作。如果沙盒进程遭到利用,目标是将程序负载造成损害的能力限制为沙盒可访问的资源。
虽然现代沙盒涉及操作系统的多个安全组件,但其中最重要的组件之一是低权限或受限令牌。可以使用诸如以下 API 创建新的沙盒令牌:
CreateRestrictedToken。有时,沙盒进程需要在执行某些初始化后锁定自身。 AdjustTokenPrivileges 和 AdjustTokenGroups API 允许此调整。这些 API 使特权和组能够以无法在不创建沙盒外部的新令牌的情况下恢复的方式从现有进程的令牌中“放弃”。
今天 常用的一种沙盒是 Google Chrome 的一部分。即使是一些 安全产品如今也开始使用沙盒。
访问令牌
Windows 提供了 OpenProcessToken API 以启用与进程令牌的交互。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 文章“访问检查的工作原理”。
攻击
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 可以解释如下
- 1: 修订版 1
- 19: SECURITY_PROCESS_TRUST_AUTHORITY
- 1024: SECURITY_PROCESS_PROTECTION_TYPE_FULL_RID
- 8192: SECURITY_PROCESS_PROTECTION_LEVEL_WINTCB_RID
缓解措施
随着本文的发布,我们还发布了对PPLGuard 概念验证的更新,该验证可以保护所有运行的反恶意软件 PPL 进程免受此攻击。它包含反恶意软件产品可以用来保护自己的示例代码。以下是它保护 Defender 的实际操作。
披露
我们于 2022 年 1 月 5 日向Microsoft 安全响应中心 (MSRC) 披露了此漏洞并提出了修复建议。他们于 2022 年 1 月 24 日回复称,他们已将其归类为中等严重性,并且不会通过安全更新来解决它。但是,他们可能会在未来的 Windows 版本中解决它。
结论
在本文中,我们披露了 Windows 受保护进程轻量级 (PPL) 机制中的一个缺陷。然后,我们演示了恶意软件如何利用此缺陷来中和 PPL 反恶意软件产品。最后,我们展示了一个简单的 ACL 修复(带示例代码),反恶意软件产品可以使用它来防御此攻击。Elastic Security 已经集成了此修复,但我们希望 Windows 在不久的将来默认实现它(或等效的修复)。