首页
社区
课程
招聘
[原创]CVE-2020-1054分析
发表于: 2020-7-24 16:02 19086

[原创]CVE-2020-1054分析

2020-7-24 16:02
19086

CVE-2020-1054是存在于win32k.sys内核模块中的一个oob漏洞,成功利用可以导致权限提升。

原exp为rust语言所写,在分析中发现该exp并不能成功执行,在分析漏洞后感觉该漏洞利用的成功率较高,因此我决定用C语言重写该exp

原exp地址

image-20200721102638813

蓝屏的POC如下非常简单

通过栈回溯,可以找到触发崩溃的地址为vStrWrite01+0x36a

在对该函数进行逆向后,下面为该函数部分逆向截图,崩溃处有标注

image-20200721103105049

在崩溃处取值给了tmp,往下继续看,tmp是机会跟某些值进行and 或者是 or运算,且最终有机会赋值给自身,如果可以控制越界地址,则有可能实现任意内存破坏

image-20200721104042298

该地址在循环内,相对于其他漏洞略为复杂。

经过分析计算越界地址如下(其中pSurface为第三个参数,pStrrun为第一个参数):

oobTarget= pSurface->mySURFOBJ->pvScan0 + pStrrun->yPos pSurface->mySURFOBJ->lDelta + 4 (pStrrun->xrl->xPos >> 5);

在进入循环前下述result为固定值

offset = pStrrun_yPos * refpSurface->SurfObj.lDelta;

result = refpSurface->SurfObj.pvScan0 + offset;

因此可以越界地址可以描述为:

oobTarget= result + 4 * (pStrrun->xrl->xPos >> 5);

如下图椭圆圈内,在进入循环后result 每次增加refpSurface->SurfObj.lDelta大小

oobTarget= result + 4 (pStrrun->xrl->xPos >> 5)+refpSurface->SurfObj.lDeltaloopCount;

在本公式中,我们需要确定的值有 pStrrun->yPos,pStrrun->xrl->xPos,refpSurface->SurfObj.lDelta以及循环次数loopCount

image-20200721111211829

本人没有像原exp作者一样的fuzz算力,因此采用比较笨,但是比较实用的方法(栈回溯),推算yPos的计算公式

过程较为复杂,有兴趣的要有耐心慢慢分析(篇幅问题,在此处可能说的不详细)

为了方便读者理解,依旧采取函数执行流程进行讲解(算法的逆向其实是倒着来的,还是栈回溯)

oobTarget动态验证

image-20200721144844094

触发漏洞的顶层函数

DrawIconEx(exploit_dc, 0x900, 0xb, (HICON)0x40000010003, 0x0, 0xffe00000, 0x0, 0x0, 0x1);

yPos由arg3(0xb),以及arg6(0xffe00000)影响

第一次运算位置为GreStretchBltInternal+0x95e处

可以看到这里将arg3与arg6相加

yPos=arg3+arg6

image-20200723134739847

运算后在函数bStretch-->vOrderStupid中有层检验,此处算法为

yPos=arg3+arg6+1

image-20200723142432919

第二次计算在EngStretchBltNew-->vInitStrDDA函数中

yPos=P.rcx.yBottom=arg3+arg6+1+v30,v30也可用arg3和arg6表示

至此,只需要对下述算法进行还原,即可确定yPos的地址

image-20200724110855441

这里的逆向比较有意思,有兴趣的小伙伴可以跟一下

我将其还原为C代码,如下

可能不完全,该函数逻辑判断较多

image-20200724114027293

算法验证

image-20200724104423216

image-20200724154000080

pStrrun->xrl->xPos的值比较简单,直接就是arg2

refpSurface为vStrWrite01第3个参数,其类型为SURFACE,下图为reactos项目中对该结构体的具体定义

image-20200721141350681

现在我们来回顾一下SurfObj对象 ,其结构如下

image-20200721141536872

在windbg中我们可以看到SurfObj相关字段的含义,其中我们比较关注的是cx,cy,lDelta

通过计算可以得到refpSurface->SurfObj.lDelta= cx / 8

其中cx为CreateCompatibleBitmap(exploit_dc, 0x51500, 0x100)中的第二个参数

loopCount==pStrrun_cRep

在分析pStrrun->yPos时其实已经解决了这个值

这个值为quotient_count由agr3和arg6影响

quotient_count=((arg3 + 1 - (arg6 + arg3 + 1))/ 0x20);

这与原作者写的ptyhon脚本算法不一样,我用原作者的测试好像不是很准确,不知道是不是有什么误解

在漏洞触发过程中漏洞函数是被调用了两次,如下图yPos还会随之而改变,但是问题不大,每次增加pStrrun->cRep大小

image-20200724113808960

现在确定了所有的参数关系,理论上可以控制oobtarget

oobTarget= pSurface->mySURFOBJ->pvScan0 + pStrrun->yPos pSurface->mySURFOBJ->lDelta + 4 (pStrrun->xrl->xPos >> 5);

我们参考pSurface结构体,可以看到pSurface->mySURFOBJ->pvScan0=dwExpBitmapObj+0x238

oobTarget= dwExpBitmapObj+0x238 + pStrrun->yPos pSurface->mySURFOBJ->lDelta + 4 (pStrrun->xrl->xPos >> 5);

也就是说我们的oobtarget不能随意控制,但是确可以基于dwExpBitmapObj进行一个偏移

image-20200721142934617

原exp中选用的偏移为0x100000000

通过这个偏移我我们可以求得DrawIconEx的各个参数(理论上不唯一)

前面的文章对oob的地址计算已经叙述过了

通过上述文档,我们可以做到对相对于漏洞内核对象偏移0x100000000+0x358处进行内存破坏,进而在最后一次循环破坏0x100000000+0x70038处内容

在windows中bitamap内核对象的排布是连续的,如下图,如果在第二个红框的位置坐落的是一个Biamap对象,那么利用起来就比较简单了

image-20200724153355676
通过布局使得大小为0x7000的bitmap对象在这个位置 图片描述
参考上述SurfObj内核对象的结构体,我们可以知道偏移为0x38处为BitmapObj->SurfObj.sizlBitmap,如果使其值破坏变成一个较大的数,那么该对象则可以实现越界读写

操纵该对象读写的函数分别为GetBitmapBits,SetBitmapBits

其所读的最大值如下

BitmapObj->SurfObj.sizlBitmap.cy (((BitmapObj->SurfObj.sizlBitmap.cx v14 + 0xF) >> 3) & 0x1FFFFFFE);

image-20200724143259908

破坏前,原始值为0x6f000

image-20200724151832545

破坏后,值为0xffffff3f

image-20200724151935098

最后通过 替换tagWND.bServerSideWindowProc窗口过程函数,进行提权(方法很多,直接替换token,HookHal表都可以)

该漏洞利用的难点在于oobtarget在循环内部,算法过程相对复杂,需要有耐心

该漏洞内存破坏的时候与一张表有关系,这张表我没仔细研究,但是应该跟当前操作系统的主题等相关
如下:
代码没变,切换了系统的主题,也成功填充了,填充值为0xffffffff,通过之前提过的GetBitmapBits能读的最大值的算法计算,最大为0,所以并不能越界读写

 
 
 
 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-7-24 16:21 被Kalendsi编辑 ,原因:
上传的附件:
收藏
免费 6
支持
分享
最新回复 (8)
雪    币: 51
活跃值: (607)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
2
学习了 学习了
2020-7-24 16:22
0
雪    币: 11695
活跃值: (7179)
能力值: ( LV13,RANK:550 )
在线值:
发帖
回帖
粉丝
3
写的不错,有需要用自动dump内存结构的工具在这里https://gitee.com/cbwang505/WindbgScript楼主用的就是这款
2020-7-27 10:44
0
雪    币: 26245
活跃值: (63297)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
4
感谢分享!关注了!
2020-7-28 13:34
0
雪    币: 1493
活跃值: (175)
能力值: ( LV5,RANK:62 )
在线值:
发帖
回帖
粉丝
5
写得好啊
2021-3-26 17:03
0
雪    币: 97
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
编译不通啊
2021-4-14 15:21
0
雪    币: 2980
活跃值: (4891)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
王cb 写的不错,有需要用自动dump内存结构的工具在这里https://gitee.com/cbwang505/WindbgScript楼主用的就是这款
感谢!
2021-4-14 18:16
0
雪    币: 220
活跃值: (721)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
LZ 这个是支持什么系统的啊?在WIN2016 ,2019上测试都不成功呢
2021-6-3 09:18
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
dayang LZ 这个是支持什么系统的啊?在WIN2016 ,2019上测试都不成功呢
win7 sp1可以成功
2021-7-22 11:21
0
游客
登录 | 注册 方可回帖
返回
//