实战分析某租房App实现一键解锁个人蓝牙门锁
字数 1324 2025-08-29 08:30:36
某租房App蓝牙门锁一键解锁实战分析
测试环境准备
- 设备: Pixel 3
- Android版本: 12
- Root工具: Magisk Delta 26.4-kitsune (26400)
分析流程
一、获取安装包
首先需要提取目标App的安装包(APK文件),可以通过以下方式获取:
- 使用ADB命令从已安装设备提取
- 从应用商店下载
- 使用第三方APK提取工具
二、反编译APK获取DEX
使用在线反编译网站或本地工具将APK转换为可分析的DEX/JAR文件:
- jadx-gui
- Apktool
- dex2jar等工具
三、使用jadx-gui分析源码
-
定位应用入口:
- 确定App主包位置:
com.xxxx.xxxxxxxxxxxx.application.MyApplication
- 确定App主包位置:
-
搜索关键字符串:
- 全局搜索"开锁成功"字符串
- 通过提示词定位到蓝牙开锁相关代码区域
-
分析蓝牙模块:
- 右键查看
onScanSuccess的查找用例 - 选择可分析的代码路径(第二个用例)
- 对
unLockResultSuccess函数使用Frida进行hook验证
- 右键查看
-
深入分析解锁流程:
- 查看
unLockResultSuccess接口实现 - 定位到75行左右的函数调用处
- 分析调用蓝牙解锁的核心代码
- 查看
四、获取蓝牙密钥
-
定位AES解密代码:
- 找到
AESUtil.Decrypt函数 - 使用Frida hook该函数并打印参数
- 找到
-
获取密钥:
- 从hook结果中提取
str2参数(蓝牙密钥)
- 从hook结果中提取
五、分析蓝牙通信流程
-
数据发送分析:
- 定位
AESUtil.Encrypt()函数 - 使用Frida hook加密函数
- 分析hook结果发现App发送两次数据
- 定位
-
通信流程解析:
App发送: 初始字符串"A" → AES加密 → 发送给门锁 门锁返回: 加密数据"B" App处理: 解密"B" → 截取第7-14位(8位) → 构造新字符串 → AES加密 → 发送给门锁 → 开锁成功 -
数据格式细节:
- 初始字符串:
"01010100000000000000000000000000" - 返回数据处理: 截取解密后字符串的第7-14位(共8位)
- 第二次发送数据格式:
02010501[8位数据]0000000000000000
- 初始字符串:
六、蓝牙调试验证
-
使用蓝牙调试助手:
- 发送第一个固定加密数据
- 验证是否能收到门锁返回数据
-
验证结果:
- 成功接收门锁返回数据,证明分析方向正确
七、实现自动化解锁
-
选择开发工具:
- 使用AutoJS(需修改其AndroidManifest.xml添加蓝牙权限)
- GitHub地址: https://github.com/SuperMonster003/AutoJs6
-
修改AutoJS权限:
<!-- 添加以下权限到AndroidManifest.xml --> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> -
编写解锁脚本:
// 1. 获取蓝牙适配器
let bluetoothAdapter = android.bluetooth.BluetoothAdapter.getDefaultAdapter();
// 2. 定义GATT回调
let gattCallback = new android.bluetooth.BluetoothGattCallback({
onCharacteristicChanged: function(gatt, characteristic) {
// 接收到特征数据变化时调用的回调
let receivedData = characteristic.getValue();
// 处理接收到的数据...
}
});
// 3. 辅助函数
function createJavaByteArray(hexString) {
// 将十六进制字符串转换为Java字节数组
}
function bytesToHexString(bytes) {
// 将字节数组转换为十六进制字符串
}
function writeCharacteristic(device, serviceUuid, charUuid, data) {
// 向设备的特征写入数据
}
// 4. 实现解锁流程
function unlockProcess() {
// 连接蓝牙设备
// 发送第一个加密数据
// 接收并处理返回数据
// 构造并发送第二个加密数据
// 完成解锁
}
- 脚本部署:
- 在AutoJS中创建快捷方式
- 点击即可执行蓝牙解锁
技术要点总结
-
关键发现:
- 成功提取蓝牙门锁的AES密钥
- 解析出蓝牙通信的双向数据流程
- 确定了数据加密前后的格式转换规则
-
安全漏洞:
- 使用固定密钥,缺乏动态更新机制
- 通信流程可被逆向重现
- 无有效的防重放攻击措施
-
防御建议:
- 实现动态密钥交换机制
- 增加时间戳或随机数防重放
- 加强通信数据加密强度
- 加入设备身份双向认证
免责声明
本技术分析仅用于安全研究目的,请勿用于非法用途。任何不当使用造成的后果由使用者自行承担。实际测试应在合法授权范围内进行。