一、新权限模型介绍
(一)Android版本演变与权限模型变更
前不久Google发布了新的系统版本Android7.0。在之前发布的6.0版本中,引入了一种新的权限模型。
新权限模型在旧模型基础上加入了运行时动态权限检查,权限不再是安装时一次性全部授予,而是运行时动态申请与授予,如果开发者未按要求动态申请权限或者权限申请未被用户许可,应用程序的相应行为将无法实施;同时,用户可以在应用程序权限管理中随时撤销掉已授予的权限。这样的动态权限模型让用户对应用程序运行时权限拥有更强的可视性与控制性,赋予了用户更多权限管理主动权,增强了权限模型的安全性。在最新的7.0版本中,依旧沿用了此权限模型。
各版本Android系统所占比例如图1所示。
图1 2016年9月Android版本分布
(图片来源:https://developer.android.com/about/dashboards/index.html)
虽然6.0及以上系统版本并非是目前使用得最多的版本,但从图2、图3所示的占比变化趋势与使用率变化趋势上来看,使用了新权限模型的6.0及以上版本系统的占比正逐步增长,截至2016年9月,其占比已达到18.70%,而使用旧权限模型的5.x与4.4.x版本系统自2016年3月以来均呈现递减趋势。Android系统版本的占比变化表明,新权限模型正在逐步取代旧权限模型。
图2 6.0及以上版本占比趋势变化
图3 Android各版本使用率变化趋势
(二)新旧模型对比
新旧模型的关键区别在于新的权限模型加入了运行时动态权限检查与申请,以及给予了用户随时管理应用权限的主动权。
1. 旧权限模型
在以往的权限模型中,开发者在AndroidManifest.xml中声明所需的全部权限,应用在安装时呈现给用户其申请的全部权限,用户可以选择全部许可来安装应用,或拒绝来放弃安装;且应用安装后,用户无法变更该应用的权限,应用在其生命周期内(即卸载应用前)可以完全自由地使用其所申请的全部权限,即“一次安装,终身使用”。
2. 新权限模型
在新权限模型中,开发者除了需要在AndroidManifest.xml中声明所需权限外,对于Dangerous(危险)级别的权限,还需在代码中每处使用该权限的地方加入权限动态检查与申请的语句,如果开发者要调用的一些函数需要某权限而用户又拒绝授权的话,这些函数将无法被正常调用,以往的“一次安装,终身使用”模式不再适用,权限使用必须通过用户的动态授权;此外,应用安装后,用户能够随时撤销应用的某项权限,一旦用户撤销了应用的某项权限,应用若再想使用该权限必须重新申请并取得用户同意,在应用权限管理方面,用户将拥有更多主动权。
作为一种新的安全策略,新权限模型与旧权限模型相比赋予了用户更多的权限管理主动权。在使用到Dangerous权限的地方,强制要求应用程序动态申请所需权限,只有在用户同意申请后才可正常使用该部分的功能;若用户察觉到应用的恶意行为,也可主动撤销掉应用的该项授权,以此阻止应用的进一步恶意行为;而恶意软件若想绕过动态权限机制直接使用权限将造成程序崩溃。
二、新权限模型中的权限使用
(一)新旧模型中的权限申请
在旧权限模型中,权限一律在AndroidManifest.xml中声明,如图4,应用程序安装时要求用户全部同意方可安装,如图5,安装完成后应用可随意使用申请的全部权限。
图4 AndroidManifest.xml 权限声明
图5 旧权限模型权限申请
在新权限模型中,在上述步骤基础上,还需在每次使用Dangerous权限的地方调用Context类的checkSelfPermission方法与Activity类的requestPermissions方法来进行动态权限检查与申请。
图6 运行时权限申请——新权限模型
(二)动态检查权限组
需要注意的是,新权限模型中的强制性动态检查只针对Dangerous级的权限而言,对于Normal级的系统权限,仍仅需在AndroidManifest.xml中声明即可。同时,Dangerous级的权限是以组的形式进行授予的,即,如果应用程序已被授权了某个权限,同组的其他权限也将被自动授权使用,而不再需要额外动态授权。以短信组权限为例,如果已经动态申请并被授予了SEND_SMS权限,那么之后使用READ_SMS、WRITE_SMS或RECEIVE_SMS等同组权限进行读、写或接收等短信操作时,可以不用再进行动态权限申请。截至SDK 23,共有9个权限组,如表1所示。
表1 SDK 23权限组
(三)新权限模型中的权限使用流程
在新权限模型动态检查—动态授权的过程中,开发者调用系统权限申请接口进行动态权限申请时会弹出系统授权弹窗,而为了增加用户授权的可能性,开发者也可以在系统弹窗之前,通过重写shouldShowRequestPermissionRationale方法来对权限申请作出必要解释,即自定义弹窗,自定义弹窗的具体文字陈述与形式可以由开发者自主定义,在用户知晓权限申请原因后,再弹出系统授权弹窗供用户选择授权与否。
图7给出了一种较完整的动态权限检查—申请流程:首先调用系统权限检查接口进行动态权限检查,若尚未授权,则弹出开发者自定义的提示框,对此项权限申请给出文字解释,用户可选择取消直接放弃授权,也可在阅读原因后点击确认进入下一步(开发者自定义),如弹出系统授权弹窗,此时若用户拒绝就会放弃授权,若同意则为应用授予此项权限。
图7 权限使用流程
(四)代码示例
环境:系统版本Android6.0,compileSdkVersion23
主程序:
重写shouldShowRequestPermissionRationale:
图8 权限使用代码
运行结果1. 点击发送短信,首先弹出自定义弹窗:
图9 自定义弹窗
运行结果2. 点击“好的”弹出系统授权弹窗,或点击“取消”直接放弃授权:
图10 系统授权弹窗
运行结果3. 首次点击“拒绝”后再次点击发送短信按钮,系统授权弹窗出现不再询问选项,若勾选,之后将不再弹出系统授权弹窗:
图11 系统授权弹窗——不再询问选项
运行结果4. 点击“允许”后可以成功进行短信发送:
图12 授权后成功发送短信
(五)低版本兼容性
Android 6.0及以上版本中引入的新权限模型带来了高低版本应用的系统兼容性问题,对于开发者而言,需要同时注意开发平台编译应用所用的SDK版本与目标用户设备系统版本的兼容问题,否则可能导致程序编译不通过,甚至应用在目标设备中运行崩溃。
目标设备系统版本与开发平台SDK版本的兼容性问题存在以下4种情况,如表2所示:
表2 兼容性
系统版本>=6.0 & SDK版本>=23
可以使用SDK 23及以上提供的动态权限检查、申请接口,如表3所示,同时在目标设备上使用新权限模型进行动态权限检查与申请;
系统版本>=6.0 & SDK版本<23
版本低于23的SDK中未提供动态权限检查与申请的接口,因此对于使用低版本SDK(低于23)开发的应用,其在6.0及以上系统版本的设备中仍然以旧权限模型运行;
系统版本<6.0 & SDK版本>=23
系统版本低于6.0的设备不支持新权限模型,为了保持应用对目标设备的向下兼容性,在进行动态权限检查与申请之前,最好先使用“Build.VERSION.SDK_INT >= 23”检查系统版本,并根据不同系统版本进行不同处理;或者直接使用兼容包提供的权限检查、申请来兼容所有设备版本,如表4所示;
系统版本<6.0 & SDK版本<23
应用旧权限模型,无需进行动态权限检查。
表3 SDK 23及以上中权限检查与申请的方法
表4 兼容包中权限检查与申请的方法
三、恶意样本开始兼容新权限模型
虽然新权限模型强制要求对Dangerous级权限的动态检查与申请,权限管理主动权在用户手中,但这种机制并非万能,我们仍然发现了大量使用了SDK 23及以上的恶意应用。我们对这些恶意应用样本进行了统计与分析,分析结果显示,动态权限模型并未从根本上阻止恶意应用的产生,尽管Dangerous权限需要用户动态授权,但很多恶意应用仍大肆申请Dangerous权限,一旦用户授权便进一步实施恶意操作,同时还加入了容错机制,即使用户拒绝授权也能继续正常运行,减少用户对其危险动机的感知。
(一)恶意应用分布
根据360烽火实验室的统计数据显示,截至2016年9月,使用了SDK 23及以上的恶意样本总数为24万个,占使用了SDK 23及以上的应用程序总量的12.2%。这些恶意样本按其恶意行为被分为162个家族,其中成员数量排名前十的家族如图13所示,从图中看到,PornBobo家族样本规模最大,该家族的主要恶意行为是色情诱导短信支付,涉及到短信相关危险权限。
图13 代表恶意家族
(二)恶意应用变化
Android 6.0的动态权限模型从技术角度上来看增加了权限使用的透明度,能够从一定程度上缓解权限滥用的问题;但是,从图14可以看出,使用SDK 23及以上的相关恶意样本数量呈明显增长之势。这也体现出动态权限模型并不能从根本上遏制恶意样本的出现。
图14 Android 6.0恶意样本占比趋势
(三)恶意应用举例
恶意软件展示——仿冒KingRoot官方应用的恶意样本,图标与应用名称都与官方应用相同
图15 恶意软件
恶意软件包含的Dangerous权限:READ_PHONE_STATE、RECEIVE_SMS、READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE
权限检查相关代码片段:
应用启动主页面后,在回调函数中调用index方法,如图16所示:
图16 应用启动后调用index方法
index方法调用Application类中定义的startPermissionChecker方法开始进行权限检查,如图17所示:
图17 在index方法中进行权限检查
startPermissionChecker方法对动态权限检查行为进行了封装:首先检测当前系统版本是否小于6.0,若不小于则启动一个新的Activity进行权限检查,如图18所示:
图18 权限动态检查
权限检查Activity代码片段:
图19 Dangerous权限检查
当恶意软件被授予短信组权限时,其利用已获取的短信组权限接收系统短信广播并拦截新接收到的短信,窃取短信内容,造成用户隐私泄露。
该恶意软件的其他恶意行为包括:
诱导用户激活设备管理器
隐藏图标
检测并获取Root权限
发送扣费短信
窃取用户隐私信息
四、小结
从总体上看,Google在Android安全策略上呈现越来越严格的趋势,一方面,这说明随着Android的不断发展完善,Google越来越重视安全问题;而另一方面,这也从侧面放映了Android安全问题的严重性。虽然Google在Android 6.0及以上的系统版本中加入了动态权限模型,但恶意应用的对抗性与兼容性也在不断增强,仅依赖动态权限模型远远不能阻止不断演变的恶意应用。对此,我们提出了一些安全建议与看法,有助于预防感染恶意应用、阻止恶意应用的进一步恶意行为:
对手机厂商而言,基于Android传统的权限授予机制与其带来的安全问题,部分手机厂商在定制自己的个性化系统时同时也添加了权限管理的功能,为用户提供了权限管理的入口,在一定程度上缓解了权限滥用问题。那么,Android 6.0的出现会给手机厂商带来怎样的影响呢?厂商在适配新的SDK版本时,如何友好地展现权限申请过程、如何优化权限管理机制、如何提高Android设备的安全程度?我们期待手机厂商给我们带来更加友好更加安全的Android设备。
对开发者而言,应尽量使用SDK23及以上的版本来开发应用,并主动进行Dangerous权限动态检查与申请。现在处于动态权限检测与静态权限授予并存的过渡时期,可以预测未来Android操作系统与软件开发程序对静态权限授予模式的支持程度会大幅降低。
对安全厂商而言,在各类Android恶意应用中,权限滥用类应用占很大比重。与之前的静态权限授予机制相比,新权限模型的出现给恶意应用作者带来不小的压力,同时给安全厂商带来更高要求。
对用户而言,不管是静态权限模型还是动态权限模型,最终权限授予的主动权都在自己手中,特别是针对动态权限模型,用户具备更加灵活的权限管理能力,能够随时有效地阻止恶意行为,但如果用户不清楚最基本的权限与行为对应关系,那么想要通过动态权限模型增强设备安全就无从谈起。因此,用户应尽可能多地了解Android高危操作所涉及到的权限,以便在做出权限相关决策时尽量降低为设备带来的风险,同时,在日常用机时,尽量养成如下良好习惯:
Ø 慎重授予应用程序请求的权限
Ø 从可靠平台下载应用程序、安装来自受信任来源的应用程序
Ø 及时更新系统版本与软件版本
Ø 养成备份重要信息的好习惯
Ø 安装安全类软件