一、前言
目前在业界有很多自动化检测APP安全性的在线扫描平台。为了了解目前国内移动APP在线漏洞扫描平台的发展情况,我进行了一次移动安全扫描平台的评测分析;主要从漏洞项对比、扫描能力对比以及扫描结果这三个方向来对比。
希望此次的调研结果可以为读者提供更加可靠的安全漏洞扫描服务建议。
二、分析对象
这一章主要介绍需要对比的扫描平台和需要测试的APP样本。
2.1 对比平台
扫描平台 | 网址 |
阿里聚安全漏洞扫描 | |
360APP漏洞扫描 | |
腾讯金刚审计系统 | |
百度移动云测试中心 | |
AppRisk Scanner | |
爱加密 | |
梆梆加固 | |
AppTest掌测 | |
TestIn测试平台 | |
腾讯优测 | |
爱内测 | |
AppScan | http://www-03.ibm.com/software/products/zh/appscan-mobile-analyzer |
Fortify SCA | http://www8.hp.com/us/en/software-solutions/application-security/ |
对上述扫描平台,我都上传APP进行了测试,简单比较它们的扫描结果。最后,综合检测结果、它们在漏洞扫描领域的知名度以及它们的用户数量,我选取表中前五个扫描平台,即阿里聚安全、360APP漏洞扫描、金刚、百度和AppRisk进行详细的对比分析;由于金刚和优测都是腾讯旗下的产品,所以我选择了专注于APP审计的金刚审计系统。
爱加密扫描速度很快,但整个漏洞扫描就是为其加密模块做铺垫,扫描项非常简单,没有实际的漏洞扫描,只是简单的字符串匹配,故扫描速度非常快。梆梆加密扫描速度也比较快,扫描内容比爱加密要丰富,一共14项,包含了一些高危漏洞的扫描,如与WebView相关的一些漏洞等,但是其漏洞扫描模块也是为了给自己的加固服务做铺垫,所以没有选取这两家。AppTest掌测测试成本太高,每次测试2999元起,所以没有对它进行详细分析。腾讯优测的扫描结果与金刚非常相似,但没有金刚详细;有时候扫描结果只有漏洞概述,没有漏洞的详细信息,也没有修复建议。爱内测的扫描结果非常简略,只判断是否存在漏洞,而不统计漏洞的个数以及漏洞位置。
AppScan和Fortify SCA是国外的扫描平台,分别属于IBM和惠普。我分析了它们的扫描结果,AppScan的免费版本检测结果没有多大的参考价值,重要的漏洞信息都没有显示,如果测试时间超过4个小时,则会中断扫描服务。Fortify SCA的扫描侧重Web应用程序,虽然也可以扫描Android程序,但扫描结果以Web漏洞为主,差强人意,而且在免费试用15天后,每测试一个APP需要花费2000美元,所以我没有详细分析这两个平台。
以下简单统计了各个平台的收费情况,如下表:
扫描平台 | 是否收费 | 备注 |
阿里聚安全漏洞扫描 | 免费 | 完全免费 |
360APP漏洞扫描 | 免费 | 完全免费 |
腾讯金刚审计系统 | 免费 | 完全免费 |
百度移动云测试中心 | 9.9元/次 | 新用户可以获得一张9元代金券,只能用百度钱包支付剩余的0.9元 |
AppRisk Scanner | 不详 | 普通账户可以测试2个app,随后可以通过可以通过邮件联系AppRisk升级账户 |
爱加密 | 免费 | 漏洞扫描主要为其加密服务做推广,扫描能力很差 |
梆梆加固 | 免费 | 漏洞扫描主要为其加密服务做推广,扫描能力较差 |
AppTest掌测 | 2999元/次 | AppTest掌测还有其他测试服务,收费标准不同,安全测试是2999元/次 |
TestIn测试平台 | 2000元/次 | 安全扫描服务需要填写非常详细的申请表才有机会获得1次试用服务 |
腾讯优测 | 200元/次 | 新用户免费使用一次。通过U币的形式付款,1U币=1元 |
爱内测 | 免费 | 爱内测免费版主要为其定制化检测做广告 |
AppScan | 混合 | AppScan将用户分为免费账户和标准账户,免费账户的扫描结果简单;标准账户可以按次收费也可以按月收费 |
Fortify SCA | 2000美元/个 | 新用户免费试用15天,超过15天后每测试一个APP需要2000美元,一年内可对同一个APP进行多次测试 |
2.2 测试样本
测试样本:
名称 | 版本 |
WiFi万能钥匙 | 4.0.9 |
墨迹天气 | 5.0916.02 |
新浪微博 | 6.7.0 |
测试app | 无 |
手机百度 | 7.4 |
通过上传精心构造的包含各种漏洞的“测试APP”,测试它们的扫描能力,随后上传应用市场中下载量较大的应用程序进行实际测试。由于受时间和资源的限制,并未大规模上传应用进行测试,也只是详细对比了WiFi万能钥匙的扫描结果。因此扫描结果有些许的片面性,但总体反映各个扫描平台的检测能力。
三、总体能力对比
3.1 扫描时间对比
以下列表各个扫描平台扫描时间的对比,金刚只能检测50M以内的APP,所以没有新浪微博的检测时间,而百度每检测一次收费9.9元,而且没有记录扫描时间;受限于时间和经费,没有再次检测APP以获取扫描时间,单位:分。
| 阿里聚安全 | 360 | 百度 | 金刚 | Apkrisk |
WiFi万能钥匙(5.38M) | 6 | 458 | 无 | 1395 | 3 |
墨迹天气(14.9M) | 16 | 1256 | 无 | 1577 | 4 |
手机百度(36.8M) | 21 | 261 | 无 | 710 | 7 |
新浪微博(53.2M) | 45 | 1112 | 无 | 无 | 8 |
补充一下,时间的获取是以扫描界面内对应APP给出的或者是以收到扫描结束通知为依据的。可以看出,阿里聚安全和AppRisk的扫描时间与APP的大小成正比,而360和金刚没有明显的规律。当用户把APP投入阿里聚安全和AppRisk中扫描时,可以根据APP的大小预测大致的扫描时间;而投入到360和金刚时却无法预测大致的扫描时间。
3.2 漏洞项对比
360将许多类型相同的漏洞分成多个具体的漏洞,我将其合并一下(组件导出归为一类,文件读写归为一类,SQL注入归为一类)。
以下是具体漏洞个数对比:
漏洞类型 | 阿里聚安全 | 360 | 金刚 | 百度 | Apkrisk |
WebView组件远程代码执行漏洞 | √ | √ | √ | √ | √ |
WebView绕过证书校验漏洞 | √ | √ | √ | √ | √ |
WebView明文存储密码风险 | √ | | | √ | √ |
WebView组件系统隐藏接口漏洞 | √ | √ | √ | √ | √ |
组件导出风险 | | √ | √ | √ | √ |
存在可以被恶意访问的表单 | | √ | | | |
存在外部可访问的表单 | | √ | | | |
本地代码执行漏洞 | | √ | | | |
本地SQL注入漏洞 | | √ | √ | | |
私有文件遍历漏洞 | | √ | | √ | |
getDir任意读写 | √ | | | | |
通用签名漏洞 | √ | | | | |
安全加固风险 | √ | | | | |
不安全的反射 | √ | | | | |
META-INF目录存在敏感文件信息 | √ | | | | |
ContentProvider文件跨域访问 | √ | | | | |
Native动态调试 | √ | | | | |
固定端口监听风险 | √ | | | | |
Zip文件目录遍历漏洞 | √ | | | | |
密钥硬编码 | √ | √ | | | |
广播信息泄露风险 | | √ | | √ | |
Url用户敏感信息泄露 | | √ | | | |
Uri用户敏感信息泄露 | | √ | | | |
外部URL可控的WebView | | √ | | | |
KeyStore风险 | | √ | √ | | |
尝试使用root权限 | | √ | | | |
Intent敏感数据泄露风险 | | | √ | √ | |
运行其他可执行程序风险 | | | | √ | |
第三方库检测 | | | √ | | |
日志泄露风险 | √ | √ | | √ | √ |
Dex文件动态加载风险 | √ | | | √ | √ |
数据库全局读写漏洞 | √ | | | √ | |
WebView File域同源策略绕过 | √ | √ | √ | | |
Fragment注入漏洞 | √ | √ | | √ | |
初始化IVParameterSpec函数出错 | √ | √ | | √ | √ |
PendigIntent误用风险 | √ | | | √ | √ |
用户自定义权限滥用风险 | √ | √ | √ | √ | |
SharedPrefs任意读写 | √ | √ | √ | √ | √ |
源码泄露漏洞(混淆率等) | | | √ | | |
App存在隐式意图调用 | | √ | √ | | √ |
加密哈希函数漏洞MD5 | | | | | √ |
加密哈希函数漏洞SHA-1 | | | | | √ |
证书弱校验 | √ | √ | √ | √ | √ |
主机名弱校验 | √ | √ | √ | √ | |
随机数加密破解漏洞 | √ | √ | √ | √ | √ |
Intent Scheme URL漏洞 | √ | | √ | | √ |
本地拒绝服务 | √ | | √ | | |
全局文件可读可写 | √ | √ | √ | √ | √ |
强制类型转换本地拒绝服务漏洞 | √ | | √ | | |
AES/DES弱加密 | √ | √ | | √ | √ |
RSA弱加密风险 | √ | | | √ | |
调试开关开启风险 | √ | √ | √ | √ | √ |
备份功能开启风险 | √ | √ | √ | √ | √ |
中间人攻击 | √ | √ | √ | √ | |
从上表可以看出,五个产品相同的扫描项有9种,其中四个产品相同的扫描项有7种。总的来说,这五个产品基本覆盖了目前Android应用程序可能出现的所有漏洞。
总体覆盖量排名:阿里聚安全(35个)>360(31个)>百度(26个)>金刚(23个)>Apkrisk(20个)
3.3 扫描能力对比
最后我用自己编写的测试APP测试各个扫描平台的扫描能力。这些扫描能力主要分为静态检测能力和动态检测能力。静态检测能力包括检测隐藏dex、过程间分析、正向分析、逆向分析;动态测试主要是指测试拒绝服务漏洞的能力,拒绝服务漏洞又可以划分为:空Intent引起的拒绝服务,强制类型转换引起的拒绝服务以及序列化对象导致的拒绝服务。由于这些检测能力决定了扫描器扫描结果的精度和准度,因此我详细分析了各个扫描平台的扫描能力。
测试方法
使用自己编写的测试APP测试各个扫描平台的扫描能力。这些扫描能力主要分为静态检测能力和动态检测能力。静态检测能力包括检测隐藏dex、过程间分析、较复杂漏洞检测、逆向分析;动态测试主要是指测试拒绝服务漏洞的能力,拒绝服务漏洞又可以划分为:空Intent引起的拒绝服务,强制类型转换引起的拒绝服务以及序列化对象导致的拒绝服务。由于这些检测能力决定了扫描器扫描结果的精度和准度,因此我详细分析了各个扫描平台的扫描能力。
3.2.1 自动化脱壳
目前很多APP通过加壳来防止自己被反编译,而扫描器都是通过在反编译的代码中进行漏洞的扫描。如果扫描器不能自动化地脱去APP加的壳,则根本无法进行有效的漏洞扫描分析。我写了一个包含五个扫描平台都有的全局文件读写漏洞的demo,通过梆梆加固之后,重签名上传到这五个扫描平台,检测结果是:阿里聚安全和百度检测出全局文件读写漏洞,而金刚、AppRisk没有检测出该漏洞。这个demo在360中没有扫描结果,所以360的脱壳能力不得而知。
3.2.2 隐藏Dex检测能力
目前插件化已经在Android开发中越来越普遍。很多APP会将一些独立模块打包成单独的dex文件,并存储到apk的其他目录中,如asset、lib等。如果扫描器没有检测隐藏dex文件的能力,则可能会漏报一些安全风险,造成扫描结果不准确。我编写了一个asset目录包含dex文件的应用程序,分别上传到上述五个扫描器,该dex文件中包含五家扫描器都可以检测的漏洞,结果只有阿里聚安全和百度成功扫描出隐藏dex文件中包含的漏洞。因此,可以推测阿里聚安全和百度具有扫描隐藏dex文件的能力,而360、金刚、百度和AppRisk都没有检测隐藏dex文件的能力。
3.2.3 过程间分析能力
五家扫描器都可以检测全局文件读写漏洞,因此我用该漏洞测试扫描器对过程间分析的能力。
openFileOutput的第二个参数可以指定文件打开的方式,如果以全局可写的方式打开会导致安全风险。这里我构造了两个测试例子。
例一, 直接对openFileOutput的第二参数设置全局可写,因此有漏洞。
例二, 通过函数的参数传递对openFileOutput的第二参数设置全局可写,也应该有漏洞。
测试代码如下:
样本一:函数内设置危险变量Context.MODE_WORLD_WRITEABLE
样本二:函数间设置危险变量Context.MODE_WORLD_WRITEABLE
样本一和样本二可以测试扫描器对过程间分析的检测能力。检测结果如表3-6所示(“√”表示扫描结果正确,“×”表示扫描结果错误。):
表3-6 函数间相互调用检测能力
| 阿里聚安全 | 360 | 金刚 | 百度 | AppRisk |
过程内检测(样本一) | √ | √ | √ | √ | √ |
过程间检测(样本二) | √ | × | × | × | × |
阿里聚安全可以检测出样本一和样本二,而360、金刚、百度和AppRisk都只能检测出样本一。
由此可以推测,360、金刚、百度和AppRisk都只能在过程内进行检测,也就是在函数内进行检测,阿里聚安全可以在过程间进行检测。
3.2.4 逆向分析能力
目前漏洞扫描规则大部分是通过定位关键函数,根据关键函数的参数确定是否会触发漏洞。这是典型的逆向分析问题,可以说逆向分析能力很大程度决定了扫描器检测漏洞的能力。这五家扫描器都有逆向分析的能力,只是逆向分析的能力有些差别。通过扫描器对全局文件读写的代码检测结果分析扫描器逆向分析的能力。
根据全局文件读写漏洞的检测规则,扫描器首先会定位openFileOutput函数,追踪该函数的第二个参数,即打开的模式。打开模式都存储在一个数组中。数组中下标为0的模式没有漏洞,而下标为1的有漏洞。如果扫描结果正确,则说明扫描器的逆向分析能力较强,可以深入到数组等较为复杂的结构中;如果扫描结果有错误,则说明扫描器的逆向分析能力较差,无法逆向追踪到复杂的数据结构中,漏报的可能性较大。
将上述测试代码上传到五家扫描平台,扫描结果如下图所示。“√”表示扫描结果正确,“×”表示扫描结果错误。
表3-7 数组下标敏感性检测结果
| 阿里聚安全 | 360 | 金刚 | 百度 | AppRisk |
样本一 | √ | √ | √ | √ | √ |
样本二 | √ | × | × | × | × |
通过扫描结果可以看到,阿里聚安全正确地扫描出两个样本,而360、金刚、百度和AppRisk都只扫描出样本一。因此可以说阿里聚安全的逆向扫描能力要强于其他四家,当逆向追踪的变量进入一个数组时,阿里聚安全可以继续在数组中进行逆向分析,而其他四家扫描器无法确定数组中各个位置代表的具体值。
我猜测当其他四家扫描器检测全局文件读写漏洞时,首先会定位openFileOutput函数,由于打开方式是由数组中的元素决定,所以360、金刚、百度和AppRisk无法确定该值具体是多少,因此也就无法判断是否存在全局文件读写漏洞。本着减少误报的原则,它们都认为不存在漏洞,所以很幸运,样本一不存在漏洞,它们的检测结果正确;样本二存在漏洞,它们的检测结果错误。
3.2.5检测较复杂漏洞的能力
为了测试扫描器检测是否能检测出由多个条件组合起来判断的漏洞,我选取了Intent Scheme URL漏洞进行对比[6],如果想避免Intent Scheme URL漏洞,parseUri函数得到的Intent必须要设置三个条件(addCategory(“android.intent.category.BROWSABLE”), setComponent(null), setSelector(null) 才能保证漏洞不会发生。
我构造了三个例子进行测试:
例一,三个条件都满足,因此没有漏洞的。
例二,缺少了条件setSelector(null),存在Intent Scheme URL漏洞。
例三,虽然三个条件都满足,但因为没有startActivity所以也不应该被检测出来。
构造如下测试代码:
代码中一共有三个case,其中只有case 2有问题。将上述代码打包成apk,上传到除360和百度之外的三家扫描平台。(360和百度不支持该扫描项,还需要使用另一种漏洞比较360、百度的检测差异)
AppRisk认为三个都有漏洞,通过其扫描报告可以看出,AppRisk只是判断是否有Intent.parseUri函数的调用,如果存在,则就存在Intent Scheme URL漏洞。因此,推测AppRisk的扫描规则仅仅是简单的特征函数匹配,数据流跟踪的能力几乎没有。在该例中仅仅匹配Intent.parseUri,而没有其他条件进行约束,因此误报率比较高。
金刚扫扫描出case 2和case 3,而case 3是没有问题的,所以有一个误报。金刚对该项的扫描比AppRisk要复杂一些,除了匹配parseUri函数外,还检测该Intent是否做了后续的处理,如addCategory、setComponent、setSelector等,如果没有这些函数调用,则认为存在该漏洞。但如果仅仅把Intent构造出来,而没有做任何启动其他组件的操作,如case 3,也是没有漏洞的,所以金刚没有考虑对获取Intent的使用操作,也容易引起误报。
360没有扫描这个漏洞,而其他常见的漏洞漏报也比较多。因此,对它的检测较复杂漏洞的能力不做推测。
当检测百度时,我使用WebView组件系统隐藏接口漏洞作为测试用例。
测试代码如下:
将代码打包成apk上传到百度移动云测试平台,测试百度是否仅仅测试是否有loadUrl函数调用,而不考虑是否启用了JavaScript。从测试代码中可以看出,case 1是有漏洞的,通过调用setJavaScriptEnabled(true)启用了JavaScript,随后调用loadUrl加载页面。Case 2是没有问题的,首先mWebView是一个全局的成员变量,当创建一个WebViewSafeCase的对象时会初始化该WebView,同时显式调用removeJavascriptInterface移除searchBoxJavaBridge,accessibility以及accessibilityTraversal,当外部调用其内部类的方法时,mWebView会启用JavaScript,随后调用loadUrl。如果单从removeFromOutterClassShouldNotFound来看,case 2是有漏洞的,但是实际上mWebView在调用loadUrl之前已经移除隐藏的接口了,如果扫描器没有追踪mWebView这个变量的能力,则很容易误认为case 2是有漏洞的。
百度的扫描结果显示case 1和case 2都包含WebView未移除隐藏接口漏洞,我推测百度没有追踪变量的能力,而仅仅是进行函数匹配。
3.2.6 动态检测能力
一些运行时漏洞,如拒绝服务,只有在程序运行时才有可能触发。如果扫描器没有动态检测的能力,则会漏报一些运行时漏洞。为了检测扫描器是否有动态扫描的能力,我在测试APP中包含4处拒绝服务漏洞的代码,分别是空Intent拒绝服务2个、1个强制类型转换拒绝服务和1个对象序列化拒绝服务。扫描结果如下表所示。
表3-8 动态检测能力扫描结果
| 阿里聚安全 | 360 | 金刚 | 百度 | AppRisk |
空Intent Fuzz | 2 | 0 | 1 | 0 | 0 |
强制类型转换 | 1 | 0 | 1 | 0 | 0 |
对象序列化 | 1 | 0 | 1 | 0 | 0 |
- 从表3-8中可以看出,阿里聚安全可以扫描出所有的拒绝服务漏洞,金刚可以扫描出3处拒绝服务漏洞,漏报一处拒绝服务代码如下:
而360、百度和AppRisk没有扫描出拒绝服务漏洞。从这个例子我推断除阿里聚安全和金刚外,其他扫描平台没有动态检测能力。
综上所述,阿里聚安全的综合检测能力最高,它不仅可以检测隐藏dex,对数组下标敏感,还可以检测函数相互调用引起的漏洞。除此之外,阿里聚安全还可以追踪变量,记录变量的一系列操作,当变量作为sendMessage的参数被Handler发送出去时,阿里聚安全还可以追踪到相应的处理函数中继续追踪;当变量作为Intent携带的参数跳转到其他组件中时,阿里聚安全还可以到对应的组件中继续追踪该变量。对变量的有效跟踪可以大大提高扫描结果的可靠性,有效降低了扫描结果的误报率。
百度可以检测隐藏的dex文件,但它不能追踪变量,无法处理函数间调用引起的漏洞,对数组下标也不能准确地处理,因此我推测百度的扫描规则是基于危险API所在的函数范围内,一旦超出这个函数,百度的误报率会大大提高。
360扫描结果让人看不明白,分析中所有的应用一旦投入到360,不但扫描时间长,而且结果与其他四家差别很大,所以这里不对360的扫描能力做推测。
金刚和AppRisk的扫描能力相对较差,只能通过简单的特征函数匹配检测漏洞,虽然漏报相对较少,但是误报率比较高。
扫描能力小结
以下表3-9是此次扫描能力的结果:
表3-9 扫描能力总览
| 阿里聚安全 | 360 | 金刚 | 百度 | AppRisk |
自动化脱壳 | √ | 未知 | × | √ | × |
静态-检测隐藏Dex | √ | × | × | √ | × |
静态-过程间分析 | √ | × | × | × | × |
静态-较复杂漏洞 | √ | × | × | × | × |
静态-逆向分析 | √ | √ | √ | √ | √ |
动态-空Intent Fuzz | √ | × | √ | × | √ |
动态-综合静态分析 | √ | × | √ | × | × |
动态-复杂对象Fuzz | √ | × | √ | × | × |
需要注意的是, 360一直没有测试APP的扫描结果,我只好把每个检测代码打包成APP进行测试,然后进行统计,因此关于360的测试结果可能有误差。
除了扫描能力以外,最后一个维度会以之前的4个第三方APP的测试结果作为对比。为了说明各个扫描平台实际扫描漏洞的能力,我将WiFi万能钥匙、墨迹天气、手机百度以及新浪微博上传到五家扫描平台。最后将以WiFi万能钥匙的扫描结果为例,详细分析一下各个平台的扫描结果的漏报和误报,从而评估其扫描结果的可信性。这部分内容将单独作为下篇进行连载,敬请期待。
四、扫描结果对比
选取的APP:说明一下这次选择的四个app是根据下载和安装量来选择,分别在网络工具类、天气、社交资讯类和搜索工具类选择了下载量和安装量最大的。出于对应用的隐私保护这里把最后选定的应用名隐去暂时叫做A应用。
评测方法:将以上4个APP分别上传到五家扫描平台,都分别得到5家平台的扫描速度和结果。除了在上篇中对比扫描时间外,这里还要对5家的扫描结果进行对比。但是实际操作下来4个APP的对比工作量实在太大,所以我最后从工作量小易于分析的原则出发,选择了A应用来最为结果对比。
下面我将以A应用的扫描结果为例,详细分析一下各个平台的扫描结果的漏报和误报,从而评估其扫描结果的可信度。
A应用的扫描结果如表4-1所示。
表4-1扫描结果总览
| 阿里 | 360 | 金刚 | 百度 | AppRisk |
WebView绕过证书校验漏洞 | 2 |
| 2 | 1 |
|
WebView组件远程代码执行漏洞 | 2 |
| 2 | 3 | 2 |
中间人攻击(Allow All host name) | 1 |
|
| 1 |
|
备份功能开启风险 | 1 | 1 | 1 | 1 | 1 |
主机名弱校验 | 1 | 1 | 1 | 1 |
|
证书弱校验 | 4 |
| 2 | 4 | 1 |
拒绝服务 | 3 |
| 1 |
|
|
Intent协议解析越权漏洞 | 1 |
|
|
|
|
AES/DES弱加密 | 1 |
|
| 15 |
|
初始化IVParameterSpec函数出错 | 9 |
|
|
|
|
PendigIntent误用风险 | 2 |
|
| 5 | 2 |
WebView明文存储密码风险 | 6 |
|
| 25 | 30 |
WebView组件系统隐藏接口漏洞 | 5 |
| 12 | 1 | 32 |
日志泄露风险 | 5 | 1 |
| 241 | 286 |
强制类型转换本地拒绝服务漏洞 |
|
| 6 |
|
|
App存在隐式意图调用 |
| 2 | 3 |
|
|
组件导出风险 |
| 22 | 24 | 23 | 17 |
Intent泄露用户敏感信息 |
| 1 |
| 1 |
|
广播信息泄露风险 |
| 2 |
|
|
|
Dex文件动态加载 | 0 |
|
| 1 | 9 |
加密哈希函数漏洞MD5 |
|
|
|
| 12 |
加密哈希函数漏洞SHA-1 |
|
|
|
| 1 |
Native动态调试 | 1 |
|
|
|
|
密钥硬编码 | 10 |
|
|
|
|
安全加固风险 | 1 |
|
|
|
|
WebView File域同源策略绕过 | 2 |
|
|
|
|
A应用只有一个dex文件,这排除了隐藏dex对结果的影响,接下来的章节中对扫描结果进行详细的对比分析。
4.1 WebView绕过证书校验漏洞
表4-3 WebView绕过证书校验漏洞分析结果
| 误报 | 漏报 |
360 | 0 | 2 |
金刚 | 0 | 未知 |
阿里 | 0 | 未知 |
百度 | 0 | 1 |
AppRisk | 0 | 2 |
WebView绕过证书校验漏洞是指onReceivedSslError函数中调用proceed方法,会导致WebView忽略校验证书的步骤。对于WebView绕过证书校验漏洞,经过比对,阿里和金刚定位的漏洞位置一致。因此我认为360和AppRisk漏报了2个,百度漏报了1个。我推测百度对于此类漏洞的检测规则是判断是否有onReceivedSslError这个函数。SslErrorHandler这个类会代表一个请求去处理ssl error。SslErrorHandler会被WebView创立然后传给onReceivedSslError函数进行处理。其实真正做证书处理的函数是SslErrorHandler类的proceed函数。这个函数一般会是在SslErrorHandler函数里面进行调用,但是它还是可能在其他函数中被调用。因此检查proceed这个函数会更加全面。阿里与金刚应该是检查Landroid/webkit/SslErrorHandler;->proceed()V。百度漏报的一个正好符合我的推论。
4.2 证书弱校验
表4-4 证书弱校验分析结果
| 误报 | 漏报 |
360 | 0 | 4 |
金刚 | 0 | 2 |
阿里 | 0 | 未知 |
百度 | 0 | 未知 |
AppRisk | 0 | 3 |
证书弱校验漏洞是在实现的X509TrustManager子类中checkServerTrusted函数没有校验服务器端证书的合法性导致的。360漏报4个,金刚漏报2个,AppRisk漏报3个。经过我的分析,一共有6处调用了checkServerTrusted,其中2处对证书进行了验证;而4处没有验证,直接返回,有两种形式,如下图所示:
我推测,漏报的原因是多了两行param导致扫描器认为对证书有校验。
4.3 WebView明文存储密码风险
表4-5 WebView明文存储密码风险分析结果
| 误报 | 漏报 |
360 | 无检测 | 无检测 |
金刚 | 无检测 | 无检测 |
阿里 | 0 | 4 |
百度 | 15 | 未知 |
AppRisk | 23 | 3 |
经过分析,我猜测AppRisk是通过loadUrl函数判断是否使用了WebView,然后在使用loadUrl的类中搜索该WebView是否调用setSavePassword(false)方法。而我在反编译的代码中进行全局搜索,一共有34处调用loadUrl;其中4处所处的类中显式调用了setSavePassword(false)方法,符合我的猜测,由于其他3处没有调用loadUrl,所以AppRisk漏报了3处。
百度的检测逻辑就比较难猜测,它不仅通过loadUrl,还通过其他方法判断是否使用了WebView,所以它可能没有漏报,但是误报率比较高。阿里没有检测出那些通过findViewById方法获得的WebView引起的明文密码存储风险,漏报了4处。
4.4 日志泄露风险
表4-6 日志泄露风险分析结果
| 误报 | 漏报 |
360 | 未知 | 未知 |
金刚 | 无检测 | 无检测 |
阿里 | 未知 | 未知 |
百度 | 未知 | 未知 |
AppRisk | 未知 | 未知 |
各个扫描平台对日志泄露风险的处理方式完全不同,在此一起讨论。
从扫描结果来看,阿里好像只检测System.out.print函数打印的内容。并没有过滤Log函数。实际上,Log函数也会泄露敏感的日志信息。
360认为只要存在Log日志,不管是System.out.print还是Log函数,都认为存在日志泄露风险。但无论日志泄露有多少,都只会给出一个存在Log日志泄露的风险,而且没有具体的漏洞位置。
百度和AppRisk对待日志泄露的态度相似,检测Log函数。
所以从我这看,阿里、360以及百度和AppRisk的出发点是不同的。结果也没有很好的可比性。能可比的,就是对待这个日志泄露风险的一个规则。
4.5 PendingIntent误用风险
表4-7 PendingIntent误用风险分析结果
| 误报 | 漏报 |
360 | 无检测 | 无检测 |
金刚 | 无检测 | 无检测 |
阿里 | 0 | 3 |
百度 | 0 | 未知 |
AppRisk | 0 | 3 |
百度的PendingIntent误用风险,不仅包括Intent为空的情况,还包含了隐式Intent的情况。A应用中,有2个是空Intent,有3个是隐式Intent。而阿里和AppRisk的PendingIntent误用风险监测可能只包括Intent为空的情况,所以只检测出2处漏洞,漏报了3个隐式的Intent。如果从两者的检测内容上看,阿里、百度和AppRisk都没有误报的情况。
4.6 WebView远程代码执行漏洞
五个扫描都具有扫描WebView远程代码执行漏洞,但是给出的结果却不一样。扫描结果如下表所示:
表 4-8 WebView远程代码执行漏洞分析结果
| 误报 | 漏报 |
360 | 0 | 3 |
金刚 | 0 | 1 |
阿里 | 0 | 1 |
百度 | 0 | 未知 |
AppRisk | 0 | 1 |
在WebView远程代码执行漏洞检测中,经过人工分析,确认阿里、金刚以及AppRisk各漏报1个,360漏报3个。阿里没有识别findViewById方法实例化的WebView,因而漏报了1个。
4.7 Dex文件动态加载
只有阿里、百度和AppRisk这三个扫描器包含该扫描项。
阿里的检测规则(猜测):
1) 检测特征函数DexClassLoader以及PathClassLoader的构造函数。
2) 检测该特征函数的传入参数(加载路径)是否包含“sdcard”字符串
百度的检测规则(猜测):
1) 检测特征函数DexClassLoader以及PathClassLoader的构造函数
AppRisk的检测规则(猜测):
2) 检测DexClassLoader中loadClass调用
我在反编译的代码中进行全局搜索“DexClassLoader;->loadClass”,一共有9处,故猜测AppRisk的检测规则为检测loadClass函数的调用。
由于检测点不一样无法判断具体的漏报和误报。
4.8 AES/DES弱加密
表4-9 AES/DES弱加密分析结果
| 误报 | 漏报 |
360 | 0 | 1 |
金刚 | 无检测 | 无检测 |
阿里 | 0 | 未知 |
百度 | 14 | 未知 |
AppRisk | 0 | 1 |
该项金刚不会检测,而360和AppRisk都没有检测出AES/DES弱加密风险,都漏报了1个。而百度却检测出15个弱加密风险。经过分析,我猜测百度只是检测是否包含AES或者DES,并没有判断加密模式是否为ECB,使用其他加密模式是不存在安全隐患的。而阿里正确检测出1个,因此我的结论是百度误报14个漏洞,360和AppRisk漏报1个。
4.9 WebView组件系统隐藏接口漏洞
表4-10 WebView组件系统隐藏接口漏洞分析结果
| 误报 | 漏报 |
360 | 0 | 未知 |
金刚 | 9 | 2 |
阿里 | 0 | 未知 |
百度 | 0 | 4 |
AppRisk | 27 | 3 |
360没有扫描出WebView隐藏接口漏洞,原因未知。
金刚误报了9个,而且还有2个漏洞漏报;百度漏报了4个漏洞,只正确找出1个。通过之前的扫描能力分析我可知,金刚可能仅仅是寻找是否有使用了WebView,而没对WebView是否启用了JavaScript进行检查,所以误报率很高。百度没有误报,但漏报很多,可能是百度没有判断WebView是否启用了JavaScript,所以本着减少误报的原则,只报告百分之百确定的漏洞。
AppRisk的检测规则可能非常简单粗暴,仅仅检查loadUrl来确定是否使用了WebView,因而误报率很高。
阿里可能首先判断WebView是否允许JavaScript运行。只有在JavaScript允许运行时移除隐藏接口才有意义;然后如果JavaScript开启,那么就判断WebView是否移除了“searchBoxJavaBridge_”、“accessibilityTraversal”以及“accessibility”这3个接口。如果都移除了才安全。所以阿里漏报和误报都很低。
五、总结和展望
通过此次评测,我基本了解了目前国内移动安全扫描平台的发展状况,了解了主流扫描平台的检测能力,包括扫描项、漏洞的检测规则等。我发现没有一家扫描平台可以覆盖所有的安全漏洞和风险。相对来说, AppRisk扫描速度最快,扫描结果展示更加专业;360和金刚作为老牌的扫描器,尽管扫描速度慢了一点,但扫描能力和结果展示也比较不错;阿里聚安全的扫描项覆盖广一些,漏报和误报率较低,检测结果更加可信一点。百度作为其中唯一一家收费的扫描平台,在某些扫描项的扫描能力上处于领先位置,扫描速度也比较快。总之,五家扫描平台在竞争中互相学习,取长补短。
Reference:
[1] 阿里聚安全 http://jaq.alibaba.com/
[2] 360APP漏洞扫描 http://dev.360.cn/mod/vulscan/
[3] 腾讯金刚审计系统 http://service.security.tencent.com/kingkong
[4] 百度移动云测试中心 http://mtc.baidu.com/startTest/safe
[5] AppRisk Scanner https://apprisk.newskysecurity.com
APP漏洞扫描收费情况
1、百度开放云平台 (收费9.9元一次,可定制)
链接:https://console.bce.baidu.com/aat/startTest/safe
目前扫描没有免费试用服务,每次扫描收取的费用都是9.9元。这个价位如果是个人用户或者应用较少且迭代不频繁的用户还是挺划算的。从扫描样例的报告上来看,当前漏洞扫描支持3大类的漏洞:“权限漏洞”、“静态漏洞”、“运行时漏洞”。
2、阿里云移动安全 (基础版免费,专业版收费包年20000元/按次1000元)
链接:https://www.aliyun.com/product/mobsec
这款产品应该新出的,仔细研究下它的收费模式。在云盾中开通移动安全服务后可以免费试用基础版。不过基础版想到与阉割版。那漏洞扫描来说,基础版是看不到应用漏洞的具体位置的,只有点击立即升级购买专业版后才可以看到信息。售卖方式想得也比较周到,有两种方式:专业版收费包年20000元不限定使用次数,按次1000元一次。
当然这里的专业版不仅仅可以是在界面上操作的版本,同时还提供API接口形式。这种方式对开发来说其实更方便,特别是有大量应用或者边修改边扫描漏洞的场景。这种收费模式来看,阿里云的移动安全应该是针对企业客户来制定的,而且相比其他的产品有这种线上售卖的流程也很方便。
3、阿里聚安全 (免费,企业版收费)
阿里聚安全在免费漏洞扫描中推广安全组件服务,并且对功能分级针对企业版收费。它的收费是通过用户类型来区分,个人用户可以免费试用漏洞扫描,而企业用户则开通了全部权限同时也提供API服务。不过具体收费方式在官网中没有找到。
4、360开发者平台 (免费,无定制,需身份认证)
360本身漏洞扫描也是不收费的,在扫描报告中会通过安全建议“使用360加固对应用进行加固保护”来推广加固服务。
5、腾讯应用乐固(免费,无定制)
链接:http://console.qcloud.com/legu
腾讯云的应用乐固在扫描界面中无法在线查看扫描的详情数据,只有通过下载报告才可以。检测项主要有分以下8种“组件公开安全检测”、“intent劫持风险安全检测”、“数据存储安全检测”、“webview高危接口安全检测”、“数据传输安全检测”、“拒绝服务攻击安全检测”、“其他安全风险检测”、“AndroidManifest.xml配置安全检测”。从整体几个功能的信息像详细度来看主要也是推广加固的。
6、梆梆 (免费 可以定制)
链接:http://dev.bangcle.com/apps/index
梆梆漏洞扫描比较简陋,主要是做定制化评估。
作为最老牌的应用安全厂商,梆梆的商业模式主要是利用线上的自动化扫描来退出他们的人工审计服务。在扫描报告的下方有更多评估项,例如“支付安全审计”、“界面劫持测试”、“输入安全评估”等定制化服务。点击“申请定制化评估”后,是一个对话窗口,可以通过窗口和客服交流。了解到这部分定制化的服务是通过线下的方式来对接的。和上面百度阿里的几款自主化产品服务形式相比,耗费在人工对接上的时间精力可能会比较大。
整体来看,针对个人用户使用上述的一些像阿里聚安全和360的免费漏洞扫描服务就可以满足了。针对企业类的用户可以考虑收费服务,比如迭代快或者应用数量较大的则可以考虑阿里云移动安全API服务或者梆梆这一类定制化服务。