APP漏洞扫描器之本地拒绝服务检测详解

APP漏洞扫描器之本地拒绝服务检测详解


作者:伊樵@阿里聚安全


阿里聚安全的Android应用漏洞扫描器有一个检测项是本地拒绝服务漏洞的检测,采用的是静态分析加动态模糊测试的方法来检测,检测结果准确全面。本文将讲一下应用漏洞扫描器在针对本地拒绝服务的检测方法。

一、本地拒绝服务产生原因和影响

Android应用使用Intent机制在组件之间传递数据,如果应用在使用getIntent(),getAction(),Intent.getXXXExtra()获取到空数据、异常或者畸形数据时没有进行异常捕获,应用就会发生Crash,应用不可使用(本地拒绝服务)。恶意应用可通过向受害者应用发送此类空数据、异常或者畸形数据从而使应用产生本地拒绝服务。

阿里聚安全的博客以前有一篇文章《Android应用本地拒绝服务漏洞浅析》,里面详细讲了产生本地拒绝服务的四种情况:

    1、NullPointerException空数据异常:应用程序没有对getAction()等获取到的数据进行空指针判断,从而导致空指针异常而导致应用崩溃。

    2、ClassCastException类型转换异常:程序没有对getSerializableExtra()等获取到的数据进行类型判断而进行强制类型转换,从而导致类型转换异常而导致应用崩溃。

    3、IndexOutOfBoundsException数组越界异常:程序没有对getIntegerArrayListExtra()等获取到的数据数组元素大小的判断,从而导致数组访问越界而导致应用崩溃。

    4、ClassNotFoundException异常:程序没有无法找到从getSerializableExtra ()获取到的序列化类对象的类定义,因此发生类未定义的异常而导致应用崩溃。

当应用被恶意应用攻击时,本地拒绝服务一般会导致正在运行的应用崩溃,首先影响用户体验,其次影响到后台的Crash统计数据,另外比较严重的后果是应用如果是系统级的软件,可能导致手机重启。Nexus 5曾经出现过这样的情况,它预装了一个用来测试网络连通性的系统应用,这个应用是隐藏状态,无法在桌面上打开,包名为com.lge.SprintHiddenMenu。在Android 4.4.3之前的版本里,这个应用里有大量导出的activity,这些 activity不需要任何权限就可以被外部调用。其中一个为com.lge.SprintHiddenMenu.sprintspec.SCRTN的组件是导出的,并且没有任何权限限制,给它发送一个空Intent,可导致Nexus 5手机重启。

二、阿里聚安全扫描器的进化提升

一个简单的本地拒绝服务类漏洞,要想进行大规模的自动化扫描,扫描器也要做不少的工作,并且随着对本地拒绝服务漏洞的认识,阿里聚安全的漏洞扫描器也在不断进行优化提高。

2.1 空Intent阶段

这个阶段的扫描器是初级阶段,一般只是通过AndroidManifest.xml文件获取应用导出的组件,然后使用adb命令发送空intent给导出组件,捕获应用日志输出,查看是否有崩溃产生。

针对空Intent导致的本地拒绝服务情况可发送如下命令测试:

adb shell am start -n com.jaq.dosappsample/.DosActivity 
adb shell am startservice -n com.jaq.dosappsample/.DosService 
adb shell am broadcast -n com.jaq.dosappsample/.DosReceiver

何为导出的组件?

在AndroidManifest.xml文件中如果应用的组件android:exported属性显式指定为“true”,或者并没有显式指定为“true”也没有显式指定为“false”,什么也没有写,但是有intent-filter并指定了相应的Action,则此组件为导出的组件。

2.2 解析Key值阶段

空Intent导致的拒绝服务毕竟只是一部分,还有类型转换异常、数组越界异常等导致的本地拒绝服务。在解析Key值阶段扫描器需要分析组件代码中是否使用了一些关键函数。

在Activity组件中的onCreate()方法中,Service组件中的onBind()和onStartCommand()方法中,BroadcastReceiver组件的onReceive()方法中,如果组件没有做好权限控制,都可接受任意外部应用传过来的Intent,通过查找getIntent()、getAction()和getXXExtra()这些关键函数,检测其是否有try catch异常保护,如果没有则会有本地拒绝服务风险。

在这一阶段扫描器遇到的挑战是找到这些关键函数中的Key值,Action值,不仅要找到,还要找到key对应的类型,来组装adb命令,发送命令给安装好的应用进行测试。

2.3 通用型拒绝服务阶段

2015年年初的时候,业界又爆出了通用型拒绝服务,由于应用中使用了getSerializableExtra() 的API,应用开发者没有对传入的数据做异常判断,恶意应用可以通过传入序列化数据,导致应用本地拒绝服务。此种方法传入的key值不管是否与漏洞应用相同,都会抛出类未定义的异常,相比解析Key值阶段通用性大大得到了提高。

针对这个常用的手工检测POC代码如下:

此阶段扫描器遇到的难题是无法直接通过adb命令进行测试,因为无法用adb命令传递序列化对象给应用。业界大部分漏洞扫描器也因为无法发送序列化对象给应用都止步解析Key值组装adb命令阶段,而阿里聚安全的漏洞扫描器能够发送序列化对象数据给指定的应用,再结合静态分析查找导出的组件和关键函数,动态运行应用,精确识别出会发生本地拒绝服务的应用组件,同时实现了大规模自动化测试。

2.4 动态注册BroadcastReceiver阶段

BroadcastReceiver组件一般分为两种,一种是静态注册,提前在AndroidManifest.xml声明组件;另外一种是动态注册,在代码中使用registerReceiver()方法注册BroadcastReceiver,只有当registerReceiver()的代码执行到了才进行注册。

动态注册BroadcastReceiver的常见使用方法如下:

很多开发者没有意识到,如上使用registerReceiver()方法注册的是全局BroadcastReceiver,和静态注册BroadcastReceiver android:exported属性为true性质一样,如果没有指定权限访问控制(permission参数),可以被任意外部应用访问,向其传递Intent,根据具体情况产生的危害可能不同,一种比较普遍的情况是容易产生本地拒绝服务漏洞。

动态注册BroadcastReceiver导致导出的Receiver这种情况非常少被大家注意,现有的一些安全检测工具、扫描器都不能发现动态注册的BroadcastReceiver。在此阶段,动态注册BroadcastReceiver隐藏在所有代码中,在应用的任何地方都可能出现,需要扫描器全局分析应用的代码找出关键函数registerReceiver,还要找出其IntentFilter所设置的Action和Receiver的权限设置,现在一般一个普通的正常Android应用都有几十M的大小,反编译成smali代码会更多,扫描器遇到的挑战主要是查找的时间和空间挑战,还有多个参数查找的准确性。目前业界只有阿里聚安全的扫描器有准确扫描动态注册BroadcastReceiver导致的本地拒绝服务的能力。

通过阿里聚安全的漏洞扫描器对一些样本进行了检测,也发现了不少动态注册BroadcastReceiver导致的本地拒绝服务攻击。

三、本地拒绝服务漏洞现状

为了了解本地拒绝服务漏洞的现状,阿里聚安全的应用漏洞扫描器针对国内外的各行业主要APP进行了扫描,共扫描了三百多款APP。

国内行业主要是通过采集国内某应用市场的APP,我们采集了各个行业的TOP APP总共有151个,发现拒绝服务漏洞的总个数为970个,平均个数为6.4个,其中影音播放类的APP本地拒绝服务个数最多,健康类安全类和运营商类比较少、游戏类的最少。

国内行业APP本地拒绝服务漏洞情况:

柱状图是国内各个行业APP按本地拒绝服务漏洞平均个数排序:

下图是各个组件引起的本地拒绝服务的数量、占比情况:

国内行业动态注册BroadcastReceiver导致的本地拒绝服务漏洞有247个,约占拒绝服务漏洞总数的25%,比静态注册BroadcastReceiver的要多不少:

国外行业主要是通过采集Google Play上的APP,我们也采集了各个行业的TOP APP总共有177个,发现拒绝服务漏洞的总个数是649个,平均漏洞个数为3.7个,平均漏洞个数最多的是办公类应用,最少的和国内行业一样是游戏。

国外行业APP本地拒绝服务漏洞情况:

国外各个行业的应用本地拒绝服务漏洞平均个数排序:

各个组件引起的本地拒绝服务的数量、占比情况:

国外行业动态注册BroadcastReceiver导致的本地拒绝服务漏洞有147个,约占拒绝服务漏洞总数的23%,比国内的情况略少,可见动态注册BroadcastReceiver导致的本地拒绝服务都没有引起大家的重视。

总体上来看,本地拒绝服务风险因为具有Android版本无关性,漏洞本身对APP影响也不大,只与应用开发者是否注意、重视有关,所以现在还经常在应用中出现。在各大厂商的安全应急响应中心评级为低危漏洞,也有厂商不收此类漏洞,但是这些攻击面依然存在,如果深入分析这些组件,有的不仅仅是引发本地拒绝服务风险,必须遵循最小权限原则,没有必要导出的组件不要导出。

四、阿里聚安全对开发者建议

(1)阿里聚安全的漏洞扫描器已经具备覆盖动态注册Receiver产生的拒绝服务漏洞(目前,还没发现友商的漏洞扫描器有这样的能力),使用阿里聚安全的漏洞扫描器进行扫描,可及时发现这些漏洞。 

(2)不必要导出的组件将其exported属性显式的设为“false”,这样可以减少应用的攻击面。 

(3)导出的组件在getIntent()后,Intent.getXXXExtra()时用try…catch做好异常处理。 

(4)在导出的组件设置好权限控制,不让任意第三方应用访问。 

(5)对于动态注册的BroadcastReceiver,尽量少用registerReceiver()方法,如果只在本应用内通信,改用LocalBroadcastManager的registerReceiver()进行本地注册,如果必须导出给外部应用,在使用registerReceiver()时要指定好相应的访问权限。

五、参考

1、Android APP通用型拒绝服务漏洞分析报告,http://blogs.360.cn/blog/android-app%E9%80%9A%E7%94%A8%E5%9E%8B%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E6%8A%A5%E5%91%8A/ 

2、 Android应用本地拒绝服务漏洞浅析,https://jaq.alibaba.com/blog.htm?id=55 

3、https://developer.android.com/guide/components/activities.html 

4、https://developer.android.com/guide/components/services.html 

5、https://developer.android.com/reference/android/content/Context.html 

6、https://labs.mwrinfosecurity.com/advisories/2014/11/05/nexus-5-4-4-2-local-dos/

作者:伊樵@阿里聚安全,更多Android、iOS安全文章,请访问阿里聚安全官网

时间: 2025-01-20 13:39:23

APP漏洞扫描器之本地拒绝服务检测详解的相关文章

APP漏洞扫描器之未使用地址空间随机化

APP漏洞扫描用地址空间随机化 前言 我们在前文<APP漏洞扫描器之本地拒绝服务检测详解>了解到阿里聚安全漏洞扫描器有一项静态分析加动态模糊测试的方法来检测的功能,并详细的介绍了它在针对本地拒绝服务的检测方法. 同时,阿里聚漏洞扫描器有一个检测项叫未使用地址空间随机化技术, 该检测项会分析APP中包含的ELF文件判断它们是否使用了该项技术.如果APP中存在该项漏洞则会降低缓冲区溢出攻击的门槛. 本文主要介绍该项技术的原理和扫描器的检测方法.由于PIE的实现细节较复杂,本文只是介绍了大致的原理.

Vue.js中数组变动的检测详解_javascript技巧

前言 最近在尝试用Vue.js重构公司的现有业务代码,组件化的设计思路和MVVM的思想让我深深沉迷于其中.但是是踩到了不少坑,就比如这篇文章介绍的数组绑定后的更新检测. 相信大家都知道Observer,Watcher,vm 可谓 Vue 中比较重要的部分,检测数据变动后视图更新的重要环节.在 vue.js中$watch的用法示例 中,我们讨论了如何实现基本的 watch . 接下来,我们来看看如何实现数组变动检测. 例子: // 创建 vm let vm = new Vue({ data: {

视频播放器之————JW Player参数详解

JW Player参数详解 1,安装 下载后,你可以得到一个例子,当用文本或HTML编辑器打开的时候,你可以发现swf是用一段短小的 javascript嵌入到页面上的.这个Javascript是Geoff Stearns写的swfobject.js,它解决了Flash需要激 活的麻烦.当复制swf到你的站点的时候,不要忘记了把swfobject.js一同复制过去.并且在页面中的 Head中加入下面代码 程序代码 <script type="text/javascript" sr

HTML5 LocalStorage 本地存储原理详解

  说到Web开发中的本地存储,大家最先想到的应该就是Cookies这玩意了,最早的Cookies自然是大家都知道,问题主要就是太小,大概也就4KB的样子,而且IE6只支持每个域名20个cookies,太少了.优势就是大家都支持,而且支持得还蛮好.很早以前那些禁用cookies的用户也都慢慢的不存在了,就好像以前禁用ja vasc ript的用户不存在了一样. userData是IE的东西,垃圾.现在用的最多的是Flash吧,空间是Cookie的25倍,基本够用.再之后Google推出了Gear

android 浏览器之多窗口方案详解

android 浏览器之多窗口方案详细介绍,需要的朋友可以过来参考下   我们Android平台是一个又一个的Activity组成的,每一个Activity有一个或者多个View构成. 所以说,当我们想显示 一个界面的时候,我们首先想到的是建立一个Activity,然后所有的操作在Activity里面实现,或者是一个Dialog或者Toast.这种方 式固然简单,但是在有些情况下,我们要求的只是简单的显示,用Activity显然是多余,这个时候,我们如何处理呢? Android的一个应用在底层也

ThinkPHP3.1新特性之字段合法性检测详解_php实例

ThinkPHP3.1版增加了表单提交的字段合法性检测,可以更好的保护数据的安全性.这一特性是3.1安全特性中的一个重要部分. 表单字段合法性检测需要使用create方法创建数据对象的时候才能生效,具体有两种方式: 一.属性定义 可以给模型配置insertFields 和 updateFields属性用于新增和编辑表单设置,使用create方法创建数据对象的时候,不在定义范围内的属性将直接丢弃,避免表单提交非法数据. insertFields 和 updateFields属性的设置采用字符串(逗

解决在Web.config或App.config中添加自定义配置的方法详解_实用技巧

.Net中的System.Configuration命名空间为我们在web.config或者app.config中自定义配置提供了完美的支持.最近看到一些项目中还在自定义xml文件做程序的配置,所以忍不住写一篇用系统自定义配置的随笔了.如果你已经对自定义配置了如指掌,请忽略这篇文章.言归正传,我们先来看一个最简单的自定义配置 复制代码 代码如下: <?xml version="1.0" encoding="utf-8" ?> <configura

钉钉APP剩余通话时长查询方法详解

给各位钉钉软件的使用者们来详细的解析分享一下剩余通话时长查询的方法. 方法分享:   打开钉钉APP后,在"我的功能"中,即可看到本月还可以免费拨打多少分钟的电话. 好了,以上的信息就是小编给各位钉钉的这一款软件的使用者们带来的详细的剩余通话时长查询的方法解析分享的全部内容了,各位看到这里的软件使用者们,小编相信你们现在那是非常的清楚了查询方法了吧,那么大家就快去按照小编上面带来的方法自己去查询自己的剩余通话时长吧.

百度云iPhone版“离线可用”与“保存在本地相册”区别详解

给各位百度云软件的用户们来详细的解析分享一下百度云iPhone版"离线可用"与"保存在本地相册"的区别. 解析分享: 在图片预览界面有2个选项,保存到相册,即可在手机相册中查看,离线可用到百度云只能在百度云中查看.   好了,以上的信息就是小编给各位百度云的这一款软件的用户们带来的详细的百度云iPhone版"离线可用"与"保存在本地相册"的区别解析分享的全部内容了,各位看到这里的软件用户们,小编相信大家现在那是非常的清楚了两者