最近,微软修补了Internet Explorer脚本引擎中一个可能导致远程代码执行的关键漏洞。该漏洞正在野外被利用,它最初由谷歌威胁分析小组的研究人员报告。微软发布了一个例外补丁,在正常的补丁周期之前修复了该漏洞。McAfee产品在补丁程序发布后不久就做出更新,以便检测此威胁。
远程攻击者可以通过特制网页针对Internet Explorer 9到11,而恶意网络上的本地攻击者也可以针对使用存在漏洞的相同脚本引擎(jscript.dll)的Web代理自动发现服务。Microsoft Edge不受影响;但是,在应用Microsoft的安全补丁程序之前,包含脚本引擎的其他Windows应用程序可能容易受到攻击。
一、前言
可以远程或本地触发的针对Internet Explorer的漏洞是网络犯罪分子破坏许多未打补丁的计算机的主要工具。这就是犯罪分子通常将这些漏洞整合到漏洞利用工具包中的原因,这些工具包会传播恶意软件或针对受感染的主机进行其他恶意活动。漏洞利用工具包的威胁是跟踪此类漏洞并确保及时部署所有安全补丁的一个原因。2018年,在Microsoft脚本引擎(Internet Explorer或Edge)中发现了100多个内存损坏漏洞。有关详细信息,请访问MITRE网站(MITRE website)。 (在纵深防御方面,McAfee Endpoint Security或McAfee Host Intrusion Prevention等产品可以检测并消除此类威胁,直到打上补丁。)
一旦发布了CVE ID,网络犯罪分子需要几周(在某些情况下几天)将其集成到他们的漏洞利用工具包中。例如,CVE-2018-8174最早是在4月底由两组威胁研究人员向微软报告的,他们观察到了它在野外的利用。微软在一周内(5月初)发布了一份公告。同时,研究人员发表了他们对该漏洞的安全性分析。仅仅两周后,一个PoC漏洞利用被公开发布。在接下来的几周内,漏洞利用工具包RIG和Magnitude集成了他们的武器化版本的漏洞利用。 (可在此处找到更详细的时间表。)
网络犯罪分子花了不到一个月的时间就将微软最初披露的漏洞武器化;因此,了解这些攻击媒介所构成的威胁至关重要,并确保采取对策措施以便在威胁造成任何损害之前制止它。
二、技术细节
IE脚本引擎jscript.dll是经过大量审核的代码库:
· https://googleprojectzero.blogspot.com/2017/12/apacolypse-now-exploiting-windows-10-in_18.html
· https://www.exploit-db.com/search?q=jscript
毫无疑问,可利用的漏洞正变得越来越异彩纷呈。这是CVE 2018-8653的情况,它采取了三种看似无辜的行为,并将它们变成了一种use-after-free漏洞。Microsoft特定的扩展会触发一个很少探索的代码路径,该路径最终行为不当并使用不常见的参数调用常规函数。这导致在野外利用的use-after-free条件。
枚举器对象:此漏洞的入口点是Microsoft特定的扩展,即枚举器对象。它提供了一个API来枚举属于Windows world (主要是ActiveX组件,例如用于列出系统上驱动器的文件系统描述符)的不透明对象。但是,它也可以在JavaScript数组上调用。在这种情况下,可以照常访问数组成员,但以这种方式创建的对象在内存中的存储方式略有不同。这就会引发有趣的副作用。
通过调用Enumerator.prototype.item函数创建的对象被识别为ActiveX对象。并且如同在创建eObj时所见,我们可以在某些情况下可以覆盖只读属性的“prototype”成员。
意外的副作用:覆盖ActiveX对象prototype成员最初看起来无害,但可以利用它来探索不可访问的代码路径。
使用“instanceof”关键字时,我们可以看到关键字的右侧需要一个函数。但是,对于特制的对象,instanceof调用成功,更糟糕的是,我们可以控制正在执行的代码。
在特制的ActiveX对象上调用instanceof的边缘情况使我们有机会从我们控制的回调中运行自定义JavaScript代码,这通常是容易出错的情况。
攻击者成功地将这个bug变成了一个use-after-free的状态,我们将在下面看到。
利用漏洞:无须深入了解细节(请参阅本文档后面的PoC部分以获取更多信息),此漏洞可以转换为primitive的“delete this”类型,类似于之前报告的漏洞。当回调函数(在前面的例子中为“f”)被调用时,关键字“this”指向eObj.prototype。如果我们将其设置为null然后触发CollectGarbage,则可以释放支持该对象的内存并在以后回收。但是,正如Project Zero漏洞报告(Project Zero bug report)中所提到的,为了成功,需要在释放内存之前清除整个变量块。
例外补丁:微软发布了一个未安排的䃼丁来修复此漏洞。对我们来说,通常的做法是查看修补程序之前和之后发生的变化。有趣的是,这个补丁改变了严格的最小字节数,而DLL的版本号保持不变。
使用流行的比对工具Diaphora,我们比较了Windows 10 x64位(功能版本1809)的jscript.dll。
我们可以看到只修改了一些功能。除了一个指向与数组相关的函数。那些可能是针对CVE 2018-8631的补丁(jscript!JsArrayFunctionHeapSort越界写入)。剩下的唯一一个经过实质性修改的是NameTbl::InvokeInterna。
Diaphora为我们提供了此函数两个版本汇编代码的差异。在此情况下,使Ida Pro中并排比较功能,更容易查看已更改的内容。快速浏览函数的末尾会显示两次调用GCRoot::~GCRoot(对象GCRoot的析构函数)。
看看~GCRoot的实现,我们看到它与编译器在旧版本DLL中创建的函数内联的代码相同。
在新版本的DLL中,此函数被调用两次;在未修补的版本中,代码只被调用一次(由编译器内联,因此没有函数调用)。用C ++的说法,~GCRoot是GCRoot的析构函数,所以我们可能想找到GCRoot的构造函数。一个简单的技巧是注意魔术偏移0x3D0,查看该值是否在其他地方使用。我们发现它靠近同一个函数的顶部(未修补的版本在左侧):
深入研究jscript.dll垃圾收集的细节超出了本文的范围,所以让我们做一些假设。在C ++ / C#中,GCRoot通常会设计一个模板来跟踪指向正在使用的对象的引用,因此那些没有CollectGarbage。这看起来好像我们将堆栈地址(也就是局部变量)保存到GCRoot对象列表中,以告诉CollectGarbage不要收集其指针位于堆栈上那些特定位置的对象。事后看来,这是有道理的;我们能够“delete this”,因为“this”没有被垃圾收集器跟踪,所以现在Microsoft确保将该堆栈变量专门添加到被跟踪的元素中。
我们可以通过跟踪instanceof的调用来验证这个假设。事实证明,在调用我们的自定义“isPrototypeOf”回调函数之前,对NameTbl :: GetVarThis的调用将指针存储在新的“受保护”堆栈变量中,然后调用ScrFncObj :: Call来执行我们的回调。
查看`instanceof`中的意外行为:好奇的读者可能想知道为什么可以在自定义对象而不是函数上调用instanceof(如前所述)。在JavaScript中调用instanceof时,会在场景后面调用CScriptRuntime :: InstOf函数。早期,该函数有两种不同情况。如果变量类型是0x81(堆上JavaScript对象的宽泛类型),那么它调用一个虚函数,如果可以调用该对象,则返回true / false。另一方面,如果类型不是0x81,则遵循不同的路径;它尝试自动解析prototype 对象并调用isPrototypeOf。
0x81路径:
不为0x81时的路径:
三、PoC
现在我们已经看到了bug的来龙去脉,让我们来看一个简单的PoC,它展示了use-after-free行为。
首先,我们创建了几个数组,以便分配所有可以预分配的数据,并且堆在处于准备状态以供空闲后使用。
然后,我们声明我们的自定义回调并触发漏洞:
出于某种原因,需要释放对象数组并在下一步利用之前CollectGarbage。这可能是由于释放ActiveX对象的一些副作用。当我们将“1”分配给reallocPropertyName属性时,将回收内存。该变量是一个魔术字符串,将被复制到最近释放的内存中以模仿合法变量。它的创建如下所示:
0x0003是一个变量类型,它告诉我们接下来的值是一个整数,并且就是1337。字符串必须足够长,以触发与最近释放的内存块相同或相似大小的分配。
总而言之,JavaScript变量(这里是RegExp对象)存储在一个块中;当释放块中的所有变量时,块本身被释放。在适当的情况下,新分配的字符串可以代替最近释放的块,并且因为“this”仍然在我们的回调中悬空,它可以用于某种类型的混淆。(这是攻击者使用的方法,但超出了本文的范围。)在此示例中,代码将打印1337而不是空的RegExp。
四、MITRE分
此漏洞的基本分数(CVSS v3.0)为7.5(高),影响分数为5.9,可利用性分数为1.6。
五、总结
CVE-2018-8653针对Internet Explorer的多个版本以及依赖于相同脚本引擎的其他应用程序。攻击者可以在未修补的主机上从特制的网页或JavaScript文件中执行任意代码。即使最近微软修复了这个漏洞,我们也可以预见漏洞利用工具包很快部署这个关键漏洞的武器化版本,利用它来针对剩余的未打补丁的系统。本文中的技术分析能为防御者提供足够的信息,以确保他们的系统能够抵御威胁并知道哪些可以作为攻击的切入点。可以利用McAfee安全产品为此威胁提供特定的“虚拟补丁”,直到可以部署完整的软件补丁,同时可以使用当前的通用缓冲区溢出保护规则来针对此漏洞和类似漏洞进行指纹攻击尝试。