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

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

\x02 测试环境
- 系统: Window 7(关闭 ALSR 以及 DEP)
- 漏洞软件: Office 2016 64位(提取码:fc1b)+ EQNEDT32.EXE(版本 2000.11.9.0)
- POC 制作脚本(Python)Github: https://github.com/GeekOnlineCode/POC/tree/master/
- POC 打包: test.doc(提取码:m43c)
- 调试器: x64dbg + x32dbg
- 反汇编静态分析器: IDA 7.2(提取码:zksm)
- OLE 对象分析软件: Oleview.exe
- 16进制编辑器: C32Asm(16进制分析文件工具,提取码:4sj8)
- 微软补丁及公告地址: https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-11882

注:以上软件有部分是第三方提供的下载支持,如没有进行杀毒处理或者未在虚拟机中安装导致电脑中毒的,后果自负
\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.dll和IPersistStorage接口实现的,当然了根据情况的不同也可以使用其他接口进行操作。当 Office 读入一个嵌入公式编辑器对象的RTF文档时,会调用Ole32.dll中的OleLoad函数对公式编辑器对象进行初始化。

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

- 最后公式编辑器组件
EQNEDT32.EXE调用IPersistStorageATL接口中的 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_406881和sub_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漏洞分析、利用及动态检测(FreeBuf):https://www.anquanke.com/post/id/87311
- CVE-2017-11882分析调试(看雪):https://bbs.pediy.com/thread-247767.htm
- 攻击互通性(翻译):https://bbs.pediy.com/thread-218941.htm
- Attacking Interoperability in Black Hat 2009 研究报告(翻译):https://blog.csdn.net/qq_38924942/article/details/93646823
- 公式编辑器 MTEF 数据结构:http://rtf2latex2e.sourceforge.net/MTEF3.html
关于 CVE-2017-11882 漏洞分析到此结束,如有错误,欢迎指正。
CVE-2017-11882:Microsoft office 公式编辑器 font name 字段栈溢出通杀漏洞调试分析的更多相关文章
- CVE-2018-0802:Microsoft office 公式编辑器 font name 字段二次溢出漏洞调试分析
\x01 前言 CVE-2018-0802 是继 CVE-2017-11882 发现的又一个关于 font name 字段的溢出漏洞,又称之为 "第二代噩梦公式",巧合的是两个漏洞 ...
- CVE-2018-0798:Microsoft office 公式编辑器 Matrix record 字段栈溢出漏洞调试分析
\x01 前言 2018 年 1 月 9 日,Office 公式编辑器再曝出新漏洞,编号为 CVE-2018-0798.提起公式编辑器大家都不陌生,之前的 CVE-2017-11882 和 CVE-2 ...
- CVE-2012-0003:Microsoft Windows Media Player winmm.dll MIDI 文件堆溢出漏洞调试分析
0x01 蜘蛛漏洞攻击包 前言:2012 年 2月,地下黑产中流行着一款国产名为蜘蛛漏洞的攻击包 -- "Zhi-Zhu Exploit Pack",该工具包含 5 个漏洞,都是在 ...
- MathType与Office公式编辑器有什么不同
说到在论文中编辑公式,有经验的人都会知道要用公式编辑器来编辑,没经验的人也会被安利使用公式编辑器.然而在使用公式编辑器时,又有了两种选择,一种是使用Office自带的公式编辑器,一种是MathType ...
- CVE-2011-0104:Microsoft Office Excel 中的栈溢出漏洞调试分析
0x01 前言 CVE-2011-0104 是 Microsoft Office 中的 Excel(没有打补丁的情况下)表格程序在处理 TOOLBARDEF 中的 Record 字节时没有对 Len ...
- CVE-2012-0158:Microsoft Office MSCOMCTL.ocx 栈溢出漏洞调试分析
0x01 Lotus Blossom 行动 在 2015 年 6 月,国外安全厂商 Palo Alto Networks 的威胁情报团队 Unit42 发现了一起针对东南亚政府的一次间谍行为,试图获取 ...
- CVE-2010-3333:Microsoft RTF 栈溢出漏洞调试分析
0x01 前言 CVE-2010-3333 漏洞是一个栈溢出漏洞,该漏洞是由于 Microsoft文档在处理 RTF 数据的对数据解析处理错误,在进行内存操作时没有对操作的数据进行长度限制,导致存在内 ...
- CVE-2010-3974:Windows 传真封面编辑器 FxsCover.exe 双重释放漏洞调试分析
0x01 堆空间申请后的双重释放 Windows FxsCover 程序存储封面编辑器的信息,封面编辑器是传真服务的一个组件,通过解析特定的传真封面文件(.cov)时,会调用类析构函数对同一内存中的栈 ...
- CVE-2010-2553:Microsoft Cinepak Codec CVDecompress 函数堆溢出漏洞调试分析
0x01 前言 微软提供一个叫 Cinepak 的视频解码器,通过调用 iccvid.dll 这个动态链接库文件可以使用这个解码器:微软自带的 Windows Media Player(视频音频软件) ...
随机推荐
- SHELL编程概念&变量剖析
一.shell软件概念和应用场景 1) 学习Linux技术,不是为了学习系统安装.命令操作.用户权限.配置IP.网络管理,学习Linux技术重点:基于Linux系统部署和维护各种应用软件.程序(Apa ...
- 越来越受欢迎的Vue想学么,90后小姐姐今儿来教你
摘要:Vue的相关技术原理成为了前端岗位面试中的必考知识点,掌握 Vue 对于前端工程师来说更像是一门"必修课". 本文原作者为尹婷,擅长前端组件库研发和微信机器人. 我们发现, ...
- 2017算法期末复习练习赛-G Beihang Couple Pairing Comunity 2017 题解(网络流)
理解不够透彻.好题不可浪费,写题解以增进理解.会陆续补充题目.(咕咕咕) G Beihang Couple Pairing Comunity 2017 题目链接 Beihang Couple Pair ...
- 开源项目renren-fast开发环境部署(后端部分)
开源项目renren-fast开发环境部署(后端部分) 说明:renren-fast是一个开源的基于springboot的前后端分离手脚架,当前版本是3.0 开发文档需要付费,官方的开发环境部署介绍相 ...
- 【图像处理】OpenCV+Python图像处理入门教程(五)阈值处理
这篇随笔介绍使用OpenCV进行图像处理的第五章 阈值处理. 5 阈值处理 阈值是指像素到达某临界值.阈值处理表示像素到达某临界值后,对该像素点进行操作和处理. 例如:设定一幅图像素阈值为200,则 ...
- IPFS挖矿的成本有哪些?
IPFS作为区块链新贵,近来风头一时无量.截止3月9日,Filecoin以257亿的流通市值超越门罗币,稳居区块链流通排行榜. 无论什么投资,其门槛一定在成本.今天就和大家细说投资市面上常见实体矿机的 ...
- IPFS挖矿靠谱吗?
IPFS是一个旨在创建持久且分布式存储和共享文件的网络传输协议,前景广阔且实用意义大,为区块链行业提供了一种新的可能.而IPFS挖矿挖出的FIL,则是在IPFS技术的基础上,对维护IPFS网络的用户的 ...
- Ubuntu20.04linux内核(5.4.0版本)编译准备与实现过程-编译前准备(1)
最近项目也和linux kernel技术有关,调试内核和内核模块.修改内核源码,是学习内核的重要技术手段之一.应用这些技术时,都有一本基本的要求,那就是编译内核.因此,在分析内核调试技术之前,本随笔给 ...
- 详解CURL状态码,最全的代码列表
curl是一个强大的命令,其中我们经常使用的通过curl 加地址和端口号,判断目标链接状态,下面列出了curl 返回的状态码. 举例: [root@k8s-master1 ~]# curl k8s-m ...
- ionic3 清除navpush的堆栈 (android真机返回键bug)
清除navpush的堆栈可以使用 方法一:ionic3文档 this.navCtrl.popToRoot(); //直接返回根组件 方法二: push 后再删除之前页面即可. this.navCtrl ...