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方法

根本原因

  1. mCASSession->decrypt未使用强指针保护会话对象
  2. 导致解密操作期间会话对象的引用计数不会增加
  3. 如果同时发生以下操作会触发UAF:
    • 解密操作正在进行
    • 另一个线程调用setMediaCasSession释放原始会话对象

技术细节

  • 当Descrambler设置新会话时,原始会话对象的引用计数会减少
  • 如果此时引用计数归零,会话对象被释放
  • 但正在进行的decrypt操作仍会使用已释放的内存

0x03 漏洞利用(PoC)

利用思路

  1. 创建两个会话:session1和session2
  2. 将session1链接到Descrambler
  3. 从会话库中删除session1,使其仅由Descrambler引用
  4. 同时执行:
    • 多线程通过Descrambler执行解密操作
    • 将Descrambler的会话设置为session2
  5. 如果解密操作未返回,说明触发了UAF

利用条件

  • Android 9+:使用已销毁的互斥锁会导致进程崩溃
  • Android ≤8.1:尝试使用释放资源的互斥锁会返回错误

0x04 复现环境

推荐环境

  • 硬件:Pixel手机(真机)
  • 系统:Android 8.0-9.0
  • 开发环境:Ubuntu 18.04

复现建议

  1. 真机优于模拟器(时序要求严格)
  2. 若必须使用模拟器:
    • setMediaCasSession函数中添加sleep
    • 提高PoC程序优先级

0x05 补丁分析

修复方案

  1. 将强指针sp<ClearKeyCASession>改为智能指针shared_ptr

    • 允许多个指针共享同一对象
    • 自动管理引用计数
  2. 引入原子操作(std::atomic)

    • 确保对共享资源的操作是原子的
    • 防止多线程竞争导致的数据不一致

关键代码修改

descramble方法中:

  1. 使用shared_ptr指向会话
  2. 通过std::atomic_load安全读取会话
  3. 通过std::atomic_store安全更新会话

0x06 防护建议

  1. 及时更新Android安全补丁(2018年11月及以后)
  2. 对关键资源访问使用原子操作
  3. 使用智能指针管理对象生命周期
  4. 对多线程共享资源添加适当同步机制

参考资源

  1. Zimperium漏洞分析原文
  2. Android HIDL文档
  3. 原子操作详解
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月及以后) 对关键资源访问使用原子操作 使用智能指针管理对象生命周期 对多线程共享资源添加适当同步机制 参考资源 Zimperium漏洞分析原文 Android HIDL文档 原子操作详解