
0x01 关于组件
Android开发四大组件分别是:活动(Activity):用于表现功能
服务(Service):后台运行服务,不提供界面呈现
广播接收器(BroadcastReceiver):用于接收广播
内容提供商(ContentProvider):支持在多个应用中存储和读取数据,相当于数据库
外链:详细讲解
在Android应用中,多一个组件暴露,就多一个攻击面。而攻击者就可以围绕这些攻击面进行测试,构造多种攻击手段。
0x02 exported属性
在AndroidManifest.xml文件中,四大组件都有android:exported属性,是个boolean值,可以为true或false
这里有个值得注意的点默认值以有无intent-filter的action属性来决定,有则为true,没有则为false
0x03 实例
1、最常见的莫过于本地拒绝服务漏洞
,四大组件都存在这个问题
Android应用本地拒绝服务漏洞源于程序没有对Intent.getXXXExtra()获取的异常或者畸形数据处理时没有进行异常捕获,从而导致攻击者可通过向受害者应用发送此类空数据、异常或者畸形数据来达到使该应用crash的目的,简单的说就是攻击者通过intent发送空数据、异常或畸形数据给受害者应用,导致其崩溃
例如导出的Broadcast Receiver组件可以被第三方APP任意调用,如果再没有对消息进行验证,就可能导致敏感信息泄露,并可能受到权限绕过、拒绝服务等攻击风险
e.g. 某手机管家com.tencent.qqpimsecure.service.InOutCallReceiver广播组件没有对消息进行校验,传入空消息导致NullPointerException异常
POC:
1 | Intent i = new Intent(); |
2、绕过本地认证
私有Activity不应被其他应用启动相对是安全的(只是相对的)
公开暴露的Activity组件,可以被任意应用启动
e.g. 某菊花网盘绕过本地密码
非root的话直接启动其他activity即可绕过认证,本地认证只是简单topActivity
1 | public void activityStart(View v) { |
e.g. 控制MIUI的手电筒开关(有趣的案例)
MIUI内置的手电筒软件Stk.apk中,TorchService服务没有对广播来源进行验证,导致任何程序可以调用这个服务,打开或关闭手电筒
1 | Intent intent = new Intent(); |
3、伪造消息代码执行
广播接收器没有对消息进行安全验证,通过发送恶意的消息,攻击者可以在用户手机通知栏上推送任意消息,点击消息后可以利用webview组件盗取本地隐私文件和执行任意代码
e.g. 某搜索引擎云盘
1 | Intent i = new Intent(); |
e.g. 优酷Android 4.5客户端升级漏洞
com.youku.service.push.StartActivityService组件从Intent从获取名为PushMsg的Serializable的数据,并根据其成员type来执行不同的流程,当type值为1时,执行App的升级操作。升级所需的相关数据如app的下载地址等也是从该序列化数据中获取。升级的具体流程在com.youku.ui.activity.UpdateActivity中,简单分析后发现升级过程未对下载地址等进行判断,因此可以任意指定该地址
POC
1 | PushMsg pushMsg = new PushMsg(); |
4、敏感信息泄漏
e.g. 某应用隐式intent发送敏感信息
缺陷代码
1 | public class ServerService extends Service { |
POC
1 | public class BcReceiv extends BroadcastReceiver { |
5、提升权限
e.g. 某系统清理工具
暴露了com.cleanmaster.appwidget.WidgetService服务组件,当向此服务发送action为com.cleanmaster.appwidget.ACTION_FASTCLEAN的intent时,便可结束后台运行的一些app进程
6、Content Provider 暴露泄露敏感信息
Content Provider 用来存放和获取数据并使这些数据可以被所有的应用程序访问,是应用程序之间共享数据的唯一方法
e.g. 一只眼app应用本地信息泄露
任意Android程序不需要任何权限就能获取本机一支眼app的所有数据,包括账号、私信聊天记录
查看聊天记录POC
1 | public void getChatMsg() { |
7、任意文件读取漏洞
e.g. 某客户端Content Provider组件任意文件读取漏洞
某客户端APP的实现中定义了一个可以访问本地文件的Content Provider组件,默认的android:exported=”true”,对应com.ganji.android.jobs.html5.LocalFileContentProvider,该Provider实现了openFile()接口,通过此接口可以访问内部存储app_webview目录下的数据,由于后台未能对目标文件地址进行有效判断,可以通过”../“实现目录跨越,实现对任意私有数据的访问
POC
1 | public void GJContentProviderFileOperations(){ |
8、启动私有组件(这就是前边提到的,私有组件也仅仅是相对安全的)
存在一个私有组件A,和一个对外导出组件B。如果B能够根据对外传入的Intent中的内容打开私有组件A,同时启动私有组件A的Intent的内容来自启动导出组件B的Intent的内容,那么攻击者就可以通过对外导出组件B,去控制私有导出组件A。这就可能会造成严重的安全风险
这里详细的看下聚安全的这篇paper
其实还有很多没有列出,如UXSS、界面劫持、services劫持等等
0x04 简单自测
1、反编译APK或直接查看源代码
查看AndroidManifest.xml文件,查看哪些组件是导出的,仔细check是否需要导出,需要导出的是否都已做了相应的安全限制
2、drozer扫描
run app.activity.info -a packagename
0x05 防患于未然
1、能不导出组件的坚决不导出
2、必须导出的组件仔细check限制策略是否到位
3、检查该组件能不能根据该组件的intent去启动其他私有组件
4、如果能启动私有组件,根据业务严格控制过滤和校验intent中的内容,同时被启动的私有组件需要做好各种安全防范
关于漏洞例子:本来想用最近遇到的问题来做实例,但考虑到漏洞的敏感性,找的是网上公开的漏洞
- Post title:Android组件暴露的安全性
- Post author:langu_xyz
- Create time:2017-06-19 21:00:00
- Post link:https://blog.langu.xyz/Android组件暴露的安全性/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.