Group of Software Security In Progress

Android Custom Permissions Demystified From Privilege Escalation to Design Shortcomings

作者:Rui Li, Wenrui Diao,Jianqi Du,Shanqing Guo

单位:Shandong University, University of California

会议:IEEE S&P 2021

链接:https://www.computer.org/csdl/pds/api/csdl/proceedings/download-article/1t0x94Xmr9C/pdf

Introduction

本篇论文系统地评估了 Android 自定义权限的设计和实现。作者开发自动化模糊测试工具CUPERFUZZER,以发现与自定义权限相关的提权漏洞。在4部 Android 9 / 10 的 Pixel 2 手机上运行,最终在执行 40,195 次模糊测试后发现了 2,384 个成功利用案例。作者在分析了30个关键路径后,总结了4个Android权限框架的设计缺陷。

Android自定义权限

作者在第三方应用市场和AndroZoo上随机选取了208,987个Apk进行了调查,回答了以下两个问题:

  1. 多少应用使用了自定义权限?

52,601个应用声明了82,052个自定义权限,权限级别的分布如表1所示。其中5,411个自定义权限被分配了权限组。

/images/2021-06-18/Untitled.png

/images/2021-06-18/Untitled%201.png

  1. 使用自定义权限的目的是什么?
  • 使用第三方提供的服务。有多达16,259个应用声明了JPUSH_MESSAGE权限获取JPush提供的消息推送服务。
  • 限制应用共享数据的访问。例如com.qidian.QDReaderMM定义了权限READ_DB限制e-book数据库的访问。
  • 控制跨App的通信。例如只有有BROADCAST_RECEIVER权限的应用才可以发送的广播给com.tencent.portfolio的广播接收器。

设计

CUPERFUZZER的设计如图2所示,包括5个主要步骤。

/images/2021-06-18/Untitled%202.png

Seed Generation

作者首先生成一个种子应用,定义和请求自定义权限,同时会申请所有dangerous和signature级别的系统权限。自定义权限的定义包含不同属性:1)权限名;2)权限级别;3)权限组。

种子应用会被分裂为两个应用,一个应用请求权限,另一个申请权限。两个应用使用不同的证书进行签名。两种种子模式:single-app mode和dual-app mode

为了避免fuzz时在构建应用上消耗大量时间,作者提前构建了大量的测试应用,测试时进行随机选择安装的应用。

Test Case Construction

应用安装,应用卸载,应用升级,系统升级操作,这四种操作都可能触发系统更新赋权状态,

  • 安装应用可能会导致加入新的自定义权限
  • 卸载应用可能会导致已有自定义权限被删除
  • 升级应用可能使自定义权限更新或删除
  • 系统升级中可能会加入或删除已有的系统权限

其中应用升级操作本质是多次安装不同版本的应用,这里测试只用考虑其他三种操作。

测试过程如图3所示,其中因为目标是检测最新版本的系统问题,所以OS update只能执行一次(Android9到Android10)。

/images/2021-06-18/Untitled%203.png

Test Case Execution

使用adb和fastboot实现设备控制和系统升级,使用PC控制多台测试设备实现并行测试。

Effective Case Checking

使用adb查看测试应用被赋予的权限,检查是否出现以下两种情况:

  • 测试应用在用户不能感知的情况下被赋予了dangerous级别权限。
  • 测试应用被赋予了signature级别的权限,但与权限定义的应用使用不同的证书进行签名。

Critical Path Extraction

对于有效的测试用例,CUPERFUZZER通过以下几步提取关键路径:

1)测试用例分类,每类用例导致同一个权限被赋予。

2)查找关键路径,修剪开始和结束的操作寻找最短路径。

3)删除重复路径。

得到关键路径后进行人工分析。

实现与结果

实验设置

电脑:Windows 10, 4G RAM, Intel Core i5

手机:4部Google Pixel 2

Android系统:Android 9(PQ3A.190801.002)和Android 10 (QQ3A.200705.002)

测试用例:

  1. 一个测试用例只包括5个操作(不计算应用安装)
  2. 由于自定义权限不能与系统权限的权限名相同,作者提前选择了三个权限:
    • android.permission.ACTIVITY_RECOGNITION,新的dangerous级别权限
    • android.permission.MANAGE_APPOPS,新的signature权限
    • com.test.cp,自定义权限名

    2个种子生成模型,3个可用的权限名,3种保护级别,12个权限组,总共有234种情况。

  3. 执行序列:由于有3种保护级别和13种组(12+无),后续的app安装操作可以安装40种(3×13+无自定义权限定义)变异测试app。 如果一个执行序列包含三个应用安装操作(不包括种子应用的安装),则有64,000(40×40×40)个组合,规模较大,所以作者进行了限制:在生成新的测试应用程序时,只能更改与之前安装的测试应用程序不同的一个属性,例如保护级别或组。 在此限制下,变异测试应用的种类变为15种,三种应用安装操作的组合减少到3346种。
  4. CUPERFUZZER 随机选择一个种子应用程序并执行由它生成的测试用例。 重复此过程,直到所有测试用例都已执行或控制器中断测试

结果总结

CUPERFUZZER执行了40,195个测试用例,花费了319.3小时,平均执行一个测试用例花费114.4s。

/images/2021-06-18/Untitled%204.png

最终,CUPERFUZZER发现了2,384测试用例触发了特权提升,包括30条关键路径。

/images/2021-06-18/Untitled%205.png

设计缺陷和攻击

  • DS#1 Dangling custom permission(CVE-2021-0307)

    normal或者signature级别的自定义权限定义在被删除后,申请权限应用权限授予状态不会删除,如果有另一个应用重新定义了这个权限可能会造成特权提升。

    /images/2021-06-18/Untitled%206.png

攻击案例:

app-ds1-d声明权限com.test.cp为normal权限,另一个应用app-ds1-r请求这个权限,同时app-ds1-r申请dangerous权限CALL_PHONE。之后app-ds1-d将自己的权限升级为列表2的dangerous级别,进行重新安装应用后,PMS将com.test.cp加入权限列表,并且app-ds1-r具有这个权限。由于CALL_PHONE和com.test.cp都是PHONE组,app-ds1-r就可以在用户不能感知的情况下获得CALL_PHONE权限。

/images/2021-06-18/Untitled%207.png

  • DS#2 Inconsistent permission-group mapping (CVE-2020-0418)

    system和自定义权限依赖不同的源来获取<permission, group>映射关系,攻击者可以利用不一致从而在用户没有感知的情况下获取dangerous权限。

    /images/2021-06-18/Untitled%208.png

    系统通过查询PLATFORM_PERMISSIONS和PackageManager获取权限的组信息。PLATFORM_PERMISSIONS是在PermissionController里硬编码的<system permission, system group>,没有自定义权限的信息。PackageManager通过系统的AndroidManifest.xml来获取组的映射关系。而在Android 10中这两个映射表存在不一致:AndroidManifest.xml把所有的dangerous系统权限放入了一个特殊的组android.permission-group.UNDEFINED。

攻击案例:

攻击者可以生成一个应用app-ds2申请权限WRITE_EXTERNAL_STORAGE,用户安装并赋予这个权限。攻击者将应用升级,定义并申请权限如列表3。用户升级应用后,该应用会被自动授予所有dangerous系统权限。

/images/2021-06-18/Untitled%209.png

当执行6-10行的时候<permission, group>的映射如列表4,而执行到11行映射会被更新到列表5。因为已经具有android.permission-group.UNDEFINED组的权限WRITE_EXTERNAL_STORAGE,所以会自动获取所有权限。

/images/2021-06-18/Untitled%2010.png

/images/2021-06-18/Untitled%2011.png

  • DS#3 Custom permission elevating(CVE-2021-0306)

    系统在覆盖自定义权限时(更改所有者),权限授予状态没有撤销。对于Android 9中为normal权限的应用如果在Android 10中变成了dangerous应用仍然可以继续使用,不需要动态请求,例如ACTIVITY_RECOGNITION。

    /images/2021-06-18/Untitled%2012.png

  • DS#4: Inconsistent permission definition(CVE-2021-0317)

    在系统初始化的过程中会扫描APK的中申请的权限和对应的级别进行更新。当一个normal或者signature级别的自定义权限被升级为dangerous级别后重启设备,在原始级别下申请权限的应用可以自动获取升级后的权限。

    /images/2021-06-18/Untitled%2013.png

    ## 建议

    1. 如果一个权限发生了变化,相关的授予状态应该撤销。
    2. 系统存储的权限定义应该与权限所有者声明的一致。