移动安全学习笔记——组件安全之BroadcastReceiver组件漏洞挖掘

0x00 BroadcastReceiver简介

1、漏洞场景
  • 广播即intent;

  • 当发送一个广播时,系统会将发送得到广播与系统中已注册的符合条件的接收者的intent-filter进行匹配,若匹配成功,则执行相应接收者的onReceive函数;

  • 发送广播时如果处理不当,恶意app便可以嗅探、拦截广播,致使敏感数据泄露;

  • 接收广播时处理不当则可以导致拒绝服务、消息伪造、越权操作。

2、漏洞分类
  • 信息泄露
  • 消息伪造
  • 权限绕过
  • 拒绝服务

0x01 敏感信息泄露

1、漏洞原理

发送的intent没有明确指定接收者,只是简单匹配Action。恶意app可以通过注册广播接收者嗅探拦截到这个广播,该广播的敏感信息将被窃取。

2、漏洞示例

隐式intent发送敏感信息:

private void d() {
    Intent v1 = new Intent();//隐私intent
    v1.setAction("com.sample.action.server_running");//设置action
    v1.putExtra("local_ip",v0.h);//设置key-value
    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:

public void onReceive(Context context,Intent intent){
	String s = null;
	if(intent.getAction().equals("com.sample.action.server_running")){
	//action匹配
		String pwd = intent.getStringExtra("connected");
		s="Airdroid => ["+pwd+"]/"+intent.getExtras();
	}
	Toast.makeTest(context,String.format("%sReceived",s),Toast.LENGTH_SHORT).show();
}
3、修复代码

使用LocalBroadcastManager.sendBroadcast发出的广播只能被app自身广播接收器接收。

Intent intent = new Intent("my-sensitive-event");
intent.putExtra("event","this is a test event");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

0x02 消息伪造

1、漏洞原理

暴露的Receiver对外接收Intent,如果攻击者构造恶意的消息放在Intent中传输,被调用的Receiver接收有可能产生安全隐患。

2、漏洞示例

比如构造短信发送内容给广播接收器:

public class SendSMSNowReceiver extends BroadcastReceiver {
    Context context;
	@Override  // android.content.BroadcastReceiver

	public void onReceive(Context arg8, Intent arg9) {
    	this.context = arg8;
   		SmsManager sms = SmsManager.getDefault();
    	Bundle bundle = arg9.getExtras();
   	 	sms.sendTextMessage(bundle.getString("phoneNumber"), null,bundle.getString("message"), null, null);
    	Utils.makeToast(this.context, "Your text message has been sent!", 1);
	}
}
3、修复代码

设置该组件注册时,声明ProtectionLevel为Signature验证。

android:protectionLevel="signature"

0x03 权限绕过*

1、漏洞原理
  • 广播接收器的两种注册方式
    • 静态注册:在Manifest.xml文件中通过<reciver>标签静态注册。
    • 动态注册:通过Context.registerReceiver()动态注册,指定相应的intentFilter参数。

动态注册的广播接收器是默认导出的,如果没有做权限限制,导致接收器可以接收一个外部可控的url或其他命令,导致越权利用某些功能。

2、防护

建议使用LocalBroadcastManager类,相较于Context.sendBroadcast(intent)有优势。

0x04 拒绝服务

1、漏洞原理

暴露的BroadcastReceiver没有设置相应的权限保护,很容易受到拒绝服务攻击。通过传递恶意畸形的intent数据给广播接收器,广播接收器无法处理异常导致crash。

2、防护

谨慎处理接收的intent以及其携带的信息。

对接收的任何数据做try catch处理,对不符合预期的信息做异常处理。

常见异常处理:

  • 空指针异常处理
  • 类型转换异常(序列化)
  • 数组越界访问异常
  • 类未定义异常
  • 其他异常

0x05 测试方法

1、查找动态广播接收器

反编译后查找registerReceiver()

2、查找静态广播接收器

反编译后查看配置文件查找广播接收器组件,注意exported属性。

3、查找发送广播内的信息

检索sendBroadcastsendOrderedBroadcast,注意setPackage方法和receivePermission变量。

0x06 安全建议

关键:intent-filter设置、exported属性设置

  • 私有广播接收器:设置exported=‘false’,并且不配置intent-filter

  • 粘性广播:不应包含敏感信息。

  • 有序广播:设置接收权限receivePermission,避免恶意应用设置高优先级抢收此广播后并执行abortBroadcast()方法。

  • 发送的广播包含敏感信息时需指定广播接收器,使用显示意图或者

     setPackage(String packageName)
    
  • 内部app之间的广播使用protectionLevel='signature'验证其是否真是内部app

  • 对接收来的广播进行验证,返回结果时需注意接收app是否会泄露信息。

0x07 参考

https://xuanxuanblingbling.github.io/ctf/android/2018/02/12/Android_app_part1/

上一篇:android基础学习——service及BroadcastReceiver


下一篇:【Android】BroadcastReceiver