探索黑客技术攻防,实战研究与安全创新

导航菜单

IE浏览器数组越界漏洞利用方法

漏洞描述

该漏洞是以CVE-2011-1999漏洞为原型来进行讨论。select元素结构中存在一个option cache结构,该结构是option兀素的指针数组,该数组存在数组越界漏洞。将option元素添加到select元素过程中,如果添加的索引是负值,那么会覆盖数组前方的数据。浏览器的数组越界漏洞属于高风险漏洞,可以同时绕过ASLR  和  DEP,能够稳定执行类似的漏洞还有:CVE-2011-1999,CVE-2010-1883,CVE-2008-3475。之所以说能够绕过ASLR和DEP,因为它能准确的获得mshtml.dll的基地址,但是有时利用mshtml.dll不能构造出合适的rop链。我的思路是通过一些变换来获得ntdll.dll中的rop链。

本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。

漏洞利用简述

首先,数组越界漏洞本身具有向任意地址写固定数据的能力。利用该数组越界漏洞,更改sela rray元素中option cache前方的某个字符串的长度位,将长度位改为较大数值,这样该字符串就可以读取该字符串后面的所有数据。通过获得该功能,先将该字符串所在虚拟空间的准确位置测算出。通过获得的准确位置和内存任意地址读取功能,获得读取内存中任意地址数据的功能。

通过获得的读取内存中任意地址数据的功能,读取option对象的虚函数表的基地址,进而获得mshtml.dll模块的基地址。为rop chain做铺垫。(可选)

具备了读写功能后,伪造对象,来触发漏洞。具体为:使用optarray中的option的指针来替换option cache中的option元素中的CTreeNode指针,然后立即删除该option元素,导致原CTreeNode指针的位置指向的内存是待释放内存,触发内存回收,然后使用恶意数据填充到该内存处,该位置处是一个伪造的CTreeNode结构对象,这样当执行corru ptedoption.rentNode.click(),即执行了CTreeNode结构对象指向的父对象的虚函数。

我的方法是通过对string字符串的调整,读取飞地中的ntdll.dll函数地址,进而获得ntd¨.dll模块的基地址。为rop chain做铺垫。

关键知识点

·  覆盖字符串长度位

·  利用该漏洞同时具备读写功能

·  内存构造对象数据结构

·  利用飞地地址

js中存在字符串,字符串在内存中的表示是前4个字节是长度位,后面是字符串内容。字符串内容的读取受到字符串长度位的限制,如果长度位足够大,那么字符串可以读取其后用户空间的所有内容。

这里和普通的漏洞触发不同,这里是手工构造出触发漏洞的条件。有一种use-after-free现在已经不可能存在了,那就是:同时有两个地方引用到某个对象,如果删除某个引用和对象,并在该对象位置放入其他恶意数据,那么另一个引用将能引用到该恶意数据。使用optarray中的option的指针来替换option cache中的option元素中的CTreeNode指针,然后立即删除该option元素,导致原CTreeNode指针的位置指向的内存是释放内存,然后使用恶意数据填充到该内存处。

用户空间的最后一块内存中存在“飞地地址”。飞地区域指的是SharedUserData内存区

早期系统调用

Ntdll中的存根函数调用ShareserData内存区的SystemCaIIStub代码。ntdll.dll中的存根函数内的代码为call edx,其中edx存储着SystemCaIIStub的地址,执行call edx将使程序转移到“飞地区域”执行程序代码。

后来系统调用

后来SharedUserData内存区没有了可执行权限,也不存放执行代码,而是仅仅用来存放地址,存放的是一个指向ntdll.d¨中的ntd¨.KiFastSmCall的地址。并且ntd¨.dll中的存根函数内的代码不是call edx,而是call [edx],SharedUserData内存区内不是SystemCaIIStub的地址,而是放入了一个指向ntdll.dll中的ntdII.KiFastSystemCall的地址。ntd¨.KiFastSystemCall在ntdll.dll中的位置固定,因此通过该地址可以得到ntdll.dll模块的首地址。伪造对象(创造触发条件)

步骤1

将selarray[99]中的option cache  指针数组中的第61个option的指针赋值给corruptedoption,  option cache指针数组中的元素删除函数

-  corrupption\=reem(optarryaddr+60*4);

-  corptedoption=selarray[99].options[60];

-  selaay[99].options.remove(60);

-  corrptaddr=corruptedoionaddr+Ox14;

步骤2

另一个options对象畸形添加给selarray[99]中的option cache指针数组中,覆盖了之前option对象中的CTreeNode指针函数

-  overwrite(corrutaddr);

步骤3

因为之前是畸形添加,导致selarray[99]遗忘了添加的option元素,空间最终被回收函数

-  selarray[99].opion.remove(0);

步骤4

函数

-  elms[i].classNae=fakeobj;

步骤5

parentNode即CTreeNode指针指向的对象已经被字符串替换,调用parentNode的click方法时,系统底层就会寻找该对象的虚函数表,并执行其中相关的函数

-  corruptedoptin.parentNode.click();

上图中绿色部分的数值为下面的fa keobj对象。

fakeobj=

u nescape("%u4141%u4141%u0024%ulclc' )+u nescape("%u4141%u4141%u414l%u4141%U 4141%U 4141%u 4141%U 4141%u 4141%U 4141%U 4141%U 4141%U 4141%u4141%u4141%u4141%u4141%u 4141%u4141%u 4141%u 4141%u 4141");

 通过指针Oxlclc0024,指向了下面构造的rop链。

图片10.png

相关推荐