深入解析CVE-2022-24547:Windows CastSrv.exe特权提升漏洞幕后剖析

本文深入剖析了Windows系统中的CVE-2022-24547漏洞,这是一个存在于CastSrv.exe组件中的特权提升漏洞。攻击者可利用会话劫持、不受检查的目录创建与不当权限设置,在系统其他用户账户下创建任意文件夹,最终实现权限提升。文章详细解释了漏洞成因、利用步骤及缓解建议。

Behind the Scenes: Understanding CVE-2022-24547

TL;dr

漏洞常常出现在我们意想不到的地方,CastSrv.exe中的CVE-2022-24547就是其中一个例子。CVE-2022-24547是CastSrv.exe中的一个特权提升漏洞,允许攻击者绕过安全限制并获取更高权限。我们将解析该漏洞的工作原理、利用方式以及防护方法。

摘要

项目 详情
厂商 Microsoft
安全影响 特权提升
CVE ID CVE-2022-24547

CVSS3.1 评分系统

基础评分: 7.8 向量字符串: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

攻击向量 (AV) 本地
攻击复杂性 (AC)
所需权限 (PR)
用户交互 (UI)
影响范围 (S) 未改变
机密性影响 (C)
完整性影响 (I)
可用性影响 (A)

受影响软件

产品: Microsoft Windows 10.0.18363.592 64位 (2020-01-14) ISO下载: https://uupdump.net/selectlang.php?id=99c9fe2f-8e78-451f-ab95-410106ee59bf 版本: Windows 10 10.0.18363.592 64位 (2020-01-14)

漏洞描述

该漏洞存在于CastSrv.exe程序的IcastServerControl::GetEnableControl函数中,允许攻击者在系统上另一个用户的账户内创建任意文件夹。

导致此漏洞的关键因素包括:

  • 会话劫持: 攻击者可以通过使用另一个已登录用户的会话来初始化程序,从而在该用户的上下文中运行CastSrv.exe。
  • 未经验证的文件夹创建: IcastServerControl::GetEnableControl函数会创建\AppData\Local\__Shared\PlayToReceiver目录,但未验证其是否为符号链接。
  • 不当权限: 创建的目录拥有完整的DACL权限,允许任何用户访问和修改(参见DACL访问控制)。

因此,该漏洞使攻击者能够在另一个用户的会话下运行CastSrv.exe,并利用IcastServerControl::GetEnableControl函数在该用户的目录中创建任意文件夹。

该接口注册信息如下:

  • clsid: f8842f8e-dafe-4b37-9d38-4e0714a61149
  • uuid: 7733f245-f909-4be2-918f-bddecbcd07cc
  • clsid 名称: CastServerInteractiveUser
  • 接口名称: ICastServerControl
  • 易受攻击的方法名称: ICastServerControl::GetEnableControl

注册的接口 (ICastServerControl) 可以通过使用“会话名字对象 (session moniker)”在机器上的任何交互式用户会话中被激活。这种能力为跨会话特权提升提供了一个潜在的攻击向量,因为接口及其关联方法都可能被利用。更多详细信息,请参考以下链接:COM Cross-Session Activation。

下文的控制流图简化了IcastServerControl::GetEnableControl函数中创建具有完整DACL权限的\\PlayToReceiver目录以及释放图像文件的底层函数调用。我将在“利用”部分对此进行更详细的描述。

漏洞利用

步骤 1: 我们需要使用目标用户的会话ID初始化CastSrv.exe。

在上图中,字符串 session:2!new:f8842f8e-dafe-4b37-9d38-4e0714a61149 表示数字 2 是目标用户的会话ID,而 f8842f8e-dafe-4b37-9d38-4e0714a61149 是 CastSrv.exe 服务的 GUID。你需要将 2 替换为目标用户的会话ID。

步骤 2: 我们需要触发 ICastServerControl 接口中的 CCastServerControl::GetEnableControl 函数。

在上图中,你可以看到 ICastServerControl 接口的虚函数表:

  • CCastServerControl::StartCastServer(void)
  • CCastServerControl::StopCastServer(void)
  • CCastServerControl::Advise(ICastAppLaunchCallback *)
  • CCastServerControl::Unadvise(ICastAppLaunchCallback *)
  • CCastServerControl::GetEnableControl(int *)
  • CCastServerControl::SetEnableControl(int)
  • CCastServerControl::PutSettings(IUnknown *)

当调用 ICastServerControl 接口中的一个方法 CCastServerControl::GetEnableControl 时,它将在 \AppData\Local\__SHARED\PlayToReceiver 下创建一个文件夹。

当调用时,CCastServerControl::GetEnableControl 会启动对 CServerHolder::GetDMRServer 的调用,随后调用 IPlayToReceiverAppRegistrar+72,该偏移量通过 DMRServer.dll 中的虚函数表对应于 CPlayToReceiverAppRegistrar::GetEnableControl

在 DMRServer.dll 内部,这些调用触发了 CSharedDMRCPlayToReceiverInternal 类的初始化。CSharedDMR 类的初始化导致创建了几个图像文件,稍后将详细讨论。同时,CPlayToReceiverInternal::RuntimeClassInitialize 方法在 %AppData% 目录内创建 PlayToReceiver 文件夹。值得注意的是,此过程未包含对符号链接的检查。

由于我们知道 ICastServerControl 的 UUID 是 7733f245-f909-4be2-918f-bddecbcd07cc,我们可以如下重新定义它:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 7733f245-f909-4be2-918f-bddecbcd07cc 是 ICastServerControl 的 UUID
class __declspec(uuid("7733f245-f909-4be2-918f-bddecbcd07cc")) ICastServerControl : public IUnknown {
public:
    virtual HRESULT __stdcall StartCastServer(void);
    virtual HRESULT __stdcall StopCastServer(void);
    virtual HRESULT __stdcall Advise(void* p0);
    virtual HRESULT __stdcall Unadvise(void* p0);
    virtual HRESULT __stdcall GetEnableControl(int64_t* p0);
    virtual HRESULT __stdcall SetEnableControl(int64_t p0);
    virtual HRESULT __stdcall PutSettings(IUnknown* p0);
};

由于我们已经从步骤1开始在 user02 的会话2中运行 CastSrv.exe,现在我们将调用 BindToObject 来获取指向 ICastServerControl 接口的指针,然后从那里触发 ICastServerControl->GetEnableControl 方法。

请注意,这是我们第一次调用 ICastServerControl->GetEnableControl 方法。然而,由于 CastSrv.exe 现在运行在另一个用户上下文中,我们已经在其目录中创建了文件夹 \user02\AppData\Local\__SHARED\PlayToReceiver

步骤 3: 我们通过调用 NtCreateSymbolicLinkObject,从 \user02\AppData\Local\__SHARED\PlayToReceiver 创建一个指向另一个路径 C:\\Users\\user02\\arbitrary_folder 的符号链接。

步骤 4: 然后我们需要再次调用 ICastServerControl->GetEnableControl,它将跟随符号链接并在指定位置创建任意文件夹。

在继续之前,我们需要删除在调用 ICastServerControl->GetEnableControl 时在 \user02\AppData\Local\__SHARED\ 中创建的一些图像文件。这些图像文件是 CastSrv.exe 从 C:\Windows\SystemResources\DDORes.dll.mun 中提取的图标文件。由于这些文件位于 SystemResources 文件夹中,修改它们需要管理员权限,而我们没有这些权限。

这些图像文件的创建是在 CSharedDMR 类初始化期间启动的。具体来说,当调用 CSharedDMR::RuntimeClassInitialize 时,它会从 DDORes.dll.mun 中提取图标,随后将它们写入上述图像文件中。

漏洞复现(可选)

  1. 创建一个拥有两个用户的 Windows 10 环境:user01 和 user02。
  2. 以 user02 身份登录,然后再以 user01 身份登录,以便同时运行两个会话。
  3. 在 user01 上运行概念验证 (PoC)。
  4. 检查 user02 中是否存在 C:\\Users\\user02\\test 目录。

利用条件

攻击者必须与目标用户处于同一系统上,并且目标用户必须具有活跃的会话,而攻击者在此会话中执行利用。

检测指南

该利用是通过利用与文件夹 \AppData\Local\__Shared\PlayToReceiver 相关联的符号链接来促成的。因此,用户应采取措施禁止创建此文件夹或验证其是否为符号链接。

建议的缓解措施

实施限制以防止创建文件夹 \AppData\Local\__Shared\PlayToReceiver

致谢

我还要感谢我的同事 Chen Le Qi 在整个研究过程中提供的宝贵指导——我真的学到了很多!

结论

在整个研究过程中,我学到了很多关于特权提升漏洞如何以微妙方式被利用的知识,尽管我从未成功利用 CVE-2022-24547。剖析漏洞、理解其流程以及试验不同方法的过程,让我对安全研究和漏洞利用开发有了宝贵的见解。虽然利用最终没有实现,但这段经历无疑扩展了我的技术知识,我希望这篇文章能为其他从事类似挑战的人提供有用的信息。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计