ღ Miranda

CVE-2013-2551 IE VML整数溢出分析

前言

这个漏洞是vupenPwn2Own上用于攻破IE10的漏洞。是用于绘制向量图形的vgx.dll模块中发生的整数溢出。

poc

poc.html:

调试分析

附加IE运行poc后程序崩溃:

往下看指令:

这里把[41414141]的值给了edx然后call edx,看来[eax]里原本存放的应该是一个函数指针,这里的41414141poc中的shape.dashstyle.array.item(0x2E+0x16+i) = 0x41414141

开启堆页调试,看看是哪里发生了溢出。

根据栈回溯,是vgx!ORG::Get中调用的memcpy导致的溢出:

复制的来源地址是通过第三个和第一个参数计算得到的,上层函数是vgx!COALineDashStyleArray::get_item,在上层的OLEAUT32!DispCallFunc是用来调用控件中的函数的,通过栈回溯可以看到ORG::Get的第一个参数来自于COALineDashStyleArray::get_item的第二个参数。

poc中设置dashstyle是通过COALineDashStyle::put_value函数设置的,poc里设置了vml1.dashstyle.array.length的值为-1导致了溢出,设置长度的函数是COALineDashStyleArray::put_length,可以在这个函数上下断点调试:

调用了CSafeRef::IGetObj取得了一个对象:

CVMLShape::FetchProp,获取array属性:

ORG::CElements函数获取dashstyle数组长度:

获取到数组大小0xfffffff,也就是-1,与原来设置的2c比较,大于等于就跳转:

这里如果大于原来的就会重新分配空间,但这里是有符号比较,所以绕过了检查。

跟进:

跟进:

ecx4*数组长度,设置数组长度,加上数组起始地址,ecx指向设置的数组:

当前数组长度是2c,修改后是2d:

设置的长度为ffffffff

数组长度等于原长度减去两者之差2d:

数组的长度被改写为ffff,而实际只有2c,这样就可以访问较大的一块内存。

漏洞利用

设置a[i].marginLeft调用的函数是COARuntimeStyle::put_marginLeft,这个函数声明:

第二个参数是输入,可以找到:

利用分析

poc中构造0x400COARuntimeStyle对象,在第0x301个创建长度44的数组,分配了4*44=0b的内存,使得这个数组与COARuntimeStyle对象相邻:

经过vml1.dashstyle.array.length的溢出vml1.dashstyle的数组就可以访问到COARuntimeStyle对象,在偏移0x58处是marginLeft在内存中的地址。

为了绕过ASLRvupen的利用方法是把这里的marginLeft地址通过ORG数组用0x7ffe0300越界重写,再使用COARuntimeStyle::get_marginLeft()0x7ffe0300处的内容读取出来。0x7ffe0300处保存着ntdll!KiFastSystemCall的地址,通过此地址减去相应偏移即可得到当前ntdll.dll的内存基址,这样就可以获得ntdll!ZwProtectVirtualMemory的地址,关闭在shellcode内存处的DEP,再用堆喷射把shellcode喷射到可预测的地址,再通过漏洞覆写虚表指针就可以实现利用。

发表评论

电子邮件地址不会被公开。