导语:作为这个专题的第一篇文章,我们将这篇中简要叙述一下BLE协议和Android关于BLE相关的接口,这些内容比较倾向于基础知识,在专题后续的文章中有很多处都会用到这些知识点。
1、概述
最近受疫情影响,已经在家办公了很长一段时间,正好借此机会把此前的工作进行了一番整理,并挑选出来了一部分可以公开的题材,最终形成了这个专题的文章。
在我们的计划中,这个专题有两个主线,分别是:
a. BLE设备安全研究
b. 智能门锁的安全研究
其中,智能门锁是我们的主要研究目标,但由于很多智能门锁在蓝牙BLE这块的设计或多或少地有些小问题,所以我们就将一些BLE设备也单独拿出来,作为另一个线索,用以帮助专题内容的展开叙述。
这个系列,我们取名为《胖猴小玩闹》,因为在整个专题中出现的各种案例或者已经修复,或者危害程度不高,所以我们将这些无伤大雅的小打小闹统一称为“小玩闹”。
作为这个专题的第一篇文章,我们将这篇中简要叙述一下BLE协议和Android关于BLE相关的接口,这些内容比较倾向于基础知识,在专题后续的文章中有很多处都会用到这些知识点。当然,这里我们只是浅尝辄止地介绍,并不做深刻地讨论,有需要了解更多内容的读者可以参考相关的文档。
2、BLE协议
我们通常所说的蓝牙,即Bluetooth,有两种形式:传统蓝牙BR(Basic Rate)和低功耗蓝牙BLE(Bluetooth Low Energy)。前者的典型使用场景是蓝牙耳机、蓝牙音箱等,而后者的典型使用场景是各种IoT设备,如蓝牙手环等。
蓝牙的数据传输模型如下图2-1所示,分为Physical层、Logical层和L2CAP层:
图2-1 蓝牙协议的数据传输模型
为了帮助理解,可以类比OSI七层网络协议:数据发送时,高层将数据发送给L2CAP层,并逐层向下流动;数据接收时,设备从Physical层获得数据,并逐层向上流动。对这三层数据传输模型有一些简单的认知,就可以极大的加快我们分析和研究的速度。
首先,来关注下L2CAP层。在这一层中,我们需要关注的内容比较少,高层应用中出现的需要发送的BLE数据和需要接收的BLE数据都会直接出现在这一层之中,所以,如果我们能够抓到这一层的通信数据,则意味着我们可以直接抓到高层应用的通信数据,虽然这些数据可能是在应用层中被加密了,但至少这些数据还没有被BLE协议栈加密。这在某种程度上方便了我们的分析。通过wireshark分析L2CAP层的通信数据如下图:
图2-2 wireshark分析L2CAP层通信
上图中,ATT协议即为运行于L2CAP层之上的通信协议,wireshark可以直接分析出ATT协议中的通信数据。在本专题的后续文章中,我们可以看到抓取未加密的L2CAP层数据用于辅助分析的案例。
然后,我们再来关注下Physical层。Physical层定义了3个广播信道和37个数据通信信道。两个BLE设备进行连接时,会随机挑选一个广播信道进行广播,连接建立之后,会在37个通信信道上进行跳频通信。下图展示了某一次通信的流程:
图2-3 某一次BLE通信
上图中,BLE通信在0x27信道进行广播,等待BLE双方成功建立连接之后,会在0x5----0xA----0xF----0x14等信道,按照一定规律进行跳频通信。
最后,我们再来关注下Logical层。该层中主要完成BLE通信过程中的各种逻辑控制,这么说并不准确,但可以帮助我们理解问题。大多数使用场景中,一次BLE通信过程存在master和slave两方,其中master是主动扫描并发起连接的一方,而slave是不断发送广播并等待连接的一方。在一次通信中,master和slave的状态变化如下图所示:
图2-4 master和slave的状态变化
其中,scanner和advertiser分别表示master和slave的扫描状态和广播状态。建立连接之后,开始跳频通信,并成为最终的master和slave。
3、Android的BLE接口
绝大部分IoT设备都需要与Android/IOS手机通信,而BLE显然是一种很常见的通信方式。为此,我们也有必要了解一下Android设备中,关于BLE通信相关的各种API。
我们先回忆一下TCP的socket通信。在socket通信中,服务端程序运行于某一IP地址上,并持续监听某一端口(port)。客户端程序选择服务端的IP和port,发起socket连接,经过三次TCP握手之后完成socket连接的建立,此后使用该socket进行通信。蓝牙BLE通信也是如此,首先我们需要扫描周围的蓝牙BLE设备,并选择某个BLE设备。此时,需要用到的API如下:
表3-1 Andorid设备BluetoothLeScanner类中的常用接口
扫描并选择完毕之后,我们就需要与之通信。在TCP通信中,发送数据和接收数据常用的函数为:send和recv。而在BLE通信中,我们使用到的API如下表所示:
表3-1 Andorid设备BluetoothGatt类中的常用接口
上表中,读者可能对characteristic有些陌生,我们在这里对characteristic有一个简短的说明。每一个BLE设备,都有一个对应的profile,用于对这个设备进行描述。一个profile中包含多个service,这些service就是该设备提供的各种服务。而在一个service中,会有多个characteristic,设备提供的service就是靠这些characteristic来完成的。用一张图片来表示上述文字,如下:
图3-1 BLE profile实例
上图中,右侧图片为一个BLE设备的实例,可以看到在图片中有4个service,前两个为Unknown service,后两个分别是Battery Service(电池服务)和Current Time Service(当前时间服务)。而在第二个Unknown service中,有一个Unknown Characteristic。值得一提的是,Service和Characteristic各自拥有一个UUID用于标识,在BluetoothGatt类的相关函数中,就是用这些UUID找到所需的service和characteristic,这就相当于TCP通信中的端口(port)。
4、小结
这个系列的第一篇到此就要结束了,在本篇中,我们简要介绍了一下BLE协议栈以及Android BLE的常用API。后续的文章中,就会挑选一些我们遇到的设备,拿过来说一说讲一讲,这些文章都偏向于实战,纯理论的介绍相对会少一些,如果有条件的话,还期待各位读者能跟着我们实际操作一下,以帮助加深印象。
此外,胖猴的邮箱是:[email protected],有什么需要讨论的事情可以随时发邮件联系我们,也可以发给我们个人的邮箱地址。最后,希望大家都能有所收获。
作者:胡一米,邮箱:Yimi Hu & Light @ PwnMonkeyLabs
本文为 胖猴实验室 原创稿件,授权嘶吼独家发布,如若转载,请注明原文地址