报告 CVE-2023-28218
漏洞概述
导致 Windows 内核权限提升的漏洞。该漏洞出现在驱动程序 Windows Ancillary Function Driver for WinSock (AFD.sys) 中。该漏洞在 2023 年 4 月 11 日的补丁中修复。CVSS 评分为 3.1,为 7.0 / 6.1,被评为 Important。
漏洞描述
- 漏洞类型:
Double fetch 和 Integer overflow 导致 pool overflow。
- 漏洞发生在函数
Afd!AfdComputeCMSGLength 和 Afd!AfdCopyCMSGBuffer 中。

这两个函数都接收 v82 作为输入参数。v82 是一个由 usermode 控制的地址。在函数 Afd!AfdComputeCMSGLength 中,该地址被直接引用来获取值。然后计算 CMSG buffer 的长度并返回。之后根据该大小分配一个 pool。通过控制两个输入参数 a1 和 a2,我们可以控制返回的大小(参数 a3)。

在函数 Afd!AfdCopyCMSGBuffer 中,地址 v82 被直接引用来获取值。经过若干检查后,该值被用作 memmove 操作的大小。

该函数中存在一个 Integer overflow 错误,结合两个函数都直接从 usermode 地址获取值,我们可以在运行时改变该值。导致 memmove 时产生非常大的 size。当复制到无法访问的内存区域时,会触发 try-catch。但在此之前已复制了前面的内存区域。从而我们可以按想要的 size 进行复制。

- 要触发 poc,首先需要创建一个
type 为 SOCK_DGRAM 的 socket。然后使用该 socket 的句柄调用 bind 函数。最后创建两个线程:一个线程持续调用 IOCTL 为 0x120D3 的 DeviceControl。设置合适的 userbuffer 以绕过一些检查。另一个线程持续修改 usermode 地址中存储的值,该值作为上述两个函数的参数。
利用
- 利用此漏洞,我们可以 overflow 一个 non-paged NX pool,且 size 和 data 完全可由 usermode 控制。
- 利用思路是 spray 大量 Namedpipe 对象,然后释放一些对象以在堆中创建空洞。接着,分配一个大小为函数
Afd!AfdComputeCMSGLength 计算出的 pool,该 size 需要与 Namedpipe 对象的大小相同。这样,pool 将被分配在刚释放的对象位置上。使用 bug 溢出相邻的 Namedpipe 对象,进而利用 Namedpipe 的机制获得内核内存的读/写权限。读取系统进程的 token 并写入当前进程的 token。
受影响范围
- Windows Server 2012 R2 (Server Core installation) build trước 6.3.9600.20919
- Windows Server 2012 R2 build trước bản 6.3.9600.20919
- Windows Server 2012 (Server Core installation) build trước bản 6.2.9200.24216
- Windows Server 2012 build trước bản 6.2.9200.24216
- Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation) build trước bản 6.1.7601.26466
- Windows Server 2008 R2 for x64-based Systems Service Pack 1 build trước bản 6.1.7601.26466
- Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation) build trước bản 6.0.6003.22015
- Windows Server 2008 for x64-based Systems Service Pack 2 build trước bản 6.0.6003.22015
- Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation) build trước bản 6.0.6003.22015
- Windows Server 2008 for 32-bit Systems Service Pack 2 build trước bản 6.0.6003.22015
- Windows Server 2016 (Server Core installation) build trước bản 10.0.14393.5850
- Windows Server 2016 build trước bản 10.0.14393.5850
- Windows 10 Version 1607 for x64-based Systems build trước bản 10.0.14393.5850
- Windows 10 Version 1607 for 32-bit Systems build trước bản 10.0.14393.5850
- Windows 10 for x64-based Systems build trước bản 10.0.10240.19869
- Windows 10 for 32-bit Systems build trước bản 10.0.10240.19869
- Windows 10 Version 22H2 for 32-bit Systems build trước bản 10.0.19045.2846
- Windows 10 Version 22H2 for ARM64-based Systems build trước bản 10.0.19045.2846
- Windows 10 Version 22H2 for x64-based Systems build trước bản 10.0.19045.2846
- Windows 11 Version 22H2 for x64-based Systems build trước bản 10.0.22621.1555
- Windows 11 Version 22H2 for ARM64-based Systems build trước bản 10.0.22621.1555
- Windows 10 Version 21H2 for x64-based Systems build trước bản 10.0.19044.2846
- Windows 10 Version 21H2 for ARM64-based Systems build trước bản 10.0.19044.2846
- Windows 10 Version 21H2 for 32-bit Systems build trước bản 10.0.19044.2846
- Windows 11 version 21H2 for ARM64-based Systems build trước bản 10.0.22000.1817
- Windows 11 version 21H2 for x64-based Systems build trước bản 10.0.22000.1817
- Windows 10 Version 20H2 for ARM64-based Systems build trước bản 10.0.19042.2846
- Windows 10 Version 20H2 for 32-bit Systems build trước bản 10.0.19042.2846
- Windows 10 Version 20H2 for x64-based Systems build trước bản 10.0.19042.2846
- Windows Server 2022 (Server Core installation) build trước bản 10.0.20348.1668
- Windows Server 2022 build trước bản 10.0.20348.1668
- Windows Server 2019 (Server Core installation) build trước bản 10.0.17763.4252
补丁
- 该漏洞已通过将两个旧函数替换为两个新函数来修复,旧函数名后添加了后缀
_old。这些新函数已经。在新函数中,虽然仍存在 double fetch,但获取的值在使用前会进行检查。使用 Rtl 系列函数替代算术运算,以防止 Integer overflow。
结论
- 该漏洞影响范围非常广,威胁到众多系统。然而,运行利用 payload 时仍有小概率因 heap spray 导致 Windows 崩溃。同时,在将 cmd 进程权限提升到 System 后,如果退出该进程,也会导致 Windows 崩溃。这是因为在利用过程中破坏了 Namedpipe 对象。
附件
- Minimal POC

- Exploit POC
