作者: evilpan
原文鏈接: https://mp.weixin.qq.com/s/Ojm3LSw8q8H5pAT-JxUyqA
本文是 2020 年中旬對于藍牙技術棧安全研究的筆記,主要針對傳統藍牙和低功耗藍牙在協議層和軟件安全性上攻擊面分析,并介紹了一些影響較大的藍牙漏洞原理,比如協議層的 KNOB、BIAS 漏洞,軟件實現上的 BlueBorne、SweynTooth 以及 BlueFrag 漏洞等。
前言
藍牙(Bluetooth)是一個短距離無線傳輸的技術,工作在免證的ISM頻段。最初名字為Wibree,在90年代由Nokia設計開發,隨后轉交給藍牙特別興趣小組(SIG)專門維護。

藍牙標準經過了數十年不慍不火的發展,核心版本從1.0迭代了到目前的5.2,其中在2010年推出的藍牙4.0版本標準中引進了Bluetooth Smart或者Buletooth Low Energy(BLE)。由于在功耗上有了極大改善,加上智能手機和智能設備的發展,BLE的應用也進入了爆發期。
4.0之前藍牙通常稱為經典藍牙(Classic Bluetooth),包括1.0提出的BR(Basic Rate,基礎速率)以及2.0提出的EDR(Enhanced Data Rate,增強數據速率),兩者往往放在一起表示與低功耗藍牙相對的傳統藍牙。BR/EDR常用于相對短距離無線的連續連接,比如耳機的音頻傳輸。
為了進一步提高藍牙傳輸速率,在3.0中又提出了基于802.11的AMP(Alternate MAC and PHY layer extension)拓展,這是和BR/EDR不并存的一種傳輸模式。
核心系統
BR/EDR和BLE雖然都稱為藍牙,但它們在實現上大相徑庭。前者主要側重于點對點的通信,連接性和傳輸速率是考慮的重點;而BLE則側重于低功耗的設計,在射頻層和基帶層上優化了多播和廣播的支持。傳統上Controller芯片只支持一種射頻模式,但越來越多設備中也同時支持兩種系統,以覆蓋盡量多的使用場景。

藍牙的核心系統架構包含一個Host和一個或多個Controller,Host可以理解為主核或者主板,運行主流的富操作系統;而Controller可以看做是藍牙芯片,運行的是裸機程序或者RTOS,主要功能是對射頻信號進行編解碼。Host和Controller之間通過HCI接口(Host Controller Interface)進行通信,可通過UART、USB等物理接口進行傳輸。核心系統中包含的組件和之間的關系如下圖所示:

其中Host部分主要是基于L2CAP抽象出的邏輯信道實現應用層的協議和功能,涉及的關鍵組件和協議有:
- Channel Manager:負責創建、管理和釋放L2CAP channel。
- L2CAP Resource Manager:負責管理PDU數據的順序、調度、分片、重組等功能,是L2CAP核心功能的一部分。
- SMP:Security Manager Protocol,實現BLE系統中的點對點安全認證功能,包括秘鑰生成和認證等;BR/EDR系統的對應功能則在Controller的Link Manager中實現。
- ATT:Atrribute Protocol,應用層attribute client和server之間的協議。
- GATT:Generic Attribute Profile,表示ATT server或者client的功能,profile描述了服務和屬性的層級結構,主要用于LE profile服務發現中。
- GAP:Generic Access Profile,表示所有藍牙設備通用的基礎功能,比如傳輸層、協議、應用所使用的模式或流程等。GAP服務包括設備和服務發現、連接模式、安全認證和關聯模型等。
Controller部分中更多是邏輯鏈路和物理鏈路的管理,包括:
- Device Manager:基帶(baseband)中控制設備行為的模塊,主要負責不與傳輸直接相關的部分,比如查詢周圍藍牙設備,連接藍牙設備,切換藍牙設備的狀態(discoverable/connectable),以及修改藍牙名稱、屬性等。
- Link Manager:負責創建、修改和釋放邏輯鏈路(logical links)以及對應的邏輯傳輸(logical transports),并更新設備之間對應物理鏈路(physical links)的相關參數。在BR/EDR系統中,與對端的Link Manager通過LMP協議(Link Manager Protocol)進行通信;在BLE系統中則使用的是LL協議(Link Layer Protocol)。
- Baseband Resource Manager:負責管理所有到射頻媒介的訪問。在鏈路層中,有兩種類型的“連接”:
- SCO:Synchronous Connection Orientated,實時窄帶數據傳輸,如電話音頻等,無重傳
- ACL:Asynchronous Connection-Less,異步無連接,用以其他所有數據的傳輸
- Link Controller:負責對指定物理信道(邏輯鏈路和邏輯傳輸)的藍牙數據進行編解碼。
藍牙核心系統的每個組件或協議都可以用獨立的章節去介紹,整個結構的宏觀理解對后面梳理藍牙的攻擊面是非常有必要的。從前面的圖中我們可以看到,BR/EDR和BLE在鏈路層以下是相當不同的,前者為LM而后者為LL,下面分別進行介紹。
BR/EDR
在傳統藍牙(即BR/EDR)中,2.4GHz的ISM頻段分成79個頻段,每個大小為1MHz,并使用特定的跳頻模式(Hopping Pattern)來決定一條物理信道,從而減少不同臨近終端之間的射頻干擾。BR/EDR使用點對點的主從模式,其中Master為確定跳頻模式的一方,Slave為與Master時鐘和跳頻模式同步的其他端點。
傳統藍牙建立鏈路層連接主要經歷兩個階段:Inquiry和Paging。
Inquiry階段,Master發送查詢請求,周圍(10米內)可被發現的設備(discoverable)收到請求后會發送查詢響應(Inquiry Response)。在查詢過程中,因為與周圍設備還未連接,因此它們很可能處于不同的信道(跳頻序列),實際上發送查詢的設備會在不同的頻率進行發送,而接收方(處于standby模式)則以更高地頻率進行足夠長時間的查詢掃描(Inquiry Scan)以確保能被正確喚起。查詢響應中包含設備ID和時鐘等信息。
Paging階段,主要解決的是鏈路層的連接問題。與Inquiry類似,此時各方同樣沒有進行時鐘和頻率的同步。Master與Slave的連接需要經過以下六步:

連接狀態的兩個設備所處于的抽象網絡稱為piconet,這是一個星狀網絡,一個Master可以有最多七個Slave,但是Master本身也可以是其他piconet的Slave,這種網絡拓撲稱為scatternet。傳統藍牙處理鏈路層連接的管理器稱為LM,即Link Manager,兩個LM之間通過LMP協議進行通信。
這只是鏈路層的連接,和我們平常所說的藍牙配對(pairing)并不是一回事。Paging只是保證了在物理層鏈路的連通性,進行應用層的通信往往還需要經歷兩步:
- 服務發現(Service Discovery):用以確認對端所支持的服務
- 服務連接(Service Connection):使用某個對端設備特定的服務或者配置(Profile)
但是實際上在服務發現之前,藍牙引入了一層安全性保障,確保雙方是自愿連接的,溝通連接意愿的過程就稱為配對。經過配對后的設備會分別記住對方,在下一次連接時就不需要進行重新配對,而是使用之前保存的連接秘鑰(Link Key)直接進行認證和連接:

藍牙Spec中定義了legacy authentication和secure authentication情況下的認證流程和狀態。當兩個設備沒有共同的link key時,就需要使用pairing流程來協商創建初始化秘鑰Kinit。 關于配對流程的分析在后面會詳細介紹。
- https://courses.cs.washington.edu/courses/cse474/18wi/pdfs/lectures/BlueTooth.pdf
- https://stackoverflow.com/questions/36396456/bluetooth-difference-between-pairing-and-paging-bonding
BLE
在BLE中,2.4GHz的ISM頻段分成40個頻段,每個大小為2MHz,其中3個信道為廣播信道(advertising channel),其余37個為通用信道(general purpose channel)。BLE也支持對建立連接后的端點在通用信道中進行跳頻通信。
各個信道的頻率為:
f = 2402 + k * 2 MHz, k = 0, 1, ... , 39
BLE鏈路層的狀態機包括以下狀態:
- Standby State
- Advertising State
- Scanning State
- Initiating State
- Connection State
- Synchronization State
- Isochronous Broadcasting State
任一時刻只能處于其中的一種狀態,有限狀態機的轉換過程如下:

實際中的鏈路層的狀態機不一定要實現上述完整的狀態,但藍牙標準中定義了一些相互依賴的狀態組合,實現了其中一種就必須要實現另外一種。任何其他狀態都可以直接進入Standby狀態,而只有Advertising和Initiating狀態才能進入Connection狀態。Connection狀態中連接的雙方分別根據來源狀態定義為:
- Master Role:從Initiating狀態進入
- Slave Role:從Advertising狀態進入
與傳統藍牙類似,一個Slave只能與一個Master進行連接。在BLE中,鏈路層數據包所包含的數據稱為協議數據單元(PDU),Advertising的三個物理信道包含Advertising PDU、Scanning PDU和Initiating PDU,數據信道包含LL Data PDU和LL Control PDU等,不同的PDU包含不同類型的Payload。當然這都是發生在雙方Controller端的LL之間,Host端還是主要使用HCI協議對其進行封裝,根據不同的場景我們可能需要專注某一端的的實現,比如對于藍牙芯片固件的研究更多是對LL端的數據進行分析,其他情況下對于應用層或者開發者則更多地關注Host端的HCI、L2CAP、ATT等協議。
Security
藍牙的服務發現和調用不考慮安全性的話可以直接在同步完物理信道后直接進行應用層交互,但為了避免竊聽和中間人等攻擊,甚至是為了避免錯誤連接到其他同名設備,藍牙服務也是必須要有安全性保障的。初次接觸藍牙Spec的人可能會對藍牙連接和配對的概念比較困惑,因為藍牙標準在不同版本中定義了不同的配對模型,而BR/EDR和BLE的配對過程又發生在不同的模塊中。比如BR/EDR配對過程由雙方Controller端的LM(Link Manager)使用LMP協議進行協商,而BLE的配對過程則主要通過Host端的協議棧(Security Manager)進行協商。
從時間線上來看,BR/EDR分為幾個階段:
- 2.1之前:使用Legacy Pairing,后續版本中稱為
BR/EDR legacy - 2.1:使用 Secure Simple Pairing
- 4.2:使用 Secure Connection
BLE也經歷了幾個階段的變化:
- 4.0和4.1:使用 Secure Simple Pairing,后續版本中稱為
BLE legacy - 4.2:使用 Secure Connection
Legacy Pairing 使用雙方輸入或者固定的PIN CODE來進行認證,現在已經非常少見,因此可以不用關注。
Secure Simple Pairing 的配對方式主要經過以下4步(以BR/EDR為例):
- IO capabilities exchange:交換對方的特性,比如是否支持顯示和鍵盤輸入等,用以后續協商認證手段
- Public key exchange:交換橢圓曲線的公鑰
- Authentication stage 1:身份認證
- Authentication stage 2:ECDH Key校驗
對于身份認證,BR/EDR定義了4種認證方式:
- Just Works:靜默認證,主要用于沒有顯示和輸入功能的設備,如耳機等
- Numeric Comparison:雙方生成隨機數并計算出一個6位數字進行比對確認
- Passkey Entry Authentication:主要用于一方有顯示功能另外一方有輸入功能的場景
- OOB(Out Of Band):使用藍牙射頻以外的其他通道(如NFC)來交換認證信息
前面說了BR/EDR 2.1和BLE4.0/4.1都使用Secure Simple Pairing進行配對,為什么還特地強調是BR/EDR呢?因為雖然他們都叫做SSP,但實際上也存在不同的地方,比如BLE的SSP沒有使用ECDH,因此數字的認證只能防止被動竊聽(passive eavesdropping),不能防止中間人攻擊,并且BLE中沒有Numeric Comparison的認證方式。
不過,這也只是過去式了。在4.2以后,BLE和BR/EDR終于統一了配對流程,稱為Secure Connection。其在SSP的基礎上進行了安全性的增強,下面是BR/EDR的對比:
| 安全特性\配對類型 | Legacy | Secure Simple Pairing | Secure Connection |
|---|---|---|---|
| 加密 | E0 | E0 | AES-CCM |
| 認證 | SAFER+ | SAFER+ | HMAC-SHA256 |
| 秘鑰生成 | SAFER+ | P-192 ECDH HMAC-SHA-256 | P-256 ECDH HMAC-SHA-256 |
而BLE也是殊途同歸,最新實現的配對方式也升級成了功能相同的 Secure Connection。
- https://stackoverflow.com/questions/39592435/pairing-differences-between-bluetooth-and-bluetooth-le
- https://security.stackexchange.com/questions/116027/difference-between-secure-simple-pairing-and-secure-connections-in-bluetooth
常見協議
在前面的介紹中我們已經多次提到,主機系統稱為Host,藍牙射頻芯片的系統稱為Controller,它們之間的通信接口稱為HCI(Host Controller Interface),同時這也是其傳輸協議的名字。HCI是Host端所能接觸的最底層協議,通過內核的HCI驅動進行操作,基于HCI逐步往上封裝和實現了一系列高級協議,本節就以自底向上的角度去進行介紹。
HCI
HCI協議是HCI接口最底層的協議,可根據傳輸層的介質分為不同類型,例如:
- UART傳輸層:在btsnoop中表示為hci_h4
- USB傳輸層:在btsnoop中表示為hci_h5
- SD傳輸層:Secure Digital
- ...
HCI數據包分為command、event和data三種類型。command表示Host發送給Controller的命令,event為Controller發送給Host的事件,data通常是實際的藍牙傳輸數據。
HCI command的格式為:
16bit opcode | 8bit 參數長度 | 可變參數
其中opcode又分為兩部分,高6位為OGF(Opcode Group Field),低10位為OCF(Opcode Command Field)。在Linuz中我們常用的bluez框架也可以直接發送hci命令:
$ hcitool cmd --help
Usage:
cmd <ogf> <ocf> [parameters]
Example:
cmd 0x03 0x0013 0x41 0x42 0x43 0x44
HCI event的格式為:
1bit event code | 1bit 參數長度 | 可變參數
通常Host發送的command都會收到Controller的返回event,提示命令的執行結果。例如,HCI命令0x200c表示LE Set Scan Enable,并通過參數控制開啟和關閉BLE的掃描,Controller執行完畢后返回event code 0x0e,即Command Complete,并附帶status作為參數表示結果是否成功。詳細的命令和事件列表可以參考Core_v5.2 Vol 4: Host Controller Interface, Part E-7 HCI commands and events。
除了command和event,HCI中還包括的一大載荷就是數據,比如前面提到的同步數據包SCO、ISO(isochronous)和無連接數據包ACL等。
ACL
HCI的ACL協議主要用于在Host和Controller之間傳輸數據,ACL數據包的格式如下:
12bit | 2bit | 2bit | 16bit | varlen
Handle | PB flag | BC flag | Data Total Length | data
其中,Handle用于區分Host與Controller之間的邏輯鏈路,PB為Packet Boundary即包邊界標志,BC(Broadcast)為廣播標志。由于數據總長度只用2個字節表示,因此數據加上頭部最多也只有65535字節,這意味著在發送過大的數據時需要在ACL層進行分包和重組,PB Flag就是為了這個目的而設置的,根據PB Flag的值可以表示當前數據包在完整數據中所處的位置。
L2CAP
ACL只提供了一個數據傳輸協議,類比于網絡協議棧中的IP協議,在其之上使用的L2CAP協議可以類比于TCP/UDP協議,實現了更為完善的數據傳輸功能,包括:
- 協議/信道(L2CAP channel)多路復用
- 分段(segmentation)和重組(reassembly)
- 基于L2CAP channel的流量控制機制
- 錯誤控制重傳機制
- 支持流式傳輸(streaming)
- 分片(fragmentation)和重組(recombination)
- QoS(Quality of Service)
- ...
L2CAP channel表示兩個設備之間的一條邏輯鏈路,使用channel id(CID)進行區分,并以此為基本單元在Controller邏輯鏈路上進行多路復用。在基于連接的信道(connection-oriented channels)中,L2CAP PDU也稱為B-Frame,其格式如下:
16bit length | 16bit CID | information payload
前32bit稱為L2CAP header,length是除了header以外的payload長度。在不同的L2CAP模式中,information payload的內容也不盡相同,比如在Supervisor Frame(S-Frame)、Information Frame(I-Frame)。而對于無連接的L2CAP數據包,在payload之前還包含大于等于2字節的PSM(Protocol/Service Multiplexer),頭部還是和B-Frame一致的。
在L2CAP之上,有著各種各樣的應用層協議,比如服務發現協議SDP,藍牙傳輸協議RFCOMM/OBEX,BLE的屬性協議ATT,甚至是通用以太網協議BNEP以及其上的TCP/IP網絡棧等。通過分層和抽象使得上層應用無需關心底層的細節,從而實現了整個藍牙協議棧的普適性和拓展性。
協議安全
這里的協議安全不是指網絡協議棧的安全性,而是藍牙核心協議,或者說藍牙標準本身的安全性。雖然藍牙SIG小組在制定標準前都經過了多方討論和研究,可依然可能存在一些沒有考慮周到的臨界情況。
KNOB
KNOB Attack是2018年3月發現,并在同年10月報告給藍牙SIG和CERT的一個通用協議漏洞。漏洞點主要出現在LMP協議的秘鑰協商階段,正常來說,兩個藍牙設備連接和配對的過程如下:

配對之后會先進行藍牙秘鑰協商,協商過程使用的是配對過程協商的ECDH臨時秘鑰以保證協商過程保密。協商過程使用LMP協議,在各自的Controller端實現:

問題就出在LMP entropy(熵)協商的階段,因為這部分的協商過程是沒有經過ECDH秘鑰保護的,所以就容易受到中間人攻擊,惡意的攻擊者可以將熵設置得盡可能小,從而可以在后面快速地爆破出Kc并實時解密藍牙的傳輸數據。這也是為什么該攻擊稱為KNOB(Key Negotiation of Bluetooth) Attack的原因。
該漏洞的編號為CVE-2019-9506,由于是藍牙核心協議中的設計漏洞,因此影響了大量的藍牙設備,比如Broadcom、CYW、Apple、Snapdragon等藍牙芯片。修復方法自然是對秘鑰熵協商的過程進行加密,不過這個要等SIG更新進標準中,而標準的更新和推進又相對緩慢,因此很多藍牙芯片廠商也各自更新了固件做簡單的patch。該漏洞的直接危害就是導致藍牙鏈路的中間人攻擊,導致傳輸信息泄露或者劫持,實際攻擊場景比如藍牙鍵盤、藍牙鼠標等應該是受影響比較大的。
參考資料:
- https://knobattack.com/
- https://github.com/francozappa/knob
- https://francozappa.github.io/publication/knob/slides.pdf
BIAS
BIAS全稱為Bluetooth Impersonation Attacks,是2020年5月左右公開的另外一個藍牙協議的漏洞,CERT編號為CVE-2020-10135。該漏洞實際上是一系列協議設計缺陷導致的認證錯誤,最終導致對未配對的設備進行連接(或者說偽造成已配對的設備)。
該漏洞主要是針對傳統藍牙(BR/EDR)的配對過程。前面已經說過,在藍牙協議的發展中,安全配對主要分為三個階段,即Legacy Pairing、SSP和Secure Connection。配對的作用是讓從未見過的設備建立可信、安全的鏈路層鏈接,宏觀來看就是我們常見的輸入配對數字過程,微觀上是協商了一個雙方持有的長期秘鑰LTK(Long Term Key,或者說鏈接秘鑰LK(Link Key),LTK用來生成后續安全鏈接的會話秘鑰(Session Key)。兩個設備只用配對一次,但可使用保存的LTK進行多次安全連接。
在藍牙連接的過程中,數據是不經過加密或者校驗的。連接建立的主要作用是讓兩個設備交換它們公開的capability信息、互相校驗對方的長期秘鑰并計算會話秘鑰。如果連接的設備支持Secure Connection,就使用安全連接方法建立鏈接,連接的過程使用AES-CCM經過加密和完整性保護;否則,就使用Legacy Secure Connection(簡稱為LSC),連接過程使用E0流加密方法進行加密,并按照對應的流程進行連接。安全連接的建立同樣通過LMP協議進行。
之所以介紹這些背景,是因為漏洞的成因與背景相關性較大,在上面的基礎上,BIAS漏洞可以描述為以下問題:
-
LSC過程中master發起連接請求,slave返回自己的LTK認證響應,但master可以不進行校驗,也就是說在LSC中對LTK的校驗只是單向的,即master校驗slave的LTK即可。因此在LSC中攻擊者可以輕易偽造成master進行連接。
-
在LSC過程中,攻擊者若想偽造成slave,則可以在收到master的連接請求后發起Role Switch角色互換請求,將自己變成master,從而在1的基礎上偽造成Slave。
- 在Secure Connection的情況下,攻擊者可以通過返回Secure Connection not Support來發起降級攻擊,從而使用LSC進行后續連接,即回退到1/2的場景中進行對端偽造。
- 在Secure Connection的情況下,另一種攻擊方法是反射攻擊。即在收到Secure Connection的請求后發起Role Switch操作,并且偽造對端的認證請求,由于兩端的LTK相同,因此對端可以返回合法的認證響應;之后再發起一次Role Switch,將合法的認證響應轉發給對端,從而完成安全鏈接。
BIAS漏洞產生的根源是藍牙協議中不嚴謹的定義,比如為了兼容性允許Secure Connection降級,并且Role Switch的設計完全沒有考慮安全性,對其發起的時機不加判斷導致被濫用。從漏洞危害來看,BIAS的直接影響是可以繞過了手動確認的配對認證與目標設備進行連接,一個典型的例子是可以偽造成目標電腦或手機曾經配對過的藍牙耳機設備,并靜默地與目標進行連接,從而實現間接控制揚聲器和麥克風的效果。
參考資料:
- https://francozappa.github.io/about-bias/
- Bluetooth SIG Statement Regarding the Bluetooth Impersonation Attacks (BIAS) Security Vulnerability
其他
上面介紹的只是兩個比較知名的協議漏洞,類似的協議設計問題還有很多,比如《Breaking Secure Pairing of Bluetooth Low Energy Using Downgrade Attacks》中就介紹了一種針對SCO(Secure Connection Only)模式的降級攻擊。實際上藍牙核心協議的每次修訂,都或多或少對以前版本的疏漏進行了修補。藍牙協議上出現的安全問題往往影響廣泛并且難以修復,因為SIG更新協議需要一定時間,從協議更新到各個廠商的實現和測試也曠日持久。通常這類問題出現后都是廠商自身根據自己的理解進行緩解性修補,這也另一方面影響了漏洞修復的質量。
實現安全
由于藍牙協議是如此復雜,而且協議本身還隨著時間的變遷而不斷更新進化,這對于藍牙的實現造成了巨大挑戰。這要求藍牙固件的開發者一方面要深入理解藍牙協議的實現過程,另一方面也要對軟件安全開發本身有一定認識。尤其是在Controller端,目前還沒有一個公開的藍牙參考實現,藍牙芯片的內部代碼都是各個廠商珍藏的intellectual property。
藍牙的協議本身都復雜到經常出現非預期的安全問題,那藍牙的實現就更不用說了。從諾基亞時代開始,就出現過許多代碼實現導致的藍牙軟件安全漏洞,比如BlueJack、BlueBugging、BlueBump、Bluesmack、SweynTooth、BlueBorne、BlueFrag等等,……下面挑選幾個比較著名的漏洞進行分析。
BlueBorne
BlueBorne是2017年左右公開的一組藍牙漏洞,當年影響了多個平臺和系統,甚至包括IoT設備如Amazon Echo和Google Home等。雖然時過境遷了,但也值得回顧一下。涉及到的漏洞如下:
- CVE-2017-0781/CVE-2017-0782:Android中l2cap/bnep的內存破壞,可導致RCE
- CVE-2017-0785:Android中SDP協議continuation請求偏移校驗不當導致的信息泄露
- CVE-2017-0783:Android中PANU交互不當導致的中間人攻擊
- CVE-2017-8628:Windows中藍牙驅動實現不當導致的中間人攻擊
- CVE-2017-1000250:Linux BlueZ中SDP實現不當導致的信息泄露,與前面Android中的SDP漏洞原理類似
- CVE-2017-1000251:Linux BlueZ中處理L2CAP配置響應不當導致的棧溢出,可進一步造成RCE
- CVE-2017-14315:iOS中LEAP (Low Energy Audio Protocol)協議的堆溢出,可進一步造成RCE
印象中這是首次在藍牙實現上批量公開的嚴重漏洞,在審計藍牙協議實現時可以發現一些常見的錯誤模式,比如用戶可控長度字段時導致的信息泄露和溢出,這些模式在不同平臺的實現中可能都有類似的紕漏,因此所產生的安全問題在不同平臺中的遷移性是比較高的。
參考資料:
- https://www.armis.com/blueborne/
- https://info.armis.com/rs/645-PDC-047/images/BlueBorne%20Technical%20White%20Paper_20171130.pdf
- https://source.android.com/security/bulletin/2017-09-01
SweynTooth
SweynTooth漏洞也是一系列漏洞的集合,在2019年左右公開。雖然把它歸類到實現安全中,但其中大部分漏洞的本質是各個廠商在實現藍牙核心協議未定義行為時引發的異常。低功耗藍牙BLE的消息交互流程如下圖所示:

從這個圖中可以引申出許多有趣的問題,比如:”如果LL加密流程在配對的過程中發起會怎么樣?“……直覺來看有可能會造成全零LTK的安裝、秘鑰大小溢出、公鑰不合法等錯誤。但由于藍牙核心協議中對這種情況沒有明確說明,因此這類的錯誤處理就全由廠商安裝自己的理解去實現了。
一個藍牙產品在打上藍牙Logo之前需要經過藍牙的認證,進行一系列基線兼容性檢查,但這個檢查也不是面面俱到的。因此,有的即便藍牙核心協議中有明確定義的行為,在實際測試中也會發現一些SoC廠商的實現不一致。比如,藍牙核心協議中定義peripheral在同一個central-peripheral連接中應該只響應一次version request請求,但實際上Telink的設備會響應多次,這都是基線測試難以顧及到的地方。
作者也就是在測試這些Corner Case的情況下,發現了一系列Bug/漏洞,命名為SweynTooth,例如:
- CVE-2019-16336, CVE-2019-17519:鏈路層Length字段溢出,導致DoS和潛在的RCE
- CVE-2019-17061, CVE-2019-17060:鏈路層的LLID處理不當導致死鎖
- CVE-2019-17517:處理L2CAP包時對長度字段的校驗錯誤導致內存越界拷貝
- ....
- CVE-2019-19194:Telink SMP的Secure Connection實現在配對過程中發起LE加密流程時會導致全零LTK的安裝
加起來一共12個公開漏洞,不過利用場景都很有限,除了全零LTK漏洞外,大部分只能造成藍牙芯片的固件崩潰重新啟動或者死鎖。不過,從這組漏洞中我們也能看到藍牙固件的實現也是有不少問題的,藍牙芯片固件的代碼本身難以進行熱更新,在一些特殊的HCI Event配合下,我們甚至可以從Controller中獲取Host的命令執行權限。
BlueFrag
BlueFrag是2020年2月在Android安全通告中披露的一個嚴重漏洞,影響藍牙子系統可實現遠程命令執行。該漏洞主要是在Android中的L2CAP層實現上,是由于L2CAP的分片和重組包長度計算出錯導致的內存破壞。
漏洞修復如下:
diff --git a/hci/src/packet_fragmenter.cc b/hci/src/packet_fragmenter.cc
index 5036ed5..143fc23 100644
--- a/hci/src/packet_fragmenter.cc
+++ b/hci/src/packet_fragmenter.cc
@@ -221,7 +221,8 @@
"%s got packet which would exceed expected length of %d. "
"Truncating.",
__func__, partial_packet->len);
- packet->len = partial_packet->len - partial_packet->offset;
+ packet->len =
+ (partial_packet->len - partial_packet->offset) + packet->offset;
projected_offset = partial_packet->len;
}
值得一提的是,這個漏洞本身會導致memcpy拷貝負數長度,正常情況下會一直拷貝直至觸發非法內存空間,但在Android的libc實現上memcpy優化的實現會令拷貝前面的若干字節以及末尾的64字節退出,從而出現一個可控的內存越界讀寫,在此基礎上可以進一步實現控制流劫持導致遠程命令執行。 Android中L2CAP的實現在用戶層中,稱為BlueDroid,用戶進程為com.android.bluetooth,因此執行命令后所獲得的權限也是bluetooth權限。
參考資料:
- https://insinuator.net/2020/04/cve-2020-0022-an-android-8-0-9-0-bluetooth-zero-click-rce-bluefrag/
- https://android.googlesource.com/platform/system/bt/+/3cb7149d8fed2d7d77ceaa95bf845224c4db3baf%5E%21/#F0
應用安全
前面介紹的都是比較底層的協議,而在一般安全論壇和關于藍牙安全的相關文章中介紹的通常更多是應用相關的安全,比如藍牙智能門鎖的重放、越權等問題。這部分協議的交互主要在LTK協商之后,基于會話秘鑰加密的信道傳輸應用層信息,當然也可以是BLE中基于廣播的通信。
在上層的通信中,一個重要的概念就是Profile,表示設備所支持功能的一種垂直切分。其中既包括所有設備都通用的如Generic Access Profile(GAP)和Generic Attribute Profile(GATT),也包括基于特定用途的Profile如Proximity Profile和Glucose Profile等。Profile本質上定義了如何使用協議來實現某種通用或者特定的目的。
Profile的存在是藍牙協議與眾不同的一個地方,為什么會有這么多Profile,而不是像通用協議一樣,定義好協議結構和字段,然后進行通用拓展呢?在《計算機網絡》中有這么一段話:
真的有必要分清楚所有應用的細節,并且為每一種應用提供不同的協議棧嗎?也許沒有這個必要。但是,由于存在多個不同的工作組,他們分別負責設計標準的不同部分,因此,每個工作組都只關注特定的問題,從而形成了自己的Profile。你可以把這個看成是康威法則在起作用。或許藍牙標準根本不用25個協議棧,兩個就可以了,一個用于文件傳輸,另外一個用于流式實時通信。
可見SIG藍牙特別興趣小組各自為戰是藍牙Profile的形式發展至今的重要原因之一。
GATT定義了一個標準的數據模型與流程用以設備發現、讀寫和推送數據。一個GATT server中通常包含多個Service,而每個Service又可以包含多個Characteristic。每個Characteristic都有一個16位或者128位的UUID,并帶有可選的數據描述Descriptor。Characteristic是GATT通信中最小的數據單元,封裝了一個單一的數據點,其中可能包含一組相關的數據,比如加速傳感器x/y/z軸的坐標數據。根據權限的不同,我們可以向Characteristic中讀寫數據。
舉個例子,對于心率計而言,可能有一個Heart Rate Service,其中包括兩個Characteristic,分別是HM(Heart Rate Measurement)和BSL(Body Sensor Location),前者還包含一個Descriptor,CCCD(Client Characteristic Configuration Descriptor),這是一個常見的descriptor,用來表示通知開關狀態。
其中大部分常用的屬性在藍牙SIG文檔中都定義了對應的UUID,當然也包括一部分Vendor Specific的UUID留給廠商自行去拓展和定義。
研究藍牙應用安全的一個常用辦法是在收發數據時候進行抓包,比如Android中支持在開發者模式中打開藍牙日志,iOS支持使用XCode的拓展工具PacketLogger進行抓包。此外還可以通過對應用進行逆向或者動態追蹤的方式來觀察應用層的交互數據,從而挖掘背后存在的安全漏洞。由于這類問題與具體的產品和應用有關,這里就不舉例說明了,感興趣的朋友可以參考相關藍牙應用設備的公開安全通告。

小結
從漏洞的影響面來看,協議類的藍牙漏洞通常影響廣泛且難以修復,因為需要修改協議并推進各個藍牙廠商去進行重新實現和更新;從危害性來看,協議類的漏洞往往影響的是藍牙信道的安全,在一般場景中危害相對有限;而實現類的漏洞通常導致內存破壞,被攻擊者精心構造利用則可以造成整個系統的淪陷,一旦被利用就很可能是個嚴重的 RCE;應用類的漏洞通常是廠商的應用開發者所造成的疏忽,在某些情況下可導致智能設備被劫持控制,雖然修復較為容易,但這類漏洞頻繁出現在不同的藍牙應用中,因此其安全影響也是不可忽視的。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1633/
暫無評論