测试IE/EDGE崩溃漏洞的可利用性

luochicun Web安全 2019年3月5日发布
Favorite收藏

导语:由于网络攻击技术的迅猛发展趋势,很多浏览器开发商也都在自己的产品加入了类似于杀毒软件之类的功能,以帮助保护用户免受安全方面的威胁。

前言

由于网络攻击技术的迅猛发展趋势,很多浏览器开发商也都在自己的产品加入了类似于杀毒软件之类的功能,以帮助保护用户免受安全方面的威胁,比如Internet Explorer (IE)和Edge相比以前,除了在用户体验上更好外,在功能上也都发生了重大变化。它们都提供了一些基本的缓解措施,这些措施一起不仅使得各种漏洞无法被利用,而且还大大提高了攻击者开发利用漏洞的成本。

由于这些变化,确定它们崩溃的可利用性变得越来越复杂,因为在分析过程中必须考虑到这些缓解的影响。

Use-after-free漏洞(简称UaF漏洞)是当前最流行的高危内存破坏漏洞,目前针对UaF漏洞的检测工作并不完善,原因是UaF漏洞产生的特征是分配内存、释放内存、使用已释放的内存并按顺序出现,而这3种事件可能出现在程序的任何位置,需要跟踪较长的执行序列并搜索潜在的危险事件序列才能检测到该漏洞,这很大程度上提高了检测的难度。

UaF漏洞产生的主要原因是释放了一个堆块后,并没有将该指针置为NULL,这样导致该指针处于悬空的状态,同样被释放的内存如果被恶意构造数据,就有可能会被利用。我们可以根据悬空指针的存储位置将UaF漏洞分为三大类:栈、堆和寄存器。

我们已经制定了两种主要的缓解措施来预防UaF:

1.内存保护(适用于IE10及以下版本),内存保护旨在保护对象免受UAF的影响,其中引用存储在栈中或寄存器中。

2.MemGC 机制(适用于Edge及IE11),MemGC的基本思想与内存保护(Memory Protector,MP)相似,都是利用类似标记清除法的GC去缓解UAF类型的漏洞,并且MemGC在MP的基础上进行了加强。当MP要实际释放内存块时会进行标记,如果栈中存在指向这个内存块指针那么就不会进行释放。不过,MP没有保护堆中的指针,可能存在堆上的悬空导致UAF的情况。

MemGC是MP的替代品,目前在Edge和IE11上启用。只有当栈、堆或寄存器上没有引用时,才会释放受保护的对象,从而提供完整的覆盖。

可利用性和服务

MemGC 机制(适用于Edge及IE11)

1.我们认为MemGC可以很好的缓解UAF,并且不会为它们专门发布安全更新。

2.在这种情况下,唯一的例外是零写入对象会导致可利用的状态,尽管我们还没有看到这种情况的发生。

内存保护(适用于IE10及以下版本)

1.我们认为基于栈和基于寄存器的UAF可以通过这种保护得到极大缓解,并且不会为它们发布安全更新,除非有下面所说的特殊情况。

2.内存保护是不会缓解基于堆引用的UAF,因此仍将通过安全更新来解决它们。

内存保护

内存保护(MP)是最初于2014年7月针对所有受支持的Internet Explorer版本引入的一种缓解方式,但现在仅适用于IE 10及更低版本。它旨在缓解由于存储在栈或寄存器上的悬空指针而导致的UaF漏洞。从设计层面看,它的工作原理如下:

1.在对象实例(object instance)上调用delete时,其内容为零写入,并将其放入队列中。一旦队列达到阈值大小,我们就开始查看释放队列中的每个对象实例是否安全。

2.为了测试释放对象实例是否安全,我们扫描寄存器和所有指针对齐的栈条目,以查看是否存在指向该对象的指针。如果未找到指针,则释放该对象,否则该对象将保留在队列中。

工作原理的第(1)步会将对象的潜在释放延迟到稍后的某个时间点,由于这个时间点具体可由攻击者控制,因此它不具有安全性缓解属性。

为了更容易确定这些漏洞的可利用性,内存保护有一种称为“Stress mode”的模式。在此模式下,内存保护的延迟释放模块会被禁用,这样栈或寄存器扫描就会在每次释放时发生,而不是在队列达到阈值大小时发生。可以使用以下注册表项启用它:

HKLM:/Software/Microsoft/Internet Explorer/Main/Feature 
Control/FEATURE_MEMPROTECT_MODE/iexplore.exe DWORD 2

注意,此注册表项和“Stress mode”仅适用于内存保护机制,并不适用于MemGC。

示例崩溃

通过强制在尽可能早的时间释放对象实例来禁用内存保护的延迟模块,现在我们可以根据第2步的原理,来集中精力确定可利用性,如下面的示例所示。

1.jpg

在这种情况下,我们有一个UaF漏洞所导致的接近于悬空(near-null )的解除引用。回顾一下,我们可以看到eax的值之前已经设置了一些指令:

2.jpg

如果我们在内存中查看这个对象,我们看到它已经被写为0,通过检查PageHeap End Magic,我们可以看到这个堆块仍然在“Stress mode”下分配:

3.jpg

现在我们需要查看是否存在对此对象实例的任何栈引用,从调用delete时的调用帧(call frame)开始。这可以使用windbg脚本完成,例如,可以扫描一个对象的引用,该对象的基本地址存储在大小为0x30的ebx中。

4.jpg

使用内存保护检查栈引用位置

在本文的示例中,我们在栈中找到了对对象实例的单个引用。有了这些信息,我们现在必须检查哪个调用帧包含此引用。

以下,就是一个对象被删除时的调用栈示例。

5.jpg

如果存在对栈或寄存器上的对象实例的引用,则内存保护将永远不会释放该对象实例。因此,如果在frame_2中第一次调用delete点,直到在frame_5中出现几乎为空的解除引用而崩溃时,始终存在栈引用。那么,攻击者就无法释放和重新分配或控制对象实例。

在此示例中,我们通过扫描栈(在0x1024ae9c处)找到的引用存储在frame_8中,由于此引用始终存在于frame_2中的释放点和frame_8中的崩溃点之间,因此我们认为这种情况不可利用,因为它会被内存保护缓解。

除此之外,还可能出现另外两种主要情况:

1.如果栈引用的位置是frame_3而不是frame_8,则在没有栈引用时,在释放对象和崩溃点之间就存在一段空白时间。这种情况可能就会被攻击者利用的,因为如果这些点之间的代码路径可以稍微改变一下,就可以强制另一个调用被删除,从而发起攻击。

2.在“Stress mode”下运行时,在压力模式下运行时,由于进行延迟的悬空模块被禁用(通常是由于引用存储在堆上),所以崩溃可能发生在已释放的块上。

MemGC

MemGC是内存保护的新替代品,目前可在Edge和所有IE11版本中使用,并以与内存保护类似的方式缓解UaF漏洞。但是,它还通过扫描堆以获取对受保护对象类型以及栈和寄存器的引用来提供额外的保护。MemGC将自由写入0并将延迟实际的空闲时间,直到触发垃圾收集并且未找到对释放的对象的引用。

就像内存保护一样,缓解UaF漏洞很可能会导致near-null 指针取消引用,或者根本就不会导致崩溃。如果你怀疑near-null 指针取消引用是一个圈套,可以使用以下步骤验证这一点:

1.找到读取near-null值的位置,确定对象的基本指针。

6.jpg

如果我们转储这个对象,如前所述,我们可以看到它已经被写为0。

7.jpg

2.使用在第一步中找到的基指针,跟踪并查找此块的分配调用栈。如果对象是用edgehtml!MemoryProtection::HeapAlloc()或edgehtml!MemoryProtection::HeapAllocClear()来分配的,这意味着该对象是由 MemGC e.g。

8.jpg

类似地,当对象被释放时,它将通过edgehtml!MemoryProtection::HeapFree() e.g来执行。

9.jpg

为了再次检查漏洞是否已成功缓解,我们可以扫描堆和栈上对该对象的引用情况。

为了扫描栈,我们可以使用与内存保护部分中描述的技术。然后再使用与上述相同的标准来确定可利用性,如果在释放点和崩溃点之间存在栈引用,我们认为MemGC的缓解效果会特别好。

在扫描堆时,我们使用了类似的方法。首先扫描堆以查找基指针和基指针之间的值,其中还有我们感兴趣的对象的object_size的引用。如果找到任何引用,我们只需要检查一下它们与哪些对象相关联。如果包含引用的对象也被MemGC跟踪,即通过HeapAlloc()或HeapAllocClear()分配,那么MemGC将不会释放我们感兴趣的对象,所以我们认为是MemGC极大地缓解了它的影响。

在本文的示例中,如果我们使用上面的栈扫描命令,我们会看到栈上有一个引用,阻止对象在删除和崩溃点之间被释放,这使得MemGC成功地缓解了它的影响。

10.jpg

总结

总之,这些新的缓解措施通过阻止UaF漏洞的利用,来显着增强浏览器的安全性。当IE和Edge中对漏洞进行分类缓解时,需要考虑这些缓解的行为,以确定这些漏洞的可利用性。

本文翻译自:https://movaxbx.ru/2019/02/20/triaging-the-exploitability-of-ie-edge-crashes/如若转载,请注明原文地址: https://www.4hou.com/web/16475.html
点赞 6
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论