CVE-2017-11882是一个Office的漏洞,虽然该漏洞已经有补丁了,且杀毒软件也能查出利用了该漏洞的恶意文档,但是学习和复现该漏洞仍是一项令人受益颇多的过程
为了复现该漏洞,我们需要准备Office2016及以前的版本,这里我选择的是2016版本,复现成功的表现是,打开文档后,一个exe被释放并执行,修改注册表让自己开机自启,以后每次开机都会弹窗
利用漏洞的主要手段是,依靠公式编辑器中的缓冲区溢出执行短长度命令行以及Office自动在TEMP目录下临时释放附件的特性,达到执行任意代码的效果
导致漏洞的罪魁祸首就是一个叫EQNEDT32.EXE的程序,该文件的位置可以用任务管理器查看进程文件来定位
我们先分析一下“官方”POC文件长啥样
表面看上去是一个挺正常的rtf文件
恶意数据来自于下图处
要理解如何构造恶意数据,我们先要了解Office内部原理
Office有一个叫Microsoft公式3.0的对象组件,点击插入后可以输入数学公式,而这一部分就是由上面所说的程序来处理的,它将输入好的公式以特定的格式保存,下次打开Office时会按照一定的方式读取并显示该公式,而读入时的代码有不严谨之处,导致可以缓冲区溢出
因此,只要精心构造数据,就能开始ROP了
可以看到该POC大概率是将ret addr覆盖成了0x430c12,我们用IDA看看此处是什么代码
这是一个32位且没有开ASLR的程序,非常nice
结果是call WinExec处,这个函数是用来执行命令行、创建进程的
我们试着打开该POC的rtf文件,发现自动弹出了计算器
再次观察,发现前面图中的636d642e…对应的字符串是cmd.exe /c calc.exe(每2位当作一个byte的十六进制写法,转换ASCII),这大概就是被当作参数传入WinExec的数据
下面来分析如何修改及构造POC
蓝色部分是OLE Equation Object的文件头,也就是我们插入的公式在文件中保存的数据结构的结构头
具体数据结构定义可以看相关文档,我们需要关注的只有其中一个DWORD,a9000000,它代表了我们接下来后面跟的数据的大小为0xa9
接下来5字节是MTEF文件头,没啥要关注的
接下来的内容就是重点了,上图蓝色部分08代表了这是一个font record数据,后面跟的是字体名,以\0结尾
正常插入的公式是不会有这个数据结构的,此处开始就是公式的内容了,而即便是有,也是正常的合法数据
我们可以看到,该POC将字体名设置为了cmd.exe /c calc.exe AAAAAA…p64(0x430c12)
接下来用IDA分析一下
栈溢出漏洞的发生之处是上图的第18行,使用了不安全的strcpy函数,将SubStr复制到String中
至此,我们已经有了利用思路
由于Office的特性,将会把嵌入的对象释放到临时目录(%TEMP%环境变量)下,我们可以将自己编写的dll释放到该目录下,并利用该漏洞执行regsvr32来加载我们的dll,达到执行任意代码的目的
下面开始编写后门程序
这个程序将在漏洞触发时被执行,将自己设为开机自启,功能是弹窗
写个小工具将整个生成的exe转换成C字符串形式,嵌入到dll文件的字符串常量中,方便写入文件
这个dll的功能是在被加载的时候将后门程序写入TEMP目录并运行
我们新建一个rtf文档,点击插入->对象->由文件创建,选择被生成的dll,点击确定
然后再点击插入->对象->Microsoft公式3.0,在出现的输入框中输入40个字符“1”,点击空白区域完成输入
接着保存并关闭这个rtf文档,用010Editor打开
发现这个文件复杂了许多,我们定位到公式处
我们将cmd.exe /c calc.exe换成cmd.exe /c “regsvr32 /s %TEMP%\CVE.dll”,补充“A”(0x41)后加上p64(0x430c12),然后后面全部填0
别忘了在前面添上\objupdate让漏洞在打开文档时自动触发
保存以后,我们的POC就大功告成了,来试试效果
这是没打开前的注册表
打开以后会立刻弹窗
再看注册表发现已经成功添加了开机启动项
至此我们就成功的完成了该漏洞的复现
在这次复现的过程中,我巩固了已经掌握的部分知识,也新学习到了很多新的技巧和方法,其中踩了不少的坑,一个一个解决深坑的过程是困难却收获很大的,自己也曾动脑想过如何绕smart screen、动手试过upx加壳、stream64清除ntfs流、bat执行等小操作等等…知识总是在一次一次对抗中积累起来的,有很多惊为天人的技术和手法是能令人茅塞顿开的,个人的见识也是在不断的学习中一步步提高的,只要一直保持好学的心,虽然每次做的、每篇博客记录的都是小事,但日积月累起来的知识却是不容忽视的
踩过的坑:
- 要先插入文件再插入公式,否则公式漏洞触发时临时文件还没有被释放
- 公式长度要和构造的数据一致,否则漏洞会触发失败
- 因为smart screen机制的存在,不能直接释放exe并执行,除非绕过此机制
- 应该使用cmd.exe /c来执行命令,而不是直接把命令传入WinExec,否则%TEMP%环境变量无法解析
- 以这种漏洞利用方式加载的dll,在regsvr32所在的System32文件夹下无权限写入文件,必须找其他位置释放后门程序
- 没有UAC权限的后门程序无法写入Local Machine主键下的注册表,这种情况下可以考虑换成写Current User的相同位置来实现自启