CVE-2012-0158 分析

生成样本

msf 生成一个 执行 计算器的 样本

拖到 office 2007word 里面打开即可弹出计算器。

漏洞分析

弹计算器一般是执行系统命令实现, 这里使用的是 kernel32.dll 里面的 WinExec 实现的。所以可以在这个函数下个断点, 然后运行样本看看。

PSx64dbg 可以选择下载指定模块的符号。

WinExec 断下来后,查看栈回溯,发现栈的数据已经被破坏。

此时可以在 调用堆栈窗口 ,右键选择 显示可能的调用堆栈帧

把结果到出来,在文本编辑器里面搜索,发现有两处 mscomctl 的地址。

002E4A2C 275C8800          24   返回到 mscomctl.275C8800 
002E4A50 275C8A0A 275C876D 8404 返回到 mscomctl.275C8A0A 

通过 rtfobj 工具可以发现 msf.doc 中用到的 ole 对象,对应的控件的 CLSIDBDD1F04B-858B-11D1-B16A-00C0F0283628

root@kali:~/vm_share/tmp# rtfobj msf.doc
rtfobj 0.53.1 on Python 2.7.15 - http://decalage.info/python/oletools
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/oletools/issues

===============================================================================
File: 'msf.doc' - size: 10296 bytes
---+----------+---------------------------------------------------------------
id |index     |OLE Object
---+----------+---------------------------------------------------------------
0  |000000A0h |format_id: 2 (Embedded)
   |          |class name: 'MSComctlLib.ListViewCtrl.2'
   |          |data size: 3584
   |          |CLSID: BDD1F04B-858B-11D1-B16A-00C0F0283628
   |          |MSCOMCTL.ListViewCtrl (may trigger CVE-2012-0158)
---+----------+---------------------------------------------------------------

然后使用

https://github.com/tyranid/oleviewdotnet

来查找 CLSID 对应的控件。

PS: 由于 word32 位的 所以需要使用 32 位的 oleview 来查找。

可以看到漏洞用到的控件就是 mscomctl.ocx , 拿 ida 打开它,跳到刚刚发现的两个地址。

002E4A2C 275C8800          24   返回到 mscomctl.275C8800 
002E4A50 275C8A0A 275C876D 8404 返回到 mscomctl.275C8A0A 

275C8800 传入的 参数为

arg1: 读取数据保存位置
arg2: 一个 CExposedStream 对象指针
arg3: 需要读取的大小

函数的作用大概为 利用 CExposedStream 对象 从 objstream 里面读取数据到 dst , 大小为 size.

下面在看看它的上层调用 275C8A0A

这里就是漏洞的位置了首先从 stream 数据读出 0xc 字节到 dst . 这是我定义的一个结构体,结构体定义为。

struct stack_struct
{
  int flag;
  int field_4;
  int next_size;
};

函数首先判断 dst->flag0x6A626F43dst->next_size >= 8 . 通过这个判断后,会再次利用 CExposedStream 读取 stream 数据到 v6 ,大小为 dst->next_size

ida 中分析可以发现 v6 是栈上的一个变量, 大小为 8 个字节, 而 dst->next_size 则为我们的输入数据是在 doc 文件里面设置的, 栈溢出!。

可以看看样本里面的相关字段。

首先使用 rtfobj 导出 ole 对象。

然后拿 010editor 打开。

可以看到这里 size 设置为了 0x00008282

下面在 275C8A05 处下个断点,然后加载文档。

可以看到 next_size 的值为 0x8282.

运行完之后,返回地址被修改,单步到 ret 指令。

27583C30 是一条 jmp esp 指令。

然后继续运行就会利用 jmp esp 跳转到栈里面的 shellcode.

一些 rtf 文件格式的东西

rtf 文件可以使用

{\object\objocx

来调用控件,控件的数据保存在

{\*\objdata

保存的方式为 16 进制字符串。

其中 D0CF11E0A1B11AE1ole 数据的签名,表明从这里开始就是 ole 的数据。

更多详细可以看

http://www.infocomm-journal.com/cjnis/CN/abstract/abstract156911.shtml#1

参考

http://www.infocomm-journal.com/cjnis/CN/abstract/abstract156911.shtml#1

https://www.anquanke.com/post/id/91643#h2-6

posted @ 2018-11-22 20:03  hac425  阅读(547)  评论(0编辑  收藏  举报