网易首页 > 网易号 > 正文 申请入驻

CVE-2021-33739&CVE-2021-26868 内核漏洞分析

0
分享至

CVE-2021-33739

漏洞简介

释放CInteractionTrackerMarshaler对象时,只是清除了objChannel保存的对象数组指针,但是没有清除CInteractionTrackerBindingManagerMarshaler对象指向CInteractionTrackerMarshaler地址的指针,导致UAF漏洞。
近年来dwm组件相关的漏洞被频繁爆出,但是笔者没发现有一篇较为详细的从poc到利用,较为完整的分析文章,因此决定用最新的一枚dwm模块漏洞来分析,篇幅较长,望耐心看完

漏洞分析

该漏洞为UAF类型的漏洞,顾名思义,User After Free,要想触发漏洞需要重点观察的地方有两点

  • 找到free对象的地方
  • free之后再次访问被free掉对象的地方

正常情况

申请一个CInteractionTrackerBindingManagerMarshaler对象,两个CInteractionTrackerMarshaler对象,并将CInteractionTrackerMarshaler绑定到CInteractionTrackerBindingManagerMarshaler上面

调用SetResourceBufferProperty之前,可以看到CInteractionTrackerBindingManagerMarshaler对象0x38处为空

调用SetResourceBufferProperty之后,发现看到CInteractionTrackerBindingManagerMarshaler对象0x38处存放了一个指针,该指针指向的一个数组,数组保存着两个被绑定的CInteractionTrackerMarshaler对象,且两个CInteractionTrackerMarshaler对象0x190处存放这引用自己的对象,也就是CInteractionTrackerBindingManagerMarshaler对象

绑定之后,我们手动释放两个CInteractionTrackerMarshaler对象,下图为释放之前,可以看到是Allocated状态

下图为释放之后,可以看到是已经是Free状态了,且其父对象(其引用对象CInteractionTrackerBindingManagerMarshaler)的0x38处保存的指针不变,但是指向的内容确已经清空

漏洞场景

漏洞场景较正常情况,只是多了一步,那就是在手动释放之前,将构造szBuffer[2]的值改为0并调用SetResourceBufferProperty

第二次调用SetResourceBufferProperty之前,可以看到情况与正常情况下一致

key

第二次调用SetResourceBufferProperty之后,我们发现两个CInteractionTrackerMarshaler对象的0x190处的父对象被填为空了,也就是这两个对象当前没有被其他对象引用

CInteractionTrackerMarshaler释放之前,可以看到CInteractionTrackerBindingManagerMarshaler对象0x38处的指针,指向的数组如下

且CInteractionTrackerMarshaler释放之后,可以看到CInteractionTrackerBindingManagerMarshaler对象0x38处的指针,指向的数组并没有被清空,这就导致了父对象0x38偏移处保持了两个已经被释放的对象

why

对比正常情况和漏洞场景我们发现,只是简单的调用了一次SetResourceBufferProperty,且设置不了不同的szBuffer,怎么就会不一样了?IDA中观看SetResourceBufferProperty更加直观一点,我们可以看到 v9 = (_DWORD )(szBuff + 8)

后续对v9进行了判断,如果v9为空,那么则会调用RemoveBindingManagerReferenceFromTrackerIfNecessary函数,该函数将会将把CInteractionTrackerMarshaler对象0x190处置空

在之后构造nCmdReleaseResource,进行释放资源时最终会调用到DirectComposition::CApplicationChannel::ReleaseResource函数,最终调用到DirectComposition::CInteractionTrackerMarshaler::ReleaseAllReferences函数,该函数最终会对CInteractionTrackerMarshaler对象0x190处做解析,如果这里为空则不会释放其父对象CInteractionTrackerBindingManagerMarshaler偏移0x38处的指针,因此在我们第二次调用SetResourceBufferProperty后,给我们保留了一个不正常的CInteractionTrackerBindingManagerMarshaler对象(对象0x38偏移处保存了两个已经被释放的对象)

漏洞触发

在漏洞分析部分我们已经找到free对象的地方,现在我们迫切的需要一个能访问到被释放对象的函数

可以看到CInteractionTrackerMarshaler对象0x18处为我们指定的HANDLE标识

我们回头继续看SetBufferProperty函数,该函数第一个参数为objCInteractionTrackerBindingManagerMarshaler,第二个参数为objChannel

经过对objChannel的逆向,其结构体部分内容如下

通过handle为索引通过obChannle偏移0x38处,获取对应的CInteractionTrackerMarshaler对象 ,以下简称为A对象和B对象

我们可以看到v21是从数组里面取出来的第一个CInteractionTrackerMarshaler对象,这里会分别对比A对象的handle和从数组里取出来第一个对象的handle,以及B对象的handle和从数组里取出的第二个对象的handle进行对比,如果一样,则只是设置szBuffer[2]的内容到数组中

那么我们在CInteractionTrackerMarshaler对象被释放后,构造Fake_CInteractionTrackerMarshaler对象,使其handle分别为0x4和0x5,占用原先的内核地址空间

然后在创建handle为4和5的CInteractionTrackerMarshaler对象,最后调用NtDCompositionCommitChannel函数去触发BSOD

BSOD内容,现在我们已经有了free之后再次访问被free掉对象的地方。win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::EmitBoundTrackerMarshalerUpdateCommands+0x4f

漏洞利用

要想成功利用漏洞则要具备WWW条件,Write What Where

我们要寻找写入点,写什么,写到哪

通过漏洞触发,我们锁定到了UAF中的Use部分,指向数组的指针偏移为0x10处不能为0,否则来不到调用处,因此之前我们最后一次调用SetResourceBufferProperty设置的szBuffer[2]为0xffff。

由下图我们可以看到在取出objCInteractionTrackerMarshaler对象,先取出objCInteractionTrackerMarshaler对象0x0处的内容,改地址为虚表指针,再取出虚表0x50处的函数进行调用

我们可以通过映射0xffffffff位置,构造一个虚表,在虚表0x50处放入我们想要调用的函数

通常我们要用到一些小函数实现任意写,内核中就有这么一个函数SeSetAccessStateGenericMapping,该函数会将rdx放到[rcx+0x48]+0x8处

由此Fake_CInteractionTrackerMarshaler的0x48处为我们的 where,rdx为我们的what,Palette对象(Fake_CInteractionTrackerMarshaler)构造如下,Fake_CInteractionTrackerMarshaler的0x0处为映射的0xffffffff指针,Fake_CInteractionTrackerMarshaler的0x018处为handle,Fake_CInteractionTrackerMarshaler的0x48处为where,objChannel+0xb8处为what,该地址保存着这样一个值为0x000000000000000~0xffff….,但是我们是一个16字节的写,至此我们有了一个任意16字节内存破坏的利用链

where的选取

每个线程都有自己的_KTHREAD,该结构体部分截图如下,我们可以尝试将where定位在PreviousMode附近,该字段表示当前线程的当前模式,1为usermode,0为kernelmode,我们只要将PreviousMode改为0,即可利用kernelmode的权限进行一下API的操作,这些API在kernelmode下有更多的权限,从而导致LPE

EXP完整利用过程

漏洞利用第一步,释放对象

为了利用漏洞我们首先先利用nCmdCreateResource创建3个对象,分别为一个CInteractionTrackerBindingManagerMarshaler和两个CInteractionTrackerMarshaler。并将handle为2 和 3的CInteractionTrackerMarshaler对象绑定到CInteractionTrackerBindingManagerMarshaler上,将handle为4 和5的CInteractionTrackerMarshaler对象留着备用

为了创建上述对象,需要调用内核态函数NtDCompositionProcessChannelBatchBuffer数,该函数内部由DirectComposition::CApplicationChannel::ProcessCommandBufferIterator分发,当为nCmdCreateResource时则会调用DirectComposition::CApplicationChannel::CreateResource函数

DirectComposition::CApplicationChannel::CreateResource函数内部继续调用CreateInternalResource进行不同资源的创建,分别会于win32kbase!DirectComposition::CApplicationChannel::CreateInternalResource+0x9c453以及win32kbase!DirectComposition::CApplicationChannel::CreateInternalResource+0x9c479分别申请 CInteractionTrackerBindingManagerMarshaler对象、CInteractionTrackerMarshaler对象

动态创建对象,用windbg下如下断点,其中伪寄存器$t1的值为当前进程的EPROCESS,可以看到下图所示,我们分别打印出了这些被创建对象的内核地址空间

ba e1 win32kbase!DirectComposition::CApplicationChannel::CreateInternalResource+0x9c453 ".if $proc==$t1 {.printf \"申请的CInteractionTrackerBindingManagerMarshaler对象 地址为=%p\\r\\n\",@rax;gc} .else{.printf \"pass\\r\\n\" ;gc}"ba e1 win32kbase!DirectComposition::CApplicationChannel::CreateInternalResource+0x9c479 ".if $proc==$t1 {.printf \"申请的CInteractionTrackerMarshaler对象 地址为=%p\\r\\n\",@rax;gc} .else{.printf \"pass\\r\\n\" ;gc}"ba e1 win32kbase!NtDCompositionProcessChannelBatchBuffer+0x1a1 ".if $proc==$t1 {.printf \"消息分发\\r\\n\"} .else{.printf \"pass\\r\\n\" ;gc}"

创建之后,构造MappedAddress,设置nCmdSetResourceBufferProperty,并调用NtDCompositionProcessChannelBatchBuffer,将hande为2和3的对象绑定到CInteractionTrackerMarshaler对象绑定到CInteractionTrackerBindingManagerMarshaler上,从下图可以看到绑定之前和绑定之后在CInteractionTrackerBindingManagerMarshaler内核地址空间偏移0x38处保存了一个指针,该指针指向一个数组,数组中的值分别为之前被绑定的CInteractionTrackerMarshaler对象

再次构造MappedAddress,设置nCmdSetResourceBufferProperty,并调用NtDCompositionProcessChannelBatchBuffer,这次较上次调用的区别如下红色框

可以看到handle为2和3的CInteractionTrackerMarshaler对象,分别简称为A,B对象。在调用SetBufferProperty函数之前,其父对象(引用该对象的对象)都为绑定的CInteractionTrackerBindingManagerMarshaler对象

通过将szBuff[3]设置为0x00,调用SetBufferProperty函数之后,可以看到其父对象(引用该对象的对象)已经为空

继续构造MappedAddress,设置nCmdReleaseResource,并调用NtDCompositionProcessChannelBatchBuffer,在调用之前可以看到CInteractionTrackerMarshaler对象依旧是Allocted状态

在调用之前可以后CInteractionTrackerMarshaler已经变为了Free状态

释放之后回到应用态是用大量的Palette对象占用该地址空间

可以看到由win32k类型的Palette对象成功占位

可看到我们构造的Fake_CInteractionTrackerMarshaler(Palette)对象,成功占位

继续用用两个handle分别为0x4和0x5的对象,并将szBuff[2]设置为0xffff ,构造MappedAddress

调用SetBufferProperty可以看到原先的CInteractionTrackerBindingManagerMarshaler这个对象偏移0x38处并未被填空,其保存的指针依旧为指向一个数组,内容为原先的handle为两个已经释放掉的CInteractionTrackerMarshaler对象,

在占位到CInteractionTrackerMarshaler对象后,我们紧接着调用NtDCompositionCommitChannel函数,最终调用DirectComposition::CInteractionTrackerBindingManagerMarshaler::EmitBoundTrackerMarshalerUpdateCommands函数

利用构造的虚假虚表,调用SeSetAccessStateGenericMapping函数

SeSetAccessStateGenericMapping会进行十六字节的写操作

替换之前PreviousMode为1

替换后PreviousMode为0

接着就是注入Winlogon进程,成功获取system权限

附录

分析中用到的exp地址

https://github.com/mavillon1/CVE-2021-33739-POC

实验环境为

windows 10 1909 x64

原exp公开的时期为2021年4月份,其实包含了两个漏洞,exp作者应该也不知道,微软也不知道,微软只修复了内核中的漏洞,并没有修复应用层的漏洞,应用层漏洞的触发只需要szBuffer[0]和szBuffer[1]中的保存的handle一样即可。

欢迎登录安全客 -有思想的安全新媒体www.anquanke.com/加入QQ交流群1015601496 获取更多最新资讯

原文链接:https://www.anquanke.com/post/id/245427

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
章子怡、汪峰共同发文,2个孩子正面曝光,都不像章子怡

章子怡、汪峰共同发文,2个孩子正面曝光,都不像章子怡

闹腾小妮子
2024-06-02 22:19:12
已经赢麻了何塞卢:这些混蛋,他们有的人都已经不庆祝了

已经赢麻了何塞卢:这些混蛋,他们有的人都已经不庆祝了

直播吧
2024-06-02 10:32:12
回顾:江苏江阴一女销售出轨客户四年,聊天记录曝光,毁人三观

回顾:江苏江阴一女销售出轨客户四年,聊天记录曝光,毁人三观

蛙斯基娱乐中
2024-05-04 15:28:05
王中磊老婆看霍思燕的眼神火了!三分不屑七分恨意,有太多故事

王中磊老婆看霍思燕的眼神火了!三分不屑七分恨意,有太多故事

娱乐的小灶
2024-06-01 19:10:31
皇马夺欧冠,2大豪强分钱:切尔西躺赚1500万,多特500万

皇马夺欧冠,2大豪强分钱:切尔西躺赚1500万,多特500万

叶青足球世界
2024-06-02 17:53:18
大陆中止ECFA关税减让后,台公布民调,称76%民众不认同九二共识

大陆中止ECFA关税减让后,台公布民调,称76%民众不认同九二共识

美食阿鳕
2024-06-01 19:35:00
又一大行原干部落马!已离职多年,参与迷信活动

又一大行原干部落马!已离职多年,参与迷信活动

证券时报
2024-06-03 00:18:07
国内996是福报,日本应届生供不应求?日企:一年129天带薪年假!

国内996是福报,日本应届生供不应求?日企:一年129天带薪年假!

今日搞笑分享
2024-06-01 01:29:39
谨以此献给1980~1989出生的人,80后无限循环的一生,太真实了!

谨以此献给1980~1989出生的人,80后无限循环的一生,太真实了!

小九聊史
2023-06-15 10:15:51
张馨予与老公骑行云南,好身材引关注,何捷疯狂拍照:老婆太美了

张馨予与老公骑行云南,好身材引关注,何捷疯狂拍照:老婆太美了

娱乐八卦木木子
2024-06-03 02:21:07
新加坡总统和总理分别会见总统乌克兰泽连斯基

新加坡总统和总理分别会见总统乌克兰泽连斯基

花非花008
2024-06-02 20:35:17
湖南衡山市场监管所被剥夺行政编制的那些公务员,事前毫不知情?

湖南衡山市场监管所被剥夺行政编制的那些公务员,事前毫不知情?

布丁塔酱
2024-06-03 01:08:37
这谁受得了!日本36岁女星“泉里香”颜值身材却依旧火辣!

这谁受得了!日本36岁女星“泉里香”颜值身材却依旧火辣!

阿芒娱乐说
2024-05-27 01:53:05
两枚洲际导弹架起待发 六艘战略核潜艇失踪:不排除爆发核战?

两枚洲际导弹架起待发 六艘战略核潜艇失踪:不排除爆发核战?

聚峰军评
2024-06-02 09:46:47
台海局势紧张,解放军揪出罪魁祸首,赖清德被点名,统一越来越近

台海局势紧张,解放军揪出罪魁祸首,赖清德被点名,统一越来越近

战域笔墨
2024-06-02 15:12:15
TES首秀速通RA!三板斧混子无所遁形弱队要更弱了

TES首秀速通RA!三板斧混子无所遁形弱队要更弱了

游戏馬蹄铁
2024-06-02 21:01:12
"一夫一妻制违背人性,95%的人结婚后会生病,因为欲望没有满足"

"一夫一妻制违背人性,95%的人结婚后会生病,因为欲望没有满足"

百态人间
2024-06-01 11:22:48
欧洲杯死亡之组诞生!世界杯冠亚军同组,西意对决上演冠军之战

欧洲杯死亡之组诞生!世界杯冠亚军同组,西意对决上演冠军之战

元爸体育
2024-06-02 12:44:52
黄金崩盘!重磅利好不涨反跌,中国人成为最后接盘者

黄金崩盘!重磅利好不涨反跌,中国人成为最后接盘者

匹夫来搞笑
2024-06-03 08:14:51
卖不出美债,耶伦走向极端,不给中国半导体投资,连拜登也拦不住

卖不出美债,耶伦走向极端,不给中国半导体投资,连拜登也拦不住

小宇宙双色球
2024-06-02 19:20:03
2024-06-03 09:54:44
安全客
安全客
有思想的安全新媒体
1360文章数 4743关注度
往期回顾 全部

科技要闻

2万字演讲|黄仁勋剧透 未来3年新品有这些

头条要闻

牛弹琴:莫迪又大获全胜 他的手腕令对手叹为观止

头条要闻

牛弹琴:莫迪又大获全胜 他的手腕令对手叹为观止

体育要闻

万人空巷!皇马举行欧冠夺冠庆典

娱乐要闻

白玉兰提名:胡歌、范伟争视帝

财经要闻

黄仁勋的计划:涉及新AI平台 HBM4 机器人

汽车要闻

吉利银河E5 Flyme Auto智能座舱首发

态度原创

数码
手机
艺术
家居
游戏

数码要闻

联想 2024 款 ThinkPad P14s 笔记本 6 月 8 日开售,7999 元起

手机要闻

618选手机太纠结?这四款手机2000左右买了不后悔

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

家居要闻

风雅自来 中式的和谐平衡

《魔兽世界》今日接入战网!巫妖王之怒开启技术测试

无障碍浏览 进入关怀版