介绍

3月1日,谷歌在FileReader API(CVE 2019-5786)的Chrome板块中发布了一个0 day漏洞。 来自谷歌漏洞分析组的Clement Lecigne报告称,这个漏洞在网络中被利用,可针对Windows 7,32位平台应用进行攻击。 该漏洞导致Renderer进程中出现代码执行的问题,并且被用于破坏主机系统。 这篇博客作为一篇技术文章,详细介绍了我们找到漏洞的全过程。在撰写本文时,漏洞报告仍然没有被发布,并且Chrome会默认进行自动安装与更新,使用最新版Chrome的用户已经受到保护,不会受到该漏洞的影响。

信息采集

1 漏洞修复

大多数Chrome代码库都基于Chromium的开源项目。 我们目前正在查看的错误内容均包含在开源代码中,因此我们可以直接查看新版本中与FileReader API相关的修复内容。除此之外,谷歌更新了其日志,以方便我们进行参考。

我们可以看到只有一个提交修改了与FileReader API相关的文件,并带有以下消息:

该消息说明对同一个底层的ArrayBuffer进行多次引用是一件危险的事情。然而目前尚不清楚它的意义,但以下内容涵盖了此消息中蕴含的智慧。

对于初学者,我们可以查看提交的diff并查看所更改的内容。 为便于阅读,下面我们列出补丁前和后的功能比较。

旧版本:

新版本:

这两个版本可以在GitHub上找到。 此处修改了ArrayBufferResult函数。而该函数负责在用户需要访问FileReader.result成员时返回数据。
函数的运作流程如下:如果结果已被“缓存”,则返回该函数。 如果没有,有两种情况:如果数据已完成加载,则创建DOMArrayBuffer,缓存结果并返回它。 如果没有,它会创建一个临时DOMArrayBuffer并返回它。 修补前后版本之间的区别在于,在部分加载的情况下,如何处理临时DOMArrayBuffer。 在案例中,我们可以看到如下内容:

这促使我们再去进行一些样例测试。 让我们比较未修补和修补情况下反馈有何不同。

我们可以从已修补版本开始,因为它最容易理解。我们可以看到对ArrayBuffer::Create的调用,它接受两个参数,一个指向数据的指针及其长度(该函数在树中定义在/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h)。

这创建了一个新的ArrayBuffer,并将其封装到scoped_refptr <ArrayBuffer>中,然后将数据复制到内部。 scoped_refptrChromium处理引用计数的一种方法。 对于不熟悉这个概念的读者,我们会跟踪这个对象被引用的次数。 在创建scoped_refptr的新实例时,底层对象的引用计数会递增。当对象退出其范围时,引用计数递减。当该引用计数达到0时,该对象将被删除(如果引用计数溢出,Chrome将终止进程)。在未修补的版本中,代码不使用ArrayBuffer::Create,而是使用ArrayBufferBuilder::ToArrayBuffer()的返回值(来自third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_builder.cc):

下面是另一个隐藏的漏洞。 根据bytes_used_的值,函数将返回其缓冲区数据(即包含数据副本的较小的ArrayBuffer)。

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖