最近了项目中遇到一个Android应用本地拒绝服务漏洞的问题,第一眼看到这个玩意,我去,什么东东?
请教了下万能的度娘亲,才知道是应用本身组件对外性的一个问题。先简单说下这个漏洞。
下面漏洞介绍摘自阿里聚安全, 详见: http://jaq.alibaba.com/blog.htm?id=55 (网站已停止运营)
1.本地拒绝服务漏洞描述
Android系统提供了Activity、Service和Broadcast Receiver等组件,并提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android系统则根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用[1]。Android应用本地拒绝服务漏洞源于程序没有对Intent.getXXXExtra()获取的异常或者畸形数据处理时没有进行异常捕获,从而导致攻击者可通过向受害者应用发送此类空数据、异常或者畸形数据来达到使该应用crash的目的,简单的说就是攻击者通过intent发送空数据、异常或畸形数据给受害者应用,导致其崩溃。
近期,两位0xr0ot和Xbalien安全研究人员发现了一处通用的本地拒绝服务漏洞。该通用型本地拒绝服务可以造成大面积的app拒绝服务[2]。通用型本地拒绝服务漏洞,主要源于攻击者向Intent中传入其自定义的序列化类对象,当调用组件收到此Extra序列化类对象时,无法找到此序列化类对象的类定义,因此发生类未定义的异常而导致应用崩溃。
本地拒绝服务漏洞不仅可以导致安全防护等应用的防护功能被绕过或失效(如杀毒应用、安全卫士、防盗锁屏等),而且也可被竞争方应用利用来攻击,使得自己的应用崩溃,造成不同程度的经济利益损失。
2. 本地拒绝服务漏洞影响范围
Android系统所有版本
3. 本地拒绝服务漏洞详情
1) 漏洞位置:
处理getIntent()的intent附带的数据
2) 漏洞触发前提条件:
getIntent()的intent附带空数据、异常或畸形数据;
处理getXXXExtra()获取的数据时没有进行异常捕获;
3) 漏洞原理:
Android系统中提供了Intent机制来协助应用间的交互与通讯,其负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,系统则根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用。调用的组件在处理Intent附加数据的时候,没有进行异常捕获,因此当处理空数据、异常或者畸形数据时,导致应用崩溃。
4. 本地拒绝服务漏洞POC
略过......
5. 本地拒绝服务漏洞修复建议
1. 阿里聚安全建议将不必要的导出的组件设置为不导出
出于安全考虑,阿里聚安全应将不必要的组件导出,防止引起拒绝服务,尤其是杀毒、安全防护、锁屏防盗等安全应用; 在AndroidMenifest.xml文件中,将相应组件的“android:exported”属性设置为“false”,如下示例:
<activity android:name="MyActivity"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action_TEST"/>
</intent-filter>
</activity>
2. 阿里聚安全建议intent处理数据时进行捕获异常
阿里聚安全建议处理通过Intent.getXXXExtra()获取的数据时进行以下判断,以及用try catch方式进行捕获所有异常,以防止应用出现拒绝服务漏洞:
1) 空指针异常;
2) 类型转换异常;
3) 数组越界访问异常;
4) 类未定义异常;
5) 其他异常;
其实简单看来就是外部应用通过广播啊,服务啊或者是Activity 调用本应用内的相关组件存在的崩溃,攻击等安全漏洞。
这里对于给出的解决两种解决方案也都不错。
确实都可以解决问题,看到这里的时候也才知道原来组件中还有android:exported 这个属性。
查看一下相关的资料,学习下这个属性的作用呗。
这个属性是属于Android 四大组件的一个属性,四个组件中的解释大同小异,就是负责管理该组件是否可以被其他应用调用。如下截图:
从这里的解释可以看到,正常情况下这个值都是默认false的,只有当组件的注册内容中包含intent-filter的时候默认值会是true。
这里有一个特殊的情况:就是provider的默认值情况。如下图:
如果minsdkVersion 或者 targetSdkVersion 是16或者16以下的版本,Provider的exported 默认值是true,其他情况下是false。
如果是使用Provider的话,这个情况需要注意一下。
了解到这个属性,其实对于这个Android应用本地拒绝服务漏洞的出现有了大概的了解。
检查一下Manifest.xml文件中注册的四大组件,对于正常组件不需要去刻意添加exported = false,默认值就是false。
找一下包含intent-filter的组件,如果不是必须要暴露给其他应用的组件,那么就使用提供的第一套方案,把这个exported = false的属性加上吧。
当然如果是有需求必须要暴露给其他应用去调用的,选择下第二套方案,在进行相关数据获取的时候,try catch下,对异常数据进行修正处理,防止程序的崩溃问题。
还有,提醒一句,别在应用的桌面启动页加这句哦,,,我试了试,如果在启动页加上这个属性false,点击桌面图标的时候直接导致android 认为你没有安装这个apk。。。
另外在系统级的广播注册中添加了exported = false 属性并没有影响其接受系统广播,不知道是因为same user ID 还是别的,有时间的时候会再测试下。