首页 > 其他分享 >CVE-2022-24481

CVE-2022-24481

时间:2023-07-24 11:15:22浏览次数:45  
标签:CLFS 漏洞 2022 pContainer ContainerContext CVE 日志 24481 ClientContext

一、漏洞信息

CVE-2022-24481是发生在CLFS驱动中的一个类型混淆漏洞,通过精巧的对blf文件的部分数据进行构造,可使LogBlockHeader中的ClientContextOffset指向ContainContext,从而造成类型混淆。

二、测试环境及漏洞复现

测试环境

  • POC: 4c1579c6a14bb8f3985be8a1a83c731c
  • 靶机: win10 x64 专业版,21H2

漏洞复现

wKg0C2Q2sNCADGRmAACqApdDnHs835.png

三、漏洞成因分析

CLFS内部结构

CLFS即通用日志文件系统是在 Windows
Vista 和 Windows Server 2003 R2 中为实现高性能而引入的日志框架,它负责提供一个高性能、通用的日志文件子系统,供专用客户端应用程序使用,提供 API 函数来创建、存储和读取日志数据。并且多个客户端可以共享以优化日志访问。CLFS驱动本质上的作用就是对BLF 日志进行格式解析及处理。

wKg0C2Q2sO6AYagaAACpvUlkLHQ344.png

BLF日志的格式如上图所示,每个日志块都以一个名为**_CLFS_LOG_BLOCK_HEADER**的结构开始:

wKg0C2Q2sPqARrwEAABiqSCl374584.png

Checksum(0xC)字段是该Log文件的CRC校验和,在对Log文件进行编码/解码操作时都需要对文件进行校验,通常在CLFS漏洞利用实现过程中都需要绕过CRC校验。

wKg0C2Q2sQOAHLjXAABIvr5kmE952.png

RecordOffsets(0x28)是日志块内记录的偏移量数组。CLFS
只处理指向 _CLFS_LOG_BLOCK_HEADER末尾的第一个记录偏移量 (0x70)。当基本日志文件存储在磁盘上时,必须对其日志块进行编码。

基本日志记录存储用于将基本日志文件与容器相关联的元数据。其结构如下:

wKg0C2Q2sQ6AcDusAAC7eLRM5CM015.png

rgClients(0x1a8)和rgContainers(0x398)字段分别是存储着ClientContext和ContainerContex偏移值的数组。

ClientContext的结构:

wKg0C2Q2sRqAc1pBAACd23BAMr8699.png

ContainerContext的结构:

wKg0C2Q2sSaARHRPAABWErwiK7Y466.png

pContainer(0x18) 实际上包含一个内核指针, 指向在运行时描述容器的类CClfsContainer。当Log文件在磁盘上时,该字段必须设置为零。

wKg0C2Q2sTAE3FfAAA0tptjrGE910.png

获取ClientContext/ContainerContext的函数分别是CClfsBaseFile::AcquireClientContext及

CClfsBaseFile::AcquireContainerContext,大致流程均是先通过CClfsBaseFile::GetBaseLogRecord获取基本日志块的地址,然后通过GetSymbol函数通过偏移找到对应的Context结构。

wKg0C2Q2sUqAF56AAABjhkWofRg013.png

漏洞触发

CVE-2022-24481漏洞原因在于CClfsBaseFile::GetSymbol获取ClientContext时对其字段的校验不够严格,攻击者进行精巧的数据布局后使rgClients的偏移指向ContainerContext。

  1. 添加容器(Container)

为Log文件添加容器,以便 BaseLogRecord中拥有ContainerContext。

wKg0C2Q2sWOAVGqdAAFu8CNwg6Y117.png

  1. 数据构造

成功创建Log文件并为其添加容器后,BaseLogRecord 0x1368和0x1528的偏移处分别存储着ClientContext和ContainerContext

wKg0C2Q2sYSASijsAAEP8IuGlCM728.png

wKg0C2Q2sZOAMxTdAADQVotuEug002.png

数据构造的目的是为了绕过CLFS在解析Log文件对context的校验。

第一部分绕过Log文件的crc校验。Log文件的BaseLogRecord在进行编码和解码都会进行CRC校验。

wKg0C2Q2sZAfgXeAACLwg0zqks834.png

在触发过程中,为绕过CLFS对Checksum字段的检查,需要自己实现一次CRC校验并将结果填充至Checksum(0xc)

wKg0C2Q2sbmAQ6tAAAB9gRKYZpA918.png

第二部分,对ClientCotext的数据进行修改,使其能够成功的绕过CLFS的检查最后指向ContainerContext。

首先,更新_CLFS_LOG_BLOCK_HEADER中 rgClients(0x1a8)字段,使rgClients存储的偏移值变为0x1520(ContainerContext offset为0x1528)

wKg0C2Q2sdqAeXPxAAAwci9d8Tg191.png

然后在0x1510及0x1514偏移处分别存储ClientContext新的起始偏移地址(0x1520)以及ClientContext的结尾偏移地址(0x1520+size(0x88)。

wKg0C2Q2seOAdBwcAAB2xq6F1o761.png

构造这两处值是为了绕过在CClfsBaseFile::GetSymbol函数中的相关检查,以使CLFS在调用

CClfsBaseFile::AcquireClientContext能够成功获取ClientContext。

wKg0C2Q2se2ABCfFAAByAhTY3O4401.png

完成以上步骤之后,rgClients已成功指向ContainerContext。

四、漏洞利用分析

漏洞成功触发之后,下一步就是要实现提权利用,对于此漏洞我们需要重点关注以下两个点:

  • 借助ClientContext对ContainerContext的修改能力
  • ContainerContext中pContainer(可将其指向R3内存)
  1. 修改pContainer

成功利用该漏洞前提就是能够控制pContainer指向的值,第一步就是通过ClientContext修改ContainerContext->pContainer的值。由于为Log文件添加容器之后,需要再次调用CreateLogFile对BaseLogRecord进行一次初始化更新

wKg0C2Q2shyAFjMAAAEiIeQLOj4265.png

大致逻辑首先获取ClientContext

wKg0C2Q2siaAHMn5AACSyNqsSFY827.png

将ClientContext中的数据保存到CclfsLogFcbPhysical类中,此处重点关注rcx+20h处的值,现存储着我们pContainer的目标值(r3可控地址0x40000000)。

wKg0C2Q2siANRAkAACwXmg05ek578.png

随后会调用CClfsBaseFilePersisted::LoadContainerQ函数加载Container并更新pContainer,让其指向在运行时描述容器的类CclfsContainer

wKg0C2Q2sjmARHHeAAE3PWG4QIo455.png

CclfsContainer类的前8个字节指向虚表

wKg0C2Q2skGAf0W1AADZ71E8Y8745.png

此时pContainer还是指向内核的CclfsContainer类,我们的可控地址0x40000000被保存到了CclfsLogFcbPhysical类的0x1a0处,经过分析发现,在close Log文件句柄过程中,CLFS会调用CClfsLogFcbPhysical::FlushMetadata对ClientContext进行更新

wKg0C2Q2smKAEF4wAAEEdO5btwg933.png

实际上就是将存储在CclfsLogFcbPhysical类中的数据重新写回到ClientContext。

wKg0C2Q2sm6ACqt8AAD9KVK4Qg173.png

由于ClientContext指向ContainerContext-0x8,这里将0x40000000赋给ClientContext+0x20就是修改ContainerContext+0x18(pContainer)为0x0x40000000。

  1. 修改previousMode

执行CloseHandle时,内核中首先会将当前线程的previousMode修改为内核态(0)

wKg0C2Q2soAMVOwAAAuaXuXbos431.png

wKg0C2Q2spKADHFtAACUELQO1cM234.png

待到成功执行完返回R3前,又会将当前线程的previousMode修改为用户态(1)

wKg0C2Q2spuAXM7RAAAte8qciKo991.png

wKg0C2Q2spAFuzyAABLLZpj4uM685.png

此漏洞的提权原理就是在返回R3前,修改当前线程的previousMode为0,下图为我们自定义构造由pContainer指向的” CclfsContainer”.

wKg0C2Q2sqqAKuA5AACvuQHhFKw934.png

0x0为“虚表指针“,0x20为文件句柄,0x30为previousMode+0x30 address

wKg0C2Q2sreATIyAAAA5Ms7iMYs168.png

漏洞利用是发生在CClfsLogFcbPhysical::CloseContainers函数中

wKg0C2Q2ssOAZuK4AAEy4Awwuw003.png

在CClfsLogFcbPhysical::CloseContainers首先通过ContainerContext获取到pContainer,然后对CclfsContainer类进行一个清理释放。这里我们拥有一个可控函数的执行!

wKg0C2Q2ssAHEnsAACCLfaq9iU653.png

CClfsContainer::Close实现:

wKg0C2Q2st2AKUqzAAA8XMWT9ek894.png

提权过程:

wKg0C2Q2suaAdRxWAABckHfKlsI239.png

随后调用ObfDereferenceObjectWithTag传入的参数为previousMode+0x30,并利用该函数的减数机制,将previousMode修改为0(内核态)

wKg0C2Q2su2Ab1pqAADLYlp1zYE046.png

此时,已到达提权目的。

最后,调用可控函数ClfsSetEndOfLog返回错误码到R3。

wKg0C2Q2svaAVMgRAABfAo5dj0M647.png

在提权样本中,利用当前线程的内核执行能力将当前线程的token替换为system token。

wKg0C2Q2swmAFiZhAAAwOpcW1aI998.png

Token替换之后,在将previousMode改回1(目的是混淆)

wKg0C2Q2sxSAQjbQAAAzynuLjuE853.png

至此,分析完毕!

标签:CLFS,漏洞,2022,pContainer,ContainerContext,CVE,日志,24481,ClientContext
From: https://www.cnblogs.com/SecIN/p/17576690.html

相关文章

  • 题解 P9474 [yLOI2022] 长安幻世绘
    看到极差,不难想到双指针。显然,如果\([l,r]\)的位置都被覆盖,那么其中最多可以选\(\lceil\frac{r-l+1}{2}\rceil\)个数。我们先将所有数离散化,排序,双指针卡取值范围。set里面存pair类型变量,表示覆盖的区间。每次将值为\(r\)的数的位置加入,在set中二分到与它相邻的区......
  • 2022 javax.management.InstanceNotFoundException: org.springframework.boot:ty
    解决"2022javax.management.InstanceNotFoundException:org.springframework.boot:ty"的步骤对于这个错误,我们需要明确以下几个步骤来解决问题。下面是一个整体的流程表格:步骤描述1确认是否存在相关的InstanceNotFoundException异常2检查org.springframework.boo......
  • JetBrains PhpStorm 2022 (Win&Mac) 中文激活版
    JetBrainsPhpStorm是一款由JetBrains开发的集成开发环境IDE),专门用于PHP语言开发。它提供了丰富的功能和工具,帮开发人员提高效率并编写高质量的PHP代码。以下是JetBrainsPhpStorm的一些常见特点和功能:代码编辑器:JetBrainsPhpStorm提供了强大的代码编辑器,支持语法高亮、代码补、代......
  • 在windows下使用vs2022编译v8引擎的稳定版本(2023.7.22)
    0.环境配置1.下载v8项目源代码2.下载开发工具3.下载配置项目4.编译安装ninja5.编译v8x64release动态库5.编译v8x64release静态库6.编译v8x64debug相关库动态版本静态版本6.编译v8ia32相关库①release版本动态静态②debug版本动态静态7.结尾......
  • 洛谷 P8490 [IOI2022] 鲶鱼塘
    洛谷传送门LOJ传送门不算很难的题,但是调起来比较恶心。下文默认下标从\(1\)开始。设第\(i\)列长堤的高度为\(h_i\)。考虑观察一些性质。Observation1:若\(h_{i-1}<h_i>h_{i+1}\),那么\(h_i=n\)一定不劣。若\(h_i<n\),\([h_i+1,n]\)的鱼是抓不到的,并......
  • Visual Studio IDE 2022 - how to disable navigation to decompiled sources
    VisualStudioIDE2022-howtodisablenavigationtodecompiledsources ......
  • 【专题】2022年中国跨境电商行业研究报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=32044近年来,我国的跨境电子商务发展迅速,在过去五年中,其贸易额增长率达到了16.2%,已经成为稳定对外贸易的一支重要力量(查看文末了解报告PDF版本免费获取方式)。点击阅读原文,获取专题报告全文,解锁文末52份跨境电商行业相关报告。一方面,随着跨境电子商......
  • Visual Studio 2022 Net6.0 无法发现testcase, 也无法执行test case
         解决办法:      <PropertyGroup>                  <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>         <GenerateAssemblyInfo>false</GenerateAssemblyInfo>     ......
  • [蓝桥杯 2022 国 B] 卡牌
    题目描述这天,小明在整理他的卡牌。他一共有\(n\)种卡牌,第\(i\)种卡牌上印有正整数数\(i(i\in[1,n])\),且第\(i\)种卡牌现有\(a_{i}\)张。而如果有\(n\)张卡牌,其中每种卡牌各一张,那么这\(n\)张卡牌可以被称为一套牌。小明为了凑出尽可能多套牌,拿出了\(m\)张空......
  • Visual Studio 2022 .NET 7读取程序集版本
    如果你也像我一样是从.NetFramwork升级到.Net7版本,那大概率会碰到不能正常读取Assembly下的正确程序集版本号,利用asm.GetName().Version读到的是0.0.0.0,解决方法是新建一个项目,并将“AssemblyInfo.cs”复制到你的项目下Properties内。一些产品名称、公司信息等自行修改,Guid可......