Service安全场景和危害
Service是android四大组件之一,一个Service是没有界面且能长时间运行于后台的应用组件。其他应用的组件可以启动一个服务运行于后台,即使用户切换到另一个应用也会继续运行。另外,一个组件可以绑定到一个service来进行交互,即使这个交互是进程间通讯也没问题。例如,一个service可能处理网络事物,播放音乐,执行文件I/O,或与一个内容提供者交互,所有这些都在后台进行。Service不是分离开的进程,除非其他特殊情况,他不会运行在自己的进程,而是作为启动运行它的进程的一部分。Service不是线程,这意味着它将在主线程里劳作。
如果一个导出的Service没有做严格的限制,任何应用可以去启动并且绑定到这个Service上,取决于被暴露的功能,这有可能使得一个应用去执行未授权的行为,获取敏感信息或者是污染修改内部应用的状态造成威胁。
Service漏洞分类
- 权限提升
- services劫持
- 消息伪造
- 拒绝服务
权限提升漏洞
当一个service配置了intent-filter默认是被导出的,如果没对调用这个Service进行权限限制或者是没有对调用者的身份进行有效的验证,那么恶意构造的APP都可以对此Service传入恰当的参数进行调用,导致恶意的行为发生比如说调用具有system权限的删除卸载服务删除卸载其他应用。
service劫持
攻击原理:隐式启动service,当存在同名service,先安装应用的service优先级高。
消息伪造
暴露的Service对外接收Intent,如果构造恶意的消息放到Intent中传输,被调用的Service接收有可能产生安全隐患。
如:指定升级下载的URL地址,可导致任意应用安装!
消息伪造
protected void onHandleIntent(Intent intent){
Intent v0;
String v23;
Serializable pushMsg=intent.getSerializableExtra("PushMsg");
...
AppVersionManager.getInstance(Youku.context).showAPpAgreementDialog();
switch(pushMsg.type){
case 1:{
goto label_53;
}
}
}
label_53:
intent.setFlags(876609536);
intent.setClass(this,UpdateActivity.class);
intent.putExtra("updateurl",pushMsg.updateurl);
intent.putExtra("updateversion",pushMsg.updateversion);
intent.putExtra("updatecontent",pushMsg.updatecontent);
intent.putExtra("updateType",2);
this.startActivity(intent);
return;
拒绝服务
Service的拒绝服务主要是来源于Service启动时对接收的Intent等没有做异常情况下的处理,导致的程序崩溃。主要体现的方面如给Service传输未null的intent或者是传输序列化对象导致接收时候的类型转化异常。
修复:
1.改成service exported false
2.删除多余测试代码,验证token
拒绝服务:防护
空指针异常
类型转换异常
数组越界访问异常
类未定义异常
其他异常
//Serializable:
Intent i = this.getIntent();
if(i.getAction().equals(“serializable_action”)){
i.getSerializableExtra(“serializable_key”);//未做异常判断
}
//Parcelable:
this.b=(RouterConfig)this.getIntent().getParcelableExtra(“filed_router_config”);//引发转型异常崩溃谨慎处理接收的intent以及其携带的信息。
对接收到的任何数据try catch处理,以及对不符合预期的数据做异常处理。
Service安全防护
- 私有service不定义intent-filter并且设置exported为false。
- 公开的service设置exported为true,intent-filter可以定义或者不定义。
- 合作service需对合作方的app签名做校验。
- 只被应用本身使用的service应设置为私有。
- service接收到的数据需谨慎处理。
- 内部service需使用签名级别的protectionLevel来判断是否为内部应用调用。
- 不应在service创建(onCreate方法被调用)的时候决定是否提供服务,应在onStartCommand/onBind/onHandleIntent等方法被调用的时候做判断。
- 当service又返回数据的时候,因判断数据接收app是否又信息泄露的风险。
- 有明确的服务需调用时使用显示意图。
- 尽量不发送敏感信息。
- 启动Activity时不设置intent的FLAG_ACTIVITY_NEW_TASK标签。