npoi 未将对象引用设置到对象的实例_类型混淆漏洞实例浅析

b01619834be456ebda2c227e9d418688.png

类型混淆漏洞一般是将数据类型A当做数据类型B来解析引用,这就可能导致非法访问数据从而执行任意代码。

本文通过IE类型混淆漏洞实例和Word类型混淆漏洞实例进行分析,来学习理解类型混淆漏洞原理。

实例一:IE/Edge类型混淆漏洞(CVE-2017-0037)

漏洞原因:函数处理时,没有对对象类型进行严格检查,导致类型混淆。

分析环境: Win7、IE11

分析工具: Windbg、od、IDA Pro

977d1ffeb730a9362b67bd87a8fe8cbb.png

在PoC中定义了一个table,标签中定义了表id为th1,在boom()中引用,然后是setInterval设定事件。

漏洞成因分析:

运行PoC,用OD或Windbg附加并加载运行,出现崩溃,如下图

3126f1bb0b74806ef377377a330712a0.png

c026848c44e91216c28c379e87b781a2.png

从崩溃点可以看到eax作为指针,引用了一个无效地址,导致崩溃,而上一条指令是一个call,如下

2a582bde184d3f9d9d76f55a6b4cf612.png

这个无效的返回值来自这个call,此时我们进行逆推,在这个call处下断点,

46bf04c4c53fb1f101fd36a58c4cc0dc.png

ecx作为参数,存放的对象是一个Layout::FlowItem::`vftable虚表

77764c4a679fd9adbf9c597cf5f7aeaf.png

这个值会在Readable函数中引用,如下图

d202a42ad819b6099aed6ca470fd094b.png

fc0a207cc9ecd9c9ae353350e1521633.png

这里读取虚表中+4的值,为0时this指针赋值v1,随后v1+16后返回,因此,Layout::FlowItem::`vftable所属指针的这个情况是正常的,函数会正常返回进入后续处理逻辑。

3b38bd208d88e15d80e3e960c3df694b.png

让程序继续运行,会再次调用该函数,此时ecx并不是一个虚表对象,而是一个int Array对象,这里我们可以通过条件断点来跟踪两个对象的创建过程,重点关注两个对象创建的函数,一个是FlowItem::`vftable对应的虚表对象,另一个是引发崩溃的int Array对象。这两个函数的返回值,也就是eax寄存器中存放的指向这两个创建对象的指针。

fa369adc3b44d61d8d1062eb118adb77.png

b2a5502bd908d94c48695030b7ef9c68.png

通过条件断点,输出每一次int Array object创建的对象信息

67595b91a07ec6c5bf6017d3a0084ef7.png

1678b6b3dde7814c825eb8f503935564.png

通过跟踪可以看到第一次调用Readable函数时ecx是一个正常的FlowItem对象,而第二次调用的时候ecx是一个int Array Object。Layout::Patchable >::Readable函数是处理虚表对象的函数,由于boom()函数中引用th1.align导致Readable函数得到第二次引用,由于没有进行对象属性检查,导致第二次调用时将table对象传入,最终发生类型混淆崩溃。

分析利用关键点

首先我们分析崩溃点上下文,通过流程走向看看是否有可利用的点,

2911c05c66c5b6272651448b84534552.png

在判断eax返回值不等于0后,会继续往下调用Readable函数,且eax会连续引用,后面看到一个call edi,这是一个虚函数,如果我们能控制edi就有可能在这里达到代码执行的效果。其中有一个控制流保护机制CFG(call __guard_check_icall_fptr),Win7系统未开启所以这里不用考虑pass。

ea49596dc7564f44bc3d95a9157284fc.png

edi是由ecx(Array Object)传递过来的,通过修改th1对象中的width值为2000000,允许我们将EAX的值移动到堆喷射中的受控内存位置。

4387c33868466ad862f1799774be1819.png

92f2d111898aa3eb342320808e3bb4e1.png

PoC中设置eip为0x41414141

81c76c519b02471b4e2f2fc150b5e46b.png

这里eax=0bebc2d8,我们的受控位置为0Xbebc200=(2000000*100),在可控范围。

6f558f2f091374363e5f0053980b85f9.png

EIP被设置为0x41414141,由于加载的所有模块均启用了ASLR,目前仍没有绕过的方法。

实例二:Word类型混淆漏洞(CVE-2015-1641)

漏洞原因:

Word在解析docx文档的displacedByCustomXML属性时未对customXML对象进行验证,导致可以传入其他标签对象进行处理,造成类型混淆。

分析环境: Win7、Word2007

分析工具: Windbg、od、oletools、notepad++、WinHex

样本: https://github.com/houjingyi233/office-exploit-case-study/blob/master/CVE-2015-1641/8bb066160763ba4a0b65ae86d3cfedff8102e2eacbf4e83812ea76ea5ab61a31.bin.gz

d862fac00725360b0dae50b6a60803e0.png

首先解压样本并改后缀名为doc,用oletools的rtfobj分析结果为4个文件,分离保存。

01e97d2a78b81ee656c09702fb439cdc.png

在样本中提取第三个OLE,构造成rtf文件(上图为文件前半部分截图),打开该文件后出错,如下图,可以看到故障模块为wwlib.dll,异常偏移为0x9d30。

77b114ffe4114003e21bd63ce2322755.png

运行word,用windbg附加word进程,再打开rtf文件,异常出现在wwlib模块中的0x5c4a9d30,代码为mov esi,dword ptr [ecx],崩溃原因是[ecx]引用到无效地址。

5f0e1c9735af679f4e9e241d44180587.png

这里ecx=0x7c38bd50,指向何处? 接下来分析保存出来的ole文件,解压后在资源文件“document.xml”中发现ecx的值正是smarttTag标签的element的属性值。

2b6ffc7e3632cfb8deafe30144571489.png

smartTag是一个智能标签,可针对人名、日期、时间、地址、电话号码等进行智能识别并允许用户执行特定操作的标签,displacedByCumtomXml属性表示此处要替换为另一个customxml标签,样本作者在smartTag的element中构造了0x7c38bd50,Word在解析docx文档处理displacedByCustomXML属性时未对customXML对象进行验证,所以能传入smartTag标签对象。

e464c40346035ce0ccf70d9bbb661980.png

由于是单独加载触发漏洞OLE引用到无效地址,因为这个地址位于” MSVCR71.DLL”模块中,而这个DLL正是通过第一个OLE对象“otkloadr.wRAssembly.1”引入的。将第一个OLE对象:{objectobjocx{*objdata180115000002000000160000006f746b6c6f6164722e5752417373656d626c792e3100000000000000000001000000400105000000000000}},添加到触发漏洞的OLE前面,构建成RTF运行,再通过Windbg下条件断点,这里先记录下crash发生的时候“0x7c38bd50 “所在的模块地址,通过它来下条件断点:

8bba6b8178af404b13877841866595db.png

0x7C38BD50是smartTag标签的element值,4294960790(0xFFFFE696)是moveFromRangeStart的值,随后对这两个值进行计算得到一个地址0x7C38BD74。计算过程如下:

b1086d20ec16d9e7eb029d97314cce7a.png

fd514e316c3f3064df69e6247006339b.png

第二个smartTag,smartTag标签的element值此时为0x7C38BD68,moveFromRangeStart的值为0x7C376FC3(十进制为2084007875),计算出的地址为0x7C38A428,最后通过memcpy函数将0x7C376FC3覆盖到地址0x7C38A428中,在调试器可以看到,0x7C38A428为虚表指针:

5cecfc499673fc99e7044bc5b3f0b720.png

接着往下执行,

会先经过一大片地址为“7C342404”的“ret”,然后进入ROP链,再往后就是shellcode。

06f02d87da9a4136aa22cf2e4fa44444.png

将id为1的OLE解压后,

在解压目录的“activeX1.bin“中看到用来堆喷的数据块:nop指令上面的是ROP链,heapspary前会使用大量地址为0x7c342404 的ret-sled,

ad64323cff389d6568034ba1ab3b8321.png

以上两实例分析文章在网上较多,这里只做一个浅析,不做深入分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值