概述

2023年8月8日,微軟 patch thuesday 發布新補丁后,我們觀察到 Windows Common Log File System Driver 模塊修復了一個 Elevation of Privilege 類型的漏洞https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-36900, 通過分析補丁目前已經寫出了 POC。

分析環境

  • windows 10 版本 10.0.19045.3208
  • x64 dbg,windbg,IDA Pro 7.5

補丁對比

通過補丁對比分析在 CClfsBaseFilePersisted::ExtendMetadataBlockDescriptor(ulong,ulong) 函數中發現新增了一處校驗,該函數用于擴展元數據塊。

使用 IDA 分析補丁前后代碼變化發現新增了一處校驗【3】,在校驗【3】之前可以看到原本已經存在一處校驗【1】。分析函數 CClfsBaseFilePersisted::ExtendMetadataBlockDescriptor 的功能后發現【1】處的校驗用于檢查添加的扇區數乘扇區大小后不會溢出,且加上原元數據塊大小后也不能溢出。在【1】處的校驗通過后會在【2】處將現元數據塊大小與扇區大小對齊,【2】處的對齊操作在原元數據塊大小是已經與扇區大小對齊的情況下沒有什么問題,可是在原元數據塊未與扇區大小對齊的情況下此對齊操作就可能存在整數溢出,從而導致對齊后的現元數據塊小于原元數據塊大小并在后面的元數據塊擴展時崩潰。

擴展元數據塊。

POC 開發

元數據塊在存儲到文件時理應是與扇區大小對齊的,但是除了控制塊元數據塊的大小外其他兩種元數據塊的大小我們是可以通過操作日志文件中存儲的數據來控制的。這樣當我們控制 CLFS_CONTROL_RECORD->eExtendState、CLFS_CONTROL_RECORD->iExtendBlock、CLFS_CONTROL_RECORD->iFlushBlock 使流程來到 CClfsBaseFilePersisted::ExtendMetadataBlockDescriptor 函數時,只需將相應的元數據塊設置為一個非對齊的大小且將要添加的扇區數設置的足夠大時便為產生整數溢出。

整體代碼如下:

BSOD

1: kd> k
 # Child-SP          RetAddr               Call Site
00 ffffb98e`089902e8 fffff807`72b162c2     nt!DbgBreakPointWithStatus
01 ffffb98e`089902f0 fffff807`72b158a6     nt!KiBugCheckDebugBreak+0x12
02 ffffb98e`08990350 fffff807`729fc1c7     nt!KeBugCheck2+0x946
03 ffffb98e`08990a60 fffff807`72a4b2f5     nt!KeBugCheckEx+0x107
04 ffffb98e`08990aa0 fffff807`7286e7b0     nt!MiSystemFault+0x1b2905
05 ffffb98e`08990ba0 fffff807`72a0bbd8     nt!MmAccessFault+0x400
06 ffffb98e`08990d40 fffff807`71becfe4     nt!KiPageFault+0x358
07 ffffb98e`08990ed8 fffff807`71c3169f     CLFS!memset+0xa4
08 ffffb98e`08990ee0 fffff807`71c3128e     CLFS!CClfsBaseFilePersisted::ExtendMetadataBlockDescriptor+0x1ff
09 ffffb98e`08990f90 fffff807`71c19dc4     CLFS!CClfsBaseFilePersisted::ExtendMetadataBlock+0x40e
0a ffffb98e`08991060 fffff807`71be1dba     CLFS!CClfsBaseFilePersisted::OpenImage+0x418
0b ffffb98e`089910e0 fffff807`71c107a2     CLFS!CClfsLogFcbPhysical::Initialize+0x326
0c ffffb98e`08991220 fffff807`71c11fab     CLFS!CClfsRequest::Create+0x75e
0d ffffb98e`08991370 fffff807`71c11d77     CLFS!CClfsRequest::Dispatch+0x97
0e ffffb98e`089913c0 fffff807`71c11cc7     CLFS!ClfsDispatchIoRequest+0x87
0f ffffb98e`08991410 fffff807`728113a5     CLFS!CClfsDriver::LogIoDispatch+0x27
10 ffffb98e`08991440 fffff807`7280d964     nt!IofCallDriver+0x55
11 ffffb98e`08991480 fffff807`72bffabb     nt!IoCallDriverWithTracing+0x34
12 ffffb98e`089914d0 fffff807`72c1571e     nt!IopParseDevice+0x11bb
13 ffffb98e`08991640 fffff807`72c0d3ea     nt!ObpLookupObjectName+0x3fe
14 ffffb98e`08991810 fffff807`72bfd5db     nt!ObOpenObjectByNameEx+0x1fa
15 ffffb98e`08991940 fffff807`72bfc299     nt!IopCreateFile+0x132b
16 ffffb98e`08991a00 fffff807`72a0f8f5     nt!NtCreateFile+0x79
17 ffffb98e`08991a90 00007fff`af24da84     nt!KiSystemServiceCopyEnd+0x25
18 000000af`893cf928 00007fff`9a742199     0x00007fff`af24da84
19 000000af`893cf930 00000000`00000000     0x00007fff`9a742199