本文介绍苹果BLE协议漏洞导致的蓝牙信息泄露。
分析
首先分析BLE流量,解锁手机并运行BLE sniffer:
python ble_adv_search.py -m 54:69:F1:23:2B:47
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
...
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
...
关上手机:
...
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c0010050b1c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c001005031c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c001005031c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c001005031c0fc556
[54:69:F1:23:2B:47] 0e02011a0aff4c001005031c0fc556
...
从中可以看出只有一个字节反映了屏幕状态的状态。苹果使用ADV_IND
消息来发送当前状态数据。
下面的典型的advertise
数据包结构:
0 1 2 3 4
+---------------------------------------------------------------------------+
| |
| Access Address |
| |
+------------------------------------+--------------------------------------+
| | |
| Header | |
| | |
+------------------------------------+ |
| |
| Advertising Address |
| |
+-----------------------------------------------------------+---------------+
| | |
| Length/Type(0x01)/Flags | Length |
| | |
+---------------+-----------------------------------------------------------+
| | | |
| Type(0xFF) | Company ID(0x004c) | Message type |
| | | nearby/airdrop|
+-----------------------------------------------------------+---------------+
| | |
|Message Length | Message data |
| | |
+---------------+-----------------------------------------------------------+
通过手机开关、点击菜单、修改设置、运行不同的APP,研究人员找出了负责WiFi和缓存状态和其他BLE消息类型的域。
0x05 - Airdrop
0x07 - Airpods
0x10 - Nearby
0x0b - Watch Connection
0x0c - Handoff
0x0d - Wi-Fi Settings
0x0e - Hotspot
0x0f - Wi-Fi Join Network
Nearby
下面是一个Nearby 消息:
0 1 2 5
+--------+--------+--------------------------------+
| | | |
| status | wifi | other |
| | | |
+--------+--------+--------------------------------+
Status状态包括:
0x0b - Home screen
0x1c - Home screen
0x1b - Home screen
0x11 - Home screen
0x03 - Off
0x18 - Off
0x09 - Off
0x13 - Off
0x0a - Off
0x1a - Off
0x01 - Off
0x07 - Lock screen
0x17 - Lock screen
0x0e - Calling
0x5b - Home screen
0x5a - Off
因此可以写一个简单的包分析器来实时获取附近苹果设备的数据:
为了进一步分析BLE 包,研究人员使用Adafruit Bluefruit LE Sniffer 来分析Wireshark BLE流量。
Wi-Fi密码分享
然后研究人员分析两个设备交互时是如何识别对方的。该过程用来连接WiFi。
在尝试连接到网络时,设备会发送以下BLE包:
c03080fc5563125c9d087555a77e3e2005f10020b0c
在不同设备上尝试连接到不同的SSID(也可以逆向IDA/radare/gydra
的sharingd
),研究人员发现发送的消息格式如下:
0 1 2 5 8 12 15 18
+--------+-------+------------------------+-------------------------+-----------------------+----------------------+----------------------+
| | | | | | | |
| flags | type | auth tag | sha(appleID) | sha(phone_nbr) | sha(email) | sha(SSID) |
| | (0x08)| | | | | |
+--------+--------------------------------+-------------------------+-----------------------+----------------------+----------------------+
可以看出,设备发送的前3个字节是phone number/email/appleID sha256(phone_number)[0:3]
的SHA256
哈希值。
下面介绍如何从哈希值的前3个字节来恢复出来手机号码。
首先要了解手机号的格式——E.164
。
手机号最大有15个数字
可以分为:
- 国家码(1-3个数字)
- 国内目的地址编码(National destination code,NDC区号)
- 用户号码(Subscriber number)
不同国家的格式可能有所不同,但思想是相同的。因此可以计算出特定城市电话号码的SHA256哈希值。
<sha256[0:3]>:<phone_number>
研究人员做出了一个人口大约500万的城市的手机号码表。考虑到用户号码的数量,碰撞是不可避免的,平均来看,哈希值的前3个字节的碰撞数是10-15
个。
研究人员开发了一个API来查询哈希值:
还有两种方法来确保识别的准确性:
- HLR (Home Location Register) Lookup,可以识别非活动的用户和其他区域的用户
- 手机号码必须与AppleID相关联,所以可以通过检查特定号码的iMessage是否可用来识别有效的手机号
通过融合这两个方法就可以准确地识别出手机号码。
那么如何在设备上激活WiFi密码风险弹窗呢?
nRF Connect这样的安卓应用持续可以克隆和重复不同的BLE消息。
Airdrop
Apple Airdrop有3个隐私选项:
- Receiving Off
- Contacts Only
- Everyone
那么设备如何识别对方呢?
运行Airdrop并打开BLE sniffer:
000000000000000001123412341234123400
消息结构如下:
0 8 9 11 13 15 17 18
+-----------------------------------------+--------+----------------+---------------------+-------------------+------------------+--------+
| | | | | | | |
| zeros |st(0x01)| sha(AppleID) | sha(phone) | sha(email) | sha(email2) | zero |
| | | | | | | |
+-----------------------------------------+--------+----------------+---------------------+-------------------+------------------+--------+
从中可以看出,设备只发送SHA256哈希值的2个字节,这就足以识别手机号。流量分析表明BLE只是用来初始化AirDrop交换。交换本身是使用AWDL
技术通过WiFi建立服务器(接收者)和客户端(发送者)的P2P连接来实现的。
然后使用Wireshark和设备上所有可用的awdl0
接口来分析AWDL
包:
在发送一些MDNS
包后,设备会交换证书,然后使用安全TLS连接进行数据交换。
白皮书A Billion Open Interfaces for Eve and Mallory: MitM, DoS, and Tracking Attacks on iOS and macOS Through Apple Wireless Direct Link https://www.usenix.org/system/files/sec19fall_stute_prepub.pdf 中详细描述了AirDrop的功能。下面简单看以下AirDrop协议工作流:
在认证过程中,设备会发送含有手机号码的全部SHA256哈希值的id数据(发送者记录的数据)。如果响应所有Airdrop BLE请求,就可以获取发送者的来呢西数据,包括手机号哈希值。
PoC
Script: ble_read_state.py
https://github.com/hexway/apple_bleee/blob/master/ble_read_state.py
该脚本可以嗅探BLE流量,并显示来自苹果设备的状态消息。该工具还可以检测来自苹果设备的密码分享请求。在这些包中,研究人员获取了SHA 256值的前3个字节,由此可以猜测出手机号码。
Script: airdrop_leak.py
https://github.com/hexway/apple_bleee/blob/master/airdrop_leak.py
该脚本可以获取想要通过AirDrop发送文件的用户的手机号码。
Script:advwifi.py
https://github.com/hexway/apple_bleee/blob/master/adv_wifi.py
该脚本可以发送含有WiFi密码分享请求的BLE消息。本PoC证明了攻击者如果攻击者知道受害者设备上的手机或邮件,就可以在目标设备上触发弹出消息。
Script: adv_airpods.py
https://github.com/hexway/apple_bleee/blob/master/adv_airpods.py
该脚本可以通过发送BLE消息模拟AirPods设备。
更多参见: