13

再探Stagefright漏洞——POC与EXP | WooYun知识库

 6 years ago
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

再探Stagefright漏洞——POC与EXP

作者:Qever

0x00 前言


在之前的《抛砖引玉——Stagefright漏洞初探》中,我们确定了漏洞的产生位置,然后整篇文章就戛然而止了。此漏洞毕竟影响很深,有些细节不知当讲不当讲。本篇文章来简单扒一扒漏洞利用的方案。只论思路,具体的Exp还是等漏洞具体细节公布后再做讨论。

0x01 手把手教你构造POC


在上篇文章里面,给出了一个POC文件,现在我们就来说说这个文件是怎么构造的。

首先,需要准备一个MP4文件。这里使用的是从网上随意下载的一个文件。

之后,需要为这个mp4文件添加一个封面。笔者使用的工具是iTunes,在显示简介的插图里面可以为其添加封面图片。

enter image description here

下一部,使用010Editor打开添加封面的poc.mp4文件。然后搜索字符串”covr”。

enter image description here

最后,把”covr”前面4个字节改为00 00 00 01,后面8个字节改为00 00 00 01 00 00 00 0F

enter image description here

保存之后,扔到手机中打开。由于mediaserver崩溃之后,会立刻重启。所以我们需要系统Log来辅助验证漏洞的触发。

enter image description here

通过Log就能发现,mediaserver。其实这幅图还包含了其他的信息,后面再说。

0x02 知其所以然


要搞清楚,POC为什么要这样做,就必须要从源码下手。 我们在/frameworks/av/media/libstagefright/MPEG4Extractor.cpp中继续看相关源码。

enter image description here

前面说过,这个漏洞的原因,在于chunk_data_size = 0xFFFFFFFF。使得chunk_data_size + 1 = 0,造成了申请内存的长度为0,然后往内存中拷贝数据时越界写。

enter image description here

那么我们就看看chunk_data_size如何才能等于0xFFFFFFFF。

enter image description here

从这里就能看出来。*offset – data_offset = 8。也就是说,chunk_data_size要等于0xFFFFFFFF。Chunk_size就必须等于0xFFFFFFF + 8

enter image description here

但是,可以看到chunk_size是从*offset处读取了4个字节进行转换的,最大值也就是0xFFFFFFFF了。 同时注意chunk_type,后面可以看到,chunk_type的值是FOURCC('c', 'o', 'v', 'r'),也就是(int)’covr’,这就是为什么要用字符串”covr”做定位的原因。

回来继续看chunk_size,发现类型实际上是uint64_t,也就是说有可能会大于0xFFFFFFFF。继续看代码。

enter image description here

这段就很清楚了。如果之前读取到的chunk_size == 1,那么就读取*offset + 8处的8个字节,作为chunk_size的值,同时data_offset会加8。

由此可以确定。当*offset处内存值设置为

00 00 00 01 ‘c’ ‘o’ ‘v’ ‘r’ 00 00 00 01 00 00 00 0F

可以使chunk_data_size的值成为0xFFFFFFFF达到攻击的目的!

0x03 没Exp你说个铲铲


看过上面的内容,相信大家也该了解到,POC还是非常简单的,实际上就是没啥技术含量。相信大多数人关心的还是Exp。不过因为是未修复的漏洞,所以想伸手要Exp的就不要想了。下面只是来讲讲利用的思路。没兴趣的就可以直接跳过了。

根据之前的分析,可以确定该漏洞是堆的越界写引起的。那么利用思路就只有一个,就是越界修改其他对象的值,造成在使用或者析构的时候出错,跳入shellcode执行。

但是这个漏洞的难点在于,攻击载体是一个视频文件,本身没有执行代码的能力,也就没办法干涉到内存布局,也没办法获取内存布局信息。由此使得基本无法稳定利用。由于内存地址问题,反正笔者目前尚未发现能比较稳定的利用方法,如果哪位大牛有,欢迎分享!

0x04 如何寻找Exp


事实上,要寻找Exp的思路还是比较简单的。从前面00 00 00 01 00 00 00 0F开始,逐渐增加文件大小,然后一直测试,收集崩溃信息。找寻利用点。

笔者还算是幸运,并没有费多大的力气,就找到了一个非常明显的利用点。 还是回到之前的崩溃截图,我们来看堆栈信息。

enter image description here

根据堆栈,可以看到,是一个HTTPBase的智能指针,在析构的时候崩溃了。

等等,android::RefBae::decStrongandroid_atomic_dec,之前研究过Android漏洞人,是不是觉得有点眼熟?这个东西实际上已经出现过一次了,是在CVE-2014-7911里面。

我们来看看decStrong的实现。

enter image description here

可以看出,当android_atomic_dec返回值为1的时候。会触发一句BLX R2。 这段通俗一点讲,就是

#!c++
If(*(*(offset + 4)) == 1){
    r2 = *(*(*(offset + 4) + 8) + 0xC)
    blx r2;
}

代码执行!!数据可控!!!

我们随后可以把mp4进行填充一下,得到以下的结果

enter image description here

也就是说,针对我的mp4文件,文件偏移在0x96a8-4处的值,就是上面所说的offset。

知道offset之后,就可以构造数据,达到代码执行的目的!!!!!

0x05 现实很骨感


到此,找到了一种利用漏洞的方案。虽然理论上可行,但是在实际操作中,并不是那么如意。

最主要的一点,在于堆越界写的地址上面,这个地址并不是固定的。好在经过测试,我们发现是在一定范围内变化。在笔者的Nexus5手机上,这个范围大概是0xb7000000~0xb9000000之间。如果通过大量的测试和调整,还是够覆盖准确的。

另外一个问题就是执行权限。在堆上申请的内存本身是没有执行权限的。所以需要一个跳板才行,但是由于攻击载体只是一个视频文件,所以这并不是一件简单的事情。

至于后续怎么编写shellcode,本身也存在一些问题。

当然,这些都不是本篇文章所考虑的内容 =。=

0x06 总结


还是那句话,本漏洞由于未修复。我们只能根据情况逐渐公开研究结果,以免造成不好的影响。

在厂商发布更新补丁之前,我们来说说防御。

对于该漏洞的防范,建议是关闭彩信自动下载。但是实际上通过任何渠道传播的视频,都可能利用该漏洞。包括通过微信发送视频,接收者根本无法分辨是否为mp4格式文件,点击播放就可能被黑客攻击。

目前大部分厂商都在尝试主动查杀视频文件的防御方案。但是笔者认为这完全是事倍功半,而且由于无法监控所有途径传播的视频文件,所以无法真正达到防御的目的。

目前,猎豹移动安全中心正在尝试一种被动式的防御方案,可以有效降低攻击危害。敬请关注猎豹移动相关资讯。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK