0289-Metaphor-A real life Stagefright exploit

# Metaphor-A real life Stagefright exploit

[http://exploit-db.com/docs/39527.pdf](http://exploit-db.com/docs/39527.pdf)

0x00 综述
=======

* * *

在本文中,我们研究了如何利用安卓系统上最臭名昭著的漏洞之一`Stagefright`。在此之前,我们一直认为这个漏洞是很难被利用的。在研究中,我们大量参考了Google公布的文章-exploit-38226和研究报告Google Project Zero: Stagefrightened。

本文中呈现了我们的研究结果,详细的介绍了这个漏洞的局限性,提供了一种绕过ASLR的途径,并为后继者提出了一些研究建议。

NorthBit团队利用的这个漏洞,能够影响到 Android 2.2-4.0和5.0-5.1版本,同时,还能够绕过Android 5.0-5.1上的ASLR技术(Android 2.2-4.0版本上没有实现ASLR)。

0x01 Stagefright
================

* * *

Stagefright是Android系统中的一个多媒体库。直到2015年7月27日,几个关键堆溢出漏洞的曝光,人们才开始注意到了Stagefright。这个漏洞最初是由Zimperium的Joshua Drake发现的,Android版本包括从1.0到5.1都受到了影响。

在下面的部分中,我们会用“libstagefright”代指Stagefright媒体库,用“stagefright”代指相应的bug。

虽然,多个Android版本的系统中都存在这个bug(接近1,000,000,000台设备),但是,很多人都认为这个漏洞无法被利用,主要是因为新版的Android实现了ASLR保护技术。

0x02 Metaphor
=============

* * *

Metaphor代指的是我们对Stagefright的利用过程。在文中,我们详细的研究了libstagefright,并提出了一种可以绕过ASLR的新技术。和Google团队一样,我们利用了CVE20153864,因为相较于Joshua Drake发现的CVE20151538漏洞,这个漏洞更容易实现。

0x03 研究目标
=========

* * *

我们之所以会持续研究这个媒体库,是因为其已经被证明了确实存在漏洞(bug和坏代码太多),受影响的设备成千上万,潜在的攻击途径也多种多样:mms(秘密进行),短信(自动进行),web浏览器(很少或几乎不需要用户交互)等等。

相比于前人的努力,我们希望实现一种更具普适性和可行性的利用方式,而可行性指的就是快速,可靠并且难以发现-理想情况下,只利用现有的漏洞。

总而言之,我们的目标是绕过ASLR。

0x04 MPEG-4文件
=============

* * *

要想理解这个漏洞,首先要理解MPEG-4文件格式。还好不难:这种文件就是TLV(类型-长度-值TypeLengthValue)数据块的集合。在这种编码方式中,会有一个“type”值指定数据块类型,一个“length”值指定数据长度,一个“chunk”值指定数据本身。

以MPEG-4为例,首先编码“length”,然后是“type”,最后是“value”。下面的pseudo-C描述的就是MPEG-4的数据块格式:

![p1](http://drops.javaweb.org/uploads/images/a2caca688644836ad18fe6dac86ad0c83011d387.jpg)

当长度为0时,数据会一直持续到文件末尾。atom字段是一个短字符串(也叫作FourCC),描述的是数据块类型。

对于需要超过2^32个字节的类型,使用的格式也稍有不同:

![p2](http://drops.javaweb.org/uploads/images/ebf59fd12882918d9ea61aeb2bb00447afab620e.jpg)

在采用了树结构的类型中,子数据块存在于父数据块的数据中。

下图中描述了一个媒体文件:

![p3](http://drops.javaweb.org/uploads/images/f2b94d0056ca5663ffc5a1b51ee44f10c20e7420.jpg)

Bug-CVE20153864

因为已经有很多文章都介绍过这个bug,所以这里就不多说了。我们使用了Android 5.1.0的源代码,如果有特殊情况,我们还会再做说明。

libstagefright中的这个bug出现在解析MPEG-4文件的过程中,或更具体的说,是解析tx3g atom字段,这个字段的作用是向媒体中嵌入字幕。

首先,我们看看这段代码的作用:

![p4](http://drops.javaweb.org/uploads/images/27a763a8b6ef2eaa73aae615d5335b98c06f3fa6.jpg)

![p5](http://drops.javaweb.org/uploads/images/0f28a7f010be15e36259a1beea522598ec266470.jpg)

相当简单-这段代码会收集所有的字幕数据块,并将其附到一个长缓冲区中。

检查了size和chunk_size,并且在我们的控制下,允许我们在这里造成了一个整数缓冲区溢出:

![p6](http://drops.javaweb.org/uploads/images/78843e5609c837ddf229366b7fcb7160efb57ae0.jpg)

要想实现堆溢出,我们需要至少一个合法的tx3g数据块,在整数溢出部分和堆溢出中都需要用到:

![p7](http://drops.javaweb.org/uploads/images/f950bc80775507b4fcb497d7f8cdb9344c90a369.jpg)

无论缓冲区实际分配的大小是多少,最终会导致data部分中的size字节被写到缓冲区中。

在构造堆时要注意,我们能够:

* 控制size-写入多少字节
* 控制data-写入多少数据
* 预测我们的对象会被分配到什么位置
* 分配的大小在我们的控制下
* Android使用了jemalloc作为其堆分配器(稍后再做说明)

考虑到这里,既然我们能够控制堆溢出的大小和数据,那么漏洞利用应该很容易实现。但是,实际中的限制很多,复杂化了漏洞的利用过程。

0x05 漏洞利用
=========

* * *

在这一部分,我们介绍了漏洞的利用原理和限制,以及一些与漏洞利用相关的发现。

### 攻击途径

这个漏洞存在于媒体解析过程中,也就是说,受害者的设备甚至不需要播放媒体,而只需要解析即可。媒体解析过程是为了获取其元数据,比如视频长度,艺术家名称,标题,字幕,注释等等。

最后,我们选择的攻击途径是通过web浏览器,因为需要执行JavaScript,这样做的优缺点也很明显。可以使用下面的这些方法来诱使受害者访问我们的恶意网页:

* 攻击性网站-可以伪装成“在线观看全高清<最新电影>”
* 入侵合法网站-页面看似合法,但植入了隐藏内容(iframe,隐藏标签…)
* XSS-可信网站中植入恶意内容
* 广告-只存在于`