使用msf
使用《漏洞战争》提供的POC,GitHub地址:https://github.com/riusksk/vul_war
IE8打开poc.html、选择“允许阻止的内容”、点击“crash”按钮,IE崩溃,poc源码如下
使用《漏洞战争》提供的POC来分析漏洞成因
WinDbg附加IE8,打开poc.html重新测试,发生访问异常;
发生在地址4b5f5f4b处,与poc中crashme函数中的代码相关(二者之间具体什么联系,后面探究
为了更好的定位漏洞代码,对IE开启页堆机制(+hpa
开启页堆后,重新测试,断在memcpy函数处,访问2a47d060时错误
观察反汇编指令,“基址+偏移”的形式(而且还*4),断定是数组访问越界,进一步推测,memcpy中传参有误
kb指令查看函数参数以及堆栈调用,可以发现2a47d060是memcpy的第二个参数即源地址,也定位到vgx的ORG::Get函数(kb显示前3个参数
IDA反汇编VGX.dll文件,函数窗口中搜索ORG::Get函数,F5得到其伪C代码
由步骤4知,出错的位memcpy的第二个参数即源地址,其由Get函数的参数1、3决定
再看栈回溯,Get中的参数1、3来自get_item的参数1、2
再回溯,找到OLEAUT32!DispCallFunc,已经脱离vgx.dll,故可以断定,vgx!COALineDashStyleArray::get_item只是用于触发异常,而非真正造成漏洞的罪魁祸首
get_item是windows中的API,一定会对应poc.html中的js函数
后面赋值的地址会引发访问错误(步骤1中),而且二者名字类似,因此可基本断定:数组越界访问的错误就是由poc中的item函数引发的//here
item怎么引起越界访问?
(1)vml1.dashstyle包含 44 个元素
(2)item函数访问vml1.dashstyle时,指定下标0x2E+0x16=68,必然访问越界
访问地址2a47d060时错误,68*4=272=110h,dd指令查看内存分布(L50指定显示多少)
前面是正常范围的元素1-44,若按照下表68访问,则越界出错
由上面分析可知,item函数的调用只是触发异常,并非真正漏洞处,分析poc,在item调用前,发现有修改length的代码,如下
赋值比较反常,0-1 = -1 = 0xFFFFFFFF,可断定,这就是引起整数溢出的罪魁祸首
基于类函数定位的漏洞分析方法(详情漏洞战争 4.3
如上指令涉及“dashstyle”、”length“等关键字,在IDA中函数窗口搜索;涉及length的有两个,通过名字猜测,put的类似set,是设置xxx用的;
因此,找到关键函数COALineDashStyleArray::put_length
WinDbg重新附加IE,在COALineDashStyleArray::put_length下断后,重新测试,页面中点击“crash”,成功进入put_length函数(bu针对某个符号下断点
p单步执行(步过),寻找敏感点
put_lenth+0x9处,取出第一个参数(具体是啥不明确,后面再说
+0x6b处调用CElements函数,由名字猜测其获得某元素,dd查看其参数eax,发现有002c=44即vml1.dashstyle的元素个数
t单步步入,进入CElements内部,+0x5时取出参数1,即vml1.dashstyle数组对象(因为有元素个数信息,故这样猜测)
继续p单步,+0x8时,取出vml1.dashstyle数组对象的元素个数0x2c,并赋值给eax即返回值;使用movzx无符号扩展指令,表示此元素个数/数组长度为无符号整数
随后退出CElements函数(返回值eax=002c,此函数就是为了获取vml1.dashstyle的数组长度),+0x6e处获取put_length的第二个参数赋值给esi,FFFFFFFF = -1,即poc中设置的
+0x71、73处,比较eax和esi,即原先的元素个数0x2c和后来设置的-1,jge是有符号跳转,必然跳(正数当然大于负数
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空间,即原先的空间不足,需要再申请
实际情况满足jge跳转,继续p,+0xcf处,有一减法操作,因为esi为负数,所以sub后eax不减反增,eax=2c - (-1) = 2c + 1 = 2d,这就是问题之所在
正常情况下,如eax=5,esi=3,满足jge,则5 - 3 = 2,eax是要减小的,而poc中设置为-1,使其变大
随后调用deleteRange函数,传参-1、poc中特殊构造的差0x2d、vml1.dashstyle数组对象
内部调用MsoDeletePx函数
内部又调用 MsoFRemovePx 函数
继续跟进MsoFRemovePx 函数,+0xa7处
ebx是2c - (-1) 的差值 = 2d,esi所指向数组长度=2c,二者相减,反过来又得到了-1 = FFFF,也就是poc中设置-1;
但此时,-1已经不是负数这么简单,其在内存是FFFF,相比原长度2c,是一个很大的数
若按照正常的情况,比如原先长度为5,新设置为2,则5-2=3得到差值,MsoFRemovePx中sub操作,5-3=2,这个2就是新长度,此时在内存中将长度改掉没有问题;
现在将数组长度由2c改为FFFF,原则上这么设置没问题,FFFF作为长度也是合理的;但是,之前cmp 2c,-1时,满足了jge跳转,导致没有调用new新申请内存;
也就是说,实际的内存空间没有增加,仅表面上增加了长度;所以,当通过item函数对数组进行素引取值时,就会导致数组越界访问
使用msf提供的rb文件来分析漏洞是如何被利用的(利用信息泄漏实现漏洞利用
创建0x400个v:shape 元素(COARunTimeStyle对象),html_info_leak函数中,如下
在第 0x301个时,创建包含 44 个元素的 dashstyle 数组(ORG数组), 总共占空间4*44=0xB0字节
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-2-19 16:13
被21Gun5编辑
,原因: