《PIAnalyzer: A Precise Approach for PendingIntent Vulnerability Analysis》
来源:ESORICS 2018 (CCF B)
关键词:Android, PendingIntent, Information flow control, Static analysis
摘要:
本文总结归纳了不安全的PendingIntent的相关攻击,并对其进行静态检测。
1.针对问题:
不安全的PendingIntent使用会导致拒绝服务、identity窃取和提权(获取系统权限以删除设备上的用户数据)等攻击,文章是第一个静态检测不安全的PendingIntent的。
PendingIntent:PendingIntent是Android组件间通信的一个特征。PendingIntent主要用来在某个事件完成后执行特定的Action。它持有一个base intent(已定义action),由另一个应用程序执行,而却拥有原app的权限和identity。此时原app进程不一定在运行,但是PendingIntent运行起来就好像是原app在运行一样。
PendingIntent与Intent之间的区别:PendingIntent就是一个可以在特定事件触发后执行的Intent,运行在新的task中,它相比于Intent的优势在于自己携带有Context对象,这样它就不必依赖于某个activity和原进程才可以存在。
PendingIntent应用场景:PendingIntent一般用于设置闹铃或者通知栏提醒。比如,一个应用想要在未来的某个时间点得到系统的通知,它就将自己创建的一个PendingIntent发送给Notification Manager,之后Notification Manager会触发该PendingIntent,使得一个预先定义好的组件可以得到通知和执行。
安全问题:隐式Intent可以被接受端app更改到任意组件上,并且拥有原app的权限,则会导致在原app的context中任意代码执行。
2.Contribution
(1) PendingIntent分析(PIAnalyzer工具):基于程序切片检测PendingIntent相关不安全代码
(2) PIAnalyzer评估及其有效性:发现了至少435个app在PendingIntent中包裹了至少一个隐式base intent,找到了1358个PendingIntent的不安全使用,包括70个严重的漏洞。平均一个app 13秒
3.Motivation
前提:原app有打电话的权限,而恶意app没有。
Listing 1.3中,任意一个定义了相应Intent filter的app都可以接受Listing 1.2中的implicitWrappingIntent,提取出PendingIntent并控制base intent,使其向收费短信发送短信。
(1) 钓鱼攻击:如果PendingIntent包裹的base intent是隐式的,那么定义了相应intent filter的多个app都可以接收,这就需要用户选择一个app来接收。这种场景就可能被钓鱼app利用。
(2) 拒绝服务攻击:一般地,PendingIntent并不会被wrapping intent包裹起来,而是直接传递到系统组件中,这些组件会调用PendingIntent的send方法来触发base intent。恶意app可以注册一个组件来接收这个base intent执行拒绝服务攻击(这些Intent就不会被传递到目标组件中)
(3) 提权攻击:(Android 4所有版本都存在这个攻击,原因是在PendingIntent中使用了隐式base intent)
Listing 1.4是 Android源码中addAccount的代码,一旦有app添加账户就会调用这里的addAccount函数,mPendingIntent会返回给注册了相应action的app,而这个app就可以在Android Setting的context下重写空的base intent,从而执行恶意行为。
恶意应用请求添加账户类型,Android Setting 一旦接收到这个intent,就会执行addAccount函数,返回vulnerable PendingIntent。Listing 1.6是恶意应用的一个Activity,由于恶意软件注册成为AccountAuthenticator,所以接收到这个PendingIntent。随后,在第3行,它创建了一个vunlnintent来执行恢复出厂设置的操作,在第5行用vunlnintent作为更新后的base intent来触发PendingIntent,手机恢复出厂设置。
4.检测方法——PIAnalyzer
从smali代码中,采用程序切片方法寻找相关的不安全代码
(1)提取PendingIntent
寻找包裹base intent的函数:getActivity,getActivities,getBroadcast,getService。
(2)分析base intent
使用后向切片来找到base intent,并确定其是隐式的还是显式的,这篇文章只关注隐式base intent。
注:有6个函数可以使隐式intent变成显式的,setClass(), setClassName(), setComponent(), setPackage() and setSelector()
(3)分析PendingIntent
使用前向切片来寻找PendingIntent的使用方式:发送到系统组件中还是被包裹成另外一个intent。由于系统组件不会执行攻击,因此主要关注wrappingIntent
(4)wrappingIntent分析
使用后向切片来分析这个wrappingIntent是否是隐式的
(5)生成调用图
intent的整个调用链
(6)报告:有三种安全级别
secure: pendingIntent + 显式base intent
warning: pendingIntent + 隐式base intent + 发送给系统组件
vulnerablity: pendingIntent + 隐式base intent + 隐式wrappingIntent
5.Evaluation
数据集:Google Play上任选1000个应用
发现:435个app在PendingIntent中包裹了至少一个隐式base intent,找到了1358个PendingIntent的不安全使用,包括70个严重的漏洞。平均一个app 13秒。80%的 vulnerabilities和98%的warnings发生在第三方库中。
这些app申请权限的情况:279危险权限和273个普通权限
检查精确性:手工检查70中的10个,9个可以精确检查出来
6.Limitation
静态分析的固有缺陷:无法检测反射、naive层以及运行时决定Intent是显式还是隐式的