专栏名称: 看雪学苑
致力于移动与安全研究的开发者社区,看雪学院(kanxue.com)官方微信公众帐号。
目录
相关文章推荐
周周打板  ·  不修复就大分歧! ·  2 天前  
周周打板  ·  不修复就大分歧! ·  2 天前  
计算机与网络安全  ·  2024大模型人才报告 ·  1 周前  
FDA食安云  ·  答复|关于现行标准下含有食品添加剂 ... ·  1 周前  
FDA食安云  ·  答复|关于现行标准下含有食品添加剂 ... ·  1 周前  
51好读  ›  专栏  ›  看雪学苑

CVE-2012-0158 两种 PoC 分析

看雪学苑  · 公众号  · 互联网安全  · 2017-05-28 17:47

正文

环境:windows xp sp3 pro
工具:windbg(dbgx866.11.1.404)   ida  office2003(standard)
样本来源:《漏洞战争》,看雪论坛

漏洞原理简介

The (1) ListView, (2) ListView2, (3) TreeView, and (4) TreeView2 ActiveX controls in MSCOMCTL.OCX in the Common Controls in Microsoft Office 2003 SP3, 2007 SP2 and SP3, and 2010 Gold and SP1; Office 2003 Web Components SP3; SQL Server 2000 SP4, 2005 SP4, and 2008 SP2, SP3, and R2; BizTalk Server 2002 SP1; Commerce Server 2002 SP4, 2007 SP2, and 2009 Gold and R2; Visual FoxPro 8.0 SP1 and 9.0 SP2; and Visual Basic 6.0 Runtime allow remote attackers to execute arbitrary code via a crafted (a) web site, (b) Office document, or (c) .rtf file that triggers "system state" corruption, as exploited in the wild in April 2012, aka "MSCOMCTL.OCX RCE Vulnerability."《NVD》 非常经典的栈溢出漏洞


PoC 分析一

此 poc 来自《漏洞战争》中的。分析流程如下:
1. 分析 poc 的行为
2. 综合利用 windbg 和 ida 进行动态和静态分析。
首先直接打开 windbg 和 word.exe,然后 windbg 中快捷键 F6 附件 word.exe 如下图所示:
 
如下图当载入 poc.doc 的

在上图中关键信息已经标注出来,当载入 poc.exe 时候,最终在 EIP = 41414141处段下,当利用 kb 命令查看堆栈的时候,发现堆栈已经被破坏掉啦。利用 dps 查看详细的栈信息.

根据上图的栈信息 0x127b30 = 41414141   而0x127afc = 275c8a0a 此处的值,直接在查看0x275c8a0a地址处的反汇编代码如下如所示:  

从上图中可以获取获取到 0x275c8a0a 是函数的返回地址,地址0x275c8a05处的函数调用极可能就是溢出函数,根据函数的信息可知道,
MSCOMCTL!DLLGetClassObject+0x41a29,此函数调用发生在 mscomctl.ocx 中,此组件是打开 doc 文件时动态加载的,所以只在下 bp 断点是断不下来的。
接下来再上图的基础上持续向上查找,查找到 0x275c8a0a 函数调用的起始处,如下图所示:
 


调试此处函数的方法


利用sxe ld mscomctl.ocx在动态加载的时候段下来。断下来之后直接在 地址0x275c89c7的地址出下int3 断点即可。

重新加载 poc 文件,如下图所示:

 
此时程序已经来到啦溢出函数的被调函数处,同时此时用 ida 打开 mscomctl.ocx 文件 (此文件在 system32 文件目录下 ) ,直接在函数窗口中打开 sub 0x275c89c7 函数地址如图所示:
   
从上图中我们可以直接获取到函数参数,以及函数的调用信息。  这里我们先主要依靠 windbg 进行分析。
接下来直接利用  u 0x275c89c7 L64 命令 查看 100 条反汇编指令如下图所示:

如图所示 重点部分已经标注,接下来直接使用命令 uf MSCOMCTL!DllGetClassObject+0x41a29 进行查看函数完整的反汇编指令。其实仔细观察会发现,在溢出的被调用函数中,总共发生过两次相同的函数调用如下图所示:
 

下面对溢出函数进行分析

单步运行到 0x275c8a05 然后 dd esp 查看函数参数值。如图:

如上图,函数三个参数分别是 0x127b24 0xbfe06b0 0x8282  以及进入溢出函数前的ebp = 0x127b2c 进入函数后 ebp = 127af8  接下来继续单步运行程序直接来到地址275c87cb 地址处如图所示:
 
如图所示当执行到地址 275c87cb 地址处的时候,可以观察 esi 内存中包含 41414141 而 ecx = ox20a0 因此当执行 此指令时后,即可表明程序的执行已经被用户控制啦。


溯源


接下来分别对 0x275c87cb 地址处相关的寄存器(ecx esi edi )进行值溯源,详细分析程序。

当程序执行到 地址 0x275c87cb 地址处的时候,再上图中可以观察到。 ecx = 20a0  edi = 127b24   esi = 5602008  从此地址向上翻看,也就是向低地址寻找的时候,发现 shr ecx,2 右移位指令,相当于将 ecx/=4==20a0 的操作。 20a0 * 4 =  8280,此处暂且谨记。  接下来重新在如 poc 样本,分别在地址 0x275c89c7 第一次调用调用溢出函数时的 0x275c876e 这两地址出下断点。 

当程序段在地址 0x275c89c7 的时候,可以查看到

此时上层函数的返回地址是 0x275e701a 此层函数的 ebp= 127b2c (执行完 mov ebp,esp 后的 ebp 的值)  接下来单步运行程序。来到地址 0x275c89da 地址出,查看栈空间,在此处特别要谨记函数调用中的三个参数(分别是:0x127b18 0x0c4e06b0 0xc)

结合着汇编指令很容易理解上图中的内容。接下来进入此函数。
 
如上图所示 地址 27589df 是此函数的返回地址,0x127b2c 是上层函数 ebp 的值。此层函数 ebp = 0x127af8.继续单步运行,
当执行完地址:0x 275c8783处的指令后,观察前后栈区数值的变化如下图所示(此函数的作用是从源地址:0xbd706b0处向0x127af4 处读取四个字节内容):  

此处的变化仅仅是地址 0127af4 地址处的值由原来的 275b2480->0x0000000c  程序运行到地址 0x275c878d处时,此函数的第三个参数与地址 0x127af4 处的值进行比较。如下图所示:    

接下来继续单步运行来到堆内存申请函数出,可以观测出申请的内存大小是0xc字节。并且函数的返回句柄保存在 eax 中(此处需要谨记)
 
接下来继续单步执行到地址:0x275c87b5 地址出 此函数作用仍然是从 poc 的文件内容中读取 0xc 字节的数据到申请的堆区内存中。当执行玩以后如下图所示表明此时:

接下来继续单步运行如下图所示:  

接下来直接执行到地址 0x275c87cb 地址处。  此时观察 edi esi ecx 的值,如下图所示:

从上图中观察出 edi = 00127b8 (即函数的第一个参数) esi 的值就是申请堆内存时返回的句柄。ecx = 3  是 shr ecx,2后的值,通过向上翻看指令可知,ecx 值来自edi 来自函数调用中第三个参数的值。

至此可以得到的是在溢出函数的被调函数中(也就是从地址0x275c89c7开始的函数中),当在栈中申请 0x14 字节内存后(内存地址是0x127b18-127b2c) 当在地址 0x275c89da 处第一次执行函数的时候,在栈区申请的0x14字节的内存已经用掉啦 0xc 字节,并且进行了复制如下图所示:
地址275c89da 此函数的作用是:间接利用堆内存,从 poc 文件中复制内容到栈区中。复制内容的多少由函数的第三个参数决定。(这个是重点)  

接着从地址 0x275c89df 开始继续进行分析单步运行程序:

从地址0x275c89df 到地址 275c89f7 处,其中两条cmp的比较指令尤为重要,决定啦是否执行esp。并且第二条cmp指令的值决定啦在0x275c8a05处第三个参数的大小。以上分析可知,0x127b18 - 127b2c中间内存的值是从poc样本中复制出来的。因此只需构造一下即可满足此两个条件。

接下来进入275c8a05地址出进行分析。(其实和地址 275c89da地址处的分析一样,只不过是数据发生啦变化)  进入函数后,如下图所示:

如上图所示:在函数返回地址后面紧跟的三个数值即为函数参数。
当执行到 0x275c8786 地址处的时候,如下如所示:

如上图所示,在地址 275c8783 地址处的函数调用中,成功读取到啦四个字节的值(0x127af4= 0x00008282) 

当执行完 0x275c879e 处指令后记下返回值 eax= 0x04ed9008,接着继续执行到地址:275c87b8 地址处,如下图所示:

地址 275c87b5 地址出的指令作用是向堆区进行复制 0x8282 字节的内容,源文件来自 poc 样本,地址是(bd706bo) 

接下来直接执行到地址 0x275c87cb 地址出,如下图所示:

如上图所示一目了然啦已经很,ecx = exc>>2 == 20a0  edi 仍然是参数,esi 仍然是堆区首地址。此时查看堆区内容如下图:

此时应该很清晰啦吧。当执行 275c87cb 地址出的指令的时候,eip肯定会被poc样本控制。


ida 分析


ida 分析起来就比较简单啦,直接将 mscomctl.ocx 拖进 ida 查找到 0x2785c89c7 地址出的函数,如图所示:
查看伪代码

直接进入溢出函数查看伪代码:

集合这汇编指令是不是很是一目了然


漏洞原因


mscomctl.ocx 0x275c89c7中,

此处的判断条件存在错误  不应该是 >=8 而是小于等于 8


PoC 分析二


样本来源: 样本来源(阅读原文查看)
此处 poc 的利用效果是打开当打开 poc 时弹出计算器。(但是使用过一次样本后需要从新载入一个新的样本,因此使用的时候请先进行备份)  
同样的直接在 msconctl.ocx 地址出下断点: 当程序执行到地址 0x275c89df地址处的时候可以看到,如下图所示:

如上图所示【ebp-0xc】的值是 0x8282 同样大于  0x8   接着执行程序:来到地址 0x275c87cb地址出如下图:

如上图所示,很明显的 0x7ffa4512(jmp esp)指令 跳转到 shellcode


总结


第一次分析 CVE 不清楚的地方请大家直接指出来共同进步
本文参考啦很多篇文章,感谢各位前辈的辛苦付出 下面附上参考文章的链接

参考文章链接: 

http://bbs.pediy.com/search-cve202012200158-1.htm

本文由看雪论坛 TKMoma 原创


你可能对以下内容感兴趣:



更多优秀文章,长按下方二维码,“关注看雪学院公众号”查看!

看雪论坛:http://bbs.pediy.com/

微信公众号 ID:ikanxue

微博:看雪安全

投稿、合作:www.kanxue.com