世界信息:[翻译] 星期二补丁- 星期三利用:24 小时内破解 WinSock (afd.sys) 的 Windows 辅助功
原文地址:/posts/patch-tuesday-exploit-wednesday-pwning-windows-ancillary-function-driver-winsock/
“星期二补丁,星期三利用” 是一句古老的黑客格言,指的是每月安全补丁公开后的第二天,漏洞就被武器化。随着安全性的提高和漏洞缓解措施变得更加复杂,制作武器化漏洞所需的研究和开发量也随之增加。这与内存损坏漏洞尤其相关。
(资料图片)
补丁差异和根本原因分析
根据微软安全响应中心(MSRC)发布的CVE-2023-21768的详细信息,该漏洞存在于辅助功能驱动程序(AFD)中,其二进制文件名为 。AFD 模块是 Winsock API 的内核入口点。利用这些信息,我们分析了 2022 年 12 月的驱动程序版本,并将其与 2023 年 1 月新发布的版本进行了比较。这些样本可以从 Winbindex 单独获取,无需从 Microsoft 补丁中提取更改的耗时过程。分析的两个版本如下所示。
/ Windows 11 22H2 / (December 2022)
/ Windows 11 22H2 / (January 2023)
Ghidra 用于为这两个文件创建二进制导出,以便可以在 BinDiff 中对它们进行比较。匹配功能的概述如下所示。
似乎只有一个函数发生了变化,afd!AfdNotifyRemoveIoCompletion
。这大大加快了我们对漏洞的分析速度。然后我们比较了这两个功能。下面的屏幕截图显示了在 Binary Ninja 中查看反编译代码时修补前后代码的变化。
Pre-patch, version
.
Post-patch, version
.
上面显示的此更改是对已识别功能的唯一更新。一些快速分析表明,正在根据以下内容执行检查
PreviousMode 。 如果 PreviousMode
为 0 (表明调用源自内核),则将值写入由未知结构中的字段指定的指针。另一方面,如果 PreviousMode 不为零,则 ProbeForWrite函数被调用确保该字段中设置的指针是驻留在用户模式中的有效地址。
补丁前版本的驱动程序中缺少此检查。由于该函数有一个针对 PreviousMode
的特定 switch 语句,因此假设开发人员打算添加此检查但忘记了(我们有时都缺咖啡☕!)。
从这次更新中,我们可以推断攻击者可以通过未知结构的 field_0x18
处的受控值到达此代码路径。如果攻击者能够使用内核地址填充此字段,则可以创建任意内核 Write-Where 原语。此时,尚不清楚正在写入什么值,但任何值都可能用于本地权限升级原语。
函数原型本身包含 PreviousMode
值和指向未知结构的指针,分别作为第一个和第三个参数。
逆向工程
我们现在知道漏洞的位置,但不知道如何触发有漏洞的代码路径的执行。在开始进行概念验证 (PoC) 之前,我们将进行一些逆向工程。
首先,交叉引用易受攻击的函数以了解其使用地点和方式。
在 afd!AfdNotifySock
中对易受攻击的函数进行了一次调用。
我们重复该过程,寻找对 AfdNotifySock
的交叉引用。我们发现没有对该函数的直接调用,但其地址出现在名为 AfdIrpCallDispatch
的函数指针表上方。
该表包含 AFD 驱动程序的调度例程。调度例程用于通过调用来处理来自 Win32 应用程序的请求 DeviceIoControl. 每个函数的控制代码可在 AfdIoctlTable
中找到。
然而,上面的指针并不像我们预期的那样位于 AfdIrpCallDispatch
表中。从 Steven Vittitoe 的 Recon 谈话幻灯片中,我们发现 AFD 实际上有两个调度表。第二个是 AfdImmediateCallDispatch
。通过计算该表的开头与存储 AfdNotifySock 的指针之间的距离,我们可以计算 AfdIoctlTable 的索引,该索引显示该函数的控制代码是 0x12127
。
值得注意的是,它是表中最后一个输入/输出控制(IOCTL)代码,表明 AfdNotifySock
很可能是最近添加到 AFD 驱动程序中的新调度函数。
此时,我们有几个选择。我们可以在用户空间对相应的 Winsock API
进行逆向工程,以更好地了解底层内核函数是如何调用的,或者对内核代码进行逆向工程并直接调用它。我们实际上并不知道哪个 Winsock 函数对应于 AfdNotifySock
,因此我们选择了后者。
我们发现 x86matthew 发布的一些代码通过直接调用 AFD 驱动程序来执行套接字操作,放弃了 Winsock 库。从隐秘的角度来看,这很有趣,但就我们的目的而言,它是一个很好的模板,可以创建 TCP 套接字的句柄以向 AFD 驱动程序发出 IOCTL 请求。从那里,我们能够到达目标函数,正如在内核调试时到达 WinDbg 中设置的断点所证明的那样。
现在,回顾一下 DeviceIoControl
的函数原型,通过它我们从用户空间调用 AFD 驱动程序。参数之一 lpInBuffer 是用户模式缓冲区。如上一节所述,该漏洞的发生是因为用户能够在未知数据结构中将未经验证的指针传递给驱动程序。该结构是通过 lpInBuffer
参数直接从我们的用户模式应用程序传入的。它作为第四个参数传递到 AfdNotifySock 中,并作为第三个参数传递到 AfdNotifyRemoveIoCompletion
中。
此时,我们不知道如何填充 lpInBuffer
中的数据(我们将其称为 AFD_NOTIFYSOCK_STRUCT
),以便通过到达 AfdNotifyRemoveIoCompletion
中易受攻击的代码路径所需的检查。我们逆向工程过程的其余部分包括遵循执行流程并检查如何访问易受攻击的代码。
让我们逐一检查一下。
我们遇到的第一个检查是在 AfdNotifySock
的开头:
此检查告诉我们 AFD_NOTIFYSOCK_STRUCT
的大小应等于 0x30 字节,否则函数会失败并显示 STATUS_INFO_LENGTH_MISMATCH
。
下一个检查验证结构中各个字段中的值:
当时我们不知道这些字段对应什么,所以我们传入一个 0x30
字节数组,其中填充了 0x41
字节(AAAAAAAAA...)。
我们遇到的下一个检查是在调用之后 ObReferenceObjectByHandle. 该函数将输入结构的第一个字段作为其第一个参数。
该调用必须返回成功才能继续到正确的代码执行路径,这意味着我们必须将有效的句柄传递给 IoCompletionObject
。没有正式记录的方法可以通过 Win32 API 创建该类型的对象。然而,经过一番搜索,我们发现了一个未记录的 NT 函数 NtCreateIoCompletion 之后,我们到达一个循环,其计数器是结构中的值之一:
该循环检查结构中的一个字段,以验证它包含有效的用户模式指针并将数据复制到其中。每次循环迭代后指针都会递增。我们用有效地址填充了指针,并将计数器设置为 1。从这里,我们最终能够到达存在漏洞的函数 AfdNotifyRemoveIoCompletion
。
进入 AfdNotifyRemoveIoCompletion
后,第一个检查是结构中的另一个字段。它必须是非零的。然后将其乘以 0x20,并与结构体中的另一个字段一起作为指针参数传递到 ProbeForWrite
。从这里,我们可以使用有效的用户模式指针 (pData2
) 和字段 dwLen = 1
进一步填充结构(以便传递给 ProbeForWrite
的总大小等于 0x20
),并且检查通过。
最后,在到达目标代码之前要通过的最后一个检查是对 IoRemoveCompletion
的调用,它必须返回 0 (STATUS_SUCCESS
)。
该函数将阻塞,直到:
完成记录可用于 IoCompletionObject
参数
超时到期,作为函数的参数传入
我们通过结构控制超时值,但简单地将超时设置为 0 不足以让函数返回成功。为了使该函数无错误地返回,必须至少有一个可用的完成记录。经过一番研究,我们发现了未记录的功能 NtSetIoCompletion 它手动增加 IoCompletionObject
上的 I/O 挂起计数器。在我们之前创建的 IoCompletionObject
上调用此函数可确保对 IoRemoveCompletion
的调用返回 STATUS_SUCCESS
。
触发任意写位置
现在我们可以到达易受攻击的代码,我们可以用任意要写入的地址填充结构中的适当字段。我们写入该地址的值来自一个整数,该整数的指针被传递到对 IoRemoveIoCompletion
的调用中。 IoRemoveIoCompletion
将此整数的值设置为调用 KeRemoveQueueEx
的返回值。
在我们的概念验证中,该写入值始终等于 0x1。我们推测 KeRemoveQueueEx
的返回值是从队列中删除的项目数,但没有进一步调查。此时,我们已经有了所需的原语,并继续完成漏洞利用链。我们后来证实了这个猜测是正确的,并且可以通过对 IoCompletionObject
上的 NtSetIoCompletion
进行额外调用来任意增加写入值。
LPE with IORING
由于能够在任意内核地址写入固定值 (0x1),我们继续将其转换为完整的任意内核读/写。由于此漏洞影响最新版本的 Windows 11(22H2),因此我们选择利用 Windows I/O 环对象损坏来创建我们的原语。Yarden Shafir 撰写了许多关于 Windows I/O 环的优秀文章,并且还开发并披露了我们在漏洞利用链中利用的原语。据我们所知,这是该原语首次被用于公共漏洞利用。 当用户初始化 I/O 环时,会创建两个独立的结构,一个在用户空间,一个在内核空间。 这些结构如下所示。
内核对象映射到 nt!_IORING_OBJECT
,如下所示。
请注意,内核对象有两个字段:RegBuffersCount
和 RegBuffers
,它们在初始化时被清零。该计数指示有多少 I/O 操作可以在 I/O 环中排队。另一个参数是指向当前排队操作列表的指针。
在用户空间端,调用 kernelbase!CreateIoRing时,如果成功,您将返回一个 I/O 环句柄。该句柄是指向未记录结构 (HIORING
) 的指针。我们对这种结构的定义是从 Yarden Shafir 所做的研究中获得的。
如果某个漏洞(例如本博文中提到的漏洞)允许您更新 RegBuffersCount
和 RegBuffers
字段,则可以使用标准 I/O Ring API 来读取和写入内核内存。
正如我们在上面看到的,我们可以利用该漏洞在我们喜欢的任何内核地址写入 0x1
。要设置 I/O 环原语,我们只需触发该漏洞两次即可。
在第二个触发器中,我们将 RegBuffers
设置为可以在用户空间中分配的地址(例如 0x0000000100000000
)。
备注:需要验证两次的原因就是 RegBuffersCount
和 RegBuffers
分别验证是否能通过带有缺陷的驱动写入。
下面的屏幕截图显示了这样一个 nt!_IOP_MC_BUFFER_ENTRY
。请注意,操作的目标是内核地址 (0xfffff8052831da20
),并且在本例中操作的大小为 0x8
字节。从结构中无法判断这是读操作还是写操作。操作的方向取决于使用哪个 API 对 I/O 请求进行排队。利用 kernelbase!BuildIoRingReadFile 导致任意内核写入,kernelbase!BuildIoRingWriteFile
导致任意内核读取。
为了执行任意写入,I/O 操作的任务是从文件句柄读取数据并将该数据写入内核地址。
相反,为了执行任意读取,I/O 操作的任务是读取内核地址处的数据并将该数据写入文件句柄。
Demo
设置原语后,剩下的就是使用一些标准内核后利用技术来泄漏系统(PID 4)等提升进程的令牌并覆盖不同进程的令牌。
视频地址:/M3IPsKAsxvQ
在野利用
在我们的漏洞代码公开后,来自360 Icesword Lab的Xiaoliang Liu(@flame36987044)首次公开披露,他们在今年早些时候发现了利用该漏洞的样本(ITW)。 ITW 样本使用的技术与我们的不同。攻击者使用相应的 Winsock API 函数 ProcessSocketNotifications
触发漏洞,而不是像我们的漏洞利用那样直接调用 驱动程序。
360冰剑实验室官方声明如下:
“360冰剑实验室专注于APT检测与防御。基于我们的0day漏洞雷达系统,今年1月份我们在野外发现了CVE-2023-21768的利用样本,该样本与 @chompie1337 和 @FuzzySec 公布的利用样本不同,它是通过系统机制和漏洞特征进行利用的。该漏洞与 NtSetIoCompletion
和 ProcessSocketNotifications
有关, ProcessSocketNotifications
获取调用 NtSetIoCompletion
的次数,因此我们使用它来更改权限计数。”
结论和最终反思
您可能会注意到,在逆向工程的某些部分,我们的分析是肤浅的。有时,仅观察一些相关的状态变化并将程序的某些部分视为黑匣子是有帮助的,以避免陷入不相关的兔子洞。这使我们能够快速扭转漏洞,尽管最大化完成速度不是我们的目标。此外,我们对 中所有报告的漏洞进行了补丁差异审查,这些漏洞被标记为“利用可能性更大”。我们的审查显示,除了两个漏洞之外,所有漏洞都是由于对从用户模式传入的指针验证不当造成的。这表明,了解过去的漏洞(尤其是特定目标内的漏洞)的历史知识,对于发现新漏洞可能会卓有成效。当代码库扩展时,同样的错误很可能会重复。请记住,新的 C 代码 == 新的 bug 。正如发现上述漏洞在野外被利用所证明的那样,可以肯定地说,攻击者也在密切监视新的代码库添加。
Windows 内核中缺乏对管理员模式访问保护 (SMAP) 的支持,这给我们提供了丰富的选项来构建新的纯数据利用原语。这些原语在支持 SMAP 的其他操作系统中不可行。例如,考虑 CVE-2021-41073,这是 Linux 的 I/O 环预注册缓冲区实现中的一个漏洞(我们在 Windows 中滥用相同的功能用于 R/W 原语)。此漏洞可以允许覆盖已注册缓冲区的内核指针,但不能用于构造任意 R/W 原语,因为如果该指针被替换为用户指针,并且内核尝试在那里读取或写入,系统将崩溃。
尽管微软尽了最大努力来消除人们喜爱的漏洞利用原语,但肯定会发现新的原语来取代它们。我们能够利用最新版本的 Windows 11 22H2,而不会遇到 HVCI(内存完整性和基于虚拟化的安全性) 等基于虚拟化的安全功能的任何缓解或限制。
引用
1.MSRC (CVE-2023-21768) (/update-guide/en-US/vulnerability/CVE-2023-21768)
2. I/O Rings – When One I/O Operation is Not Enough (@yarden_shafir) (/i-o-rings-when-one-i-o-operation-is-not-enough/)
3.IoRing vs. io_uring: a comparison of Windows and Linux implementations (@yarden_shafir) (/ioring-vs-io_uring-a-comparison-of-windows-and-linux-implementations/)
4.One Year to I/O Ring: What Changed? (@yarden_shafir)(/one-year-to-i-o-ring-what-changed/)
5. One I/O Ring to Rule Them All: A Full Read/Write Exploit Primitive on Windows 11 (@yarden_shafir)(/one-i-o-ring-to-rule-them-all-a-full-read-write-exploit-primitive-on-windows-11/)
6. Arbitrary Kernel RW using IORING’s (@FuzzySec) (/Posts/Arbitrary+Kernel+RW+using+IORING's)
7.NTSockets – Downloading a file via HTTP using the NtCreateFile and NtDeviceIoControlFile syscalls (@x86matthew)(/view_post?id=ntsockets)
8. Reverse Engineering (@bool101)(/2015/slides/r)
9. Microsoft Windows Ancillary Function Driver for WinSock privilege escalation CVE-2023-21768 Vulnerability Report(/vulnerabilities/243235)
上一篇:天天速看:景良东:黄金反弹中阳,震荡仍需关注欧盘定强弱!
下一篇:最后一页
夏季补水新风尚 市场上功能性饮料新品频出
前段时间,刘畊宏引爆了全民健身热潮,与此同时,全国多地迎来高温天气。在多重因素的影响下,越来越多的消费者意识到了补充电解质的重要性
2022-08-09郑州管城区、二七区今天开展核酸检测,最全采样点看这里
今天(5月18日)郑州市管城区7:00—17:00二七区9:00—16:00开展核酸检测管城回族区新冠肺炎疫情防控指挥部办公室关于在全区范围开展新冠病
2022-05-19郑州发布99号通告:调整封控管控区域
郑州市新冠肺炎疫情防控指挥部办公室关于调整封控管控区域的通告(2022年99号)根据疫情形势变化,经郑州市疫情防控指挥部研究,自5月18日
2022-05-195月17日河南新增本土确诊病例3例、本土无症状感染者8例
5月17日0—24时,全省新增本土确诊病例3例(郑州市3例),含1例无症状感染者转确诊病例(在郑州市),新增本土无症状感染者8例(郑州市6例
2022-05-19【行走郑州·读懂最早中国】锁定“云游麦田里的博物馆”直播,探寻最早中国
黄河孕育华夏,麦穗延续苍生,文物折射历史,历史照亮未来。看直播 抽门票为全面展示郑州城市魅力,深入塑造行走郑州·读懂最早中国品牌体
2022-05-19郑州约谈百果园郑州地区负责人
今日记者获悉,针对近期成都、武汉相继曝出百果园销售腐败变质水果切盘的负面新闻,为全面加强能力作风建设,严格落实国家食品安全示范城市
2022-05-19全力备汛!郑州94支队伍10313人集结到位
记者从近日召开的郑州市2022年城市防汛工作会议上了解到,郑州市组建了94支共10313人的防汛应急抢险队伍。目前,这些队伍正在全力备汛。据
2022-05-19【行走河南·读懂中国】河南四大文旅集团入榜全国文旅集团品牌影响力百强
2022年5月16日,迈点研究院发布《2022年4月中国文旅业发展报告》,河南省的四个知名文旅集团,银基文旅集团、建业文旅、洛阳文旅集团、河南
2022-05-19图集|来自郑州五月的浪漫,闯入莫奈的花园
遇见郑州五月的浪漫,走进这片虞美人和矢车菊的花海,彷佛置身于莫奈的花园。色彩缤纷的花儿在微风中摇曳生姿,好似步入童话般的世界。
2022-05-19郑州市普通中专采用网上报名 志愿填报时间为5月22日〜25日
5月17日上午,《2022年郑州市普通中等专业学校招生工作意见》发布,今年,郑州市普通中专采用网上报名。普通中专志愿填报时间为5月22日至25
2022-05-19X 关闭
X 关闭