\x01 漏洞简介

  • 在 2017 年 11 月微软的例行系统补丁发布中,修复了一个 Office 远程代码执行漏洞(缓冲区溢出),编号为 CVE-2017-11882,又称为 “噩梦公式”。该漏洞从修复之日起已经隐藏了 17 年之久,而且通杀目前流行的所有 Office 版本,可见其危害程度。该漏洞位于 Office 的 EQNEDT32.EXE 组件中,该组件的作用是通过 OLE 对象的互操作性协助 Office 软件进行公式的处理,由于在拷贝 Office 传入 font name 字段时没有对该字符串的长度进行限制,所以造成了缓冲区的溢出。攻击者可以利用该漏洞以当前登录的用户身份执行任意命令。

  • CVE-2017-11882 漏洞影响的 Office 版本:

\x02 测试环境

注:以上软件有部分是第三方提供的下载支持,如没有进行杀毒处理或者未在虚拟机中安装导致电脑中毒的,后果自负

\x03 RTF 文件中的 OLE 对象互操作性

1)OLE 对象和 RTF 文件格式介绍

  • OLE 全称 Object Linking and Embedding,及对象的嵌入与链接技术,是 COM 技术的前身。该技术允许在程序之间链接和嵌入对象数据,从而建立复合文档。Office 当中的各种软件都会采用 OLE 技术储存文件规范,通过该规范,一个文件中不仅可以包含文本,而且还可以包括图形、电子表格、甚至是声音视频信息。如下图所示:

  • 富文本格式RTF)规范是为了方便在应用程序之间轻松储存格式化文本和图形的一种编码方法。由 Microsoft 公司制定,它适用于不同的设备、操作环境和操作系统。下图列出了部分 RTF 文档 16 进制内容信息:

2)RTF 中的公式编辑器对象的嵌入

  • 根据 RTF Specification Version 1.7 的文件格式规范,RTF 文件语法格式主要有三类:控制字(如 \rtf)、控制符(如 \~)和组( { } )。而 RTF 中的 OLE 对象主要是通过控制字 \object 进行识别,并且在外围包裹着一个完整的组。具体流程如下图所示:

  • 插入公式编辑器对象(OLE)。

  • 插入完成之后保存。

  • 使用 16 进制编辑器打开刚刚插入公式编辑器的 RTF 文档,搜索 object 关键字即可发现插入的对象。

  • 下图中的 Equation.3 表示的是公式编辑器对象。插入的对象由 \*\objclass 引用控制字进行识别。

注:如果想要更详细的了解 RTF 文件中的 OLE 对象的嵌入信息,请参照 RTF 文件规范 v1.7:https://pan.baidu.com/s/11w-xGVoguP-jtpJ6ocpwSA(提取码:9xar)

3)RTF 中的公式编辑器对象的处理

  • 既然 RTF 文档中可以嵌入公式编辑器对象,那么 Office 是怎么与之进行数据交互的呢?答案是通过 Ole32.dllIPersistStorage 接口实现的,当然了根据情况的不同也可以使用其他接口进行操作。当 Office 读入一个嵌入公式编辑器对象的 RTF 文档时,会调用 Ole32.dll 中的 OleLoad 函数对公式编辑器对象进行初始化。

  • 初始化完成之后,继续调用 ole32.dll 中的 CoCreateInstance 函数来初始化公式编辑器对象中的数据。注意这个函数的第一个参数 CLSID,作用是识别 OLE 对象,因为每个 OLE 对象都有自己的 CLSID。到此为止初始化对象就完成了,此时数据会以持久化的方式(序列化)储存。

  • 最后公式编辑器组件 EQNEDT32.EXE 调用 IPersistStorage ATL 接口中的 Load 方法就可以对数据进行处理, 也就完成了数据的交互操作。



\x04 调试分析

  • 使用 Python 脚本制作 POC 样本文件,功能是弹出计算器。



  • x32dbg 调试器设置为附加调试,注册表路径为 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\EQNEDT32.EXE

  • 打开含有漏洞的文档,断下 WinExec 函数(因为该漏洞文档触发漏洞的方式为使用 WinExec 函数来打开计算器),运行之后成功断在了此函数上。

  • 此时栈结构如下图所示,可以看到返回地址已经被覆盖了,因为漏洞模块没有开启任何的安全保护,所以不需要通过 ROP 等方式绕过安全保护。因此栈结构还没有被完全破坏,通过栈向上找出是哪一个函数调用的 WinExec

  • 如下图所示,eqnedt.4115A7 即为栈中找到的最靠近漏洞触发点的函数。

  • eqnedt.4115A7 函数下断,重新运行程序后单步调试,发现到达此位置时函数的返回值会被覆盖,由此确定这个就是漏洞的触发点。

  • 运行到函数的返回处。

  • 查看此时栈中的数据,发现函数的返回值已经被覆盖为 WinExec 函数的地址。

  • 查看 0x0018F354 地址的值,这个也就是让 WinExec 函数执行的命令。
  • 值得注意的是命令和溢出字符是以 0x26 隔开的,成功的避开了空格对拷贝字符的影响;而且 WinExec 函数是 EQNEDT32.EXE 模块本身就有的函数(因为没有 ASLR 保护),并不是从库中调用的。

  • 继续 F8 执行下去,运行到了 WinExec 函数的地址,最后会弹出计算器。



  • 由于 EQNEDT32.EXE 模块是通过 IPersistStorage 接口对 RTF 文档中传入 OLE 的数据进行处理的,所以找到 IPersistStorage::Load 函数分析其处理方式。
  • 因为 IPersistStorage 接口的函数是通过 EQNEDT32.EXE 模块本身调用的,所以并没有相应的符号文件,但是可以从 IPersistStorage 接口的初始化和调用方式推出 IPersistStorage::Load 函数的具体位置。IPersistStorage 接口的初始化如下图所示:



  • 通过比对后发现 sub_406881 就是我们要找的 IPersistStorage::Load 函数。



  • 之后通过对比 x32dbg 的调试结果和 IDA 的交叉引用,得出了函数调用链:

  • 需要注意的是 sub_406881sub_43B418 这个两个函数。在 sub_406881 中,先调用 GlobalAlloc 函数从堆中分配指定的字节数,然后调用 GlobalLock 函数锁定全局内存对象并返回指向对象内存块第一个字节的指针,指针储存在局部变量 var_3C 中。

  • 之后以 eax 为虚函数表的首地址,调用偏移地址为 0x0C 的函数 IUnknown_QueryInterface_Proxy 来获取 MTEF Byte Stream 数据。

  • 而获取到的 MTEF Byte Stream 数据就储存在局部变量 var_3C 中,也就是下图中的 [ebp-3C] 中。

  • 再来看看 sub_43B418 函数,该函数会通过 sub_4164FA 函数取出 MTEF Byte Stream 中的 font name 字段的数据并且拷贝到局部变量 [ebp-104] 当中。



  • 样本对照如下:

  • 在函数调用链的最后会将 font name 压入,压入参数之后调用漏洞函数 sub_41160F

  • 漏洞函数会将 font name 中的数据拷贝到局部变量 var_28 中。

  • 由于并没做任何的判断,并且只要数据的大小超过 0x28,就会造成栈溢出,这也是漏洞产生的根本原因。

  • 最后使用带有 mona.py 脚本插件的 Immunity Debugger 查询 EQNEDT32.EXE 模块的安全防护,发现确实没有开启任何防护措施。

\x05 补丁修复分析

  • 下载微软安全更新中心关于 CVE-2017-11882 的补丁并打好补丁。这里需要根据 Office 的版本和系统位数自行选择。



  • 对比之前的未打过补丁的版本,打过补丁的版本对 font name 字符串的长度做了判断,如果长度大于 0x21 的话就将拷贝的长度限制为 0x20,从而达到了防止缓冲区溢出的目的。



\x06 参考文献

关于 CVE-2017-11882 漏洞分析到此结束,如有错误,欢迎指正。

CVE-2017-11882:Microsoft office 公式编辑器 font name 字段栈溢出通杀漏洞调试分析的更多相关文章

  1. CVE-2018-0802:Microsoft office 公式编辑器 font name 字段二次溢出漏洞调试分析

    \x01 前言 CVE-2018-0802 是继 CVE-2017-11882 发现的又一个关于 font name 字段的溢出漏洞,又称之为 "第二代噩梦公式",巧合的是两个漏洞 ...

  2. CVE-2018-0798:Microsoft office 公式编辑器 Matrix record 字段栈溢出漏洞调试分析

    \x01 前言 2018 年 1 月 9 日,Office 公式编辑器再曝出新漏洞,编号为 CVE-2018-0798.提起公式编辑器大家都不陌生,之前的 CVE-2017-11882 和 CVE-2 ...

  3. CVE-2012-0003:Microsoft Windows Media Player winmm.dll MIDI 文件堆溢出漏洞调试分析

    0x01 蜘蛛漏洞攻击包 前言:2012 年 2月,地下黑产中流行着一款国产名为蜘蛛漏洞的攻击包 -- "Zhi-Zhu Exploit Pack",该工具包含 5 个漏洞,都是在 ...

  4. MathType与Office公式编辑器有什么不同

    说到在论文中编辑公式,有经验的人都会知道要用公式编辑器来编辑,没经验的人也会被安利使用公式编辑器.然而在使用公式编辑器时,又有了两种选择,一种是使用Office自带的公式编辑器,一种是MathType ...

  5. CVE-2011-0104:Microsoft Office Excel 中的栈溢出漏洞调试分析

    0x01 前言 CVE-2011-0104 是 Microsoft Office 中的 Excel(没有打补丁的情况下)表格程序在处理 TOOLBARDEF 中的 Record 字节时没有对 Len ...

  6. CVE-2012-0158:Microsoft Office MSCOMCTL.ocx 栈溢出漏洞调试分析

    0x01 Lotus Blossom 行动 在 2015 年 6 月,国外安全厂商 Palo Alto Networks 的威胁情报团队 Unit42 发现了一起针对东南亚政府的一次间谍行为,试图获取 ...

  7. CVE-2010-3333:Microsoft RTF 栈溢出漏洞调试分析

    0x01 前言 CVE-2010-3333 漏洞是一个栈溢出漏洞,该漏洞是由于 Microsoft文档在处理 RTF 数据的对数据解析处理错误,在进行内存操作时没有对操作的数据进行长度限制,导致存在内 ...

  8. CVE-2010-3974:Windows 传真封面编辑器 FxsCover.exe 双重释放漏洞调试分析

    0x01 堆空间申请后的双重释放 Windows FxsCover 程序存储封面编辑器的信息,封面编辑器是传真服务的一个组件,通过解析特定的传真封面文件(.cov)时,会调用类析构函数对同一内存中的栈 ...

  9. CVE-2010-2553:Microsoft Cinepak Codec CVDecompress 函数堆溢出漏洞调试分析

    0x01 前言 微软提供一个叫 Cinepak 的视频解码器,通过调用 iccvid.dll 这个动态链接库文件可以使用这个解码器:微软自带的 Windows Media Player(视频音频软件) ...

随机推荐

  1. java安全初学之动态代理

    前言:作为安全人员,代理大家用的都很多,那什么是java中的动态代理呢?事实上,java中的"动态"也就意味着使用了反射,因此动态代理是基于反射机制的一种代理模式. 简介: 代理是 ...

  2. 扫盲贴|如何评价一款App的稳定性和质量?

    作者:友盟+移动开发专家 张文 「崩溃」与「卡顿」.「异常退出」等一样,是影响App稳定性常见的三种情况.相关数据显示,当iOS的崩溃率超过0.8%,Android的崩溃率超过0.4%的时候,活跃用户 ...

  3. WPF 基础 - x 名称空间详解

    名称 种类(默认Attribute) 备注 x:Array 标记拓展 可作为 ListBox.ItemsSource 的值 x:Class 指定与 .cs 中哪个类合并,所指示的类型在声明时使用 pa ...

  4. VS2008开发WinCE程序编译速度慢的解决办法

    1.找到以下文件 C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets 2.用记事本打开该 ...

  5. 递归实现1-n的全排列(JAVA语言)

    思路: For example: 123的全排列= 1在最前面 23的全排列 + 2在最前面 13的全排列 + 3最前面 12的全排列 所以只需交换和最前面元素的位置,生成剩余元素的全排列即可. im ...

  6. P1036_选数(JAVA语言)

    题目描述 已知 n 个整数x1​,x2​,-,xn​,以及1个整数k(k<n).从n个整数中任选k个整数相加,可分别得到一系列的和.例如当n=4,k=3,4个整数分别为3,7,12,19时,可得 ...

  7. python3表格数据处理

    技术背景 数据处理是一个当下非常热门的研究方向,通过对于大型实际场景中的数据进行建模,可以用于预测下一阶段可能出现的情况.比如我们有过去的2002年-2018年的黄金价格的数据: 该数据来源于Gite ...

  8. java连接sql server--关于登录验证及对数据库增删改查应用

    一:步骤## 1.sql server建立数据库和相关表 2.建立数据源  (1).打开控制面板找到管理,打开ODBC选项或直接搜索数据源  (2).打开数据源配置后点击添加,选择sql server ...

  9. Android Studio 通过 ListView 学习 ArrayAdapte

    ListView •前言 ListView 绝对可以称得上是 Android 中最常用的控件之一,几乎所有的应用程序都会用到它. 由于手机屏幕空间有限,能够一次性在屏幕上显示的内容并不多,当我们的程序 ...

  10. 自己挖的坑自己填--jxl进行Excel下载堆内存溢出问题

    今天在进行使用 jxl 进行 Excel 下载时,由于数据量大(4万多条接近5万条数据的下载),数据结构过于负责,存在大量大对象(虽然在对象每次用完都设置为null,但还是存在内存溢出问题),加上本地 ...