Firefox UAF漏洞分析

栏目: 编程工具 · 发布时间: 5年前

内容简介:2018年12月,Mozila通过我们可以使用如下PoC触发该漏洞:

Firefox UAF漏洞分析

0x00 前言

2018年12月,Mozila通过 mfsa2018-29 发布了Firefox 64,修复了多个安全问题,其中就包含CVE-2018-18492,这是一个与 select 元素有关的UAF(use-after-free,释放后重用)漏洞,最早由Nils发现并报告。 之前 我们已经讨论过UAF问题,也看到厂商采取了多种 保护措施 想消除这些问题。但直到目前为止,我们还是经常能在web浏览器中发现与UAF相关的漏洞,因此理解这些问题对查找及修复漏洞来说至关重要。在本文中,我们将与大家分享这个UAF漏洞以及相关补丁的具体细节。

0x01 触发漏洞

我们可以使用如下PoC触发该漏洞:

Firefox UAF漏洞分析

图1. PoC

在存在漏洞Firefox版本中运行该PoC,我们可以看到crash时的栈跟踪状态如下:

Firefox UAF漏洞分析

图2. 崩溃时的栈跟踪状态

从图中可知,当解析填充 0xe5e5e5e5 的某个内存地址时,会出现read access violation(读取访问冲突)。 0xe5e5e5e5jemalloc 用来“污染”已释放内存的一个值。这里的“污染”指的是以一种可识别模式来填充已被释放的内存,这样便于分析。正常情况下,我们选择的填充模式不要对应于可访问的地址,这样任何尝试从已填充内存中解析值的操作(比如UAF)都会导致crash。

0x02 漏洞分析

PoC包含6行代码,让我们来逐行分析:

  • 创建一个 div 元素
  • 创建一个 option 元素
  • option 元素附加到 div 元素,现在这个 div 元素是 option 元素的父节点
  • DOMNodeRemoved 事件监听器添加到 div 元素中。这意味着如果 option 节点被移除,就会调用我们在这里添加的函数
  • 创建一个 select 元素

这里再深入分析一下:

当使用JavaScript创建 select 元素时, xul.dll!NS_NewHTMLSelectElement 函数就会获得控制权,该函数会为这个 select 元素分配大小为 0x188 字节的一个对象:

Firefox UAF漏洞分析

图3. xul.dll!NS_NewHTMLSelectElement 函数

如上所示,在代码底部会跳转至 mozilla::dom::HTMLSelectElement::HTMLSelectElement 函数。

Firefox UAF漏洞分析

图4. mozilla::dom::HTMLSelectElement::HTMLSelectElement 函数

在该函数中会初始化新分配对象的各种字段。需要注意的是,这里也会分配大小为 0x38 字节的另一个对象,将其初始化为 HTMLOptionsCollection 对象。因此,每个 Select 元素默认情况下都会对应一个options collection(选项集合)。让我们看一下PoC的最后一行。

  • 将第二行创建的 option 元素移动到 select 元素的options collection中

在JavaScript中执行该操作将导致 mozilla::dom::HTMLOptionsCollection::IndexedSetter 函数被调用(大家可以在图2的栈跟踪状态中看到该函数被调用)。

Firefox UAF漏洞分析

图5. IDA中观察到的程序逻辑

这里浏览器会执行一些检查操作。比如,如果选项索引值大于当前options collection的长度值,那么就会调用 mozilla::dom::HTMLSelectElement::SetLength 函数来扩充options collection容量。在PoC中,这个长度值为为 0 (参考图1第6行的 [0] )。然后浏览器会进入图5的红色方框处的检测逻辑。如果待设置的索引值不等于options collection的选项数,那么就会进入右分支。在PoC中,我们使用的索引值为 0 ,而选项数也为0,因此会执行左分支。因此浏览器会调用 nsINode::ReplaceOrInsertBefore 函数,如下红框所示:

Firefox UAF漏洞分析

图6. 调用 nsINode::ReplaceOrInsertBefore 函数

nsINode::ReplaceOrInsertBefore 函数中,浏览器会调用 nsContentUtils::MaybeFireNodeRemoved 函数,通知父节点关于子节点移除的相关事件(如果父节点在监听这类事件)。

Firefox UAF漏洞分析

图7. 调用 nsContentUtils::MaybeFireNodeRemoved 函数

由于我们在PoC第4行(参考图1)中,在 div 元素上设置了 DOMNodeRemoved 事件监听器,因此这里浏览器就会触发我们设置的函数。在这个函数中,第一个 sel 变量会被设置为 0 ,该操作会移除对 select 元素的最后一个引用。接下来,函数会创建一个巨大的数组缓冲区,这会给内存带来较大负担,触发垃圾回收机制(garbage collector)。此时会释放 select 元素对象,因为已经没有关于该对象的任何引用。现在被释放的内存已被 0xe5e5e5e5 填充。最后,函数会调用 alertflush挂起的异步任务 。从 nsContentUtils::MaybeFireNodeRemoved 函数返回后,被释放的 select 对象会被用来读取指针,触发read access violation:

Firefox UAF漏洞分析

图8. 触发Read Access Violation

这里需要注意的是,如果浏览器执行的是右分支,那么还是会调用同一个函数( nsINode::ReplaceOrInsertBefore ),但在调用该函数之前,会使用 AddRef 函数来增加 select 对象的引用计数。如果是这样操作,就不会出现UAF问题:

Firefox UAF漏洞分析

图9. 通过 AddRef 函数避免出现UAF问题

0x03 补丁分析

Mozilla通过 d4f3e119ae841008c1be59e72ee0a058e3803cf3 改动修复了这个漏洞。这里最主要的改动是修改options collection中对 select 元素的弱引用逻辑,替换成强引用:

Firefox UAF漏洞分析

图10. 补丁细节

0x04 总结

虽然UAF是大家都比较熟悉的一个问题,但在许多浏览器中依然存在。在几个月之前,有攻击者成功利用了Google Chrome浏览器中的 UAF漏洞 。UAF漏洞也不局限于浏览器,Linux内核之前也推出过一个 补丁 ,用来修复由UAF导致的拒绝服务问题。澄清UAF触发原理是检测这类漏洞的关键所在。与缓冲区溢出问题一样,我们认为软件中无法完全避免UAF。然而,通过正确的编程以及安全的开发实践,在未来我们可以进一步消除、或者缓解UAF所带来的影响。

大家可以关注 @hosselot 以及我们的官方 推特 了解最新的漏洞利用技术及安全补丁情况。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP&MySQL Web数据库应用开发指南

PHP&MySQL Web数据库应用开发指南

Hugb E. Williams、David Lane / 谢君英 / 中国电力出版社 / 2003-5 / 69.00元

一起来看看 《PHP&MySQL Web数据库应用开发指南》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器