安卓libStagefright高危漏洞分析

-序-

本周早些时候, 国外安全公司Zimperium爆出多处Android系统漏洞, 瞬间占据各大媒体头条. 号称一条彩信即可控制手机, 影响范围从Android 2.2到5.1通杀, 号称Android上的”心脏滴血”. 本着不放过任何漏洞细节的原则, 扒了一下相关信息. 要做这篇分析报告的时候, 一开始是拒绝的, 后来各种夸张新闻刷屏, 真的有这么恐怖吗?


-漏洞信息初探- 

根据原博文指出, 漏洞细节将在下月初的Black Hat以及DEFCON上公布, 但提到了[CVE-2015-1538,CVE-2015-1539,CVE-2015-3824,CVE-2015-3826,CVE-2015-3827,CVE-2015-3828,CVE-2015-3829], 搜索CVE后发现状态都是reserved. 看来除了文中提到的Stagefright, 彩信是不会有太多可用信息了, 好在搜到著名Android第三方ROM CyanogenMod发布的信息, 从中得知CM团队已在前几周修复了该漏洞, 用户可以使用nightly build的版本.  顺藤摸瓜, 前往CM的codereview一探究竟. 顺利从包含libstagefright代码的frameworks/av历史中找到了相关修复信息.

-labs-6f7af216-d10e5180-86e15787-beecb8eb.png

-漏洞影响分析-

根据CM的漏洞修复信息得知受害者为由于会调用libstagefright.so的/system/bin/mediaserver. 根据修复commit说明, 得知漏洞大致是解析mp4格式视频存在溢出或越界.

service media /system/bin/mediaserver class main user media group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm ioprio rt 4

从init脚本来看, mediaserver所在用户组权限还蛮高, 可以访问网络, 访问手机存储, 访问摄像头等等权限.  那么又有哪些app会去调用libstagefright库从而触发漏洞呢?

00001. 

1. 首先漏洞原文提到彩信, 如果攻击者构造恶意的视频, 通过自动下载彩信后触发解析溢出. 那么真如原文所说一条彩信就能拿下机器.

00002. 

-labs-8e841f39-c3ba016f-89543549-1534723d.png

00003. 

2. 另外如果用户从不明网址下载恶意的视频到sdcard上, 再通过文件管理浏览时, 由于文件管理会解析视频文件得到缩略图, 这个时候也会触发漏洞, 图库应用同理. 

3. 如果是直接通过浏览器, 访问恶意视频地址, 或者是通过播放器播放恶意视频时, 同样会触发 

4. 再者, 要是视频存在sdcard上, 每次开机, 由于MediaProvider会扫描sd卡上所有文件, 同样扫描到该视频也会触发 

… 

虽然原文提到Google官方在内部已经修复了该漏洞并提供给合作伙伴, 但伴随着各大厂商滞后的更新, 漏洞在一定时间内会依然存在, 并且一些老旧机器, 可能根本不会再更新.

-漏洞细节分析-

由于几处漏洞细节基本都属于一个类型的, 大都是在解析元数据metadata中出的问题, 不是越界就是溢出, 选典型进行说明

1.解析3GP元数据出现的两个越界首先看两个补丁同样都是在MPEG4 Extractor: :parse3GPP Meta Data解析元数据的时候

看补丁增加的判断很快能判断出来读越界。往后会到setCString转至https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/MetaData.cpp

00001. 

-labs-d6497bcf-c4e2fa9f-9d9acfcf-91bf16a0.png

00002. 

可能导致一些元数据的泄漏

00003. 

同一个地方的第二处补丁

00004. 

如果size小于6造成underflow, 在后面的很大片的bswap_16操作可以造成越界写 

00005. 

2. 解析ChunkType为tx3g的堆溢出从补丁来看, 如果将’size’和’chunk_size’相加起来大于2^32, 那么会造成整数溢出, 实际导致分配内存会较小, 后面memcpy即可导致堆溢出. 

3. 解析ChunkType为covr的越界以及溢出当chunk_data_size小于kSkipBytesOfDataBox会造成underflow, 传给SetData会越界读同一个地方当chunk_data_size等于SIZE_MAX, 可以导致整数溢出, 后面的readAt操作会继续读写操作, 导致写越界. 

-漏洞POC-

通过漏洞细节只要构造指定tag造成溢出可导致mediaserver的崩溃, 参考代码如下。 该方法针对ChunkType为tx3g的堆溢出。

以下为通过发送彩信,收到后mediaserver崩溃日志以及还有通过播放器触发的崩溃日志:

[plain]  view plain  copy
 print ?
  1. <p style="font-family:'Microsoft YaHei'; margin-top:15px; margin-bottom:15px; line-height:1.75em">V/WindowManager( 642): Adding window Window{211b514d u0 com.android.gallery3d/com.android.gallery3d.app.MovieActivity} at 7 of 13 (after Window{2bad10ee u0 android/com.android.internal.app.ResolverActivity})<br style="">V/WindowManager( 642): Adding window Window{1458b549 u0 SurfaceView} at 7 of 14 (before Window{211b514d u0 com.android.gallery3d/com.android.gallery3d.app.MovieActivity})<br style="">W/ALooperRoster(23642): failed to post message. Target handler 0 still registered, but object gone.<br style="">E/WVMExtractor(23642): Failed to open libwvm.so: dlopen failed: library “libwvm.so” not found<br style="">F/libc (23642): Fatal signal 11 (SIGSEGV), code 1, fault addr 0×4 in tid 23677 (generic)<br style="">I/ActivityManager( 642): Displayed com.android.gallery3d/.app.MovieActivity: +301ms<br style="">I/DEBUG ( 213): <br style="">* *<br style="">I/DEBUG ( 213): Build fingerprint: ‘google/occam/mako:5.1.1/LYZ28E/1863243:user/release-keys’<br style="">I/DEBUG ( 213): Revision: ‘11’<br style="">I/DEBUG ( 213): ABI: ‘arm’<br style="">I/DEBUG ( 213): pid: 23642, tid: 23677, name: generic >>> /system/bin/mediaserver <<<<br style="">I/DEBUG ( 213): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0×4<br style="">W/NativeCrashListener( 642): Couldn’t find ProcessRecord for pid 23642<br style="">I/DEBUG ( 213): r0 00000000 r1 74657874 r2 b5145a60 r3 b5145a68<br style="">E/DEBUG ( 213): AM write failure (32 / Broken pipe)<br style="">I/DEBUG ( 213): r4 b5145a78 r5 74783367 r6 b5145a68 r7 00000000<br style="">I/DEBUG ( 213): r8 b7c39728 r9 74783367 sl b5145bf0 fp b66cd40c<br style="">I/DEBUG ( 213): ip b6609f43 sp b5145a18 lr b6c1a3d1 pc b662a79c cpsr 600f0030<br style="">I/DEBUG ( 213):<br style="">I/DEBUG ( 213): backtrace:<br style="">I/DEBUG ( 213): #00 pc 0007979c /system/lib/libstagefright.so (android::MPEG4Extractor::parseChunk(long long*, int)+4539)<br style="">I/DEBUG ( 213): #01 pc 0007a023 /system/lib/libstagefright.so (android::MPEG4Extractor::readMetaData()+58)<br style="">I/DEBUG ( 213): #02 pc 0007a1e5 /system/lib/libstagefright.so (android::MPEG4Extractor::getMetaData()+8)<br style="">I/DEBUG ( 213): #03 pc 0005995f /system/lib/libmediaplayerservice.so (android::NuPlayer::GenericSource::initFromDataSource()+206)<br style="">I/DEBUG ( 213): #04 pc 0005a259 /system/lib/libmediaplayerservice.so (android::NuPlayer::GenericSource::onPrepareAsync()+420)<br style="">I/DEBUG ( 213): #05 pc 0005ab89 /system/lib/libmediaplayerservice.so (android::NuPlayer::GenericSource::onMessageReceived(android::sp const&)+60)<br style="">I/DEBUG ( 213): #06 pc 0000c4c3 /system/lib/libstagefright_foundation.so (android::ALooperRoster::deliverMessage(android::sp const&)+166)<br style="">I/DEBUG ( 213): #07 pc 0000be45 /system/lib/libstagefright_foundation.so (android::ALooper::loop()+220)<br style="">I/DEBUG ( 213): #08 pc 000104d5 /system/lib/libutils.so (android::Thread::_threadLoop(void*)+112)<br style="">I/DEBUG ( 213): #09 pc 00010045 /system/lib/libutils.so<br style="">I/DEBUG ( 213): #10 pc 00016133 /system/lib/libc.so (__pthread_start(void*)+30)<br style="">I/DEBUG ( 213): #11 pc 0001405b /system/lib/libc.so (__start_thread+6)<br style="">I/ActivityManager( 642): Killing 18417:com.android.deskclock/u0a29 (adj 15): empty #17<br style="">I/DEBUG ( 213):<br style="">I/DEBUG ( 213): Tombstone written to: /data/tombstones/tombstone_05<br style="">I/BootReceiver( 642): Copying /data/tombstones/tombstone_05 to DropBox (SYSTEM_TOMBSTONE)<br style="">W/AudioSystem( 642): AudioPolicyService server died!<br style="">W/AudioSystem( 642): AudioFlinger server died!<br style="">I/ServiceManager( 194): service ‘media.audio_policy’ died<br style="">I/ServiceManager( 194): service ‘media.audio_flinger’ died<br style="">W/AudioSystem(23263): AudioFlinger server died!<br style="">I/ServiceManager( 194): service ‘media.player’ died<br style="">W/IMediaDeathNotifier(23263): media server died<br style="">I/ServiceManager( 194): service ‘media.camera’ died<br style="">E/MediaPlayer(23263): error (100, 0)<br style="">I/ServiceManager( 194): service ‘media.sound_trigger_hw’ died<br style="">E/MediaPlayer(23263): Error (100,0)<br style="">D/CodeauroraVideoView(23263): Error: 100,0<br style="">E/AudioService( 642): Media server died.<br style=""></p>  

-漏洞防护-

目前除了公开信息表示已经修复漏洞的CyanogenMod外, 其他厂商暂时没有任何动态, Google表示已经内部修复并提交给合作伙伴, 不过目前还没看到AOSP中有相关记录, 估计还没push上来. 介于厂商更新速度, 还是不容忽视.
由于mediaserver的所在用户组权限涉及一些敏感权限(访问网络, DRM等), 并且不能排除部分权限通过跳板拿到更高权限. 最好还是将彩信的自动下载关闭, 如下图所示.

具体根据不同手机可能不同. 另外需要警惕不明渠道获得的视频,,如微信,浏览器下载或直接访问,蓝牙等。尽可能的开启手机OTA更新功能, 如果厂商第一时间发布推送, 可以及时更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值