网站首页 > 博客文章 正文
上篇BLE分析及实践——模拟智能门锁已经通过树莓派把智能门锁模拟好了,下一步来进行抓包实践
这个已经完成了分析,下篇来最终说明对智能门锁的攻击过程
使用蓝牙扫描APP
环境:android
工具:no.nordicsemi.android.mcp_87.apk
依次点开可以看到相应的属性及属性值
使用工具bleah
地址:https://github.com/evilsocket/bleah/ 安装上,直接运行bleah。
输出
+ b8:27:eb:90:28:e1 (-45 dBm) -----------------------------------------------+
| Vendor | Raspberry Pi Foundation |
| Allows Connections | ? |
| Flags | LE General Discoverable, BR/EDR |
| Manufacturer | u'4c0002156834636b6d334c30634b38454163304e49c7d89dc5' |
这个就是我们模拟出来的智能门锁。
使用bleah -b "b8:27:eb:90:28:e1" -e 连接
输入的内容为:
+--------------+------------------------------------------------------------+-----------------------+------------------+
| Handles | Service > Characteristics | Properties | Data |
+--------------+------------------------------------------------------------+-----------------------+------------------+
| 0001 -> 0005 | Generic Access ( 00001800-0000-1000-8000-00805f9b34fb ) | | |
| 0003 | Device Name ( 00002a00-0000-1000-8000-00805f9b34fb ) | READ | u'raspberrypi' |
| 0005 | Appearance ( 00002a01-0000-1000-8000-00805f9b34fb ) | READ | Generic Computer |
| | | | |
| 0006 -> 0009 | Generic Attribute ( 00001801-0000-1000-8000-00805f9b34fb ) | | |
| 0008 | Service Changed ( 00002a05-0000-1000-8000-00805f9b34fb ) | INDICATE | |
| | | | |
| 000a -> 0015 | 6834636b-6d33-4c30-634b-357276314333 | | |
| 000c | 6834636b-6d33-4c30-634b-436852436d44 | WRITE | |
| 000f | 6834636b-6d33-4c30-634b-436852443454 | NOTIFY INDICATE | |
| 0013 | 6834636b-6d33-4c30-634b-436852537434 | NOTIFY READ INDICATE | |
| | | | |
+--------------+------------------------------------------------------------+-----------------------+------------------+
工具已经做好了data的解析
可以看到handle为 000c的是可写的,uuid是: 6834636b-6d33-4c30-634b-436852436d44,是属于厂商自定义的uuid值,但是此时并不知道是写入的啥值才能操作智能门锁。
使用工具gatttool
直接运行 gatttool -b b8:27:eb:90:28:e1 -I
此时出现:
[b8:27:eb:90:28:e1][LE]> connect
Attempting to connect to b8:27:eb:90:28:e1
Connection successful
[b8:27:eb:90:28:e1][LE]>
提示连接成功,此时已经与智能门锁建立了链接
使用 primary查看主要的server
使用 characteristics 查看所有的属性
handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0007, char properties: 0x20, char value handle: 0x0008, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x000b, char properties: 0x08, char value handle: 0x000c, uuid: 6834636b-6d33-4c30-634b-436852436d44
handle: 0x000e, char properties: 0x30, char value handle: 0x000f, uuid: 6834636b-6d33-4c30-634b-436852443454
handle: 0x0012, char properties: 0x32, char value handle: 0x0013, uuid: 6834636b-6d33-4c30-634b-436852537434
使用 char-read-hnd或 char-read-uuid来读取里面的值
我们来读
[b8:27:eb:90:28:e1][LE]> char-read-uuid 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0003 value: 72 61 73 70 62 65 72 72 79 70 69
是ASCII码,转码的话可以看到就是 raspberrypi
里面还有
char-write-req <handle> <new value> Characteristic Value Write (Write Request)
char-write-cmd <handle> <new value> Characteristic Value Write (No response)
两个方法,就可以往智能门锁中写入蓝牙数据。
获取BLE的数据
1、手机蓝牙日志首先需要打开开发者调试工具,抓取蓝牙数据包,这个网上有不少的教程,这里不再细说。
抓取到的log文件可以直接用wireshark打开,这里做了两个操作,一个开锁,一个关锁。
wireshark打开后的界面显示如下:
APP端为localhost,智能门锁为remote。
结合下文的协议栈可以看到上层的协议为ATT:
过滤协议ATT:
可以看到均是对handle为000c的写操作,符合前面的分析。
直接看数据值,有两个值:bb010203040506070809101112131415 和 aa010203040506070809101112131415
也就是说发送这两个数据就会产生开锁和关锁的操作,这里先记录下来,后面我们演示攻击时候再用。
这时候直接发送这个数据,门锁是不认的,原因是没有进行配对操作,在看树莓派上的日志输出可以看到:
Status read request:
AUTH INIT: returning random challenge : 6db291ac9963003618ca6aa15063c4d6
>> received cmd: ae2d1892143ec2c986edeff444abfabc00
KEY ID: 0
AUTH RESP: ae2d1892143ec2c986edeff444abfabc
CRYPTED step 1: 37c3fb1f48f5038af2cb250123e6d67a
CRYPTED final: ae2d1892143ec2c986edeff444abfabc
AUTHENTICATION OK!
里面是包含了认证的过程的。
我们在手机上抓包认证过程:
2、 认证过程分析我们分析这个认证过程:
客户端请求handle:0x0013 uuid:6834636b?6d33?4c30?634b?436852537434
服务器端返回一个值:769675d7c11f336ae6573e7e533570ec
客户端写入一个值:e1cbdfb88d05890a935bf830fb9fbd1000
此时完成了认证过程。
客户端应该是利用服务器返回的值计算一个值,与服务端一致则可通过认证 这个值得计算过程在app中应该是存在的,我们反编译APP查找计算逻辑。
反编译的过程不再多说。
找到的逻辑为:
Log.d("Authentication", "Challenge: " + v5);
if(v5.equals("AUTHENTICATED")) {
DeviceControlActivity.this.hackmelockDevice.status = Status.AUTHENTICATED;
return;
}
byte[] v2 = utils.hexStringToByteArray(v5);
int v7 = 0;
if(DeviceControlActivity.this.hackmelockDevice.isOwn()) {
v7 = 0;
}
else if(DeviceControlActivity.this.dbHelper.getKey(DeviceControlActivity.this.hackmelockDevice.Major, DeviceControlActivity.this.hackmelockDevice.Minor, 1) != null) {
v7 = 1;
}
else {
Log.e(DeviceControlActivity.TAG, "No configured key!");
}
DeviceControlActivity.this.mBluetoothLeService.queueWriteDataToCharacteristic(DeviceControlActivity.this.hackmelockCommandChar, DeviceControlActivity.this.hackmelockDevice.calculateResponse(v2, v7));
calculateResponse函数为:
public byte[] calculateResponse(byte[] arg22, int arg23) {
byte[] v5;
byte[] v11 = new byte[17];
new byte[16];
byte[] v10 = new byte[1];
Arrays.fill(v10, ((byte)arg23));
int v17 = 4;
try {
byte[] v16 = new byte[v17];
Arrays.fill(v16, 0);
byte[] v9 = new byte[16];
Log.d("Crypto", "Key[" + arg23 + "]=" + utils.bytesToHex(this.keys[arg23]));
System.arraycopy(this.keys[arg23], 0, v9, 0, 12);
System.arraycopy(v16, 0, v9, 12, 4);
Log.d("Crypto", "KeyFinal " + utils.bytesToHex(v9));
SecretKeySpec v12 = new SecretKeySpec(v9, "AES");
Cipher v4 = Cipher.getInstance("AES");
v4.init(1, ((Key)v12));
byte[] v14 = Arrays.copyOf(v4.doFinal(arg22), 16);
Log.d("Auth", "Step 1 - session key : " + utils.bytesToHex(v14));
SecretKeySpec v7 = new SecretKeySpec(v14, "AES");
Cipher v13 = Cipher.getInstance("AES");
v13.init(1, ((Key)v7));
v5 = Arrays.copyOf(v13.doFinal(utils.hexStringToByteArray("DDAAFF03040506070809101112131415")), 16);
Log.d("Auth", "Step 2 - auth : " + utils.bytesToHex(v5));
}
catch(Exception v8) {
Log.e("Auth", "Cannot initialize AES! " + v8.getMessage());
}
System.arraycopy(v5, 0, v11, 0, 16);
System.arraycopy(v10, 0, v11, 16, 1);
return v11;
}
相关的配置信息是:
public static final String cmdCloseLock = "BB010203040506070809101112131415";
public static final String cmdDataTransfer = "01AA0203040506070809101112131415";
public static final String cmdOpenLock = "AA010203040506070809101112131415";
public byte[][] keys;
public int own;
public static final String passLogin = "DDAAFF03040506070809101112131415";
public Status status;
public static final String statusAuthenticated = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
public static final String statusConfigMode = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
static {
HackmelockDevice.HACKMELOCK_IBEACON_UUID = UUID.fromString("6834636b-6d33-4c30-634b-38454163304e");
HackmelockDevice.HACKMELOCK_SERVICE_UUID = UUID.fromString("6834636b-6d33-4c30-634b-357276314333");
HackmelockDevice.HACKMELOCK_COMMAND_UUID = UUID.fromString("6834636b-6d33-4c30-634b-436852436d44");
HackmelockDevice.HACKMELOCK_STATUS_UUID = UUID.fromString("6834636b-6d33-4c30-634b-436852537434");
HackmelockDevice.HACKMELOCK_DATATRANSFER_UUID = UUID.fromString("6834636b-6d33-4c30-634b-436852443454");
从这个配置信息也能看到开锁和关锁的蓝牙数据。
加密逻辑采用了AES算法:
1. 首先使用key对传递过来的挑战码进行AES加密,生成下一步用的加密key
2. 使用生成的加密key对登入密码DDAAFF03040506070809101112131415进行加密,生成认证码
关键是找首次加密的key,在第一次启动的时候会有个唯一的设备号,第一次的私钥应该是和设备号的生成有关。
初始化设备和app,重新使用wireshark抓包 门锁传递密钥.log
可以看到是app给设备端写的密钥,所以应该是app生成的密钥信息,然后写给设备端。
触发这个写密钥的操作为:
app首先请求设备端的handle为0x0013的值,设备返回未空,
也就是BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 后面app向0x000c写一个设备号,然后写密钥信息进去,然后设备AES计算完成配对。
其实设备端留有个后门:
if ( (authResponse === fin_16.toString('hex')) || (authResponse === '4861636b6d654c6f636b4d6173746572')) {
console.log('AUTHENTICATION OK!'.green);
this.authenticated = true;
this.status = statusAuthenticated;
}
有个万能密钥:4861636b6d654c6f636b4d6173746572
3、ubertooth嗅探
ubertooth是个很强大的蓝牙嗅探工具,安装比较复杂,你要信任docker的话直接用docker启动ubertooth就可以,还是比较方便的。
需要注意的是需要特权模式,将dev目录挂载到docker里面
docker run --rm -it --privileged -v /dev:/dev meatmanek/ubertooth:latest
查看版本号:
root@da81bdbaf272:/ubertooth-2015-10-R1/host/kismet/plugin-ubertooth-phyneutral# ubertooth-util -v
Firmware revision: 2015-10-R1
说明docker识别了设备
上面我们知道了模拟门锁的mac地址为:b8:27:eb:90:28:e1,只要使用ubertooth ?f ?t b8:27:eb:90:28:e1 跟踪数据,进行嗅探即可。
4、中间人
采用的工具是https://github.com/DigitalSecurity/btlejuice
搭建测试环境,具体过程不细说了,具体用到了一个虚拟机,可以在`https://mega.nz/#!vxU0zIwJ!fMotiX3ARWcwNm67IAtn2ymHKldpVJgo43YkVZrtH4A` 下载虚拟机镜像
过程中出现了vbox无法识别usb设备的问题,这个只需要把当前用户加到vbox的组里就行,还有出现一些无法发现 service的问题,具体可以在issus中查找到问题原因。
搭建好了之后:
vbox运行代理:btlejuice_proxy
宿主机运行btlejuice ?u 代理ip ?w
打开本地的8080端口,出现web页面
后面直接操作即可,很直观的操作。
下面主要是分析,我们用APP连接设备,看到web上有数据输出,也就是说代理已经截获到了app与设备之间的数据:
根据前面的分析得知read首先去读取的是挑战码,然后APP根据AES计算处认证值写入设备完成匹配,看到第二条数据应该就是认证码,第三条数据是写入开锁的操作。
- 上一篇: wireshark抓包及结果分析知识大全
- 下一篇: 开发过程中快速抓包并解析(编写抓包工具)
猜你喜欢
- 2024-10-19 IP和TCP抓包分析实验(ipv4抓包实验)
- 2024-10-19 抓包分析之蠕虫网络行为特征(蠕虫抓取软件)
- 2024-10-19 wireshark抓包工具的使用详解(wireshark抓包工具的工作原理)
- 2024-10-19 西门子S7协议抓包分析并用代码实现(二)
- 2024-10-19 玩玩抓包(七)巧用“科来”,让分析更轻松
- 2024-10-19 WireShark抓包报文结构分析(wiresharkicmp抓包分析)
- 2024-10-19 wireshark及抓包分析助力网络工程师甩锅、TCP滑动窗口机制
- 2024-10-19 SSL/TLS握手详解抓包分析(ssl握手失败是什么意思)
- 2024-10-19 记一次抓包的最基本原理(抓包程序原理)
- 2024-10-19 如何使用Wireshark捕获和分析网络数据包?
你 发表评论:
欢迎- 367℃用AI Agent治理微服务的复杂性问题|QCon
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 357℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 346℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 345℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 342℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)