PendingIntent重定向:一种针对安卓系统和流行App的通用提权方法——BlackHat EU 2021议题详解 (下)

以用户隐私安全为中心,用责任兑付信任,OPPO成立子午互联网安全实验室(ZIWU Cyber Security Lab)。实验室以“保护用户的安全与隐私,为品牌注入安全基因”为使命,持续关注并发力于业务安全、红蓝对抗、IoT安全、Android安全、数据和隐私保护等领域。

本篇文章源自OPPO子午互联网安全实验室。

1 不安全PendingIntent的通用利用方法

1.1 不安全PendingIntent的特征

至此,我们已经解决了本议题的第一个问题,经过研究表明,Android系统中使用的PendingIntent大都 可以被三方App获取。

获取方式包括bind SliceProvider、监听通知、连接媒体浏览器服务或者bind容纳 窗口小部件的AppWidgetsProvider。

于是,引入议题研究的第二个关键问题:如果这些PendigIntent不安全,如何利用才能造成安全危害?

首先,我们需要辨别什么样的PendingIntent是不安全的。前面描述的公开漏洞案例,均为劫持base Intent为空Intent的广播PendingIntent,说明如下empty base Intent构建的PendingIntent确定存在安全问题。

Android 12之前的开发者文档也对base Intent为隐式Intent的PendingIntent提出了安全警告,但却没 有明确告知到底存在何种危害。而且在AOSP代码和流行App当中,如下的代码模式广泛存在。这不禁让 我们思索, Implicit base Intent构建的PendingIntent是否真正存在问题?唯有找到一种确定的针对这 种PendingIntent的漏洞利用方法,才能真正证明安全问题的存在。

1.2 深入Intent fillIn改写机制

寻找利用方法之前,需要深入探索PendingIntent的改写机制,这决定了其他App获得PendingIntent以 后,如何对base Intent进行改写。这个机制由 Intent.fillIn 函数提供:


在上述代码中,this对象指向当前Intent,other为其他Intent。如果当前Intent中的成员变量为空,则可 以被other中相应的成员变量覆盖。比较特殊的是Intent中的component和selector成员,即使当前Intent中的component和selector为空,也不能被other所改写,除非PendingIntent
设置了FILL_IN_COMPONENT
或者FILL_IN_SELECTOR标志。

1.3 PendingIntent重定向攻击

因此在获取PendingIntent之后,其base Intent的action、category、data、clidpdata、package、flag、extra等成员都是有可能改写的,而component和selector无法改写,如图所示。特别地,对于base Intent为隐式Intent的这种情况,action已经被设置了,因此也无法被改写,攻击者无法如前面安 卓系统broadcastAnyWhere漏洞那样,通过劫持PendingIntent、在base Intent中重新添加action,隐式打开一个受保护的组件。

图 Intent成员

这里就来到了问题解决的关键点,由于package可以指定,回想到以前在Intent Bridge漏洞中的利用方 法,我们可以通过设置intent中的flag来巧妙地解决这个问题。Intent提供了有关临时授权的标志:

  • FLAG_GRANT_READ_URI_PERMISSION:Intent携带此标志时,Intent的接收者将获得Intent所携 带data URI以及clipdata URI中的读权限
  • FLAG_GRANT_WRITE_URI_PERMISSION:Intent携带此标志时,Intent的接收者将获得Intent所携 带data URI以及clipdata URI中的写权限

简言之,恶意App对PendingIntent进行了指向恶意App自己的重定向,通过对PendingIntent base Intent的部分修改(修改包名、授权标志和data/clipdata),使其以受害App的权限打开恶意App自身, 这样恶意App在被打开的瞬间即获得对受害App私有数据的读写权限。具体的利用方法如图所示:

图 PendingIntent重定向攻击

步骤如下:
1、受害App通过getActivity构建PendingIntent,在通知、SliceProvider、窗口小部件中使用,假定其base Intent为隐式Intent;

2、攻击App 通过前面探讨的各种渠道获取受害App的PendingIntent;

3、攻击App修改PendingIntent中的base Intent,由于是隐式Intent,因此action、component和selector都不能修改。但可以做如下修改:

  • 修改data或者clidpdata,使其URI指向受害App的私有ContentProvider;
  • 修改package,指向攻击App;
  • 添加FLAG_GRANT_READ_URI_PERMISSION和FLAG_GRANT_WRITE_URI_PERMISSION 标志。

同时攻击App声明一个Activity支持隐式启动,其Intent-filter与base Intent中的action一致。

4、攻击App调用PendingIntent.send;

5、由于这个PendingIntent代表了受害App的身份和权限,因此将以受害App的名义发送修改后的base Intent,打开攻击App的Activity;

6、在攻击App Activity被打开的瞬间,即被授权访问base Intent中携带的URI,也就获得了对受害App私有ContentProvider的读写权限。

上面受害App的私有ContentProvider,需要携带属性 grantUriPermission=true ,不限于受害App自 己的ContentProvider,也包括受害App有权限访问的ContentProvider。手机上一个常⻅的具有 grantUriPermission=true 属性的ContentProvider就是代表通讯录的Contacts Provider,只要受 害App具有 READ_CONTACTS 权限,出现这样一个PendingIntent漏洞后将导致通讯录泄露。

这样,我们通过上述6个步骤,就可以成功实现对隐式Intent构建PendingIntent的漏洞利用,读写受害App的私有数据,这也就解决了本研究提出的第二个关键问题:通过隐式Intent构建的PendingIntent可遭受通用的重定向提权攻击,也是不安全的。

由于这里使用了grantUri的技巧,因此并不适用于broadcast PendingIntent,因为广播接收器是不可以 被grantUri的。另外,从Android 5.0以后,Service不能隐式启动,因此也很难看到base Intent为隐式Intent的service PendingIntent。所以,这里的PendingIntent重定向攻击主要适用于Activity PendingIntent。

2 安卓系统中的真实案例

令人惊讶的是,在Android 12之前的AOSP代码以及流行App中,隐式Intent构建的ActivityPendingIntent广泛存在,以下是我们发现的典型案例,可能导致手机的敏感信息泄露,甚至以受害app的权限执行任意代码。这些漏洞案例均已被厂商所修复。

图 不安全PendingIntent典型案例

2.1 CVE-2020-0188

不安全的PendingIntent存在于AOSP SettingsSliceProvider中,
一旦SettingsSliceProvider被blind,
在返回的Slice中将携带一个不做任何操作的noOpIntentPendingIntent:

攻击App通过bind SettingsSliceProvider获取PendingIntent,修改base Intent并以Settings的权限发送,等待自己的Activity被打开,就可以实现Settings某些私有Content Provider的读写。如图所示:

图 CVE-202-0188 POC

2.2 CVE-2020-0389

不安全的PendingIntent存在于
AOSP SystemUI RecordingService当中,为用户录屏保存成功后发送的通知所使用。


恶意App可以实现一个NotificiationListener
Service,修改base Intent,将其clipdata指向ContactsProvider :

由于SystemUI具有READ_CONTACTS权限,因此恶意App 被打开时,即可成功读取通讯录。

2.3 A-166126300

不安全的PendingIntent存在AOSP BluetoothMediaBrowserService中

恶意App可以连接BluetoothMediaBrowserService ,通过MediaBrowserCompat.ConnectionCallback 获取PendingIntent。
由于BluetoothMediaBrowserService存在于具有通讯录权限Bluetooth应用中,因此通过PendingIntent重定向攻击可读取通讯录

2.4 某流行App

某具有通讯录权限的流行App实现了窗口小部件,用户点击窗口小部件的按钮实现跳转,但这个跳转是通过隐式Intent构建PendingIntent实现的。

对窗口小部件所属的AppWidgetProvider进行bind,通过反射逐次获取 RemoteViews->mActions->mResponse->mPendingIntent ,最终可以拿到上述不安全的PendingIntent,进而如法炮制,读取通讯录。

2.5 CVE-2020-0294

这些不安全的PendingIntent存在安卓系统服务中,对于某些bind服务,系统提供了PendingIntent,跳转到服务的管理界面。

这些PendingIntent可以直接通过系统APIActivityManager.getRunningServiceControlPanel 获得,后面进行PendingIntent重定向,读取Settings中的保护ContentProvider。

2.6 危害

上述多个案例均可造成通讯录这类个人敏感信息泄露,但实际上,由于PendingIntent重定向攻击还具有写数据的能力,因此可能造成更大的危害。

例如,很多App都具有热更新功能,一般将dex/jar/apk/so等文件放在自己的私有目录中,如果这些私有目录可以被 grantUriPermission=true 的ContentProvider所引用,就可以利用PendingIntent重定向攻击去改写热更新文件,将攻击者自己的代码注入到其中,实现以受害App的权限执行任意代码。

对于CVE-2020-0188和CVE-2020-0294这类源于系统uid的PendingIntent,由于在UriGrantsManagerService当中进行了限制,因此在原生系统中的危害很有限,只能读取特定的几个Content Provider。

但是由于Android系统的定制化,上述限制可能在OEM厂商中被打破,造成更大的危害。

Google对安卓系统中这类漏洞的修复,起初是将base Intent设置为显式Intent,指定明确的组件。后来均使用FLAG_IMMUTABLE修复,当使用这个flag时,PendingIntent的base Intent将无法通过Intent.fillIn 函数改写,例如

3 自动化分析

基于对不安全PendingIntent特征的掌握,我们编写了一个自动化扫描工具PendingIntentScan,该工具基于Soot[4]这一Java静态分析框架对apk进行数据流静态分析,其体系结构如图所示。

图 PendingIntentScan原理

首先,使用Soot将apk的字节码转换为Jimple形式的IR,然后搜寻一系列生成PendingIntent的API,并挑选出没有使用FLAG_IMMUTABLE的:

然后,通过Soot提供的ForwardFlowAnalysis对PendingIntent的Intent参数进行检查,查看是否调用下列函数。如果都没有使用,则认为PendingIntent是不安全的:

这个工具目前开源在
https://github.com/h0rd7/Pend...,可以迅速发现apk中存在的不安全PendingIntent,效果如下。

4 安卓12安全变更

针对我们的研究成果,Google 安卓安全团队对AOSP代码进行了全面排查,几乎修复了所有的不安全PendingIntent。大部分的修复使用了PendingIntent.FLAG_IMMUTABLE,小部分的修复将base Intent设置为显式Intent。

而在Android 12大版本中,安卓系统对PendingIntent的行为进行了重大安全变更,引入了一个新的flag:PendingIntent.FLAG_MUTABLE,表示base Intent可以改写。这与原有的FLAG_IMMUTABLE共同描述PendingIntent 的可变性。

对于Target S+的App,Android系统要求开发者必须明确指定PendingIntent的可变性,FLAG_IMMUTABLE和FLAG_MUTABLE必须使用其一,否则系统会抛出异常。这就要求开发者对自己PendingIntent的使用有清晰的理解,知道PendingIntent是否会在将来被改写。

Google也对开发者提出了详细的安全编码建议:

  • 尽可能使用FLAG_IMMUTABLE来生成不可改写的PendingIntent;
  • 如果使用FLAG_MUTABLE来生成可改写的PendingIntent,base Intent一定要使用显式Intent,明确指定Intent的组件。

同时AndroidStuido IDE中也引入了一个新的lint检查插件PendingIntentMutableFlagDetector,用于检查PendingIntent是否使用了FLAG_IMMUTABLE。

5 结论

本议题解决了PendingIntent的获取问题,明确了不安全PendingIntent的特征,提出了有关不安全PendingIntent的重定向攻击利用方法,从而揭示了安卓系统和流行app有关PendingIntent使用的一种通用安全⻛险。Google针对议题描述的漏洞均已进行了修复,并在Android 12中引入了缓解此问题的重大安全变更,对开发者提出了详细的安全编码建议。

开发者在使用FLAG_IMMUTABLE构建PendingIntent时应格外小心,除了要使用显式Intent以外,还要保证 base Intent其他没有填充的字段不会造成安全影响。例如下面存在问题的代码源于一个真实app的案例。这个PendingIntent 已经设置了显式Intent,在通知中使用,用于启动内部不导出的MainActivity

在MainActivity中,
可以对EXTRA_REDIRECT_INTENT 进行处理,最后调用startActivity:

这样,劫持PendingIntent仍然可以设置EXTRA_REDIRECT_INTENT,通过startActivity去打开应用的任意保护组件。

因此,每一个没有使用FLAG_IMMUTABLE的PendingIntent均应该仔细审查,这是我们对开发者的最后安全忠告。

6、参考

[1]http://retme.net/index.php/20...

[2]https://www.slideshare.net/Ca...

[3]https://mp.weixin.qq.com/s/SA...

[4] http://soot-oss.github.io/soot/

[5]https://developer.android.com...

作者简介

heeeeen 安全架构师

毕业于北京航空航天大学,现工作于OPPO子午互联网安全实验室,擅长Android框架与APP漏洞挖掘,多次获得Google安全致谢

获取更多精彩内容,请扫码关注[OPPO数智技术]公众号


OPPO数智技术
OPPO前沿互联网技术及活动分享,公众号:OPPO_tech
604 声望
943 粉丝
0 条评论
推荐阅读
OPPO云数据库访问服务技术揭秘
MySQL是OPPO使用最广泛的关系数据库,不同编程语言的微服务都是通过MySQL官方的SDK直连真实的数据库实例。这种最传统的使用方式,会给业务开发和数据库运维带来一系列影响效率和稳定性的问题。

OPPO数智技术1阅读 924

http 和 https 的通信过程及区别
🎈 两者的区别端口: http 端口号是80, https 端口号是443传输协议: http 是超文本传输协议,属于明文传输; https 是安全的超文本传输协议,是经过 SSL 加密后的传输协议安全性: https 使用了 TLS/SSL 加密,...

tiny极客2阅读 2.8k评论 2

封面图
JWT 登录认证
🎈 Token 认证流程作为目前最流行的跨域认证解决方案,JWT(JSON Web Token) 深受开发者的喜爱,主要流程如下:客户端发送账号和密码请求登录服务端收到请求,验证账号密码是否通过验证成功后,服务端会生成唯一...

tiny极客2阅读 939评论 1

封面图
支付对接常用的加密方式介绍以及java代码实现
加密解密密钥是相同的。这些算法也叫秘密密钥算法或单密钥算法,它要求发送者和接收者在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都能对消息进行加密解密。只要通信需要...

京东云开发者3阅读 424

封面图
ctf(pwn&reverse)总结
F5/tab 查看伪代码空格 查看汇编代码视图->打开子视图->字符串 :查看所有字符串编辑->修补程序 :修改程序 修改完后点击修补程序应用到输入文件即可保存修改

白风之下阅读 2.8k

什么是跨域?如何解决跨域?
跨域: 它是由浏览器的 同源策略 造成的,是浏览器对 JavaScript 实施的安全限制,所谓同源(即指在同一个域)就是两个页面具有相同的协议 protocol,主机 host 和端口号 port 则就会造成 跨域

tiny极客1阅读 789评论 1

封面图
隐私计算之多方安全计算(MPC,Secure Multi-Party Computation)
如今,组织在收集、存储敏感的个人信息以及在外部环境(例如云​​)中处理、共享个人信息时, 越来越关注数据安全。这是遵守隐私法规的强需求:例如美国加利福尼亚州消费者隐私法 (CCPA)、欧盟通用数据保护条例 (G...

京东云开发者阅读 1k

封面图
604 声望
943 粉丝
宣传栏