您的位置首页  基金资讯

IE浏览器漏洞的花式利用(二windbg调试

  • 来源:互联网
  • |
  • 2016-10-10
  • |
  • 0 条评论
  • |
  • |
  • T小字 T大字

eax=0x0c0c0c0c那么calldwordptr[eax+8]程序就会去执行#xchgeax,esp#ret,xchgeax,esp后,esp指向了0x0c0c0c0c,再来一个ret,,就会跳转到另一个ret指令,然后进入下一条rop指令,#popebx#ret,这样一个pop就将我们刚才执行过的xchg指令绕过了。

那么DEP到底啥呢?DEP(数据执行,DataExecutionPrevention)的基本原理是将数据所在的内存页标识为不可执行,当程序溢出成功转入ShellCode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执意指令.而我们之前的漏洞利用的最后一步都是直接跳到数据区去执行代码的,这样在DEP作用下我们先前所有的漏洞利用都会被操作系统终结到最后一步,是不是很气...我觉得当时的hacker们一定常无奈的(我都搞定eip了,你却不让我执行我的代码,你逗我玩呢...),但hacker的信条里没有"放弃"这个词,有的只是"突破一切".一段时间的困惑之后,有些聪明hacker发现,你不是不让我执行我的数据吗,那好我就不执行我的数据,我执行你程序自身的数据总可以了吧,应为程序自身肯定是需要执行代码的,于是我们可以通过重用程序的代码把他们拼接起来最终实现我们需要的功能.这种技术被称为ROP(ReturnOrientedProgramming,返回导向编程).关于ROP技术详细介绍,利用的方式网上已有大量的文章进行了说明,请不熟悉的读者自行百度,在这里就不赘述了^_^.

对比脚本代码,我们知道堆喷射也成功了.位于0x0c0c0c0c地址处的数据恰好是rop的开头.前面代码的rop链构造的有些奇怪,和我开头所说的有点不同,它在xchg指令之前还有一些指令,这是为什么呢?其实这是根据漏洞实际情况来构造的.我们看看劫持程序时的一个情景:

对于DEP,现在我们就有了ROP这一技术来对其进行绕过.引入了ROP技术的同时,也引入新的问题,大多数情况下我们不会用rop链来实现我们shellcode所需的功能,更通用的方式是通过调用一些系统提供的可以设置内存属性的函数来将shellcode所在内存区域设置为可执行属性,这样一来我们就能执行我们的输入数据了^_^.我们知道用于rop的一些代码段(我们称之为gadgets)是一些以ret指令结尾的代码片段.而ret指令是对栈上的数据进行操作的,而现实是我们现在获得的ie漏洞基本没有可以控制栈数据的了.我们能控制的只有堆的数据(通过使用"堆喷射"技术),这时我们要用到一个有趣的指令:xchgreg,esp这样的一条指令作用是交换reg寄存器与esp寄存器的值.而在一些堆相关的漏洞中我们往往能控制至少一个寄存器的值,设想一下我们将某个寄存器的值设为0x0c0c0c0c(没错又是这个有趣的地址),再使用一条xchg指令将esp的值和该寄存器的值互换,这样一来程序的栈就变成了我们可控的地方了,漏洞利用是不是又变得优雅了一些.

在更改dashstyle数组的长度时,程序会将重新设置的长度与当前数组长度进行比较,如果大于当前数组长度就会重新分配一块内存来存储数组。小于的话就不分配内存。而在进行长度值比较时,使用的是有符号比较,所以当我们将长度设为0-1=0xffffffff时,就会发生整数溢出,使得不重新分配内存,但是数组的长度已经变大,于是我们就能越界读写相邻的内存了。

再来一个ret,我们就会跳转到ntdll!ZwProtectVirtualMemory函数,执行,函数的参数已经布置好了。函数执行完毕时,我们的shellcode所在的内存区域就会被设置为可执行,并会跳转到shellcode这样就绕过了DEP。我们来实际调试下这样的一段rop指令。改怎么调试呢?我们可以在0x0c0c0c14处下硬件读取断点。因为位于0x0c0c0c14处的值就是xchg指令的地址,一般而言这种ie的rop链第一步就是使用类似于xchg指令来把堆伪造成栈。所以我们在这下断点。

0x775e70b0-0x470b0=0x775a0000等于模块址,说明成功.现在我们已经得到了ntdll模块址于是我们就能构造我们的rop链了.下面我们将使用先前得到的模块址构造rop链之后再用”精准的堆喷射”技术将rop链精准的布置到0x0c0c0c0c处.由于先前已经介绍了获取址的方式,这里直接定义址的值以减少篇幅.喷射代码:

2.通过第一步中泄露出来的址,使用ntdll模块中的指令构造出rop链来调用ntdll!ZwProtectVirtualMemory函数将shellcode地址设置为可读可写可执行权限,从而绕过DEP,并利用"精准堆喷射"技术将rop链的开头喷射到0x0c0c0c0c这个地址处,再次的触发漏洞,修改对象的虚表,从而获得代码执行.覆盖虚表的关键代码如下:

其中第一个表达式求出0x0C0C0C0C到UserPtr的距离,因为JavaScript中字符串是Unicode形式的,所以在第二个表达式中我们进行了除以2的操作,又因为堆块的对齐粒度是0×1000,所以将结果对0×1000进行取余。注意每一次查看0x0C0C0C0C所在堆块的UserPtr会不尽相同,但是在特定的下计算出来的最终结果基本是一致的,于是堆中每一块0×1000大小的数据看起来如图所示:

和先前说的一样通过vml1.dashstyle.array.item(0x2E+0x16)=0x7ffe0300将marginLeft属性值的地址设为0x7ffe0300,之后通过读取marginLeft属性值获取0x7ffe0300处四字节数据,减去0x470b0(即290992,同时dll版本不同偏移也不一样)得到ntdll的址,来看看效果:

这样,这个漏洞的漏洞利用就被我们分段的完成了,我们回过头来看看整个漏洞利用过程。首先我们通过数组越界修改对象的属性值地址,读到了一个值,通过这个值计算出了ntdll模块的址,并通过该址构造出rop链,之后又再次触发了漏洞,修改对象虚表指针,劫持程序执行流,完成了整个漏洞利用。这其中的每一步都是那么精妙,可以说只要稍微有点偏差,整个漏洞利用就会失败。可以说这样的漏洞利用真正的可以配得上"优雅"这个词语了。整个漏洞利用的一个连贯过程,metasploit上实现的非常棒,我们来看看效果。

1.通过构造0x400个COARuntimeStyle对象,在第0x301处创建一个包含44个元素的dashstyle数组.这样一来会分配4*44=0xb0大小的ORG数组.这样一来ORG数组和COARuntimeStyle对象就会相邻,此时利用漏洞越界访问到位于COARuntimeStyle对象偏移0x58的字符串(即marginLeft属性值)的地址,之后将其地址设置为0x7ffe0300,在这个地址处存放的值与ntdll.dll模块的址有一个固定的偏移,这样我们再读取marginLeft属性值就能读到那个有固定偏移的值,在通过计算我们可以得到ntdll.dll模块址绕过aslr.poc中的相关代码如下:

现在还剩下最后一个问题:在我们成功执行rop链设置shellcode所在内存为可执行属性之前,我们没有办法执行堆上的数据的,所以在我们使用类似于xchgreg,esp的指令切换好栈后,我们ret的地址必须是在rop链的第一个地址.要解决这个问题就要用到"精准的堆喷射"技术.我们知道动态申请的内存的地址是不断变化的,所以位于0x0c0c0c0c地址处的数据也应该是会变化的,所谓的"精准的堆喷射"就是使用一些特殊的堆布局使得位于0x0c0c0c0c处的数据为一个恒定的值,这样一来,在ie中使用rop的又一道被突破.下面来实战下"精准的堆喷射"吧^__^.

这里的eax的值就是通过vml1.dashstyle.array.item(6)=0x41414141设置的,设置成0x41414141的目的是为了便于分析劫持程序流程时的一些情况.可以看到eax的值就是我们设置的.程序最终会调用calldwordptr[eax+8]指令来实现虚函数调用.我们来将eax假定为0x0c0c0c0c,对照着rop链来推理一波

那么我们应该怎么利用这种漏洞呢?套是,分配大量的其他的对象,在他们的中间插入一个存在越界读写漏洞的对象(在这里是dashstyle数组)。之后触发漏洞,读取相邻对象的一些特殊的结构,来计算模块址绕过ASLR,构造rop链,之后再次触发漏洞,将相邻对象的虚表指针修改以控制程序的执行流程。

在上一篇文章中,我们讲了一些早期的ie相关的漏洞的利用,从最基础,最简单的栈溢出漏洞的利用说起,到相对而言更加复杂的UAF漏洞利用.透过这些漏洞利用的演变,我们仿佛可以看到人类社会由原始的社会向一个文明的社会的演变的一个缩影.针对IE的漏洞利用,最开始是使用栈溢出漏洞,栈溢出漏洞的利用非常的简单,我们可以直接通过过长的字符串覆盖掉函数的返回地址或者seh链的结构来直接的劫持掉程序的eip,控制程序的执行流程.在实际利用时,为了稳定性和简便性,一般先使用堆喷射技术将我们的payload(nops+shellcode)布置到一个可以预测的地址,这个地址一般是0x0c0c0c0c,之后将通过溢出把eip的值控制为0x0c0c0c0c实现,之后程序会跳入到nops块中,最终执行到shellcode区,完成漏洞利用.可以看到这整个过程非常的简单,用仙果的话来说就是这样的漏洞利用”不优雅",后来UAF漏洞出现了,漏洞利用技术也变得优雅了起来,针对UAF漏洞的利用,hacker们的手法也比之前的栈溢出漏洞的利用手法,精细了不少,利用的套是:等存在漏洞的对象被后,申请一些大小与被对象所占内存大小相同的对象,实现"占坑",之后在修改那块内存的数据(一般是开始4字节,虚表),最后调用虚函数,触发漏洞,劫持eip.可以很明显的感受到整个漏洞利用的流程比之前要优雅了不少,hacker们需要小心的内存的分配,以实现对那块的内存的重利用.当然这整个过程还是有"不优雅"的地方,在漏洞利用的最后阶段,我们利用的还是最开始的那一种布置shellcode的方法,就直接大量地喷射内存,不管三七二十一把eip设为0x0c0c0c0c实现漏洞的利用.这种方式在没有DEP的情况下还是可取的.但是DEP爸爸一来,什么都变了.

免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186
友荐云推荐