类型混淆
clfs.sys
由于对 rgContainers[0] 的校验逻辑不够严格,伪造 rgContainers[0] 后,ClientContext 与 ContainerContext 结构发生重叠。如果伪造数据被接受,在 CloseHandle 之后,CClfsLogFcbPhysical::FlushMetadata 会恢复 ClientContext 数据。
伪造 rgContainers[0] 后,ClientContext 与 ContainerContext 结构发生重叠。如果伪造数据被接受,在 CloseHandle 之后,CClfsLogFcbPhysical::FlushMetadata 会恢复 ClientContext 数据。由于结构重叠,该过程会将 ContainerContext->pContainer 更改为伪造数据。最后,当调用 CClfsBaseFilePersisted::RemoveContainer 时,会触发一次间接成员函数调用,执行特定 gadget,并导致权限提升。
createlog 创建一个新的日志文件。
添加一个 Container 条目。
创建一个指向当前目录的符号链接 X:\。
清除 cbSymbolName_start -> cbSymbolName_end 范围。
将 cbSymbolName_start 设置为 X:\N。
将 ContainerContext_start -> New_cbSymbolName_end 中的数据复制到 ClientContext。
更新 rgContainers[0],使其指向新的 ContainerContext_start 位置。
更新新的 ContainerContext->pContainer 值。
重新计算校验和。
在内核内存中定位 gadget 地址。
构建伪造的虚函数表。
完成其余内存设置。
CClfsLogFcbPhysical::Initialize
00000001C0002EDB 存储 ClientContext 数据。
在 CloseHandle 之后,执行 CClfsRequest::Cleanup->CClfsLogFcbPhysical::FlushMetadata。
它将伪造数据复制回 ClientContext。由于 ClientContext 与 ContainerContext 重叠,ContainerContext->pContainer 会被伪造数据覆盖。
随后 CClfsBaseFilePersisted::RemoveContainer 执行我们的 gadget,实现对任意地址的 16 字节写入。
https://zhuanlan.zhihu.com/p/645490730
https://github.com/fr4nkxixi/CVE-2022-24481-POC
https://securelist.com/windows-clfs-exploits-ransomware-cve-2022-24521/111580/
https://starmap.dbappsecurity.com.cn/blog/articles/2022/05/10/cve-2022-24481/
https://www.4awl.net/9646.html
win10_21H2_19044.1620
CClfsLogFcbPhysical::Initialize(0x??7c) 用于打开文件的初始化例程
bp clfs!CClfsLogFcbPhysical::Initialize + 0x45F
该代码存储 ClientContext 内存。

在 CloseHandle 之后,执行 CClfsRequest::Cleanup->CClfsLogFcbPhysical::FlushMetadata。
bp clfs!CClfsLogFcbPhysical::FlushMetadata + 0x46
这会恢复 ClientContext 数据。

CClfsBaseFilePersisted::RemoveContainer
bp clfs!CClfsBaseFilePersisted::RemoveContainer + 0x10F
使用伪造的虚函数表指针到达 gadget。

请注意,如果伪造文件失败,打开文件将失败,GetLastError 会显示原因。在这种情况下,利用流程无法继续。
CClfsBaseFilePersisted::RemoveContainer

CLFS!ClfsEarlierLsn
nt!SeSetAccessStateGenericMapping

nt!SeSetAccessStateGenericMapping

movdqu xmmword ptr [rax+8], xmm0 向 [rax+8] 写入 16 字节(XMMWORD,128 位)。
顺序执行后,结果是将来自 poi(rdx) 0xFFFFFFFF 的 16 字节数据写入 poi(poi(rcx+0x48)+0x8)。
rcx 是虚函数表指针位置,该位置可由我们控制。
https://github.com/uname1able/CVE-2022-24481.git
winver
win10_21H2_19044.1620

bp clfs!CClfsBaseFilePersisted::RemoveContainer + 0x10F
winver
win11_21H2_22000.593

bp clfs!CClfsBaseFilePersisted::RemoveContainer + 0x183