CVE-2022-37969

简介

Windows通用日志文件系统驱动程序(CLFS.sys)中存在越界写漏洞,在解析精心构造的BLF文件时,BLF日志块头的SignaturesOffset字段,会导致分配Symbol时的越界写,并破坏某些对象的虚拟函数表指针,成功利用此漏洞可实现本地权限提升。

成因

zscaler已于2022年10月将细节公布出来了, 该漏洞为已在野使用的漏洞,且内容较为详细。
下图为该文章原文:

文章内容简单总结下,该漏洞问题出在Initialize函数,ResetLog函数,AllocSymbol函数与CClfsContainer结构体:

Initialize函数会根据文件内容调用ResetLog, ResetLog函数会在特定情况下对指定位置的赋值0xffffffff, 从而绕过AllocSymbol函数写位置的校验, 最终造成越界写CClfsContainer结构体的指针, 从而在关闭Handle的时候任意代码执行。

基本流程

blf文件中需要修改如下值, 其中偏移0x800为文件中修改块的偏移

地址 原始值 目标值 备注
0x868 80 79 00 00 50 00 00 00 SignatureOffset
0x9a8 68 13 00 00 30 1b 00 00 ClientContextOffset
0x1b98 f8 00 00 00 4b 11 01 00 cbSymbolZone
0x2390 00 – b8 1b 00 00 30 1b 00 00 Client Context0
0x23a0 00 – 07 fd fd c1 88 00[0x03] 00 00 00 01 Client Context1
0x2418 00 – 20 00 00 00 Client Context2

step1

其中ClientContextOffset修改后, 指向了我们的fakeClientContext, 根据已有的文档我们可以发现, 因为fakeClientContext->eState=CLFS_LOG_SHUTDOWN, 所以在Initialize函数初始化的时候根据该值, 会调用ResetLog函数,

其中在ResetLog中会将指定位置赋值为0xffffffff00000000

step2

其中SignaturesOffset修改后, 在Initialize函数初始化的时候根据该值, 将指定位置的0x2*0x3d长度的值, 展开写到固定的位置, 并在Initialize函数的结尾, 将数据回写到上述指定的位置

其中原始位置与展开位置在Initialize函数的结尾时, 分别如下
原始位置的内容如下

展开位置的内容如下