对微软Outlook的CVE-2018-8587深入分析报告

2019-04-04 约 2315 字 预计阅读 5 分钟

声明:本文 【对微软Outlook的CVE-2018-8587深入分析报告】 由作者 s小胖不吃饭 于 2018-12-22 08:45:00 首发 先知社区 曾经 浏览数 1765 次

感谢 s小胖不吃饭 的辛苦付出!

前言

在今年的初期,Fortinet的FortiGuard实验室研究员Yonghui Han在研究 Fortinet’s responsible disclosure的过程中发现了Office Outlook中的Heap Corruption漏洞并向office进行了报告。在在2018年12月的周二,微软将此漏洞进行了修补并发布了相关的公告声明,之后为其分配了漏洞编号:CVE-2018-8587

作为Microsoft Office的组件之一,Microsoft Outlook被用于发送和接收电子邮件、管理联系人、记录日常的安排并执行其他的相关任务。在我们的调查研究中,我们发现了多个Windows上的不同版本的Outlook堆漏洞,其版本涵盖了Outlook 2010到最新版的Outlook 2019,除此之外还包括Office 365 ProPlus的所有32/64位版本。

该漏洞可能由具有错误格式的RWZ(邮件分类规则)文件触发。由于缺少边界检查,当Outlook收到不正确的RWZ文件时,它会分配过少的堆内存并导致堆的Out of Bounds写入。

在本博客中,我将分享此漏洞的详细分析。

漏洞重现

要重现此漏洞,我们需要运行Microsoft Outlook,然后单击“规则=>管理规则和警报=>选项=>导入规则”并选择导致Outlook崩溃的PoC文件。

以下是调用堆栈发生崩溃时的图片:

漏洞分析

正如我们从调用堆栈图中看到的情况哪有,系统崩溃常常发生在堆块发布时。 由于我们无法确认释放的堆块的具体问题,所以我们可以打开整页堆来跟踪有问题的堆块。 命令如下:

YOUR_WINDBG_INSATALL_LOCATION\gflags.exe /p /enable outlook.exe /full

可以看到以下返回的结果,表明它已成功执行。

完成此操作后,我们再次打开Outlook、选择PoC文件后对新的崩溃堆栈进行监控。

现在我们可以看到ECX指向的非零内存地址是不可读的,并且在将数据写入该内存地址时会发生异常。 所以尝试将数据写入未分配(或释放)的内存具有很高的可能性。 我们可以通过检查内存页面的分配情况来验证我们的预测,在图中我们可以看到内存具有Reserve属性。 下面是截图:

现在,我们需要研究程序为什么要将数据写入未使用的内存页面。 通过静态分析,我们可以看到ECX的值来自EDI,并且在调用MAPIAllocateBuffer之后对EDI进行修改,如下面的屏幕截图所示:

通过静态分析,我们了解到函数MAPIAllocateBufferRtlAllocateHeap的包装,它对堆的大小进行检查并要保证其参数不大于0x7FFFFFF7。这并不能说明它是不安全的。但是在这种情况下,它并不会检查0是否可以用作参数。 又由于实际分配的堆大小比请求的堆大小多8个字节,所以这8个字节用0x0000000001000010填充。

之后,MAPIAllocateBuffer在填充这8个字节后返回堆地址。 因此,调用MAPIAllocateBuffer后的EDI值为8 +从RtlAllocateHeap接收的分配堆地址。 截图如下:

从上面静态分析的结果中,我们可以猜测在Reserve堆中写入数据的概率之高是由整数溢出引起的。 经过调试,我们发现调用MAPIAllocateBuffer的堆大小参数确实为0。由于MAPIAllocateBuffer请求分配大小为0 + 8 = 8的堆,因此RtlAllocateHeap不会返回错误而是成功返回正确的堆地址。 但是,MAPIAllocateBuffer使用这8个字节写入0x0000000001000010,然后向用户返回无效的堆尾地址。 截图如下:

接下来我们需要研究清楚为什么请求堆大小的值会变为0。结合调试和静态分析,我们发现0这个值来自当前函数的参数:arg_4(eax = arg_4 * 4 + 4)。 但是当调用当前函数时,arg_4的值不是传入参数的值,这意味着此函数会修改arg_4。 通过调试我们可以看到更改是在子函数sub_65F7DA中完成的。 截图如下:

我们分析子函数sub_65F7DA发现其是另一个包装函数。 经过一系列调试,我们最终发现名为ReadFile的函数 - 即arg_4的值实际上来自PoC文件。 截图如下:

调试显示arg_4读取的文件内容为0xFFFFFFFF,然而由于整数溢出,传递的堆的分配大小为0xFFFFFFFF * 4 + 4 = 0。 但是程序并没有检查这一点,导致Out-of-Bounds Writing威胁发生。 截图如下:

检查PoC文件时,我们可以看到0xFFFFFFFF值确实存在。

我们将其修改为0xAABBCCDD,之后我们再次执行调试并设置相同的断点以验证溢出是由这4个字节引起的。

我们能够看到我们已经成功。

我们将代码与Patch发布版进行比较后发现现在的版本已经添加了对所请求分配堆大小的验证。 请参见下面的截图:

使用这种修补程序至关是十分重要的,因为成功利用此漏洞的攻击者可以使用特殊的文件在当前用户的系统中执行命令。

结论

我们鼓励所有用户升级到最新版本的Outlook或立即下载最新的补丁。 此外,已部署Fortinet IPS解决方案的用户可以通过以下签名保护自己的系统。

MS.Outlook.CVE-2018-8587.Remote.Code.Execution
本文为翻译稿件,来源为:https://www.fortinet.com/blog/threat-research/a-deep-analysis-of-the-microsoft-outlook-vulnerability-.html

关键词:[‘技术文章’, ‘翻译文章’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now