栈溢出入门之CVE-2012-0158漏洞分析
2019-06-26 09:25:00 Author: xz.aliyun.com(查看原文) 阅读量:110 收藏

漏洞原理:

  • 这个漏洞发生在office的一个组件MSCOMCTL.OCX,多个版本office的该模块都存在这个漏洞,MSCOMCTL.OCX这个漏洞模块是office解析activeX控件用到的一个动态库,当一个office文档中包含activeX这类控件元素的话,比如按钮、列表、树形控件时,文档通过office打开时,MSCOMCTL.OCX就会被自动载入office程序的进程空间被调用来解析和显示控件。
    #### 漏洞类型:缓冲区栈溢出。
  • 测试环境:XPSP2+office2007。
  • 调试器:Immunity Debugger。
  • 先用一个POC来观察溢出发生的时候栈中的数据分布。首先打开WINWORD.EXE,然后用Immunity Debugger附加WINWORD.EXE,然后F9运行,之后将POC测试文档poc.doc拖进WINWORD.EXE,如图:程序在0x41414141这处地址断下,这是一个无效的内存地址,所以程序无法继续运行,根据栈溢出的利用方式判断,0x41414141这个位置应该是函数返回地址一类的数据。接着观察这个返回地址属于哪个函数,在右下角的栈区右键=>”Follow in Dump”,在左边的内存数据区出现虚拟地址对应的机器码,在该区右键=>”Disassemble”就看到了对应的汇编指令,向上回溯就看能到函数sub_275C89C7。

  • 漏洞存在的位置是MSCOMCTL.OCX模块,因此sub_275C89C7也就对应于MSCOMCTL.OCX的位置,接下来下断点看看数据是怎么复制到缓冲区的,如果直接在这里下断点是没法断下的,对比书上的分析可知,MSCOMCTL模块是在打开poc.doc时才加载,这里先“Alt+E”找到MSCOMCTL对应的路径,再用Immunity Debugger加载运行,然后bp 0x275C89C7,之后在加载poc.doc就可以在sub_275C89C7断下。

  • 这里一共调用了两次sub_275C876D:

  • 同时将MSCOMCTL.OCX模块在IDA反编译用F5看看这段代码的基本用途:

  • IDA中的伪代码“if(V5 == 1784835907)”中,1784835907对应的十六进制为0x6A626F43,对应的ASCII码为“jboC”,按照小端存储规则逆过来就是“Cobj”,在Immunity Debugger中F7跟进sub_275C876D可以知道,第一次调用sub_275C876D是复制了“Cobjd”,这应该是判断程序接着要处理的对象名字是不是“Cobj”,由MSCOMCTL的结构可知,这是MSCOMCTL.OCX模块的第二个对象。Cobj::load用来读取数据。

  • 之后再跟进第二个sub_275C876D:发现了溢出的现场就在这个函数,对比刚开始加载时的栈状态,0x275C87CB处的指令将数据复制到栈中,并覆盖了栈中0x00124C0C处的返回地址。

  • 在IDA中的伪代码中,要执行第二个sub_275C876D,需要满足“if ( v5 == 0x6A626F43 && dwBytes >= 8 )”,如果dwByte小于8就不执行。此时在Immunity Debugger中可以看到:ss:[EBP-C]==0x00008282,这远远大于8,满足了这里判断条件,这样Cobj::load就可以读取多余的数据,这个意思好像就是非得让你溢出不可了,原本的判断条件应该是“if ( v5 == 0x6A626F43 && dwBytes <= 8 )”,正是这个误写的大于使得多余的数据也能被复制到栈中

  • 接着用一个可以弹出计算器的word文档再看看溢出的发生和利用:

  • 先来到溢出发生的地方,在调试器看到,是从DS:[ESI]这个位置开始复制,在内存中跟随看看,可以看到这段代码用了0x7FFA4512,即”jmp esp”作为跳板地址,那么shellcode的起始位置就是esp的值。

  • 数据被通过溢出被复制到栈中:

  • 通过“jmp esp”跳回栈中执行shellcode,ESP此时的值为0x00124C6C

  • 栈中的shellcode被当作代码执行:

  • 弹出计算器:

  • 修复后的函数在IDA中如下,在新的判断条件中,“Cobj::load”读取的长度必须为8字节,否则不进行复制。


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