COMpromise - 再次写入 Registry,第 4 部分

admin 2025年3月5日21:07:51评论7 views字数 4382阅读14分36秒阅读模式

【翻译】The Key to COMpromise - Writing to the Registry (again), Part 4 — Neodyme

COMpromise - 利用 TOCTOU 竞争获取 SYSTEM 权限

COMpromise - 通过劫持 COM 接口攻击防病毒软件和 EDR

COM 劫持之钥:获取 SYSTEM 权限

在我们关于 COM 劫持系列的最后一部分中,我们将研究 Bitdefender Total Security 实现的自定义命名管道 IPC 协议,并详细介绍我们对其进行逆向工程的方法。我们将探讨如何利用 COM 劫持和这种自定义通信来获取 SYSTEM 权限(CVE-2023-6154)。此外,我们还将研究如何减轻在这一系列博客文章中讨论的漏洞。最后,我们将演示如何利用 COM 劫持对安全产品执行拒绝服务(DoS)攻击。

一旦目标产品启动前端用户界面,它就会访问 dataexchange.dll 的 COM 接口。我们如在本系列的 第一部分 中所述劫持了这个 COM 接口。在劫持 COM 接口后,我们提供的 DLL 被加载到前端进程中,使我们能够在受信任进程的上下文之外与后端进程进行通信。

COMpromise - 再次写入 Registry,第 4 部分
我们的 DLL 被加载到前端进程中

为了利用这个原语,我们需要更深入地理解前端和后端之间的通信。下一部分详细介绍我们的逆向工程过程。

逆向工程通信

与我们分析和利用的其他安全产品类似,seccenter.exe(前端进程)与一个高权限的后端进程进行通信。然而,在 Bitdefender 中,高级接口实现了通信,因此我们不需要深入分析 RPC 调用。

在分析 seccenter.exe 的过程中,我们迅速识别出加载的 DLL safeelevatedrun.dll,它包含一些用 C++ 编写的插件式接口。三个引人注目的字符串引起了我们的注意:

  • CEleveatedOperationsClient
  • CRegistryOperationsClient
  • CFileOperationsClient

这些字符串似乎引用了在 safeelevatedrun.dll 中实现的类,并提供了前面提到的与后端服务通信的高级接口。

COMpromise - 再次写入 Registry,第 4 部分
在 safeelevatedrun.dll 中初始化 CRegistryOperationsClient 实例

CRegistryOperationsClient 类似乎特别有趣,因为它的名称暗示它处理注册表操作,这可能是提升我们权限的一个向量。当我们看到前端进程 seccenter.exe 使用 CSecurityCenterApp::SaveRegValue 参考一个 Registry operations client 类对象时,我们的怀疑得到了证实。这强烈暗示了与上述提到的 CRegistryOperationsClient 类的连接。

COMpromise - 再次写入 Registry,第 4 部分
从 seccenter.exe 使用注册表操作客户端

我们需要获取这个类的实例,以便在前端进程中与 CRegistryOperationsClient 进行交互。该对象是通过一个插件式系统动态创建的,该系统将内部 GUID 传递给动态创建方法。

COMpromise - 再次写入 Registry,第 4 部分
CRegistryOperationsClient 的动态插件实例化

最终,在一些额外(且不那么有趣)的逆向工程之后,我们创建了以下流程来创建 CRegistryOperationsClient 类的实例。我们希望这个类能够让我们与注册表进行交互。对注册表的无限制写入交互将使我们能够提升权限。

  1. seccenter.exe(以及内部的 safeelevatedrun.dll)使用内部 GUID 动态创建 CEleveatedOperationsClient 和 CRegistryOperationsClient 对象。
  2. 新实例化的 CRegistryOperationsClient 对象暴露了一个接口,用于将 registry_ops 结构传递给后端服务。
  3. CSecurityCenterApp::SaveRegValue 提供了一个高级接口,以执行对服务的低级 RPC 调用。

或者,更详细地:

COMpromise - 再次写入 Registry,第 4 部分
CRegistryOperationsClient 对象创建和最终 SaveRegValue 调用的抽象流程

对于我们的利用,我们需要逆向工程 registry_ops 结构的基本字段。

typedefstruct { DWORD hive; DWORD unknown;wchar_t key[100];wchar_t value[100]; DWORD regtype;wchar_t value2[522]; DWORD value_len_qq;registry_ops_t;

一个关键参数 DWORD hive 指定了注册表项将被写入的注册表树。为了针对 HKEY_LOCAL_MACHINE,该键的值必须设置为 0x80000002,如 某些 Windows 内部文档 中所述。

最终的利用调用是使用动态创建的注册表客户端对象和构造的 registry_ops 结构构建的。下面提供了该利用的简化实现:

typedefDWORD_PTR(WINAPI* SaveRegvalue_Orig_t)(__int64 this_ptr, registry_ops_t* a2);// [...]registry_ops_t ops = { 0 };ops.hive = 0x80000002;ops.unknown = 0xFFFFFFFF;wcscpy_s(ops.key, 0x64ui64, L"SYSTEM\CurrentControlSet\Services\NetSetupSvc");wcscpy_s(ops.value, 0x64ui64, L"ImagePath");wcscpy_s(ops.value2, 0x64ui64, L"C:\poc\SpawnSystemShell.exe");ops.regtype = REG_SZ;ops.value_len_qq = strlen("C:\poc\SpawnSystemShell.exe") * 2 + 1;SaveRegvalue_Orig_t saveRegValue = (SaveRegvalue_Orig_t)((uint64_t)seccenter + 0x10DCF0);uint64_t global_reg_handler = (uint64_t)((uint64_t)seccenter + 0x198DC0);saveRegValue(global_reg_handler, &ops);

提升我们的权限

在理解了后端通信后,我们可以在路径上不受限制地写入注册表项。我们的目标是利用这一能力,而不需要管理员登录或系统重启。

我们决定修改服务的二进制路径,使其指向我们控制的可执行文件。虽然许多服务可以用于此目的,但大多数需要系统重启。最终我们选择了 NetSetupService,因为它默认未启动,以 SYSTEM 身份运行,并且可以由低权限用户启动。

我们创建了一个 COM DLL,利用上述功能指示后端将该服务的 ImagePath 更改为受控路径。一旦修改完成,我们可以启动该服务,从而以 SYSTEM 身份执行我们的二进制文件。我们的二进制文件随后在我们的桌面上以 SYSTEM 权限生成一个 cmd.exe 进程。

综合起来,我们的利用过程如下:

  1. 我们劫持了 dataexchange.dll 的 COM 接口。
  2. 我们启动前端 UI 以触发 COM 接口并将我们的 DLL 加载到前端。
  3. 我们的 DLL 将与后端通信,并指示后端写入注册表。
  4. 后端将更改 NetSetupService 服务的 ImagePath
  5. 我们将可执行文件放置在新的 ImagePath 下并启动服务。
  6. 我们的可执行文件以 SYSTEM 身份启动,并在我们的桌面上生成一个以 SYSTEM 身份运行的 cmd.exe 进程。
为了减轻 COM 劫持作为权限提升攻击向量的风险,供应商应避免给予在低权限用户上下文中运行的应用程序特殊权限。微软并未在同一用户上下文中运行的进程之间强制执行安全边界,因此供应商可能总是需要追赶新技术,这些技术被用于注入其他进程。要求管理员权限进行所有关键操作的产品,例如设置排除项,被发现对类似利用更具抵抗力。

供应商可能允许用户在没有管理员权限的情况下触发某些操作以提高可用性。然而,他们应实施措施以防止代码注入到这些进程中。最有效的方法是将前端进程设置为受保护的轻量级进程(PPL)。不幸的是,根据 微软的文档,微软不支持为提供 UI 的进程设置 PPL。

因此,如果前端进程被赋予特殊权限,供应商必须尝试防止代码注入到该进程中。目前大多数供应商通过使用过滤驱动程序来实现这一点。另一种措施是钩住涉及 DLL 加载的函数,以强制执行签名验证和允许列表。如果正确实施,这将有助于防止 COM 劫持,如我们在帖子中所述。然而,这些方法需要持续更新,以应对可能允许攻击者在受信任的前端进程中执行代码的新注入技术。

在这项研究中,我们偶然发现了另一个有趣的问题:我们可以通过 COM 将 DLL 注入到端点检测和响应(EDR)的前端进程中。我们能否对后端做同样的事情,从而可能对安全解决方案造成拒绝服务(DoS)攻击?

我们经常在系统上永久停用现有安全解决方案时遇到困难,以便它不会干扰我们的工具。

注意:您不希望在生产系统上执行此操作。然而,我们经常使用专门为项目设置的系统,并在之后进行清除。在渗透测试场景中,在特定系统上停用安全解决方案是可以辩护的,因为这提高了渗透测试人员工作的效率,并允许测试蓝队的响应。

COM 劫持使我们能够将 DLL 注入到安全解决方案的中央后端进程中。最直接的方法是在 DLL 加载时终止该进程,从而有效地禁用安全软件。更高级的方法可能涉及挂起特定进程功能,使解决方案看起来功能正常,同时中和其有效性。

那么,后端进程是否使用 COM?我们的一些目标产品确实使用。我们发现了两个 EDR 产品,其后端进程利用了 COM 接口,我们能够劫持它们。作为我们的概念验证,每次我们的 DLL 被安全供应商的进程加载时,我们都会终止该进程。这有效地禁用了安全解决方案,并允许我们在没有干扰的情况下执行 mimikatz 等工具。

由于这需要 SYSTEM 权限,并且仅是 DoS 问题而不是权限提升问题,因此我们报告的两个供应商都拒绝发布修复。因此,这可能仍然是您下次想要摆脱 EDR 而不需要过于隐蔽的可行技术。

结论

在本系列的最后一部分中,我们详细介绍了自定义 IPC 协议的逆向工程,并演示了如何将其与 COM 劫持结合以获得 SYSTEM 权限。我们还探讨了防止类似漏洞的缓解技术,并讨论了 COM 劫持如何促进对安全产品的 DoS 攻击。

原文始发于微信公众号(securitainment):COMpromise - 再次写入 Registry,第 4 部分

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月5日21:07:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   COMpromise - 再次写入 Registry,第 4 部分http://cn-sec.com/archives/3796386.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息