Broadcast Receiver安全场景和危害
BroadcastReceiver是Android的四大组件之一,这个组件涉及两个概念:广播发送者和广播接受者。 这里的广播实际上指的就是intent。 当发送一个广播时,系统会将发送的广播(intent)与系统中所有注册的符合条件的接收者的IntentFilter进行匹配,若匹配成功,则执行相应接收者的onReceive函数。 发送广播时如果处理不当,恶意应用便可以嗅探、拦截广播,致使敏感数据泄露等;如果接收广播时处理不当,便可导致拒绝服务攻击、伪造消息、越权操作等。
Broadcast Receiver漏洞分类
- 敏感信息泄露
- 权限绕过
- 消息伪造
- 拒绝服务
敏感信息泄漏漏洞
发送的intent没有明确指定接收者,而是简单的通过action进行匹配。恶意应用便可以注册一个广播接收者嗅探拦截到这个广播,如果这个广播里存在敏感数据,就被恶意应用窃取了。
隐式意图发送敏感信息:
代码语言:javascript复制private void d() {
Intent v1 = new Intent();
v1.setAction("com.sample.action.server_running");
v1.putExtra("local_ip",v0.h);
v1.putExtra("port",v0.i);
v1.putExtra("code",v0.g);
v1.putExtra("connected",v0.s);
v1.putExtra("pwd_predefined",v0.r);
if(!TextUtils.isEmpty(v0.t)){
v1.putExtra("connected_usr",v0.t);
}
sendBroadcast(v1);
}
POC:
代码语言:javascript复制public void onReceive(Context context,Intent intent){
String s = null;
if(intent.getACtion().equals("com.sample.action.server_running")){
String pwd=intent.getStringExtra("connected");
s="Airdroid => [" pwd "]/" intent.getExtras();
}
Toast.makeTest(context,String.format("%sReceived",s),Toast.LENGTH_SHORT).show();
}
敏感信息泄露漏洞:修复
修复后代码,使用LocalBroadcastManager.sendBroadcast()发出的广播只能被app自身广播接收器接收。
代码语言:javascript复制Intent intent = new Intent("my-sensitive-event");
intent.putExtra("event","this is a test event");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
权限绕过漏洞
可以通过两种方式注册广播接收器,一种是在AndroidManifest.xml文件中通过标签静态注册。另外一种是通过Context.registerReceiver()动态注册,指定相应的intentFilter参数。然而动态注册的广播默认是导出的。如果导出的BroadcastReceiver没有做权限控制,导致BroadcastReceiver组件可以接收一个外部可控url、或者其他命令,导致攻击者可以越权利用应用的一些特定功能,比如发送恶意广播、伪造消息、任意应用下载安装、打开钓鱼网站等。
程序加锁解锁是靠广播来控制的,并且这两条广播没做权限限制,任意应用可以发送此广播达到恶意解锁、恶意锁定应用的目的。
code:
代码语言:javascript复制android.intent.action.PACKAGE_FULLY_REMOVED
漏洞证明:
代码语言:javascript复制简单测试方法用adb shell 发送广播
code区域:
代码语言:javascript复制am broadcast -a android.intent.action.PACKAGE_FULLY_REMOVED -d package:com.wumii.android.mimi
权限绕过漏洞:修复
推荐使用呢LocalBroadcastManager类,这个类相较于Context.sendBroadcast(intent)有下面三方面的优势。
1.不用担心敏感数据泄露,通过这种方式发送的广播只能应用内接收。 2.不用担心安全漏洞被利用,因为其他应用无法发送恶意广播给你。 3.它比系统的全局广播更高效。
消息伪造
代码语言:javascript复制暴露的Receiver对外接收Intent,如果构造恶意的消息放在Intent中传输的,被调用的Receiver接收有可能产生安全隐患。
Intent i= new Intent();
i.setAction("com.baidu.android.oushservice.action.MESSAGE");
Bundle b = new Bundle();
JSONObject jsobject = new JSONObject();
JSONObject custom_content_js = new JSONObject();
jsobject.put("title","百度云盘【漏洞你中奖了!】");
jsobject.put("descrption","");
//jsobject.put("url","http://bcscdn.baidu.com/netdisk/BaiduYun_5.1.0.apk");
JSONObject customcontent_js = new JSONObject();
customcontent_js.put("type","1");
customcontent_js.put("msg_type","resources_push");
消息伪造 防护
代码语言:javascript复制设置为签名验证
android:protectionLevel="signature"
<receiver android:name="com.umeng.message.UmengMessageBootReceiver" android:protectionLevel="signature">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
拒绝服务
如果敏感的BroadcastReceiver没有设置相应的权限保护,很容易受到攻击。最常见的是拒绝服务攻击。拒绝服务攻击指的是,传递恶意畸形的intent数据给广播接收器,广播接收器无法处理异常导致crash。
拒绝服务攻击的危害视具体业务场景而定,比如一个安全防护产品的拒绝服务、锁屏应用的拒绝服务、支付进程的拒绝服务等危害就是巨大的。
拒绝服务 防护
- 空指针异常
- 类型转换异常
- 数组越界访问异常
- 类未定义异常
- 其他异常 //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处理,以及对不符合预期的数据做异常处理。
Broadcast安全防护
- 私有广播接收器设置exported=’false’,并且不配置intent-filter。(私有广播接收器依然能接收到同UID的广播)。
- 对接收来的广播进行验证。
- 内部app之间的广播使用protectionLevel=’signature’ 验证其是否真是内部app。
- 返回结果时需注意接收app是否会泄露信息。
- 发送的广播包含敏感信息时需指定广播接收器,使用显示意图或者setPackage(String packageName)。
- 使用LocalBroadcastManager。