做了一遍 BLE_CTF 貌似只是学习了如何是用工具与 ble 设备进行通信,希望扩展一下学些知识
参考:http://doc.iotxx.com/index.php?title=BLE技术揭秘
角色
低功耗蓝牙设备主要分为两种角色:主机(Central)和从机(Peripheral),主机与从机建立连接之后才能互相收发数据,主机可以发起对从机的扫描(例如手机),从机只能广播并接受主机的链接(例如智能手环)
另外还有观察者和广播者暂不讨论
蓝牙协议栈没有限制设备的角色,一个设备可以是主机也可以是从机(称为主从一体),可以发起连接也可以被别人连接
广播
从机每隔一段时间发送一次广播数据包,时间间隔称为广播间隔,只有从机处于广播状态时主机才能够发现从机
广播包最多能携带 31 字节的数据,一般包含可读的设备名称,设备是否可连接等信息
当主机收到从机广播的数据包后,它可以再发送获取更多数据包的请求,这个时候从机将广播扫描回应数据包,扫描回应数据包和广播包一样,可以携带31个字节的数据
扫描
主机通过扫描,可以获得从机的广播包以及扫描回应数据包,可以对已扫描到的从机发起连接请求,从而进行连接并通信
连接
连接的时候采用跳频方案,在特定时间、特定频道上通信
这里解释一下为啥要在没连接的时候开始抓包,因为 CC2540 USB Dongle 只能抓一个信道的数据,BLE 广播的时候在 37,38,39 随机选取一个信道,建立连接时根据一些设定好的参数跳频通信,只要抓到下面说的这个包,就可以跟着跳频通信
跳频算法
在建立连接的这个 ADV_CONNECT_REQ 包里面的 LLData 数据段中,有 ChM 和 Hop,这两个字段,其中 ChM 表示那些频道可用,Hop 表示跳频计算时的一个“参数”
例如我这个
ChM Hop
0c 01 00 00 1f 07
ChM 转为二进制是 00001100 00000001 00000000 00000000 00011111
ChM 二进制从右往左是各个频道的可用状态,1 为可用,0 为不可用
在这里可用频道就有 use=[0,1,2,3,4,24,34,35],可用频道数量为8
计算下一次使用频道的公式为 fn+1 = (fn + hop) mod 37
,其中第一次fn为0
所以下一次使用的频道是 fn+1=(0+7) mod 37 = 7,但是可用频道列表里面没有7
就用 use[ 7 mod 可用信道数 ] 即 use[7 mod 8] 即 use[7] = 35 即 0x23
上一次的fn+1作为下一次的fn,再来一遍上面的操作
fn+1 = (7+7) mod 37 = 14,14不可用,所以use[14 mod 8] = 34 即 0x22
fn+1 = (14+7) mod 37 = 21,21不可用,所以use[21 mod 8]= 24 即 0x18
fn+1 = (21+7) mod 37 = 28,28不可用,use[28 mod 8] = 4 即 0x4
……
验证一下:
交换 Feature 和 Version
LL_Connect_Update_Req
通信
BLE 协议里引入了服务(Service)和特征值(Characteristic)的概念,每个服务和特征值都有唯一的 UUID,一个从机包含一个或多个服务,每个服务又有一条或多条特征值,每个特征值都有自己的属性(Property),属性有:可读(Read)、可写(Write)、通知(Notify),可读可写表示该特征值可以被主机读写,通知表示从机可以主动向主机发送通知数据
配对过程分析
协议中其实只有三步:
1、Pairing Feature Exchange(配对特征交换)
2、STK/LTK Generation(短期或长期密钥生成)
3、Transport Specific Key Distribution(密钥分发)
用简单的话来说,配对目的就防止两种攻击:被动监听和MITM,防止MITM需要人机交互操作,所以所有的JUSTWORK都没法防止这种攻击。被动监听目前采用非对称加解密方式,即可破解,所以采用EDCH的SSP以及LE SECURE CONNECTION都能防止这种攻击。
作者:城市牧场 链接:https://www.zhihu.com/question/29076831/answer/201659080
配对特征交换
这一步会交换双方的配对能力与认证要求,例如 IO Capability 表示设备有哪些输入输出能力(是否能用键盘或者显示信息啥的)、OOB 表示设备是否可以通过其他方式(比如 NFC、红外)进行认证、MITM 表示设备是否请求中间人身份验证(这样就会需要人工判断信息)还会根据 Secure Connection 选择是使用安全连接( LE Secure Connections)还是遗留配对(LE legacy pairing)
具体来看,IO Capability 表示支持哪些 IO 能力(一个字节)
值 | 描述 |
---|---|
0x00 | 只能显示 |
0x01 | 显示且能输入YES还是NO |
0x02 | 只有键盘 |
0x03 | 没有输入输出 |
0x04 | 有键盘且能显示 |
0x05-0xFF | 预留 |
是否支持 OOB,即通过带外通道的方式进行认证,因为对于蓝牙攻击者来说这种方式是不可见的,所以安全些(一个字节)
值 | 描述 |
---|---|
0x00 | OOB 数据没有发送 |
0x01 | OOB 数据通过远端设备发送 |
0x02-0xFF | 预留 |
AuthReq 也是一个字节,但是不同的位有不同的含义,分别是
Reserved、Keypress Flag、Secure Connection Flag、MITM Flag、Bonding Flags
Keypress Flag 仅在 Passkey Entry 协议中使用,当设置为 1 时使用 摁键配对
Secure Connection Flag 如果设备支持 LESC 安全连接配对就设置为 1,否则为 0
MITM 如果设备请求 MITM 保护中间人身份验证,就设置为 1,否则为 0
Bonding Flags 表示设备请求绑定的类型
值 | 描述 |
---|---|
00 | 不绑定 |
01 | 绑定 |
10 | 预留 |
11 | 预留 |
关于配对方式的选择
应该是先判断 OOB,如果双方 OOB 均为 1 的话,优先使用 OOB,任何一个没有 OOB 就根据 MITM 判断,如果两个都没有要求 MITM 的话就 JUST WORK 了,如果是任何一个有 MITM 的话就看 IO 能力,画个表格大概是这样的
OOB 为 1 | OOB 为 0 | MITM 为 1 | MITM 为 0 | |
---|---|---|---|---|
OOB 为 1 | 用 OOB | 看 MITM |
|
| | OOB 为 0 | 看 MITM | 看 MITM |
|
| | MITM 为 1 |
|
| 看 IO 能力 | 看 IO 能力 | | MITM 为 0 |
|
| 看 IO 能力 | JUST WORK |
根据两个设备 IO 能力的不同,有不同的配对方式,知乎上大佬做了个图很清晰(照着大佬的图画个表)
发起者/应答者 | 只能显示 | 显示且能输入YES/NO | 只有键盘 | 无输入输出 | 键盘和显示 |
---|---|---|---|---|---|
只能显示 | just work或数字比较,工作链路不可靠 | just work或数字比较,工作链路不可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 | just work,工作链路不可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 |
显示且能输入YES/NO | just work或数字比较,工作链路不可靠 | just work或数字比较,工作链路不可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 | just work,工作链路不可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 |
只有键盘 | 输入密码:应答者显示,发起者输入。加密链路可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 | 输入密码:发起者输入。加密链路可靠 | just work,工作链路不可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 |
无输入输出 | just work,工作链路不可靠 | just work,工作链路不可靠 | just work,工作链路不可靠 | just work,工作链路不可靠 | just work,工作链路不可靠 |
键盘和显示 | 输入密码:应答者显示,发起者输入。加密链路可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 | just work,工作链路不可靠 | 输入密码:应答者显示,发起者输入。加密链路可靠 |
双方生成 Key Generation
密钥生成的方式是根据上一步的配对特征确定的
对于 LE legacy Pairing 会生成两个 key:
- Temporary Key,用于生成 Short Term Key 的临时密钥
- Short Term Key,用于加密配对后的通信的临时密钥
对于 LE Secure Connections 会生成一个 Key:
- Long Term Key,用于加密配对后的通信
当完成配对特征交换之后进行配对确认,先是发起者向应答者发送一个确认值(Confirm Value),然后应答者返回一个确认值,双方确认对方发送的确认值跟自己计算出来的确认值是否相同,相同就进入到下一步互相发送 Random Value
发送一个
协议栈
各芯片厂商具体实现各有不同,但都很相似,自顶向下大致分为三层
Application(应用)、Host(主控)、Controller(控制器)
其实 Application 使用来调用协议栈提供的接口的实现蓝牙功能的,不属于协议栈
Physical Layer 物理层
Link Layer 链路层
HCI层
Host Controller Interface,提供了标准的蓝牙事件以及命令接口,用于上下层通信
L2CAP层
Logical Link Control and Adaption Protocol 逻辑链路控制和适配层
负责逻辑链路的连接和数据的分发
ATT 和 SMP层
GAP 和 GATT
GAP是 Generic Access Profile 的缩写,中文含义是:通用访问配置文件,定义了 BLE 设备如何使其自身可用,以及两个设备如何直接相互通信,定义了 Peripheral 和 Central、Broadcaster 和 Observer。前者是建立连接后通信,从设备通常是外设,比如手环、血压计等,主设备通常是手机、PC。后者不建立连接通信的,是通过广播和解析广播的方式进行数据的传播与获取。
GATT是 Generic Attribute Profile 的缩写,是基于 ATT 的 Profile,中文含义是:通用属性配置文件,定义了一旦建立连接后如何传输属性,整合了 ATT 的读写操作,提供给上层的 Profile 用
GATT 中存在服务端和客户端的定义,与主从设备无关,主要取决于数据的流动方向,比如客户端(主机如手机)需要从服务端(从机如手环)读取心跳等信息
GATT 提供了通知(notifications)和指示(indications),客户端可以请求服务器请求通知一项特征(Characteristic),服务器可以在其变为可用时发送给客户端,避免客户端轮询服务器造成服务器无线电一直保持运行状态,指示(indication)与通知类似,但是它需要客户端响应已收到的消息
即通知(notification)只是告知客户端,不需要确认,指示(indication)需要客户端确认
BLE 所有的 Profile 都是有 service 和 characteristic 构成的,一个标准的 Profile 至少有一个 service 组成,一个 service 至少有一个 characteristic 组成,每个 characteristic 都有一个 value,这个 value 就是 BLE 的实际数据