从BinDiff到0day 在IE中利用CVE-2019-1208

2019-09-20 约 111 字 预计阅读 1 分钟

声明:本文 【从BinDiff到0day 在IE中利用CVE-2019-1208】 由作者 ret2nullptr 于 2019-09-21 06:01:00 首发 先知社区 曾经 浏览数 2 次

感谢 ret2nullptr 的辛苦付出!

本文是翻译文章,原文链接:https://blog.trendmicro.com/trendlabs-security-intelligence/from-bindiff-to-zero-day-a-proof-of-concept-exploiting-cve-2019-1208-in-internet-explorer/

去年六月,我向微软公布了internet Explorer(IE)中的UAF漏洞,它被评为严重等级,并被命名为CVE-2019-1208,接着在微软的9月补丁星期二发表

我通过BinDiff工具发现了这个漏洞,并编写了一个PoC,展示了如何在Windows 10 RS5中利用它

这篇文章对此漏洞进行了更深入的分析,以下是该研究的概述

深入分析:https://documents.trendmicro.com/assets/Tech-Brief-A-Proof-of-Concept-Exploiting-CVE-2019-1208-in-Internet-Explorer.pdf

前言

如上所述,CVE-2019-1208UAF漏洞,这类安全漏洞可以破坏有效数据、引发进程crash、并且可以精心利用最终导致任意代码执行。而对于本文介绍的CVE-2019-1208而言,成功利用此漏洞的攻击者可以获得系统当前用户权限。如果当前用户具有admin权限,则攻击者可以劫持系统——从安装或卸载程序,查看和修改数据 到 创建具有完全权限的用户。

潜在影响

还有一种更有形的攻击情形,攻击者向不知情的用户发送钓鱼邮件,并诱使他们通过IE访问恶意网站(存在CVE-2019-1208的漏洞)。

或者,攻击者可以发送带有附件的垃圾邮件,其中包含该漏洞的exp。这些附件可以是启用了IE渲染引擎的Microsoft Office文档,也可以是嵌入了ActiveX控件的的应用程序,而ActiveX控件又包含exp。

攻击者还可以在一些合法网站上布置攻击代码,例如那些接受用户的输入的网站。

下图为VbsJoin的代码流:

漏洞是如何被发现的?

我的研究始于BinDiff,当时我正试图比较vbscript.dll的5月和6月的版本,寻找其中被更改的函数,而这个模块包含VBScript引擎的API函数。最终我发现通过SafeArrayAddRefSafeArrayReleaseDataSafeArrayReleaseDescriptor函数进行了一些修复

然而,受我之前发现的漏洞CVE-2018-8373的启发,进一步分析后我使用VBScriptClass经过下列步骤触发了UAF漏洞:

  1. arr = Array(New MyClass),创建一个SafeArray并在arr[0]处保存VBScriptclass: MyClass

  2. Callback: arr = Array(0)Join(arr)将触发MyClass的回调函数Public Default Property Get。在此回调中,为变量创建了一个新的SafeArray,如下图所示而这个新的SafeArray不受SafeArrayAddRef函数的保护。因此,正常的代码流假设 被这个回调打破

  1. arr(0) = Join(arr),当从Public Default Property Get返回时,VBsJoin中的代码将会调用SafeArrayReleaseDataSafeArrayReleaseDescriptor来减少SafeArrayDataSafeArrayDescriptor的引用计数。但是,新的SafeArray不受SafeArrayAddRef保护,并且SafeArrayDataSafeArrayDescriptor的引用计数为0。

    因此,新的SafeArray的SafeArrayDataSafeArrayDescriptor将在函数SafeArrayReleaseDataSafeArrayReleaseDescriptor被free,如下图所示:

其中,代码快照显示内存中的arr = Array(New MyClass)(顶部),内存中的arr = Array(0)callback位于底部

将VbsJoin的返回值保存到arr(0)时,PoC在vbscript!AccessArray中崩溃(见下图),因为SafeArrayDescriptor被free,Variant arr仍然保存释放的SafeArrayDescriptor的指针。

显示PoC如何在vbscript!AccessArray中触发crash的代码快照

PoC是否成功触发UAF?

在某种程度上,这个回答是肯定的

为了演示如何完全触发UAF,我使用了basic string/binary string(BSTR)作为数据结构。SafeArray是一个多维数组,但由于VBsJoin只能处理一位数组,因此我更改了回调中的SafeArray的维度。

不幸的是,它仍然没有用,它会抛出一个运行时错误,指出数组类型在Join中不匹配。不过没有关系,我使用On Error Resume Next来绕过这个运行时错误,下图为修改过后的PoC:

在获得了0x20字节的已释放内存后,我使用大小为0x20字节的BSTR来伪造一个较大size的SafeArray。

通过使用堆风水,这个BSTR可以稳定地重用0x20字节的已释放内存,如下图所示:

我终于得到了一个伪造的一维数组SafeArray,一共有0x7fffffff个元素,每个元素大小为1字节,如下图:

伪造的SafeArray(顶部)和读/写的固定地址(底部)

到目前为止,我已经可以伪造一个SafeArray,可用于读/写0x00000000到0x7fffffff的内存

为了泄露一些读/写地址以便利用,我参考了Simon Zuckerbraun之前的研究并使用堆喷射来获得一些固定的读/写地址(0x28281000)

从UAF到RCE

如Simon Zuckerbraun的博客中所述,我使用Scripting.Dictionary对象来完成远程代码执行,但使用另一种方法来伪造一个假的Dictionary。这一次,我使用了BSTR并将它们带出来

Faked Dictionary内存布局如下:

  1. 使用内存读/写函数来读取原始的Dictionary内存,将其数据保存到一个BSTR,并将VBADictionary::Exists替换为kernel32!Winexec
  2. 将之后用到的Winexec参数\..\clac.exe写入此BSTR
  3. 将此BSTR保存到util_memory+0x1000,并修改util_memory + 0x1000 – 8 = 9以使fake_array(util_memory + 0x1000)成为对象
  4. 使用fake_array(util_memory + &h1000),利用dummy来触发Winexec函数

最终利用结果,成功弹出计算器:

这个漏洞对IE意味着什么?

在2019年8月13日,已在Windows 10中禁用的VBScript 又同时在Windows 7,8中禁止IE使用。因此,上文详述的PoC是在本地模式下开发的。但正如微软所说,仍然可以通过注册表或组策略启用此设置。同样,用户和组织应始终采用最佳实践:保证系统打上补丁和保持更新,禁用不需要(或限制使用)的组件,并派样网络安全意识,如垃圾邮件和其它社会工程学威胁

研究的完整细节在本技术简报

关键词:[‘安全技术’, ‘二进制安全’]


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