\x01 前言

  • CVE-2018-0802 是继 CVE-2017-11882 发现的又一个关于 font name 字段的溢出漏洞,又称之为 “第二代噩梦公式”,巧合的是两个漏洞竟由同一个函数 sub_421774 所引发,而且都属于栈溢出。据说是国内安全厂商 360 率先截获了全球首例利用此漏洞的攻击,并且立即公布了该漏洞的具体细节,给安全厂商们赢得了宝贵的时间,避免攻击进一步扩大。在 2018 年 1 月的微软例行安全更新中有此漏洞的具体细节,以及针对 Office 各个版本的补丁。

注:需要注意的是,由于该漏洞是按笔者自己的流程进行分析的,所以可能有些地方写的不是很详细,导致看不懂,有看不懂的地方可以留言

  • CVE-2018-0802 影响的 Office 软件版本:

\x02 调试环境

注:CVE-2018-0802 是在 CVE-2017-11882 补丁的基础上触发的,换句话说就是必须满足存在 CVE-2017-11882 漏洞并且打上了补丁这两个条件才能触发 CVE-2018-0802。所以基于此点建议先研究分析 CVE-2017-11882 漏洞后再分析 CVE-2018-0802。

\x03 调试分析漏洞成因

  • 首先搭建好基于 CVE-2017-11882 的环境,并且打上补丁,由此确保 CVE-2018-0802 能够触发。

  • 使用 cve-2018-0802_poc.py 脚本生成 test.doc 样本文件。

  • 双击 test.doc 样本,成功弹出计算器,这表明漏洞确实存在,并且在加载文档之前触发。下面就来研究一下为什么打开文档会弹出计算器吧…

  • 先设置 x64dbg 为附加调试模式,这样就可以在 Office 载入 EQNEDT32.EXE 模块时自动开启调试器进行调试,这个也是调试子进程最方便的方法之一。

  • 然后重新打开 test.doc 文档,调试器附加成功后在 WinExec 函数上下断点,因为弹出计算器的操作是由这个函数完成的。



  • 由于之前分析过 CVE-2017-11882 这个漏洞,所以根据之前下的断点得出在 sub_421774 函数调用后会断在 WinExec 上,接下来对这个函数的返回值进行分析,判断问题是否出在 sub_421774 中。对 sub_421774 函数的开头和结尾下条件记录断点。









  • 断点下好后,重新打开 test.doc 文档,得到日志如下图所示。经过分析可以得出 EQNEDT32.EXE 模块在运行期间多次调用了 sub_421774 函数。需要注意的是最后调用 sub_421774 时出现了问题(红圈圈中的),在 start 处压栈时压入的返回地址为 0x004214E2,但是在 end 出栈时返回地址却变成了 0x00420025,说明返回地址被恶意覆盖了,由此确定了 sub_421774 函数中存在内存泄漏的状况,下面开始调试该函数,查找是什么原因导致。

  • 根据日志设置条件断点,在 start 处当 esp == 18F308 && [esp] == 4214E2 时断下,方便调试。

  • 重新打开文档之后断在了 sub_421774 上,且满足 esp == 18F308 && [esp] == 4214E2 的条件。然后经过调试之后发现漏洞出现在 sub_421E39 这个函数中,因为执行完此函数后返回值会被覆盖,而 sub_421E39 函数中的复制字符串指令 rep 就是漏洞导致的根本原因,由于局部变量的大小为 0xAC,只要复制长度超过 0xAC 就会照成栈溢出。







  • 查看 rep 指令执行结束后堆栈的状态,栈空间 sub_421774 函数的返回地址已经被覆盖成了 0x00420025。而且复制的数据是 font name 字符串地址,是通过参数传递进来的,如下图内存窗口所示:

  • 样本中的对照数据如下图所示,该数据是嵌入在 RTF 文件的 \object 组中的,属于公式编辑器对象(OLE)。

  • 然后运行到 sub_421774 的结尾处会进行 ret 返回操作。

  • sub_421774 函数返回之后成功劫持了程序的 EIP 并且运行到了 0x00420025 处。



  • 最终实现了执行任意代码的目的(安全限制绕过及 shellcode 会在之后进行分析)。



\x04 CVE-2017-11882 补丁 + CVE-2018-0802 结合分析

  • 既然 CVE-2018-0802 是在 CVE-2017-11882 补丁的基础上才会触发,那么来研究一下到底是为什么。对于打补丁和未打补丁之间的切换,直接更换 EQNEDT32.EXE 文件即可,别忘了做备份。

  • 首先恢复到打补丁之前的版本,也就是能够触发 CVE-2017-11882 的版本,之后打开 CVE-2018-0802 看看会发生什么。由于之前的条件断点,所以运行之后断在了 sub_421774

  • 之后运行完 sub_421E39 后,由于复制的数据 font name(lpLogFont) 大于局部变量的大小 0xAC,所以导致栈溢出,返回值被覆盖为 0x00420025,到此为止没有任何问题。





  • 接着运行到 sub_4115A7 函数处,F7 进入该函数,注意传入的参数为 font name 字段,



  • 再运行到 sub_41160F 处,F7 再次进入,传入的参数为依然包括 font name 字段。



  • 如下图所示,在 0x00411658 地址处就是 CVE-2017-11882 漏洞的触发点,rep 指令会将 font name 字段复制到当前函数的局部变量中,由于局部变量只有 0x28 大小,所以会再次造成栈溢出。



  • 接着运行到 sub_44C430 函数处,F7 进入该函数。

  • 在运行到如图所示的这条语句上时会导致异常,因为传入该函数的第二个参数已经被 font name 字段给覆盖了,导致 mov dl,byte ptr ds:[ecx] 读取了一个未知地址的数据,故触发异常。





  • 异常导致程序直接运行到 0x7DE915EE 地址上,导致程序退出,从而不会运行到返回地址处。

  • 运行流程图:

  • 对比打上了 CVE-2017-11882 补丁之后的效果,运行完 sub_421E39 后触发了 CVE-2018-0802,返回地址被覆盖为 0x00420025



  • 接着进入到 sub_41160F 函数中,触发 CVE-2017-11882



  • 由于打上了补丁,所以会对 font name 字段的长度进行判断,如果 font name 字段的长度超过了 0x21,则将拷贝的长度限制为 0x20



  • 这样的话 sub_44C430 中的 mov dl,byte ptr ds:[ecx] 就不会触发异常,因为 ecx 没有被 font name 字段恶意覆盖,这也是为什么打了 CVE-2017-11882 补丁才能够触发 CVE-2018-0802根本原因



  • 接着就可以成功的运行到 sub_421774 函数的结尾并且跳转到 0x00420025 的地址当中去。

  • 运行流程图:

注:在进行 CVE-2018-0802CVE-2017-11882 双重 POC 构造时,如果在同一个对象中,就需要注意避开异常

\x05 安全限制绕过分析

  • 如果原来没有开启系统的 ASLR 的话,需要开启 ASLR。本实验系统是 Windows 7,所以需要用 EMET(微软的增强减灾工具)来开启 ASLR,同时这个工具也可以关闭 ASLR

  • 如果同时开启了 DEP 的话,需要将其关闭,因为该样本无法绕过 DEP

  • 之后使用 Immunity Debugger!mona modules 命令查看开启的防护,发现打上 CVE-2017-11882 补丁之后,开启了 ASLR

  • 下面看看样本是如何绕过 ASLR 的。打开 test.doc 样本之后,直接运行要 sub_421774 函数的返回处,此时栈中的返回地址已经被覆盖了。

  • 对于 ASLR 的基本知识主要有两点,第一个是映像基址随机化,第二个堆栈地址随机化(还有一个就是 TEB/PEB 的随机化),对于 32 为程序,映像基址(模块基址)随机化只针对地址的前半部分,比如 0x00240035 只随机化 0x0024 的部分,而 0x0035 保持不变;而堆栈地址随机化相对于堆栈开辟来说则是全部随机化。
  • 结合该样本分析,返回地址只是覆盖了地址的后半部分为 0x0025,为的是保留前半部分以绕过 ASLR

  • 然后 F8 运行,程序直接返回到了 0x00240025,该地址是一条 ret 指令(对于 ret 指令的选取,直接在模块中搜索该条指令即可)



  • 接着继续 F8 单步运行,返回到了 0x001DF084 地址,该地址就是溢出的 font name 字段中的数据,这一步是完成内存数据到程序指令的转变。

  • 指令 sub esp,edx 会将 esp 减去 0x200,这样做的目的是让 shellcode 使用未初始化过的栈空间,避免了对栈空间的破坏,让程序能够流畅的运行。



  • 完成以上操作后,使用 F7 进入下图所示的 call 中,地址是 0x0051EC82,该地址储存着 shellcode



  • shellcode 的实现很简单,利用线程环境块动态调用 WinExec API 函数,函数地址储存在 eax 中,参数储存在 ebx 中,由 jmp 指令进行调用。

  • 样本中的 shellcode 如下所示:

  • 最后会运行到 WinExec 的地址,进行打开计算器的操作。



\x06 CVE-2018-0802 补丁分析

  • 进入微软官网对照各个版本下载相应补丁,本实验的 Office 版本是 2016(64bit) ,下载完成之后安装。



  • 使用 IDA 直接定位到 CVE-2018-0802 漏洞处,也就是 sub_421E39,之后对补丁进行分析。但是好像并没有什么变化。

  • 且运行之后还是能弹出计算器。

  • 再次安装更新也显示此系统已经安装了更新。

  • 额,不知道是为什么,但是鉴于上面的情况,建议开启系统的 DEP 防护来缓解 CVE-2018-0802 的危害…

关于 CVE-2018-0802 的漏洞分析到此结束,如有错误,欢迎指正

CVE-2018-0802:Microsoft office 公式编辑器 font name 字段二次溢出漏洞调试分析的更多相关文章

  1. CVE-2017-11882:Microsoft office 公式编辑器 font name 字段栈溢出通杀漏洞调试分析

    \x01 漏洞简介 在 2017 年 11 月微软的例行系统补丁发布中,修复了一个 Office 远程代码执行漏洞(缓冲区溢出),编号为 CVE-2017-11882,又称为 "噩梦公式&q ...

  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. CVE-2010-2553:Microsoft Cinepak Codec CVDecompress 函数堆溢出漏洞调试分析

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 修改 Hosts 解决 Github 访问缓慢问题

    背景 最近访问 Github 经常出现访问速度慢的问题,甚至会出现无法连接的情况.有一天,在一次家常聊天中提到了这个事情,有一位热心的 Gitee 朋友就说:你改一下 Hosts 文件就可以了.修改了 ...

  2. 报错NameError: name ‘null’ is not defined的解决方法

    报错NameError: name 'null' is not defined的解决方法 eval()介绍 eval()函数十分强大,官方demo解释为:将字符串str当成有效的表达式来求值并返回计算 ...

  3. java基础:数据类型拓展

    public static void main(String[] args) { //单行注释 //输出hello,world! //System.out.println("hello,wo ...

  4. git分支管理--rebase&merge详解

    目录 分支合并 git merge --squash [分支名] 注意点 git rebase [分支名] git rebase git rebase --abort git rebase -i gi ...

  5. JetBrains Projector 体验

    先来一张最终效果图: JetBrains Projector 是 JetBrains 的"远程开发"解决方案,基于 Client + Server 架构,对标的是微软 VSCode ...

  6. 剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知 ...

  7. Go 语言入门教程,共32讲,6小时(已完结)

    Go语言入门教程,共32讲,6小时(完结) 在B站:https://www.bilibili.com/video/BV1fD4y1m7TD/

  8. TypeError: myMethod() takes no arguments (1 given) Python常见错误

      忘记为方法的第一个参数添加self参数 ---------------------------------------------------------------

  9. [GDKOI2021] 提高组 Day 2 总结

    [ G D K O I 2021 ]    提 高 组    D a y   2    总 结 不明的感觉今天的题比昨天的简单些,感觉今天爆炸的可能性很低. 嗯,于是乎,就很自信地打完了比赛.然后下午 ...

  10. 鸿蒙开源第三方组件——SlidingMenu_ohos侧滑菜单组件

    目录: 1.前言 2.背景 3.效果展示 4.Sample解析 5.Library解析 6.<鸿蒙开源第三方组件>文章合集 前言 基于安卓平台的SlidingMenu侧滑菜单组件(http ...