首页
社区
课程
招聘
[原创]CVE-2019-0803复现调试笔记
发表于: 2019-7-16 15:08 17198

[原创]CVE-2019-0803复现调试笔记

王cb 活跃值
11
2019-7-16 15:08
17198

360分析
看雪分析

关于漏洞的成因,以上两篇引用文章对漏洞的成因已经介绍的很详细,这里不再赘述.本文主要分析漏洞复现的调试过程,和漏洞利用方式的讨论.
在poc中先创建大小为0x350的AcceleratorTable,计算公式为:

然后又创建了0xcb0大小的AcceleratorTable,这么多个0x350之间的存在空隙,由于其他线程会创建对象占用池的原因,那些创建的小块一般不会大于0xcb0,所以会在多个0x350之间的存在空隙之间堆积,而之后创建的0xcb0大小的AcceleratorTable正好以0xcb00+0x350和方式占满整个一页也就是0x1000大小的空间,又因为0xcb0大小的块数量多余0x350的块,最后0xcb0下方方空余部分可以被同样0x350大小的bitmap和gdi对象占位即图中标识为free的块,占位后池排序方式如下图:
图
poc中出现了2种类型对象,一种是CreateAcceleratorTableW产生的user object对象,还有一种是通过CreateBitmap或GetCurrentObject产生的gdi对象.
在用户态只返回了产生对象的句柄,但是可以通过如下2中方式找到对象的内核泄露地址,
user object可以在user32.dll的导出函数gSharedInfo中找到泄露内核地址,具体计算公式为(SHAREDINFO->aheList+sizeOf(HANDLEENTRY)*(AcceleratorTabl句柄&0xffff))

对于gdi对象可以在PEB结构体中的GdiSharedHandleTable中找到泄露内核地址,具体计算公式为(PEB->GdiSharedHandleTable+ sizeof(HANDLEENTRY) *(gdi对象句柄&0xffff)),下面我们来看调试验证过程.
笔者使用在exsi上用windbg和vs双虚拟机调试内核和用户态的2种方法,具体方法见我的另一篇文章.
对win32k的NtUserCreateAcceleratorTable和win32k!HMAllocObject下断点得到到创建的AcceleratorTable泄露内核地址为fffff900c2877630.

在用户态查看栈变量

在内核态验证这个AcceleratorTable泄露内核地址

接下来验证gdi对象hgdiObj=00000000`0F050D4E,内核地址为FFFFF900C3041CC0,在内核态验证

在ddclient进程退出后再次查看gdi对象的池分布情况

之后poc中把后方存在大量0xcb0的AcceleratorTable和0x350的bitmap占满整个一页池布局中的bitmap清除,此时这个gdi对象必定在这些bitnap中一个位置,马上使用0x350的CreateAcceleratorTableW占位,再来看下池布局

池风水情况如图:
图
poc使用SetDIBColorTable对这个uaf的gdi对象进行操作,实现了任意地址3字节的写,原poc采用了写入Window的cbWNDExtra字段操作的buff指针和方式替换systemtoken实现提权,笔者认为太麻烦,改为hookhal函数至shellcode方式实现提权,可以实现相同效果.下面分析uaf的利用过程.
SetDIBColorTable会调用ZwGdiDoPalette进入内核态调用NtGdiDoPalette

NtGdiDoPalette接着又调用了GreSetDIBColorTable

这里xp是一个PALETTE64结构正确逆向结果如下,vCopy_rgbquad函数向xp的+0x80+(4*iStartRef)处写入3个字节也就是PALETTEENTRY的rbg3种颜色,可以由用户控制,这里iStartRef是索引值为0

下面我们看调试来验证这个结果:
surf->xpobj就是uaf的gdi对象相对于AcceleratorTableW+0x78偏移量位置的对,也就是最终被任意位置写入内存的对象,
在内核态查看:

继续运行程序至以下代码,然后在用户态查看:

再回到内核态查看

此时可以看到hal地址+8位置的内存数据已经被修改成target地址也就是shellcode地址
接下去调用NtQueryIntervalProfile执行eshellcode,最后成功在win7x64机器上弹出system的cmd,经测试成功率在50%左右,如图:
图

引用

我的poc地址

作者来自ZheJiang Guoli Security Technology

 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-8-9 09:01 被王cb编辑 ,原因:
收藏
免费 6
支持
分享
最新回复 (13)
雪    币: 203
活跃值: (1139)
能力值: ( LV9,RANK:195 )
在线值:
发帖
回帖
粉丝
2
2019-7-16 18:49
0
雪    币: 41
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
与github上的代码一致。
2019-7-19 16:18
0
雪    币: 11695
活跃值: (7179)
能力值: ( LV13,RANK:550 )
在线值:
发帖
回帖
粉丝
4
我的版本是采用覆盖hal方式利用
2019-7-19 16:27
0
雪    币: 41
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
@王cb 如果要支持其他系统修改那些地址。
2019-7-19 16:55
0
雪    币: 11695
活跃值: (7179)
能力值: ( LV13,RANK:550 )
在线值:
发帖
回帖
粉丝
6
自己逆向结构和偏移量
2019-7-19 19:33
1
雪    币: 3171
活跃值: (76)
能力值: (RANK:250 )
在线值:
发帖
回帖
粉丝
7
赞,自己动手调试,归纳,就是一个很好的学习过程。另外建议大家还是虚心学习,同样的代码自己调试研究一遍,分享下心得是很好的事情,还是尽量少一些,诸如这与哪一样,这不就是什么的感叹。
2019-7-22 08:14
1
雪    币: 16506
活跃值: (6392)
能力值: ( LV13,RANK:923 )
在线值:
发帖
回帖
粉丝
8
snowdbg 赞,自己动手调试,归纳,就是一个很好的学习过程。另外建议大家还是虚心学习,同样的代码自己调试研究一遍,分享下心得是很好的事情,还是尽量少一些,诸如这与哪一样,这不就是什么的感叹。
赞!我也觉得,别人能分享出来就已经很不错了!
2019-7-22 10:52
0
雪    币: 495
活跃值: (147)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
看不懂太菜了 谢谢大佬分享
2019-11-10 16:27
0
雪    币: 419
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
大师您好,有几个地方我有点不懂,这里我下了断点后go一直在断点上,无法回到win7里面去运行程序,我该怎么进入0:000啊,还有您计算的几个量分别从哪里看出来的啊
2021-2-25 21:40
0
雪    币: 419
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
大师,这个用户态调试一直显示私有符号表加载失败,请问要怎么弄呢
2021-2-26 20:22
0
雪    币: 419
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
请问有大佬可以帮忙解惑一下,那个用户态查的各种信息是怎么计算转换的吗
2021-2-27 01:50
0
雪    币: 419
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
请问gdi对象hgdiObj=00000000`0F050D4E,是怎么出来的啊
2021-2-27 09:50
0
雪    币: 419
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
在用户态查看栈变量要attach到哪个进程啊
2021-2-27 17:16
0
游客
登录 | 注册 方可回帖
返回
//