CVE-2018-9539:特权Android服务中的Use-After-Free
字数 1813 2025-08-27 12:33:42
Android MediaCasService UAF漏洞分析 (CVE-2018-9539)
0x00 漏洞概述
CVE-2018-9539是一个在Android 8.0-9.0版本中存在于ClearKey CAS descrambler中的Use-After-Free漏洞。该漏洞允许攻击者通过竞争条件(race condition)触发UAF,可能导致权限提升。谷歌在2018年11月的安全补丁中修复了该漏洞。
0x01 背景知识
1. Project Treble架构
Android 8.0引入的Project Treble重新设计了Android框架,主要特点包括:
- 分离AOSP和供应商代码
- 使用HIDL(HAL Interface Definition Language)定义HAL和其他组件间的接口
2. MediaCasService组件
MediaCasService是Android的解扰码器服务,位于HAL层,主要功能:
- 允许应用程序解扰受保护的媒体流
- 通过两个主要对象与应用程序交互:
Cas:管理密钥Descrambler:执行实际解扰操作
3. ClearKey插件实现
实际解扰操作由插件执行:
- ClearKey插件库:
libclearkeycasplugin.so - 会话管理通过
ClearKeySessionLibrary实现(哈希表结构)- 键:会话ID
- 值:会话对象
4. 引用计数机制
- 会话对象通过强指针(
sp类)管理引用计数 - 引用可能来自:
- 会话库
- Descrambler的
mCASSession成员
- 当引用计数归零时,会话对象被释放
5. Binder IPC机制
- 使用共享内存进行进程间通信
- 通过共享文件描述符实现内存映射
- 允许多个进程访问相同内存区域
0x02 漏洞分析
漏洞位置
frameworks/av/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp中的descramble方法
根本原因
mCASSession->decrypt未使用强指针保护会话对象- 导致解密操作期间会话对象的引用计数不会增加
- 如果同时发生以下操作会触发UAF:
- 解密操作正在进行
- 另一个线程调用
setMediaCasSession释放原始会话对象
技术细节
- 当Descrambler设置新会话时,原始会话对象的引用计数会减少
- 如果此时引用计数归零,会话对象被释放
- 但正在进行的
decrypt操作仍会使用已释放的内存
0x03 漏洞利用(PoC)
利用思路
- 创建两个会话:session1和session2
- 将session1链接到Descrambler
- 从会话库中删除session1,使其仅由Descrambler引用
- 同时执行:
- 多线程通过Descrambler执行解密操作
- 将Descrambler的会话设置为session2
- 如果解密操作未返回,说明触发了UAF
利用条件
- Android 9+:使用已销毁的互斥锁会导致进程崩溃
- Android ≤8.1:尝试使用释放资源的互斥锁会返回错误
0x04 复现环境
推荐环境
- 硬件:Pixel手机(真机)
- 系统:Android 8.0-9.0
- 开发环境:Ubuntu 18.04
复现建议
- 真机优于模拟器(时序要求严格)
- 若必须使用模拟器:
- 在
setMediaCasSession函数中添加sleep - 提高PoC程序优先级
- 在
0x05 补丁分析
修复方案
-
将强指针
sp<ClearKeyCASession>改为智能指针shared_ptr- 允许多个指针共享同一对象
- 自动管理引用计数
-
引入原子操作(
std::atomic)- 确保对共享资源的操作是原子的
- 防止多线程竞争导致的数据不一致
关键代码修改
在descramble方法中:
- 使用
shared_ptr指向会话 - 通过
std::atomic_load安全读取会话 - 通过
std::atomic_store安全更新会话
0x06 防护建议
- 及时更新Android安全补丁(2018年11月及以后)
- 对关键资源访问使用原子操作
- 使用智能指针管理对象生命周期
- 对多线程共享资源添加适当同步机制