
Deep-dive analysis of Windows CLFS type confusion (CVE-2022-24481) with root-cause explanation, exploitation flow, kernel gadget details, and working local privilege escalation PoC.
Type confusion
clfs.sys
Because the validation logic for rgContainers[0] is not strict, after forging rgContainers[0], ClientContext overlaps with the ContainerContext structure. If the fake data is accepted, after CloseHandle, CClfsLogFcbPhysical::FlushMetadata restores the ClientContext data.
After forging rgContainers[0], ClientContext overlaps with the ContainerContext structure. If the fake data is accepted, after CloseHandle, CClfsLogFcbPhysical::FlushMetadata restores the ClientContext data. Because the structures overlap, this process changes ContainerContext->pContainer to the forged data. Finally, when CClfsBaseFilePersisted::RemoveContainer is called, it triggers an indirect member-function call, executes a specific gadget, and leads to privilege escalation.
createlog creates a new log file.
Add a Container entry.
Create a symbolic link X:\ that points to the current directory.
Clear the cbSymbolName_start -> cbSymbolName_end range.
Set cbSymbolName_start to X:\N.
Copy the data in ContainerContext_start -> New_cbSymbolName_end into ClientContext.
Update rgContainers[0] so it points to the new ContainerContext_start location.
Update the new ContainerContext->pContainer value.
Recompute the checksum.
Locate the gadget address in kernel memory.
Build the fake virtual table.
Perform the remaining memory setup.
CClfsLogFcbPhysical::Initialize
00000001C0002EDB stores the ClientContext data.
After CloseHandle, CClfsRequest::Cleanup->CClfsLogFcbPhysical::FlushMetadata runs.
It copies the forged data back into ClientContext. Because ClientContext overlaps with ContainerContext, ContainerContext->pContainer is overwritten with the forged data.
CClfsBaseFilePersisted::RemoveContainer then executes our gadget, resulting in a 16-byte write to an arbitrary address.
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) initialization routine for opening the file
bp clfs!CClfsLogFcbPhysical::Initialize + 0x45F
This code stores the ClientContext memory.

After CloseHandle, CClfsRequest::Cleanup->CClfsLogFcbPhysical::FlushMetadata is executed.
bp clfs!CClfsLogFcbPhysical::FlushMetadata + 0x46
This restores the ClientContext data.

CClfsBaseFilePersisted::RemoveContainer
bp clfs!CClfsBaseFilePersisted::RemoveContainer + 0x10F
Use the forged virtual table pointer to reach the gadget.

Note that if the forged file fails, opening the file will fail and GetLastError will reveal the reason. In that case, the exploit flow cannot continue.
CClfsBaseFilePersisted::RemoveContainer

CLFS!ClfsEarlierLsn
nt!SeSetAccessStateGenericMapping

nt!SeSetAccessStateGenericMapping

movdqu xmmword ptr [rax+8], xmm0 writes 16 bytes to [rax+8] (XMMWORD, 128 bits).
After sequential execution, the result is to write the 16-byte data from poi(rdx) 0xFFFFFFFF into poi(poi(rcx+0x48)+0x8).
rcx is the virtual table pointer location, and this location is under our control.
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