CVE-2017-13253 :Android Drm服务 堆溢出漏洞
字数 2054 2025-08-22 18:37:22

Android Drm服务堆溢出漏洞(CVE-2017-13253)深入分析

0x00 漏洞概述

CVE-2017-13253是Android Drm服务中的一个堆溢出漏洞,影响Android Native多媒体框架中的DRM(数字版权管理)组件。该漏洞允许攻击者通过构造恶意的解密请求,在DRM服务进程中执行堆溢出攻击,可能导致任意代码执行或服务崩溃。

0x01 DRM架构基础

1. Android DRM框架

Android DRM属于Android Native多媒体框架的一部分,主要用于播放受DRM保护的内容(如Google Play电影中的加密影片)。关键特点:

  • 负责安全解密加密数据
  • 可以访问证书和密钥存储等敏感组件
  • 由于供应商依赖关系,DRM进程尚未应用于所有情况

2. Crypto Plugins

Crypto Plugins是DRM方案之一,在Android术语中,每个DRM方案的处理程序称为插件:

  • 供应商负责提供这些插件
  • AOSP包含ClearKey DRM方案插件的完整开源实现
  • 涉及的关键参数变量参考MediaCodec.CryptoInfo

0x02 漏洞技术分析

1. Binder通信机制

MediaDrmserver通过Binder提供ICrypto接口(现改名为CryptoHal),允许非特权应用解密DRM数据。Binder C++库中的相关类结构:

  • 接口类:以"I"为前缀,定义通过Binder调用的方法
  • 客户端类:以"Bp"为前缀,负责序列化输入和反序列化输出
  • 服务器端类:以"Bn"为前缀,负责反序列化输入和序列化输出

2. 共享内存结构

关键结构成员:

  • mHeapSeqNum:共享内存的标识符
  • mSharedMemory成员:表示堆内缓冲区的偏移和大小

值得注意的是:

  • mSharedMemory是一个IMemory,实际连接到自己的堆
  • 但该堆被忽略,偏移量和大小用于mHeapSeqNum
  • 这是Project Treble重构后的结果

3. 漏洞根源

漏洞存在于DRM服务的解密过程中,具体表现为:

  1. 验证不完整

    • 检查了源缓冲区是否越界
    • 检查了目标缓冲区是否在堆内
    • 没有检查目标缓冲区+拷贝数据是否会超出堆边界
  2. 关键代码片段:

    // 源缓冲区检查
    if (source.offset + offset + source.size > sourceBase->getSize()) {
        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
        return Void();
    }
    
    // 目标缓冲区检查(过于简单)
    if (destBuffer.offset + destBuffer.size > destBase->getSize())
    
    // 实际拷贝操作(漏洞点)
    memcpy(reinterpret_cast<uint8_t*>(dstPtr) + offset, 
           reinterpret_cast<const uint8_t*>(strPtr) + offset, 
           subSample.mNumBytesOfClearData);
    
  3. 漏洞利用条件:

    • 构造恶意的解密请求,使拷贝数据超出目标缓冲区边界
    • 可以覆盖堆上的相邻内存区域

0x03 动态调试分析

1. 调试环境差异

  • 原始调试环境:Nexus设备,HAL实现没有分开
  • 本文调试环境:Pixel设备,HAL实现分开

2. 预期行为

根据POC作者说明,不同情况下表现不同:

  1. 2018年3月后的Android版本:decrypt返回bad_value(-22)
  2. 无crash情况(覆盖数据可写):返回拷贝的数据量
  3. HAL作为单独进程(如Pixel 2):返回UNKNOWN_ERROR(-32)
  4. HAL在同一进程(如Nexus 5X):返回0

3. 调试流程

涉及三个关键函数:

  1. android::BnCrypto::onTransact:序列化+验证
  2. Android::CryptoHal::decrypt:序列化+验证
  3. Clearkeydrm::CryptoPlugin::decrypt:实际memcpy操作

调试技巧:

  1. 对于多进程调试(HAL分开实现的情况):

    • 通过Android.mk或Android.bp文件找到local_module
    • 或通过adb shell ps | grep 'xxxserver'查找服务端进程
  2. 关键观察点:

    • 从反序列化获取total值(如0x2000)
    • 验证缓冲区边界检查逻辑

0x04 影响范围与补丁

1. 影响范围

受影响流程取决于供应商实现方式:

  1. HAL未分开:mediadrmserver受影响
  2. HAL分开:使用默认加密插件的每个HAL服务受影响

2. 补丁分析

补丁方案简单有效:

  • 增加对目标缓冲区的完整检查
  • 验证目标偏移+拷贝数据 ≤ 目标缓冲区堆大小
  • 即检查:dest->offset + subSample.mNumBytesOfClearData ≤ dest->size()

0x05 参考资源

  1. 原始分析文章
  2. Android Binder机制
  3. 漏洞简介
  4. Android DRM框架
  5. MediaDrm文档
  6. Android编译流程
  7. Google驱动下载
  8. Android版本标记

0x06 总结

CVE-2017-13253暴露了Android DRM服务在内存管理上的缺陷,通过不完整的缓冲区边界检查,攻击者可能实现堆溢出攻击。该漏洞的分析过程涉及:

  1. Android DRM框架和Binder通信机制
  2. 共享内存管理实现细节
  3. 多进程环境下的调试技巧
  4. 供应商特定实现的影响差异

补丁通过增加完整的目标缓冲区检查解决了这一问题,体现了安全开发中"防御性编程"的重要性,特别是对于处理敏感数据的组件。

Android Drm服务堆溢出漏洞(CVE-2017-13253)深入分析 0x00 漏洞概述 CVE-2017-13253是Android Drm服务中的一个堆溢出漏洞,影响Android Native多媒体框架中的DRM(数字版权管理)组件。该漏洞允许攻击者通过构造恶意的解密请求,在DRM服务进程中执行堆溢出攻击,可能导致任意代码执行或服务崩溃。 0x01 DRM架构基础 1. Android DRM框架 Android DRM属于Android Native多媒体框架的一部分,主要用于播放受DRM保护的内容(如Google Play电影中的加密影片)。关键特点: 负责安全解密加密数据 可以访问证书和密钥存储等敏感组件 由于供应商依赖关系,DRM进程尚未应用于所有情况 2. Crypto Plugins Crypto Plugins是DRM方案之一,在Android术语中,每个DRM方案的处理程序称为插件: 供应商负责提供这些插件 AOSP包含ClearKey DRM方案插件的完整开源实现 涉及的关键参数变量参考 MediaCodec.CryptoInfo 0x02 漏洞技术分析 1. Binder通信机制 MediaDrmserver通过Binder提供ICrypto接口(现改名为CryptoHal),允许非特权应用解密DRM数据。Binder C++库中的相关类结构: 接口类 :以"I"为前缀,定义通过Binder调用的方法 客户端类 :以"Bp"为前缀,负责序列化输入和反序列化输出 服务器端类 :以"Bn"为前缀,负责反序列化输入和序列化输出 2. 共享内存结构 关键结构成员: mHeapSeqNum :共享内存的标识符 mSharedMemory 成员:表示堆内缓冲区的偏移和大小 值得注意的是: mSharedMemory 是一个IMemory,实际连接到自己的堆 但该堆被忽略,偏移量和大小用于 mHeapSeqNum 堆 这是Project Treble重构后的结果 3. 漏洞根源 漏洞存在于DRM服务的解密过程中,具体表现为: 验证不完整 : 检查了源缓冲区是否越界 检查了目标缓冲区是否在堆内 但 没有检查目标缓冲区+拷贝数据是否会超出堆边界 关键代码片段: 漏洞利用条件: 构造恶意的解密请求,使拷贝数据超出目标缓冲区边界 可以覆盖堆上的相邻内存区域 0x03 动态调试分析 1. 调试环境差异 原始调试环境:Nexus设备,HAL实现没有分开 本文调试环境:Pixel设备,HAL实现分开 2. 预期行为 根据POC作者说明,不同情况下表现不同: 2018年3月后的Android版本 :decrypt返回bad_ value(-22) 无crash情况 (覆盖数据可写):返回拷贝的数据量 HAL作为单独进程 (如Pixel 2):返回UNKNOWN_ ERROR(-32) HAL在同一进程 (如Nexus 5X):返回0 3. 调试流程 涉及三个关键函数: android::BnCrypto::onTransact :序列化+验证 Android::CryptoHal::decrypt :序列化+验证 Clearkeydrm::CryptoPlugin::decrypt :实际memcpy操作 调试技巧: 对于多进程调试(HAL分开实现的情况): 通过Android.mk或Android.bp文件找到local_ module 或通过 adb shell ps | grep 'xxxserver' 查找服务端进程 关键观察点: 从反序列化获取total值(如0x2000) 验证缓冲区边界检查逻辑 0x04 影响范围与补丁 1. 影响范围 受影响流程取决于供应商实现方式: HAL未分开 :mediadrmserver受影响 HAL分开 :使用默认加密插件的每个HAL服务受影响 2. 补丁分析 补丁方案简单有效: 增加对目标缓冲区的完整检查 验证 目标偏移+拷贝数据 ≤ 目标缓冲区堆大小 即检查: dest->offset + subSample.mNumBytesOfClearData ≤ dest->size() 0x05 参考资源 原始分析文章 Android Binder机制 漏洞简介 Android DRM框架 MediaDrm文档 Android编译流程 Google驱动下载 Android版本标记 0x06 总结 CVE-2017-13253暴露了Android DRM服务在内存管理上的缺陷,通过不完整的缓冲区边界检查,攻击者可能实现堆溢出攻击。该漏洞的分析过程涉及: Android DRM框架和Binder通信机制 共享内存管理实现细节 多进程环境下的调试技巧 供应商特定实现的影响差异 补丁通过增加完整的目标缓冲区检查解决了这一问题,体现了安全开发中"防御性编程"的重要性,特别是对于处理敏感数据的组件。