ie浏览器漏洞严重吗(IE浏览器漏洞综合利用技术)
ie浏览器漏洞严重吗(IE浏览器漏洞综合利用技术)不过对于早期的利用,ASLR并没有对利用者造成太大的困扰。因为ASLR早就在诸如Office Word之类的软件中启用了,Hacker们直接套用了在这些软件中的做法即利用一些未开启ASLR的模块进行利用。因为当时很多的模块并不支持ASLR因此加载在固定基地址。这种方法也是比较简单粗暴的而且通用性比较差,比如以前在IE中常用的Java6的msvcr71.dll,如果目标并没有安装JRE或者版本不对利用都不能成功。自IE8开始,DEP和ASLR成为浏览器中默认启用的缓解措施,如何bypass ASLR和DEP成为了攻击者首要面对的问题。我们简单介绍一下DEP和ASLR,如果是熟悉Linux的同学,那么Linux下的NX保护与DEP是很类似的,都是把一些非代码段内存设为不可执行来阻止攻击者运行shellcode。在其它的软件中bypass DEP通常使用ROP技术,但是由于IE几乎都是基于堆的漏
作者:Ox9A82
稿费:400RMB
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
前言
在前一部分中,我们介绍了从IE6到IE11的堆喷射方法,其实堆喷射只是一种手段目的还是为了实现最后的漏洞利用。在这一篇文章中,我们会根据时间顺序来讲解IE浏览器漏洞利用技术的发展,我们会把主要精力放在UAF漏洞的利用上面,同时会涉及一些其它类型的漏洞作为辅助以绕过漏洞缓解措施,这篇文章主要介绍技术发展脉络,实际的漏洞调试会放在下一章,期间我阅读了大量的文档、会议PPT和博客文章,在此也对前辈们的分享表示感谢。同时给大家分享两句我很喜欢的话,一句来自大家应该都很熟悉的陈皓大牛,一句来自charles petzold大家应该都有读过他的书
4.IE8早期漏洞利用(石器时代)
前面我们说IE6时期是史前时期,因为那时的漏洞利用简单粗暴。相比于当时,IE8时代的利用技术向前走了一大步,不过因为安全体系的问题早期的IE8利用依然只能称为是石器时代,还是相当的原始。
自IE8开始,DEP和ASLR成为浏览器中默认启用的缓解措施,如何bypass ASLR和DEP成为了攻击者首要面对的问题。我们简单介绍一下DEP和ASLR,如果是熟悉Linux的同学,那么Linux下的NX保护与DEP是很类似的,都是把一些非代码段内存设为不可执行来阻止攻击者运行shellcode。在其它的软件中bypass DEP通常使用ROP技术,但是由于IE几乎都是基于堆的漏洞不存在直接进行ROP的条件所以并不能通过简单的ROP实现bypass DEP。而ASLR会使得模块装载的地址变得不确定,对漏洞利用有一些了解的同学肯定知道Rop技术是依赖于一些rop gadgets来进行不断的跳转利用的,ASLR的启用会直接妨碍我们获取rop gadgets。
不过对于早期的利用,ASLR并没有对利用者造成太大的困扰。因为ASLR早就在诸如Office Word之类的软件中启用了,Hacker们直接套用了在这些软件中的做法即利用一些未开启ASLR的模块进行利用。因为当时很多的模块并不支持ASLR因此加载在固定基地址。这种方法也是比较简单粗暴的而且通用性比较差,比如以前在IE中常用的Java6的msvcr71.dll,如果目标并没有安装JRE或者版本不对利用都不能成功。
因为此时仍然比较原始,所以我们称之为石器时代。事实上,今天的应用程序不支持ASLR的已经非常少见了,想通过不支持ASLR的模块来实现ROP已经不大可能了。所以我们把完整的利用方法放到下一章中详述。
5.IE8浏览器结合信息泄漏利用(铁器时代)
据说人类跟动物的区别是人类会使用工具,那么这一时期利用技术的进步堪比从石器进化到铁器。
这一时期的标志事件是Peter Vreugdenhil在Pwn2Own2010中攻破IE8项目,这一过程中的技术手段对后来的利用技术发展有着重要的作用。Peter Vreugdenhil利用IE8的手段是把一个OOB漏洞与一个UAF漏洞相互结合,我们首先来说OOB漏洞。Peter Vreugdenhil通过内存布局把BSTR布置在存在OOB的对象后面,目的是进行信息泄漏,通过越界写来改变BSTR的长度,实现了越界读。
我们在前面说过BSTR不是简单的Unicode字符串,BSTR的结构由4字节的长度(size)域、2字节的结束符(\x00\x00)加上Unicode字符串构成。通过我们精心构造内存布局,使BSTR对象紧随漏洞对象的后面。之后再在BSTR后面再放置目标对象,这样当触发漏洞对象发生越界访问的时候就可以覆盖掉BSTR结构的size域。一旦我们把size域覆盖为更大的数值,我们就能够使得BSTR发生越界读(因为BSTR只可读不可写)。然后通过js脚本读取BSTR字符串,就能够读到BSTR之后的对象。我们的目的是获取后面对象的虚表地址(首4个字节)。如果你想了解的更详细可以参见(http://vreugdenhilresearch.nl/Pwn2Own-2010-Windows7-InternetExplorer8.pdf )
为什么获得虚表地址就可以bypass ASLR呢?因为对于C 程序来说虚函数表是被编译在全局数据段的,就是说对于模块的基地址的偏移是固定的。我们通过泄漏的虚函数表的地址减去偏移就可以知道对象所处的dll模块的基地址,也就可以使用这个模块中的gadgets了。
这种方法有两个需要解决的问题:第一是如何构造稳定的内存布局使我们上述的内容得以实现。第二是当我们覆盖成功后,如何通过javascript脚本层面上的操作把值获取到。其实我们后面要讲到的方法都面临着这两个问题。
由于这种利用较为简单,可以直接参考泉哥的著作《漏洞战争:软件漏洞分析精要》里面第三章的CVE-2012-1876的利用分析,其使用的方法就是通过BSTR进行泄漏,我们也会在下一篇中给出实际的漏洞调试。
单单绕过ASLR是无法实现漏洞利用的,因为DEP的存在我们没有办法在堆上执行指令。为此Hacker们想了很多办法,其中我认为最早实现成功利用的依然是Pwn2Own 2010上Peter Vreugdenhil使用的方法,虽然与我们这里讲的不完全相同,但是我觉得是Peter Vreugdenhil方法的进化版。我们忽略Peter Vreugdenhil的方法(感兴趣的可以查看上面的连接),我们使用的手段是stack pivot,所谓stack pivot就是通过mov esp eax、xchg esp eax等指令来实现把栈转移到堆上,因为一般的UAF漏洞触发时我们都可以控制至少一个寄存器的值。通过把esp指向我们喷射的内存,我们就可以把堆伪造成栈,从而像普通的栈溢出一样进行ROP,通过执行ROP最终实现代码执行。
但是这一利用方法首先要确保的是我们要能够精准的计算堆喷射的地址,因为堆不可执行所以我们不能再依赖于用于缓冲的nop指令了。好消息是我们在前一篇文章中已经讲过准确计算的原理和实现了,这里再简单复述一下。当我们大量分配堆块时可以发现地址的最低几位是一直不变的,地址改变的熵只是固定的地址高位并且堆块的分配相当的稳定。这样如果我们使偏移都落在地址的高位,那么我们的指向就会是整块进行偏移,从而保证了每次指向的都是计算好的准确的地址。
举个例子:我们可以以每个块为单位计算出ROP链第一条地址的偏移,然后其实我们可以想一下0x0C0C0C0C这个地址还有没有用?在这种利用环境下,第一不需要跳板指令,第二我们跳转目的地址是精确的,那么0x0C0C0C0C这种地址就根本没有存在的价值了。我们要的就只是一个堆喷射可达的稳定的地址。
无堆喷射,通过ANIMATECOLOR对象实现利用
这种方法不需要进行堆喷射就可以实现利用,堆喷射其实并不能说是一种优雅的利用方法,因为分配内存需要一定的时间,而且如果目标机器的配置较低的话可能会导致卡顿从而被目标察觉。我之前在binvul上看到过一些所谓的“不弹不卡不喷射不风水”的样本其实指的就是这种技术。
ANIMATECOLOR是IE8版本起提供的一种对象,由于这种对象的特殊构造所以可以不使用堆喷射来实现利用,我们在下一篇实际漏洞调试时再来进行分析。
6.结合Flash的利用(中世纪)
到这里浏览器利用技术又是一个飞跃,结合flash利用虽然不能说特别优雅(因为要依靠第三方),但中世纪是文艺复兴的先声,可以说自此之后利用技术又进入了一个发展的新巅峰。
这种利用技术不是来自于Pwn2Own也不是来自于某次会议的分享,相反,随着时间的发展,在2013年网上流传出了一些无需多漏洞结合使用,通过单一漏洞就可以bypass缓解措施 执行代码的exp样本,这些exp样本应该是用于实际攻击的武器。其主要特点是结合了flash进行漏洞利用,这种利用技术最早应该是由李海飞前辈在《Smashing the Heap with Vector:Advanced Exploitation Technique in Recent Flash Zero-day Attack》这文章中提出的(CVE-2013-0634)。
1This is in fact a somehow new technique which leverages the custom heap management on Flash Player to gain highly-reliable exploitation bypassing both the ASLR and DEP.
就像李海飞前辈所说,这完全是一种新技术。并且这种新技术可以只凭借一个单一的漏洞实现bypass全部的缓解措施并且执行最终的shellcode,这一点是以前的exploit所做不到的事情。
我们简单的概括一下利用的方法,我们先忽略漏洞的细节简单的认为它是一个0x90个字节的堆块发生的溢出。我们首先分配一系列0x90大小的Vector对象,对于储存数字的Vector来说每个数字占8个字节,16个数字加上16字节的固定结构正好满足0x90的大小。
我们在vector对象布置完成之后,通过代码来释放一些0x90大小的vector,再触发漏洞。之后会分配具有溢出的0x90大小的堆块,因为尺寸与我们之前释放的vector尺寸相同,根据堆的特性漏洞堆块会重用我们之前释放的vector对象内存。这一步操作称为挖坑(make holes),挖坑的目的是为了使得漏洞堆块处于vector对象的包围之中。
下一步,我们只需要利用溢出就可以覆盖掉相邻vector对象的“Number_of_elements”域。
覆盖的结果是使得相邻的vector可以发生越界访问,通过操作这个越界的vector我们又可以覆盖下一个vector的“Number_of_elements”域,但这次我们可以直接把“Number_of_elements”域改的很大,从而实现了整个进程地址空间的任意读写。
一旦实现了整个内存空间的进程读写,就可以做到bypass DEP和ASLR了。
如果说这次利用只是因为漏洞本身有比较合适的尺寸便于布局、有直接的溢出便于覆盖结构。那么陈小波前辈发布的《ASLR Bypass Apocalypse in Recent Zero-Day Exploits》中就给出了一个通用的思路,其中提到了很重要的一点就是:如何把一个常规的UAF漏洞往我们上面说的Flash vector越界写上面进行转化。对于这个问题作者提供了如下的思路:以CVE-2013-0634为例,这是一个在IE浏览器中常见的UAF漏洞,在利用这个漏洞时exp作者在代码执行路径上发现了一条指令:
1or dword ptr [esi 8] 20000h
其中esi的值是我们可控的(来自UAF对象,可以通过占位进行控制),作者把它指向布置好了的Vector对象的长度域,在执行了or之后长度域会变大从而使得这个vector可以进行越界操作。之后可以通过这个vector越界写紧邻的下一个vector的长度域从而实现了整个进程地址空间的任意读写。此外还要解释一下为什么可以知道Vector对象的长度域的地址,
之后的IE浏览器利用从基本思想上发生了转变,攻击者不再追求结合多个漏洞泄漏信息再进行堆上ROP,而是继承了flash vector的任意读写转化思路,试图从UAF转化到任意地址读写,再通过任意地址读写来实现绕过缓解措施。
7.UAF转化与Element Attribute(启蒙时代)
之后漏洞利用进入启蒙时代,相比flash利用这一时期的优点是不再依赖于flash模块。这样可以提高漏洞利用的成功率和降低成本,因为此时一个漏洞就可以实现多个漏洞的利用效果并且在flash利用爆发后安全软件对夹杂flash的页面十分敏感,不依赖flash可以提高漏洞利用的成功率。
在《A BROWSER IS ONLY AS STRONG AS ITS WEAKEST BYTE》这篇文章中,作者以CVE-2013-3147为基础详细讲解了如何从crash地点进行分析来寻找一条合适的代码路径把UAF转化成inc [address](绝对地址加),并且避开虚函数调用以免引发crash。简单的概括就是查找crash附近的代码流程,寻找有没有写原语,如果存在这样的原语就想办法满足逻辑条件把执行流程引导写原语上去。
值得注意的是作者在利用这个任意地址加的过程中并没有依靠flash vector,而是通过喷射Element Attribute来实现利用。首先简单介绍一下Attribute是什么,如果你有看过HTML那么应该知道一些标签是具有属性的,比如每个标签都有id属性用做唯一的标识。对应于底层实现来说,每个DOM元素对应的CElement结构中也会有指针指向Attribute Array,每个属性占其中一项。那么Element Attribute是如何实现利用的呢?
首先我们忽略漏洞的细节,只看漏洞导致的效果,经过转化操作这个UAF漏洞可以引导到如下的路径上
而第二个DWORD的值为属性名的哈希值,第三和第四个值为实际的属性内容,如果属性内容是诸如字符串这样的值,那么它会是一个指针。
作者的核心思路是对第三个DWORD那个指针进行加1操作,因为是以字节为单位进行加1,所以实际的操作效果可能是指针偏移0x1、0x100、0x10000、0x1000000。在这种思路之下作者进行了内存布局,通过构造相同大小的BSTR字符串和一个元素来使得它们彼此相邻的分配(相同大小通过计算可以轻易的得到,而且也正是因为它们大小相同所以才会发生彼此相邻的分配),在布局完成之后对指针进行加1操作就可以读出后面元素的内容,在实际利用过程中布局要更加复杂一些不过原理是一致的。
实际利用过程中作者一次性创建了含有0x7FFE个属性的元素,然后复制它直到大小为0x800000个字节。然后对这些元素进行遍历,每隔0x1000个属性就把它的值设置为一个0x8A大小的字符串,这个设置会导致在内存中分配0x8A字节的字符串,然后马上创建一个body元素并添加9个默认属性(大小正好是0x8A)这样就做到了BSTR和元素的紧邻分配。接下来就像我们上面所说的对指针加1就能读到body元素的内容了。因为body默认属性中包含一些域,通过读取它就可以算出mshtml.dll的基地址。
然后作者在这个基础上继续进行改进,因为作者认为mshtml.dll的版本变化比较多对于利用不是很理想,而且现在我们做的还只是泄漏操作没有实际的进行执行流劫持,而我们这一阶段的主题就是只通过单个漏洞来实现完整的利用。作者为了实现流程控制对属性表进行了覆盖操作,但是又会受到低碎片堆机制的限制,为此又要伪造堆头结构。可见这种利用方法还是比较麻烦的,但是对Element Attribute结构的利用思路对后来的漏洞利用思路有很大的帮助。
之后在2014年,这个时候Ivan Fratric的《Exploiting Internet Explorer 11 64-bit on Windows 8.1 Preview》发布出来。这篇文章的意义在于,作者针对javascript array对象进行了分析,然后对array对象进行Feng shui布局并且通过它的capacity域实现了利用。由于js引擎是根据capacity域对数组大小进行判断的,因此我们一旦篡改了capacity域就可以对数组进行越界访问。在下一阶段的利用中,我们就会看到array object在漏洞利用中起到的作用。
此外在2015年的Pwn2Own上,360 vulcan团队就是通过Element Attribute对IE11浏览器进行的利用。不过与我们这里的情形不同,vulcan利用的漏洞恰好就是在处理Element Attribute时出现的未初始化问题,由于与文章主题无关这里就不赘述了,不过相信读完本文之后你就可以理解古河讲的利用思路了,利用的详情可以查看http://www.ichunqiu.com/course/52149。
8.IE11与针对jscript9引擎的攻击(近现代)
CanSecWest2014上,ga1ois在议题《The Art of Leaks》中讨论了几个很关键的问题。
第一是自IE9以后引入的jscript9引擎——jscript9.dll使用与以前不同的custom heap,而且这个custom heap并没有做任何的分配随机化措施,这一点给我们进行内存布局提供了可能。
第二是从UAF转化为任意地址读写的过程中可能因为虚表访问而导致crash和如何避免发生这种crash。
在IE9之前的版本中,javascript是由javascript解析引擎——jscript.dll负责解析的,这个dll在分配内存时使用的是系统的进程堆。而在最新的javascript解析引擎——jscript9.dll中,在分配一些对象时引擎会使用custom heap,这个custom heap是由jscript9自己负责管理和维护的。并且这个custom heap在分配时没有进行随机化处理,以至于攻击者可以通过布局一些对象(所谓的feng shui技术)来预估出对象所处的地址。
其中直到0xf000之前的都是我们的array object填充数据,而自0xf000起是我们想要的目标对象,这里以int32Array作为目标对象的例子。
因为后续我们还会涉及到int32Array这个对象,所以我们这里详细的介绍一下。int32Array属于Typed array的一种,根据MDN的介绍Typed array有以下几种
我们知道javascript是一种脚本语言,是难以像C语言一样表示一些底层数据类型的,Typed array的设计就是为了解决这个问题。我们虽然可以直接使用new来创建一个Typed array对象,诸如
其中Arraybuffer Data就是直接保存数据的区域,并且这块内存是分配在process Heap上的。
一旦可以预估出对象的地址那么就可以通过把UAF转化为绝对地址写去篡改Int32Array对象的长度域,来实现Arraybuffer Data的越界读写。因为Arraybuffer Data是储存在process Heap中的因此需要一个分配在process Heap上的对象来配合利用。这里作者使用的是LargeHeapBlock,因为这个对象处于process Heap中,并且恰好存在合适的域来实现任意地址读写。我们可以看出这种利用jscript9的方法明显比之前的做法要更稳定和易于操作。
至于UAF到读写的转化,与我们前面提过的大体相同就是跟踪漏洞触发附近的执行流程寻找有没有合适的转化原语(opcode)。在转化过程中可能会导致crash的问题,成功利用写入原语之后会发生虚函数调用,如果虚表被破坏的话虚函数调用就会导致crash。对此ga1ois给出了解决方案:
之后,在同年的Hitcon上exp-sky进一步发展了这一技术,代码和文档可以在作者github中找到(https://github.com/exp-sky)。与ga1ois的不同之处在于exp-sky没有使用typed array进行布局,而是将IntArray Object作为目标对象进行布局。这一操作的优点在于IntArray全部都是基于custom heap进行操作的,如果你还记得我们上面讲的内容的话,你应该知道我们在对typed array进行篡改操作后进行越界编辑的是Arraybuffer Data,而这块内存是存放于process heap中的,这就意味着我们还要进一步的对process heap进行布局,而这种方法则完全没有这个必要。
注意这两个结构都处于Custom Heap并且是分配在一起的。
因此喷射IntArray相比前面的方法要更方便也更容易控制,由于ArrayBuffer对象存在有保存当前缓冲区大小的域(buffer_size),只要通过绝对地址写改写这个域为很大就可以转化为任意内存读写了,之后再修改相邻块的域这一点与前面的技术是相同的。
总体来说,这一时期的利用思路基本都在于喷射一些关键的对象,并结合各种feng shui技术(尤其是jscript9中的)进行布局。然后试图把UAF转化为绝对地址写,来写我们喷射对象的关键域从而实现从UAF到任意地址读写的跨越。
一旦获得了任意地址读写就相当于可以让攻击者进行随意利用,这时各种漏洞缓解措施就不再能够阻挡攻击者的脚步了。
这里我使用了一张demi6od在《Smashing the Browser》议题中使用的图,这张图很好的说明了我们所讲的思路。
后记
其实这一系列的文章,我在去年10月份的时候就已经写完了,但是一直在硬盘里放了近半年都没有投出来。我主要是考虑到这系列文章涉及的话题太广、内容太多、历史又太悠久,考虑到自己仅是个大二学生水平较低、接触漏洞方面也不久,唯恐内容中出现错误和纰漏。但是做了一番修改后我还是鼓起勇气发出来了,希望大家能够帮忙修正文章中错误和提出修改建议,可以通过微博私信给我 id:Ox9A82。
Reference
《The Art of Leaks – The Return of Heap Feng Shui》Gaois
https://cansecwest.com/slides/2014/The Art of Leaks ‐ read version% 20‐ Yoyo.pdf
《IE 11 0day & Windows 8.1 Exploit》exp-sky
《Smashing the Browser》demi6od
《浏览器漏洞攻防对抗的艺术》仙果
http://bbs.pediy.com/thread-211277.htm
《Exploiting Internet Explorer11 64-bit on Windows 8.1 Preview》
http://ifsec.blogspot.com/2013/11/exploiting-internet-explorer-11-64-bit.html
《ASLR BYPASS APOCALYPSE IN RECENT ZERO-DAY EXPLOITS》
https://www.fireeye.com/blog/threat-research/2013/10/aslr-bypass-apocalypse-in-lately-zero-day-exploits.html
《A BROWSER IS ONLY AS STRONG AS ITS WEAKEST BYTE》
http://blog.exodusintel.com/2013/11/26/browser-weakest-byte/
《A browser is only as strong as its weakest byte – Part 2》
https://blog.exodusintel.com/2013/12/09/a-browser-is-only-as-strong-as-its-weakest-byte-part-2/
《Smashing the Heap with Vector:Advanced Exploitation Technique in Recent Flash Zero-day Attack》
https://sites.google.com/site/zerodayresearch/smashing_the_heap_with_vector_Li.pdf?attredirects=0
《IE安全系列:IE浏览器的技术变迁(上)》
http://www.infoq.com/cn/articles/Internet-Explorer-Security1
《IE安全系列:IE浏览器的技术变迁(下)》
http://www.infoq.com/cn/articles/InternetExplorer-Security2
《攻破Windows 8.1的64位IE - 分享Pwn2Own黑客大赛成果》
《Pwn2Own 2010 Windows 7 Internet Explorer 8 exploit》
http://vreugdenhilresearch.nl/Pwn2Own-2010-Windows7-InternetExplorer8.pdf
《Flash Vector漏洞利用的蜕变》
http://www.cnetsec.com/article/14571.html
《Array Object Heap Spraying》
http://www.cnblogs.com/wal613/p/3958692.html