阿里移动安全 · 2015/07/31 16:53html
做者: 迅迪 没羽 轩夏 成淼 奋龙 逆巴android
StageFright是一个Android中的系统服务,可处理各类多媒体格式,由Natvie C++代码实现,多媒体应用如何与Android Native多媒体进行交互可参考以下图:c++
而Stagefright所涵盖的模块很是广git
|-- stagefright
| |
| |-- codecs //提供解码器实现
| |
| |-- colorconversion //颜色空间转换
| |
| |-- foundation //基本数据结构的实现
| |
| |-- httplive //m3u8解析
| |
| |-- id3 // ID3 TAG解析(通常用于MP3格式的metadata容器)
| |
| |-- include //基本头文件
| |
| |-- matroska //matroska文件解析
| |
| |-- mpeg2ts //mpeg2ts文件解析和数据获取一些处理
| |
| |-- mp4
复制代码
因为多媒体处理的实时性特征,该库经过Native代码实现,这也是的该库存在内存破坏的问题远远多于Java实现的代码。github
以色列移动信息安全公司Zimperium研究人员Joshua Drake在7月21号发布的声明,声称会在8月的BlackHat会议上发布细节。浏览器
Android Stagefright框架中发现了多个整数溢出和下溢,不正确整数溢出检查等漏洞,可致使任意代码执行等问题。安全
攻击者经过发送包含特制媒体文件的MMS或WEB页来触发该漏洞。因为stagefright不仅是用来播放媒体文件的,还能自动产生缩略图,或者从视频或音频文件中抽取元数据,如长度、高度、宽度、帧频、频道和其余相似信息。所以接收到恶意彩信的用户只要查看缩略图就可触发该漏洞。数据结构
“Stagefright”媒体播放引擎库在Android 2.2中引入,至5.1的全部版本上均存在此漏洞,预计会有95%的Android设备,约有九亿五千万的安卓设备受该漏洞影响.app
使用Stagefright库的应用程序以Media权限运行,成功利用漏洞,容许攻击者浏览器媒体库相应的文件,但经过权限提高攻击,可彻底控制设备。框架
该Stagefright漏洞所对应的CVE ID以下:
CVE-2015-1538
CVE-2015-1539
CVE-2015-3824
CVE-2015-3826
CVE-2015-3827
CVE-2015-3828
CVE-2015-3829
复制代码
根据https://github.com/CyanogenMod/android_frameworks_av/commits/cm-12.1
提供的补丁,进行了相关的分析:
4.1 Prevent reading past the end of the buffer in 3GPP
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/57db9b42418b434751f609ac7e5539367e9f01a6
复制代码
该漏洞产生在如下的chunk中:
这是一个堆内存读越界漏洞,parse3GPPMetaData方法中调用mDataSource->readAt( offset, buffer, size)
读取size大小的数据到申请的buffer中,而后下面会调用mFileMetaData->setCString()
方法进行内存拷贝:
咱们来看setCString()方法的最终会调用memcpy进行内在拷贝:
#!c++
void MetaData::typed_data::setData(uint32_t type, const void *data, size_t size) {
clear();
mType = type;
allocateStorage(size);
memcpy(storage(), data, size);
}
复制代码
因为对memcpy中size的处理不当,致使越界读取了内存数据。
4.2 Prevent integer underflow if size is below 6
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/9824bfd6eec1daa93cf76b6f4199602fe35f1d9d
复制代码
该漏洞是一个integer underflow漏洞,对于构造的size来讲,若是size<6,可致使len16的值变的很大:
致使接下来的内存越界操做:
4.3 Fix integer overflow when handling MPEG4 tx3g atom
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/889ae4ad7227c395615d03b24a1667caa162c75f
复制代码
该漏洞产生在“tx3g”的chunk中,chunk_size是uint,与size之和溢出,会致使实际分配比size小的内存。后面的memcpy函数将会发生堆溢出:
当mLastTrack->meta->findData(kKeyTextFormatData, &type, &data, &size)
函数调用返回为真,size值将不会为0,chunk_size与size都为uint8_t,之和后发生整数溢出,这样致使new一个比size更小的空间,在随后的memcpy将发生堆溢出:
#!c++
bool MetaData::findData(uint32_t key, uint32_t *type,
const void **data, size_t *size) const {
ssize_t i = mItems.indexOfKey(key); //键值存在 i>0
if (i < 0) {
return false;
}
const typed_data &item = mItems.valueAt(i);
item.getData(type, data, size);
return true;
}
复制代码
接下来new (std::nothrow) uint8_t[size + chunk_size]
,size与chunk_size之和发生整数溢出,值将小于size,此后的memcpy发生堆溢出:
4.4 Fix integer underflow in covr MPEG4 processing
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/b1f29294f1a5831eb52a81d3ee082a9475f6e879
复制代码
从patch代码可知,因为未检测chunk_data_size的长度,致使后面的chunk_data_size – kSkipBytesOfDataBox为负数,
向上追溯,chunk_data_size = offset + chunk_size - data_offset;off64_t data_offset = *offset + 8;其中chunk_size为mpeg4格式中box的chunk_size,offset为当前的box的起始位置。由patch代码可知,有这样的不等或成立才能避免该漏洞的出现:
chunk_data_size <= kSkipBytesOfDataBox
⇨ *offset + chunk_size - *offset - 8 <= 16
⇨ chunk_size - 8 <= 16
⇨ chunk_size <= 24(0x18)
复制代码
因此当chunk_size的值<=24时会触发漏洞。构造的一个样本(0x08)截图以下:
4.5 Prevent integer overflow when processing covr MPEG4 atoms
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/7ff5505d36b1cfd8b03497e0fb5aa24b5b099e45
复制代码
从patch代码可知,因为未对chunk_data_size的长度进行限制,当chunk_data_size>=SIZE_MAX-1时,chunk_data_size+1>=SIZE_MAX
,致使ABuffer分配0长度的内存,后续再进行内存操做就致使堆越界。
4.6 Fix integer overflow during MP4 atom processing
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/3854030bf70cb78ec0afbf90d0e7d8e1cf8f9904
复制代码
从代码分析可知,要构造出知足条的POC样本,须要chunk_size=1,而后unint64来存储chunk_size。对于该漏洞POC的构造,咱们假设:mNumSampleToChunkOffsets = 0xFFFFFFFF/0xC
可得,mNumSampleToChunkOffsets = 0x15555555
咱们构造以下样本:
其中chunk_size 为1,large_chunk_size
为0x100000007
, mNumSampleToChunkOffsets
为0x15555555
。
加载该样本,运行截图以下:
4.7 Fix integer underflow in ESDS processing
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/e586b3e891e7c598449d40a9c44c70fd6663d064
复制代码
从patch代码可知,因为未对size的大小进行检测,后续会进行屡次-2操做,致使size为负数,致使堆下溢出。
要构造poc需进入ESDS.cpp查看详细代码:
首先获取偏移的值,并进行一系列运算,当more=true时中止,并返回data_size,而后开始解析ESDS。
从代码能够看出来当3个标志位都为1时,才会进行size-2操做,所以构造的poc必须知足3个标志位,0xE0以上数值就知足要求。所以将size修改成5,标志位修改成0xE3就能触发漏洞的畸形样本截图以下:
4.8 Fix several ineffective integer overflow checks
补丁连接:
https://github.com/CyanogenMod/android_frameworks_av/commit/16c78bb6608dd5abbf3a1fc1cd98e8fc94cfb241
复制代码
此漏洞有3处patch,涉及到3个chunk分别是“stts”、“ctts”、“stss”。是因为几个uint32型数据相乘,再赋值给uint64可能会致使溢出:
以“stts”chunk为例来讲一下poc的构造: 代码分析,我可得“stts”chunk的结构头以下:
第4个4字节的值即为mTimeToSampleCount,咱们假设存在这样一个等式:mTimeToSampleCount * 2 * 4 = 0xFFFFFFFF+0x1
可得,mTimeToSampleCount=0x20000000
咱们以mTimeToSampleCount=0x20000000构造的一个POC以下:
运行结果:
chunk“ctts”、“stss”也能够经过相似的方法构造出POC。
Amazon Barnes and Noble
Google HTC
Huawei Technologies
Kyocera Communications
LG Electronics
Motorola, Inc.
Samsung Mobile
Sony Corporation
复制代码
等
因为Stagefright是一个底层的多媒体处理库,所以调用该库的应用都受此漏洞影响,咱们随机检测国内主流的几个应用作,发现都存在此问题:
6.1 绝大多数视频APP都受影响,以乐视视频为例
- 受影响版本:Android/5.9.3
- 点击特制构建的视频文件,选择“乐视视频”播放:
复制代码
-查看日志信息,能够看到libstagefright.so的crash信息,在MPEG4Extractor::parseChunk(off64_t *offset, int depth)
方法中解析文件出错,受影响代码能够参考:
https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r8/media/libstagefright/MPEG4Extractor.cpp:
复制代码
6.2 某手机浏览器
- 版本:
Android/6.0.1.1560
- 测试:
使用某手机浏览器的二维码功能,扫描生成的视频PoC文件,
在浏览器弹出的提示窗口中选择“直接打开”:
复制代码
-查看手机端,播放视频文件出错:
-查看日志信息,能够看到libstagefright.so的crash信息,在MPEG4Extractor::parseChunk(off64_t *offset, int depth)
方法中解析文件出错。
6.3某SNS通信工具
- 版本:
Android/6.2.2
- 发送特殊构建的视频文件时,点击播放会弹出“播放失败”窗口,如图:
复制代码
能够看到解析视频文件时发生崩溃,经过视频发送或SNS形式传播,可大范围的影响用户。
Google已经发布Android 5.1.1_r5修复该漏洞,注意不是全部Android 5.1.1 (Lollipop)手机应用了该补丁,须要安装patchlevel r5补丁:
https://android.googlesource.com/platform/frameworks/av/+/0e4e5a8%5E!/
https://android.googlesource.com/platform/frameworks/av/+/5c134e6%5E!/
https://android.googlesource.com/platform/frameworks/av/+/030d8d0%5E!/
复制代码
CyanogenMod中的cm12.1 branch已经修复该漏洞:
https://github.com/CyanogenMod/android_frameworks_av/commits/cm-12.1
复制代码
积极联系经过厂商OTA进行更新
- http://blog.zimperium.com/experts-found-a-unicorn-in-the-heart-of-android/
- http://www.kb.cert.org/vuls/id/924951
- http://www.forbes.com/sites/thomasbrewster/2015/07/27/android-text-attacks/
- http://www.zdnet.com/article/stagefright-just-how-scary-is-it-for-android-users/
- http://arstechnica.com/security/2015/07/950-million-android-phones-can-be-hijacked-by-malicious-text-messages/
- https://android.googlesource.com/platform/frameworks/av/+/0e4e5a8%5E!/
- https://android.googlesource.com/platform/frameworks/av/+/5c134e6%5E!/
- https://android.googlesource.com/platform/frameworks/av/+/030d8d0%5E!/
- http://source.android.com/devices/media.html
- https://www.duosecurity.com/blog/exploit-mitigations-in-android-jelly-bean-4-1
复制代码