再探Stagefright漏洞——POC与EXP


作者:Qever

0x00 前言


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

0x01 手把手教你构造POC


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

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

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

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

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

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

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

0x02 知其所以然


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

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

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

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

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

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

这段就很清楚了。如果之前读取到的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开始,逐渐增加文件大小,然后一直测试,收集崩溃信息。找寻利用点。

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

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

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

我们来看看decStrong的实现。

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

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

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

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

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

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

0x05 现实很骨感


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

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

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

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

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

0x06 总结


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

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

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

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

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

评论

燕子侠 2015-08-01 17:27:19

这是刷存在感的文章吧,跟没写一样

Q

QEver 2015-08-01 20:29:10

哈哈~有些东西目前是不好拿到明面上说的,但我已经暗地里指出来了。如果你看不懂的话,[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */

B

bupter 2015-08-02 10:11:31

非常不错啊

0

0x4d5c 2015-08-02 10:20:42

有点浮躁,不能说出来的,就不要表现出来,所说的exp,如果不能稳定,最好谦虚的称它为poc.....

Q

QEver 2015-08-02 11:18:56

目前我们只有技术人员,所以写的难免偏重技术方面,不像友商那么通俗易懂。但论技术目前并没有见到比我们讲的更深入的。并不是说别人没能力,相反我知道很多厂商研究更深入,但却敝扫自珍,我见到有朋友要POC都各种理由不愿拿出来分享,才决定写这篇文章。
这种文章对一般人确实用处不大,但是如果研究此漏洞陷入瓶颈的同行,肯定会有所收获。但这个漏洞真正要用,依旧有个关键问题没有解决。这只能等漏洞发现者来解惑了。
@0x4d5c @路人甲

A

ACGT 2015-08-02 14:07:43

@QEver 谢谢分享。大家都是搞技术的,就别管什么厂商了,那是公关的工作。

小荷才露尖尖角 2015-08-02 20:57:31

感谢

猎豹移动安全中心

猎豹移动公司安全技术团队

twitter weibo github wechat

随机分类

运维安全 文章:62 篇
Ruby安全 文章:2 篇
二进制安全 文章:77 篇
区块链 文章:2 篇
硬件与物联网 文章:40 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

Article_kelp

因为这里的静态目录访功能应该理解为绑定在static路径下的内置路由,你需要用s

N

Nas

师傅您好!_static_url_path那 flag在当前目录下 通过原型链污

Z

zhangy

你好,为什么我也是用windows2016和win10,但是流量是smb3,加密

K

k0uaz

foniw师傅提到的setfge当在类的字段名成是age时不会自动调用。因为获取

Yukong

🐮皮

目录