上周的Flash 0day漏洞各位玩爽了吧。知其然还要知其所以然,玩耍累了坐下来看看这个漏洞的成因。趋势科技近日对漏洞进行了详细的分析,笔者翻译过来,以飨读者。
漏洞背景:Flash曝严重安全漏洞,影响全部版本Windows系统、IE和FireFox浏览器
上周六,Adobe又一次更新了Flash Player软件,这次更新的目的是修复被编号为CVE-2015-0311的0day严重漏洞。这个漏洞是由知名安全研究人员Kafeine提交的。
该漏洞正被攻击者广泛的利用中,通过发动强迫下载(drive-by-download)攻击绝大部分Windows系统。该漏洞已被公司标记为了高危,也就意味着攻击者可以执行恶意代码,甚至是在用户完全不知情的情况下。
这个漏洞是Flash长期存在的未公开漏洞,允许攻击者远程获取PC控制权;Windows、OS X及Linux的Flash版本都包含该漏洞。 更多漏洞信息
我们分析截获的样本后发现,实际Flash文件被嵌入到一个经过高强度混淆的恶意.SWF文件内。剥离混淆代码后,我们全面的分析了漏洞并发现了Exp的运行方式。
在介绍细节之前,分享一下我们的“神秘”发现:这些代码片段竟与CVE-2014-8439的漏洞利用代码颇有几分相似之处。这两个漏洞利用代码极有可能出自同一黑客之手。
分析发现这是一个UAF类型的漏洞。这种情况下,domainMemory引用的内存会被释放掉,攻击者能够读写内存甚至执行任意代码。
漏洞触发的步骤如下:
创建一个ByteArray实例并写入大量数据,然后压缩实例内容。
图 1. ByteArray 创建代码
从0×200开始覆盖ByteArray的压缩数据并将ByteArray赋予domainMemory。
图 2. 覆盖 ByteArray
解压ByteArray的数据。因为上一步的操作,程序将抛出IOError异常。代码捕获异常然后用另一ByteArray保存释放后的内存地址,接下来ByteArray被0xBBBBBBBB填充。
图 3. IOError与异常捕获
清除ByteArray内的占位符数据。
图 4. 释放ByteArray内存
在AvmPlus项目代码中,我们在ByteArray::UncompressViaZlibVariant函数中发现了漏洞所在。函数是这样设计的:首先它会分配一个缓冲区来存储未经压缩的数据,如果解压缩成功,它会通知domainMemory使用新的缓冲区。如果解压缩失败,它将不通知domainMemory使用新缓冲区同时释放新申请的缓冲区。
这看上去是无可非议的,好戏还在后面。在解压缩的过程中,新分配的缓冲区会变大。类Grower控制缓冲区的动态增长,增长结束后,类Grower的析构函数通知domainMemory使用扩展缓冲区。最终domainMemory在解压过程中使用了新的缓冲区,如果解压失败,新创建的缓冲区将被释放。这就打乱了原来ByteArray::UncompressViaZlibVariant的逻辑:解压缩失败,domainMemory却使用了新的缓冲区。
这就是经过上面的步骤,domainMemory指向填充0xBBBBBBBB的被释放内存空间的原因,到这一步,Exp已经可以通过使用内部指令来读写这块被释放的内存空间了。
图 5. 读被释放的内存空间
与最近的大部分Flash漏洞利用代码类似,这个Exp通过控制内存布局将攻击向量置入被释放的内存并覆盖攻击向量的长度标识,从而达到任意读取和写入内存的目的。
图 6. 覆盖内存
很明显,内存布局在解压缩过程中被改变了,向量长度也被覆盖(见下图)。在我的调试环境中,UAF内存地址为0×05120000。
图 7. 解压缩后的内存布局(头部信息已经被成功解压)
图 8. 0xBBBBBBBB覆盖ByteArray后的内存布局
图 9. ByteArray释放后的内存布局和攻击向量
图 10. 攻击向量长度被覆盖后的内存布局
攻击向量长度被覆写为0×40000000后,示例代码就能任意读写内存;此时的内存容量也足以执行任意代码了。
接下来Exp只需要触发一个伪造的虚函数即可完成全部利用过程。
[参考信息来源 趋势科技 ,翻译/Taogogo,译者微博: http://weibo.com/taogogo ,转载须注明来自FreeBuf.COM]