CVE-2024-6768 是 Windows 的公用日志文件系统(CLFS.sys)驱动程序中的一个漏洞, 由输入数据中指定数量的验证不当所致。 该缺陷会导致不可恢复的不一致状态,触发 KeBugCheckEx 函数并引发蓝屏死机(BSoD)。 该问题影响所有版本的 Windows 10 和 Windows 11、Windows Server 2016、Server 2019 和 Server 2022,即使已应用所有更新也不例外。 概念验证(PoC)表明,通过在 .BLF 文件中构造特定值, 非特权用户即可诱发系统崩溃。 潜在问题包括系统不稳定和拒绝服务,因为 恶意用户可利用此漏洞反复使受影响系统崩溃,扰乱正常运作并可能导致数据 丢失。
在最近两次针对公用日志文件系统(CLFS)的研究工作中,我 在两种情况下都实现了 RCE。(如果你感兴趣,以下是我为 CLFS CVE-2023-28252 和 CLFS CVE-2022-37969 所做的分析)。 然而,当我修改正在研究的 PoC 中的某些值时,我 观察到它在目标系统上触发了 BSoD。因此,我 决定报告此问题。本文档有助于理解该 BSoD, 并提供有关如何复现它的指导。
此漏洞源于输入中指定 数量的验证不当 (CWE-1284)
它会导致 CLFS.sys 驱动程序出现不可恢复的不一致状态, 强制调用 KeBugCheckEx 函数, 从而使 非特权用户能够在 Windows 中引发 BSoD。在本文中,我 以 CLFS.sys 版本 10.0.19041.3324 为例,但该问题 影响所有版本的 Windows 10 和 Windows 11,包括已应用所有更新的最新版本。
基础评分:CVSS 4.0:6.8 中等
向量字符串 CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
攻击向量 (AV):本地
攻击复杂度 (AC):低
攻击要求 (AT):无
所需权限 (PR):低
用户交互 (UI):无
机密性 (VC):无
完整性 (VI):无
可用性 (VA):高
机密性 (SC):无
完整性 (SI):无
可用性 (SA):无
当系统检测到不可恢复状态后,它会调用 KeBugCheckEx 函数,从而导致 BSoD,正如微软在 这篇文章中所述: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-kebugcheckex。

CClfsLogFcbPhysical::FlushLog+6F2 是 CLFS.sys 版本 10.0.19041.3324 中产生对 KeBugCheckEx 调用的地址:
CClfsLogFcbPhysical::FlushLog+6D5
CClfsLogFcbPhysical::FlushLog+6D5 loc_FFFFF8062EED4F35: ;
BugCheckParameter2
CClfsLogFcbPhysical::FlushLog+6D5 mov r8d, eax
CClfsLogFcbPhysical::FlushLog+6D8 and \[rsp+0A8h+Timeout\], 0
CClfsLogFcbPhysical::FlushLog+6DE mov r9, rbx ; BugCheckParameter3
CClfsLogFcbPhysical::FlushLog+6E1 mov edx, 3Ah ; ':' ;
BugCheckParameter1
CClfsLogFcbPhysical::FlushLog+6E6 mov ecx, 0C1F5h ; BugCheckCode
CClfsLogFcbPhysical::FlushLog+6EB mov r10, cs:\_\_imp_KeBugCheckEx
CClfsLogFcbPhysical::FlushLog+6F2 call **near ptr nt_KeBugCheckEx**
要开始分析,有必要了解 .BLF 文件格式, 它由易受攻击的公用日志文件系统驱动程序 CLFS.sys 处理, 该驱动程序位于 %windir%\system32 文件夹中。要了解更多信息, 请参阅本文末尾的参考资料部分。
在我们的概念验证仓库中, 54.blf 文件在偏移量 0x1c10 处有一个构造值(0xffffffff00ff01)。

该构造值位于 _CLFS_CLIENT_CONTEXT 结构的偏移量 0x38 处, 在 CClfsLogFcbPhysical::Initialize 中被复制到 CClfsLogFcbPhysical 结构的偏移量 0x538 处。

下方以 cidNode = 0xC1FDF006 开头的蓝色标记区域是 CLFSHASHSYM 结构

其后,以 cidNode == 0xC1FDF007 开头的是 _CLFS_CLIENT_CONTEXT 结构
在偏移量 0x38 处是字段 lsnOwnerPage,它将被构造值 0xffffffff00ff01 填充:
struct _CLFS_CLIENT_CONTEXT
{
CLFS_NODE_ID cidNode;
CLFS_CLIENT_ID cidClient;
USHORT fAttributes;
ULONG cbFlushThreshold;
ULONG cShadowSectors;
ULONGLONG cbUndoCommitment;
LARGE_INTEGER llCreateTime;
LARGE_INTEGER llAccessTime;
LARGE_INTEGER llWriteTime;
*CLFS_LSN **lsnOwnerPage; ***// offset 0x38
CLFS_LSN lsnArchiveTail;
CLFS_LSN lsnBase;
CLFS_LSN lsnLast;
CLFS_LSN lsnRestart;
CLFS_LSN lsnPhysicalBase;
CLFS_LSN lsnUnused1;
CLFS_LSN lsnUnused2;
CLFS_LOG_STATE eState;
union
{
HANDLE hSecurityContext;
ULONGLONG ullAlignment;
};
};
执行 PoC 时,它会构造 lsnOwnerPage 的值并调用 CreateLogFile,该值随后会在 UpdateCachedOwnerPage 中使用, 如下面的调用堆栈所示:

这是 PoC 调用 CreateLogFile 的地址, 构造值就在此处开始被使用:



在 AddLsnOffset 内部,会根据该构造值计算并返回一个 ulloffset:

返回的 ulloffset 为 0xFFFFFFFF00000000

之后,该值会被比较,然后退出函数 CClfsLogFcbPhysical::UpdateCachedOwnerPage

之后,流程返回到用户模式下的 PoC,当其退出时, 会使用原始构造的 ullofset 调用 CClfsLogFcbPhysical::FlushLog

该值会在循环中被比较,如果在任何一次循环中不相等,由于 系统处于不可恢复状态,便会调用 KeBugCheck 产生 BSoD 以重启自身:


你可以在 Fortra 的 GitHub 上找到包含源码和构造的 BLF 文件的可运行 PoC。
希望本文对你有帮助。如有任何问题,请联系 [email protected]。
公用日志文件系统(CLFS)参考资料: