欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

深入分析Microsoft Outlook漏洞CVE-2018-8587

来源: 作者: 时间:2019-02-24 19:29 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助

今年早些时候,FortiGuard实验室研究员Yonghui Han通过Fortinet的负责任披露流程,向微软报告了Office Outlook中的Heap Corruption漏洞(Heap Corruption vulnerability)。2018年12月的周二补丁日,微软宣布他们已修复此漏洞,发布了相应的通报(corresponding advisory),并为其分配了漏洞ID号CVE-2018-8587。
Microsoft Outlook是Microsoft Office套装的组件之一,广泛用于发送和接收电子邮件、管理联系人、记录和跟踪日程安排以及执行其他任务。在Windows系统上的多个Outlook版本中都发现了Heap Corruption漏洞,涵盖了从Outlook 2010到最新的Outlook 2019以及Office 365 ProPlus的所有32/64位版本。该漏洞由格式错误的RWZ(邮件分类规则)文件触发。当Outlook收到不正确的RWZ文件内容时,分配的堆内存不足并且缺少适当的边界检查,从而导致堆的越界写入。
在本博客中,我将分享对此漏洞的详细分析。
一、重现漏洞
要重现此漏洞,需要运行Microsoft Outlook,然后单击“规则=>管理规则和警报=>选项=>导入规则”,并选择导致Outlook崩溃的PoC文件。

图1.重现漏洞
发生崩溃时,调用堆栈如下所示:

图2.崩溃发生时的堆栈
二、漏洞分析
正如从调用堆栈中看到的那样,崩溃发生在堆释放时。由于我们现在无法确认释放的堆块有什么问题,我们可以打开整页堆来跟踪有问题的堆块。命令如下:
YOUR_WINDBG_INSATALL_LOCATION\gflags.exe /p /enable outlook.exe /full
可以看到如下返回结果,表明它已成功执行。

图3.完整页面堆已成功打开
完成此操作后,我们可以再次打开Outlook并选择PoC文件以便在发生崩溃时监视新堆栈:

图4.打开Full Page Heap时的崩溃位置
现在我们可以看到ECX指向的非零内存地址是不可读的,并且在将数据写入该内存地址时会发生异常。因此将数据写入未分配(或释放)的内存的可能性很高。可以通过检查内存页面分配来验证这个预测,我们可以看到内存仍然具有Reserve属性。这是截图:

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

图6. ECX值的来源
通过静态分析,我们了解到函数MAPIAllocateBuffer是RtlAllocateHeap的封装函数,它进行检查确保请求的堆大小参数不大于0x7FFFFFF7。这意味着它不是负的。但是,在此情形之下,它不会检查0是否可以用作参数。并且因为实际分配的堆大小比请求的堆大小多8个字节,这8个字节用0x0000000001000010填充。之后,MAPIAllocateBuffer在这8个字节后返回堆地址。因此,调用MAPIAllocateBuffer后的EDI值为8 +从RtlAllocateHeap接收的分配堆地址。截图如下:

图7.检查分配的堆的大小

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

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

图10.堆大小为0的源头
分析子函数sub_65F7DA,我们发现它是另一个封装函数。经过一系列调试后,我们终于知道名为ReadFile的函数,即arg_4的值,实际上来自PoC文件。截图如下:

[1] [2]  下一页

今年早些时候,FortiGuard实验室研究员Yonghui Han通过Fortinet的负责任披露流程,向微软报告了Office Outlook中的Heap Corruption漏洞(Heap Corruption vulnerability)。2018年12月的周二补丁日,微软宣布他们已修复此漏洞,发布了相应的通报(corresponding advisory),并为其分配了漏洞ID号CVE-2018-8587。
Microsoft Outlook是Microsoft Office套装的组件之一,广泛用于发送和接收电子邮件、管理联系人、记录和跟踪日程安排以及执行其他任务。在Windows系统上的多个Outlook版本中都发现了Heap Corruption漏洞,涵盖了从Outlook 2010到最新的Outlook 2019以及Office 365 ProPlus的所有32/64位版本。该漏洞由格式错误的RWZ(邮件分类规则)文件触发。当Outlook收到不正确的RWZ文件内容时,分配的堆内存不足并且缺少适当的边界检查,从而导致堆的越界写入。
在本博客中,我将分享对此漏洞的详细分析。
一、重现漏洞
要重现此漏洞,需要运行Microsoft Outlook,然后单击“规则=>管理规则和警报=>选项=>导入规则”,并选择导致Outlook崩溃的PoC文件。
copyright 无奈人生
图1.重现漏洞
发生崩溃时,调用堆栈如下所示:

图2.崩溃发生时的堆栈
二、漏洞分析
正如从调用堆栈中看到的那样,崩溃发生在堆释放时。由于我们现在无法确认释放的堆块有什么问题,我们可以打开整页堆来跟踪有问题的堆块。命令如下:
YOUR_WINDBG_INSATALL_LOCATION\gflags.exe /p /enable outlook.exe /full
可以看到如下返回结果,表明它已成功执行。

图3.完整页面堆已成功打开
完成此操作后,我们可以再次打开Outlook并选择PoC文件以便在发生崩溃时监视新堆栈:

图4.打开Full Page Heap时的崩溃位置

内容来自无奈安全网

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

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

图6. ECX值的来源
通过静态分析,我们了解到函数MAPIAllocateBuffer是RtlAllocateHeap的封装函数,它进行检查确保请求的堆大小参数不大于0x7FFFFFF7。这意味着它不是负的。但是,在此情形之下,它不会检查0是否可以用作参数。并且因为实际分配的堆大小比请求的堆大小多8个字节,这8个字节用0x0000000001000010填充。之后,MAPIAllocateBuffer在这8个字节后返回堆地址。因此,调用MAPIAllocateBuffer后的EDI值为8 +从RtlAllocateHeap接收的分配堆地址。截图如下: 本文来自无奈人生安全网

图7.检查分配的堆的大小

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

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

copyright 无奈人生



图10.堆大小为0的源头
分析子函数sub_65F7DA,我们发现它是另一个封装函数。经过一系列调试后,我们终于知道名为ReadFile的函数,即arg_4的值,实际上来自PoC文件。截图如下:
本文来自无奈人生安全网

[1] [2]  下一页 无奈人生安全网

。 (责任编辑:admin)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。