?
本環境是蛇矛實驗室基于"火天網演攻防演訓靶場"進行搭建,通過火天網演中的環境構建模塊,可以靈活的對目標網絡進行設計和配置,結合虛實結合技術能夠快速將wifi、藍牙等進行接入并保證正常運行邏輯,從而可以快速進行場景搭建和復現驗證工作。
?
背景
?藍牙技術始于愛立信公司的1994年方案,它是研究在移動電話和其他配件間進行低功耗、低成本無線通信連接的方法。發明者希望為設備間的通訊創造一組統一規則(標準化協議),以解決用戶間互不兼容的移動電子設備。1997年前愛立信公司此概念接觸了移動設備制造商,討論其項目合作發展,結果獲得支持。1998年項目正式啟動。1998年5月,愛立信、諾基亞、東芝、IBM和英特爾公司等五家著名廠商, 在聯合開展短程無線通信技術的標準化活動時提出了藍牙技術,其宗旨是提供一種短距離、低成本的無線傳輸應用技術。這五家廠商還成立了藍牙特別興趣組,以使藍牙技術能夠成為未來的無線通信標準。芯片霸主Intel公司負責半導體芯片和傳輸軟件的開發,愛立信負責無線射頻和移動電話軟件的開發,IBM和東芝負責筆記本電腦接口規格的開發。1999年下半年,著名的業界巨頭微軟、摩托羅拉、三康、朗訊與藍牙特別小組的五家公司共同發起成立了藍牙技術推廣組織,從而在全球范圍內掀起了一股“藍牙”熱潮。全球業界即將開發一大批藍牙技術的應用產品,使藍牙技術呈現出極其廣闊的市場前景,并預示著21世紀初將迎來波瀾壯闊的全球無線通信浪潮。
?
如對藍牙基礎有過了解,可以直接看第三章。
1.藍牙基礎
藍牙出現的原因,是為了解決從有線數據傳輸到無線傳輸數據過程的問題。目前藍牙的版本:1.1、1.2、2.0、2.1、3.0、4.0、4.1、4.2、5.0、5.1、5.2、5.3。藍牙版本一直在更新,"<4.0" 的被稱為經典藍牙(Classic Bluetooth),">=4.0" 開始有了低功耗藍牙(Bluetooth Low Energy,一般簡寫為BLE)。其實我們常說的藍牙4.0并不等同于BLE,BLE只是藍牙4.0的子集;藍牙4.0是一個綜合性協議規范。藍牙4.0版本以后技術模式上分為低功耗藍牙(BLE)和經典藍牙(BR/EDR)兩種、市場藍牙產品大多數為僅支持BLE的,也有兩者都支持的。藍牙 4.0 的芯片模式分為 Single mode 與 Dual mode。Single mode 只能與藍牙 4.0 互相傳輸無法向下與 3.0/2.1/2.0 版本兼容;Dual mode 可以向下兼容 3.0/2.1/2.0 版本。前者應用于使用紐扣電池的傳感器設備,例如對功耗要求較高的心率檢測器和溫度計;后者應用于傳統藍牙設備,同時兼顧低功耗的需求。
Bluetooth :經典藍牙 ,特點是耗電量大,傳輸距離近,速度一般,適合數據量大的傳輸。(相關設備:藍牙耳機、藍牙音響)
Bluetooth Smart :Single mode藍牙只支持低功耗藍牙,特點是耗電量小,傳輸距離遠速度快,適合數據量小的傳輸。(相關設備:藍牙鎖、藍牙燈泡、藍牙手環)
Bluetooth Smart Ready:Dual mode藍牙同時支持經典藍牙和低功耗藍牙。(相關設備:手機)
藍牙5.0是由藍牙技術聯盟在2016年提出的藍牙技術標準,藍牙5.0針對低功耗設備速度有相應提升和優化,有著更廣的覆蓋范圍和相較四倍的速度提升,同時還提供了基于AoA/AoD 等定位的功能,并且針對物聯網進行了很多底層優化,讓使用藍牙做為標準的物聯網應用更加強大。
?
BLE協議架構
要實現一個BLE應用,需要一個支持BLE射頻的芯片,然后基于一個與芯片配套的協議棧,開發藍牙應用。協議棧的作用就是軟件和硬件之間的橋梁,對應用數據進行封包然后生成可以通過射頻發送的空中數據包及其逆向過程。藍牙協議將藍牙整體分成了兩層架構,底層是核心協議,描述了藍牙核心技術的基礎和規范,包括了Host和Controller。應用層協議則基于具體需求,使用核心協議提供的機制,實現不同的功能策略。這兩部分在不同的藍牙協議版本中略有區別,但大致上是,Controller完成硬件側的規范制訂,包括信號調制解調,會抽象出用于通信的邏輯鏈路,可能存在一個或多個,如LE Controller、BR/EDR Controller;Host則在邏輯鏈路的基礎上完成更友好的封裝,屏蔽掉技術細節,方便應用層對數據的使用。
BLE協議架構由下面幾部分組成:
1.物理層(PHY):PHY層用來指定BLE所用的無線頻段,調制解調方式和方法等。
2.鏈路層(LL):LL層是整個BLE協議棧的核心,要做的事情非常多,比如具體選擇哪個射頻通道進行通信,怎么識別空中數據包,具體在哪個時間點把數據包發送出去,怎么保證數據的完整性,ACK如何接收,如何進行重傳,以及如何對鏈路進行管理和控制等等。LL層只負責把數據發出去或者收回來,對數據進行怎樣的解析則交給上面的GAP或者GATT。
3.主機控制接口(HCI):HCI主要用于2顆芯片實現BLE協議棧的場合,用來規范兩者之間的通信協議和通信命令等。這一層可以是軟件或者硬件接口,如UART、SPI、USB等。
4.通用訪問配置文件(GAP):GAP是對LL層payload(有效數據包)如何進行解析的兩種方式中的一種,而且是最簡單的那一種。GAP簡單的對LL payload進行一些規范和定義,因此GAP能實現的功能極其有限。GAP目前主要用來進行廣播,掃描和發起連接等。
5.邏輯鏈路控制級自適應協議(L2CAP):L2CAP對LL進行了一次簡單封裝,LL只關心傳輸的數據本身,L2CAP就要區分是加密通道還是普通通道,同時還要對連接間隔進行管理。
6.安全管理(SMP):SMP用來管理BLE連接的加密和安全的,如何保證連接的安全性,同時不影響用戶的體驗,這些都是SMP要考慮的工作。
7.屬性協議(ATT):簡單來說,ATT層用來定義用戶命令及命令操作的數據,比如讀取某個數據或者寫某個數據。BLE協議棧中,開發者接觸最多的就是ATT。BLE引入了attribute概念,用來描述一條一條的數據。Attribute除了定義數據,同時定義該數據可以使用的ATT命令,因此這一層被稱為ATT層。
8.通用屬性配置文件(GATT):GATT 是在 ATT 上面的一層結構,定義了使用 ATT的服務框架,GATT用來規范attribute中的數據內容,并運用group(分組)的概念對attribute進行分類管理,GATT規定配置文件(profile)的結構。沒有GATT,BLE協議棧也能跑,但互聯互通就會出問題,也正是因為有了GATT和各種各樣的應用profile,BLE擺脫了ZigBee等無線協議的兼容性困境,成了出貨量最大的2.4G無線通信產品。GATT定義了使用ATT的服務框架。在BLE中,所有被profile或者服務用到的數據塊稱為“特性”,兩個建立連接的設備之間的所有數據通信都是通過GATT子程序處理。GATT層用于已連接的藍牙設備之間的數據通信,應用程序和profile直接使用GATT層。當兩個設備建立連接之后,它們就處于下面兩種角色之一:GATT服務器:為GATT客戶端提供數據服務的設備。GATT客戶端:從GATT服務器讀寫應用數據的設備。
2.低功耗藍牙工作流程
在BLE中存在兩個角色,一個是中心角色(Central),一個是外圍角色(Peripheral),藍牙設備或手機都可以單獨作為Central或Peripheral角色。外設角色的作用是為中心角色提供各種數據,中心角色可以掃描并接收多個外設角色數據( 外圍角色中的設備進行廣播,中心角色的設備掃描尋找廣播),數據以服務(Service)和特性(Characteristic)的形式呈現。
藍牙工作流程:藍牙廣播->掃描設備->設備配對->數據傳輸。
這里以智能手環為例,我們簡單理解藍牙的工作流程為:智能手環(外圍設備)開啟藍牙后會進行廣播,這時智能手環會在3個廣播信道(37,38,39)上發送相同的廣播報文,此時手機(中心設備)打開藍牙后,手機中藍牙適配器自帶掃描器開始工作(掃描也在三個特定的廣播信道進行),掃描器接收廣播信道的報文后,發出掃描請求報文,智能手環發送掃描響應報文,這時手機就知道了發現了周邊有一個智能手環設備。手機在點擊連接智能手環時,發起連接請求報文,智能手環收到并處理后返回連接回應報文,此時倆者一旦連接建立之后,則開始使用數據報文(這里不理解也沒關系,后面會講解)。連接成功后,倆者開始通信,通信過程中手機發現藍牙耳機存在某種服務,服務中存在一些特性如獲取人體心率,這些特性允許手機通過特定的信道發出讀、寫等請求進行數據傳輸,上面過程中所有的數據傳輸均以無線的形式在空中傳播。
?
如何通過無線發送藍牙數據包
再理解藍牙工作流程的細節前,我們先來看藍牙無線通信是如何進行的。下面部分內容來自于該文章(https://www.cnblogs.com/schips/p/12293062.html),原理講解比較通透,所以我拷貝了一部分。假設有設備A和設備B,設備A要把自己目前的電量狀態83%(十六進制表示為0x53)發給設備B,該怎么做呢?作為一個開發者,他希望越簡單越好,對他而言,他希望調用一個簡單的API就能完成這件事,比如send(0x53),實際上我們的BLE協議棧就是這樣設計的,開發者只需調用send(0x53)就可以把數據發送出去了,其余的事情BLE協議棧幫你搞定。很多人會想,BLE協議棧是不是直接在物理層就把0x53發出去,就如下圖所示:
這種方式初看起來挺美的,但由于很多細節沒有考慮到,實際是不可行的。首先,它沒有考慮用哪一個射頻信道來進行傳輸,在不更改API的情況下,我們只能對協議棧進行分層,為此引入LL層,開發者還是調用send(0x53),send(0x53)再調用send_LL(0x53,2402M)(注:2402M為信道頻率)。這里還有一個問題,設備B怎么知道這個數據包是發給自己的還是其他人的,為此BLE引入access address概念,用來指明接收者身份,其中,0x8E89BED6這個access address比較特殊,它表示要發給周邊所有設備,即廣播。如果你要一對一的進行通信(BLE協議將其稱為連接),即設備A的數據包只能設備B接收,同樣設備B的數據包只能設備A接收,那么就必須生成一個獨特的隨機access address以標識設備A和設備B兩者之間的連接。
廣播方式
我們先來看一下簡單的廣播情況,這種情況下,我們把設備A叫advertiser(廣播者),設備B叫scanner或者observer(掃描者)。廣播狀態下設備A的LL層API將變成send_LL(0x53,2402M, 0x8E89BED6)。由于設備B可以同時接收到很多設備的廣播,因此數據包還必須包含設備A的device address(0xE1022AAB753B)以確認該廣播包來自設備A,為此send_LL參數需要變成(0x53,2402M, 0x8E89BED6, 0xE1022AAB753B)。LL層還要檢查數據的完整性,即數據在傳輸過程中有沒有發生竄改,為此引入CRC24對數據包進行檢驗 (假設為0xB2C78E) 。同時為了調制解調電路工作更高效,每一個數據包的最前面會加上1個字節的preamble(前導幀),preamble一般為0x55或者0xAA。這樣,整個空中包就變成(注:空中包用小端模式表示!):
上面這個數據包還有如下問題:
沒有對數據包進行分類組織,設備B無法找到自己想要的數據0x53。為此我們需要在access address之后加入兩個字段:LL header和長度字節。LL header用來表示數據包的LL類型,長度字節用來指明payload的長度
設備B什么時候開啟射頻窗口以接收空中數據包?如上圖case1所示,當設備A的數據包在空中傳輸的時候,設備B把接收窗口關閉,此時通信將失敗;同樣對case2來說,當設備A沒有在空中發送數據包時,設備B把接收窗口打開,此時通信也將失敗。只有case3的情況,通信才能成功,即設備A的數據包在空中傳輸時,設備B正好打開射頻接收窗口,此時通信才能成功,換句話說,LL層還必須定義通信時序。
當設備B拿到數據0x53后,該如何解析這個數據呢?它到底表示濕度還是電量,還是別的意思?這個就是GAP層要做的工作,GAP層引入了LTV(Length-Type-Value)結構來定義數據,比如020105,02-長度,01-類型(強制字段,表示廣播flag,廣播包必須包含該字段),05-值。由于廣播包最大只能為31個字節,它能定義的數據類型極其有限,像這里說的電量,GAP就沒有定義,因此要通過廣播方式把電量數據發出去,只能使用供應商自定義數據類型0xFF,即04FF590053,其中04表示長度,FF表示數據類型(自定義數據),0x0059是供應商ID(自定義數據中的強制字段),0x53就是我們的數據(設備雙方約定0x53就是表示電量,而不是其他意思)。
最終空中傳輸的數據包將變成:“AA D6BE898E 60 0E 3B75AB2A02E1 02010504FF5900 53 8EC7B2”
AA – 前導幀(preamble)
D6BE898E – 訪問地址(access address)
60 – LL幀頭字段(LL header)
0E – 有效數據包長度(payload length)
3B75AB2A02E1 – 廣播者設備地址(advertiser address)
02010504FF590053 – 廣播數據
8EC7B2 – CRC24值
有了PHY,LL和GAP,就可以發送廣播包了,但廣播包攜帶的信息極其有限,而且還有如下幾大限制:
無法進行一對一雙向通信 (廣播是一對多通信,而且是單方向的通信)
由于不支持組包和拆包,因此無法傳輸大數據
通信不可靠及效率低下。廣播信道不能太多,否則將導致掃描端效率低下。為此,BLE只使用37(2402MHz) /38(2426MHz) /39(2480MHz)三個信道進行廣播和掃描,因此廣播不支持跳頻。由于廣播是一對多的,所以廣播也無法支持ACK。這些都使廣播通信變得不可靠。
掃描端功耗高。由于掃描端不知道設備端何時廣播,也不知道設備端選用哪個頻道進行廣播,掃描端只能拉長掃描窗口時間,并同時對37/38/39三個通道進行掃描,這樣功耗就會比較高。
而連接則可以很好解決上述問題,下面我們就來看看連接是如何將0x53發送出去的。
連接方式
到底什么叫連接(connection)?像有線UART,很容易理解,就是用線(Rx和Tx等)把設備A和設備B相連,即為連接。用“線”把兩個設備相連,實際是讓2個設備有共同的通信媒介,并讓兩者時鐘同步起來。藍牙連接有何嘗不是這個道理,所謂設備A和設備B建立藍牙連接,就是指設備A和設備B兩者一對一“同步”成功,其具體包含以下幾方面:
設備A和設備B對接下來要使用的物理信道達成一致
設備A和設備B雙方建立一個共同的時間錨點,也就是說,把雙方的時間原點變成同一個點
設備A和設備B兩者時鐘同步成功,即雙方都知道對方什么時候發送數據包什么時候接收數據包
連接成功后,設備A和設備B通信流程如下所示:
如上圖所示,一旦設備A和設備B連接成功(此種情況下,我們把設備A稱為Master或者Central,把設備B稱為Slave或者Peripheral),設備A將周期性以CI(connection interval)為間隔向設備B發送數據包,而設備B也周期性地以CI為間隔打開射頻接收窗口以接收設備A的數據包。同時按照藍牙spec要求,設備B收到設備A數據包150us后,設備B切換到發送狀態,把自己的數據發給設備A;設備A則切換到接收狀態,接收設備B發過來的數據。由此可見,連接狀態下,設備A和設備B的射頻發送和接收窗口都是周期性地有計劃地開和關,而且開的時間非常短,從而大大降低系統功耗并大大提高系統效率。
現在我們看看連接狀態下是如何把數據0x53發送出去的,從中大家可以體會到藍牙協議棧分層的妙處。
對開發者來說,很簡單,他只需要調用send(0x53)
GATT層定義數據的類型和分組,方便起見,我們用0x0013表示電量這種數據類型,這樣GATT層把數據打包成130053(小端模式!)
ATT層用來選擇具體的通信命令,比如讀/寫/notify/indicate等,這里選擇notify命令0x1B,這樣數據包變成了:1B130053
L2CAP用來指定connection interval(連接間隔),比如每10ms同步一次(CI不體現在數據包中),同時指定邏輯通道編號0004(表示ATT命令),最后把ATT數據長度0x0004加在包頭,這樣數據就變為:040004001B130053
LL層要做的工作很多,首先LL層需要指定用哪個物理信道進行傳輸(物理信道不體現在數據包中),然后再給此連接分配一個Access address(0x50655DAB)以標識此連接只為設備A和設備B直連服務,然后加上LL header和payload length字段,LL header標識此packet為數據packet,而不是control packet等,payload length為整個L2CAP字段的長度,最后加上CRC24字段,以保證整個packet的數據完整性,所以數據包最后變成:
AA – 前導幀(preamble)
0x50655DAB – 訪問地址(access address)
1E – LL幀頭字段(LL header)
08 – 有效數據包長度(payload length)
04000400 – ATT數據長度,以及L2CAP通道編號
1B – notify command
0x0013 – 電量數據handle
0x53 – 真正要發送的電量數據
0xF650D5 – CRC24值
雖然開發者只調用了 send(0x53),但由于低功耗藍牙協議棧層層打包,最后空中實際傳輸的數據將變成下圖所示的模樣,這就既滿足了低功耗藍牙通信的需求,又讓用戶API變得簡單,可謂一箭雙雕!
AAAB5D65501E08040004001B130053D550F6
在理解了上面的知識后,我們可以進行下面的內容了。
?
藍牙廣播
低功耗藍牙一共有40個信道,頻段范圍從2402兆赫茲到2480兆赫茲,每兩兆赫茲一個信道,其中37、38、39是廣播信道,剩余的是數據信道。
藍牙廣播就是在這37,38,39三個信道上廣播數據,一個廣播數據包最長37個字節,其中有六個字節用作藍牙設備的mac地址,剩余的31個字節又被分為若干個廣播數據結構體,藍牙規范里面稱為ad structure。每一個廣播數據結構體有三部分組成,分別是結構體長度類型和內容。其中長度占用1字節,類型1字節,和若干個字節內容。這里面長度等于一加N(內容字節數)。
下圖中共有兩個廣播數據結構體,第一個廣播數據結構體的長度為0x4,表示后面有四個字節屬于這個結構體。緊接著是第二個廣播數據結構體,長度為0x03,表示后面有三個字節屬于這個結構體。上面提到了一個廣播數據結構體最大可用的字節數為31個,如果沒有用完的話,系統會在后面自動補零,湊夠31個字節。
注意:藍牙廣播最多只能廣播31個字節的數據,如果要廣播的數據超過了31個字節,可以把一部分數據放到掃描響應里面。
上面提到了廣播數據結構體組成方式,如果我們要想知道這些廣播數據的具體含義,就必須知道每一個廣播數據結構體的廣播類型,廣播類型藍牙官網已經制定了詳細的標準,我們可以在官網下載完整的AD type 進行查看。下圖是幾個比較常用的類型,比如009表示藍牙設備的名稱,0xa表示藍牙設備的發射功率,0xff為廠商自定義類型。我們知道了廣播數據結構體的類型,后面的數據內容是我們比較關注的,這些內容采用的是utf-8編碼,所以可以傳輸中文。下圖中的數據內容0x31 0x32 0x33 0x34 表示的字符串是"1234"。那么第一個廣播結構體所表示的含義就是指定了藍牙設備名稱為1234,第二個廣播數據結構體發射功率為8dbm。第三個廣告數據結構體是廠商自定義數據,其數據內容的含義由廠商決定。
?
掃描與響應
藍牙廣播大致可以分為如下四類:
?
可連接非定向可連接 定向不可連接 非定向可掃描 非定向可連接
?
非定向是大部分普通的藍牙設備采用的廣播方式
可連接定向呢主要用于已配對設備中的快速連接
不可連接非定向是藍牙信標或藍牙傳感器常用的廣播方式
可掃描非對象是在不可連接非對象的基礎上加入了掃描響應的功能,能夠通過掃描響應來承載更多的數據
這個表格總結出了這幾種廣播類型的功能。藍牙廣播是藍牙設備主動發射的一些數據,而掃描響應的是藍牙從機收到藍牙主機的掃描請求之后,回復給藍牙主機的數據,掃描響應的數據格式和藍牙廣播的數據格式完全一樣,不同的是廣播數據是主動發射的,而掃描響應的數據呢是在收到其他設備的掃描請求之后才會觸發的。
掃描響應數據和廣播數據格式是一樣的,掃描響應數據是非必需的,掃描響應數據可以作為廣播數據的補充,掃描響應需要一定的觸發條件。
?
服務與特性
以藍牙鼠標為例,我們來看一下它的服務和特性是如何實現的,在手機上打開名叫谷雨藍牙的微信小程序,搜索藍牙鼠標后點擊連接。連接成功后,展示的就是該設備的服務列表,一共有五個服務,每個服務上面的英文單詞是服務的名稱。
下面還有一行uuid,隨便點開一個服務,展開是該服務里面的特性,每一個特性由特性名稱,特性uuid和特性的訪問權限組成。一個藍牙設備里面可以包含若干個服務,一個服務里面包含若干個特性,每個特性里面又可以有讀寫通知等權限,每一個服務和特性都要有一個uuid。
uuid是藍牙組織定義的用于區分各個服務和特性的標識符,用戶可以自定義16 bit uuid,也可使用官方定義好的16bit uuid。uuid總長度是128bit,比如下面就是兩個標準的uuid。但是藍牙設計者考慮到128bit的uuid太長,使用起來不太方便。為了方便使用,藍牙組織定義了一些16位的uuid的基地址,可以與16位uuid進行拼接,形成128bit的uid。
?
數據傳輸
上面我們學習了藍牙服務和特性,我們知道了服務與特性。那么數據之間是怎么傳輸的呢,這里我們學習一下數據的傳輸,低功耗藍牙通信是基于一個個特性實現的,每一個特性可以被看作一個數據點,數據的收發都要依托于這些數據點。對數據點的操作方法有如下常用的五種類型:
read
write
write with no response,
notify
indicate
這幾種通信方式的區別,設備作為從機,手機作為主機
read操作,就是手機讀取設備中某個特性的值。
write操作就是手機修改設備中某個特性的值。
write with no response,與write操作類似,只不過寫完之后不需要設備回應,write操作則需要設備回應。
notify,操作是設備里面的數據發生變化之后,通知手機來取數據,需要在手機端訂閱相應的通知才有效。
indicate與notify操作類似,不同之處在于,indicate需要手機回應,notify則不需要。
上面部分內容來自于課程(https://www.bilibili.com/video/BV1ad4y1d7AM/),如果大家感興趣,可以前去學習。
3.藍牙抓包分析
?電腦抓包
這里以windows為例,我們作為初學者,一般使用CC2540/nrf52840 usb dongle來抓取藍牙數據包,買板子后并且按照手冊安裝好環境后,更新驅動。利用平臺USB設備接入模塊接入藍牙模塊,并可連接對實物藍牙手環進行測試
打開wireshark就可以看到nrf sniffer的接口后,我們直接雙擊就可以抓包了。
開啟抓包后,使外圍設備開啟廣播模式。等待外圍設備廣播包穩定后,點擊wireshark 中 Device列表外圍設備的mac地址,開啟中心設備進行掃描和連接,就可以抓取倆個設備之間的通信包。
注意:下圖中devcies下拉列表中沒有鼠標的mac地址,說明并不能抓取設備連接后通信過程,但是這里還是可以分析一下廣播和連接的過程。
廣播包中PDU的類型如下:
?
? 0000 ADV_IND:可連接通用連接廣播 ??0001 ADV_DIRECT_IND:可連接定向連接(指定設備)廣播 ??0010 ADV_NONCONN_IND:不可連接通用廣播 ??0011 SCAN_REQ:掃描請求 ??0100 SCAN_RSP:掃描響應 ??0101 CONNECT_REQ:連接請求 ??0110 ADV_SCAN_IND:可掃描通用廣播 ??0111-1111 Reserved ??位[4:5]:保留 ??位[6]:RxAdd ??位[7]:TxAdd ??位[8:13]:廣播數據長度 (最大為37 字節) ??位[14:15]:保留
?
?
BLE 連接過程中有三個重要的數據包:SCAN_REQ, SCAN_RSP 和 CONNECT_REQ(CONN_REQ又稱為CONNECT_IND)。SCAN_REQ:掃描請求,由主設備向從設備發出,目的是為了獲得從設備的響應以得到更多的從設備廣播數據信息(包括設備名字,或者服務UUID,及其它如廠家特定格式的信息(如硬件版本,軟件版本號,設備系列號等等)。
?
?
?
SCAN_RSP: 從設備對就主設備發起的SCAN_REQ的響應,作為廣播包的補充,從設備可以給主設備更多的廣播數據,比如說,有些設備在廣播包里面沒有設備名字,這個時候就可以把設備名字放在這個包里面發給主設備。
CONNECT_REQ(CONN_REQ又稱為CONNECT_IND):主設備向從設備發出連接請求。至此連接建立完成(從設備不會響應這個請求),如果從設備沒有連接上面的問題的話,以后主從雙方會開始相互交換有效數據(基于GAP,GATT及SMP協議)或者交換空包。
BLE抽象出一個協議:Attribute protocol,該協議將這些“信息”以“Attribute(屬性)”的形式抽象出來,并提供一些方法,供遠端設備(remote device)讀取、修改這些屬性的值(Attribute value)。一般情況下,ATT 層用來定義用戶命令及命令操作的數據,當我們想要給設備發送惡意報文,這些操作需要在ATT協議層完成,這里我們需要重點關注一下ATT報文。
下圖中,實線包含的部分為ATT層。ATT報文由Attribute Opcode和Attribute Parameters組成。
ATT層是固定的CID,當L2CAP層的CID為0x4時,為ATT層。
ATT報文中的Opcode決定了后面的Parameters,例如后文中0x1b為Notify,那么后面的Parameters就為Attribute Handle和Attribute Value組成,我們在分析時需要重點關注Attribute Value的值。
上面在數據傳輸小節中已經講解了Notify,Notify是當中心設備訂閱從設備相應服務時,從設備里面的數據發生變化后,從設備通知中心設備來取數據。下圖為opcode為Notification的ATT報文。
除了上述方法外,我們還可以使用藍牙適配器(電腦自帶也行)與藍牙調試工具進行抓包分析,使用方法位正常連接藍牙設備后,藍牙啟動調試工具就可以看到服務與特性,并且可以看到通信日志以及發送報文到設備。藍牙調試工具比較多,這里不進行推薦,百度搜索下載就行。
Linux系統抓包與上面相同,大多采用適配器與調試工具組合進行抓包分析,bluetoothd、hcitool和gatttool都是比較好用的工具。
?
手機抓包
當我們想要抓取手機app與藍牙設備的通信時,有時ble sniffer板子無法抓到通信包,那么就我們需要安裝adb環境進行藍牙調試,整個過程比較方便。
下面我以某智能手環為例,進行藍牙抓包分析。windows安裝好adb并配置環境后,下載adb驅動安裝包,打開ADB Driver Installer程序,通過數據線將手機與電腦連接。手機開發者選項中打開usb調試,此時出現密鑰并保存后,ADB Driver installer點擊refresh就會出現手機設備。
打開android killer,點擊android,在已找到的設備中選擇手機設備后,點擊日志即可查看Android設備日志信息。
點擊開始進行日志記錄,此時手機app綁定智能手環進行操作時,就會抓取到手機app的日志信息。
日志信息中,會包含藍牙通信等信息,有助于幫助我們分析藍牙通信流程。若此時出現有利于我們分析藍牙流程的日志信息,我們可以通過有限的信息對app進行逆向分析,找出藍牙實現的功能實現。
當Android killer日志信息不能獲取到有效信息時,我們可以手機開發者選項中打開啟用藍牙HCI信息收集日志開關,設置完之后電腦adb連接手機,然后打開藍牙設備和手機上和連接設備的APP,這個過程藍牙設備和app間發送的數據包都會被記錄下來。
收集完畢后,我們可以使用"adb pull /data/log/bt"將已收集的藍牙日志文件保存到adb環境中的bt文件夾下。
使用wireshark分析日志文件,當使用手機app查看今日數據時,手環會發送總步數、心率、睡眠時間等信息給手機app。
當使用手機收到短信時,手環會進行提醒,此過程中app藍牙數據包傳入手環。
一個簡單例子
上面我們講解了低功耗藍牙的基礎知識和抓包技巧。這里做一個簡單的攻擊示例,目的是向手環發送信息使其顯示。
首先是抓包分析,這里嘗試使用nrf52840對其進行抓包,只能抓到廣播通道報文,抓包無果。
然后嘗試使用Android killer日志信息
根據其調試信息,嘗試對手機app進行逆向分析,并沒有找到發送信息相關的有效代碼,分析無果。
最后,使用hci調試日志進行抓包,抓取其通信包裹。
獲取log文件后,使用wireshark進行分析。發現當我們連接手環后的讀取信息的操作與寫入操作均在handle 0x11進行操作,返回handle位0x0e,并且wirte指令操作在uuid為0xff00的特性中,那么我們就明確了攻擊的服務特性和handle。
重新使用hci調試日志進行抓包,這次抓包過程做了發送倆次信息的操作,手環并且成功顯示。
第一次發送信息人為:pwn,信息為:111
第二次發送信息人為:pwn,信息為:222
分析時,我們重點關注write command,并且handle為0x11,找到了發送信息人前面的報文為0x0a020000020e
這里為發送提示信息人的報文
這里為發送信息內容的報文
這里為發送信息內容的報文的后一條報文
緊接著就是第二次發送信息人之間的一條報文
后面與第一次發送報文相同
那么我們就知道了,發送第一次信息和第二次信息都發送了4個報文,分別為信息推送報文,信息人報文,信息內容報文,結束推送報文。那么我們就可以在0xff02特性中進行write with no response操作,重放這些報文進行驗證。
注意:中心設備與手環發送消息需要發送報文進行綁定,這里為了方便操作,這里我直接使用手機藍牙調試工具進行發送。
驗證成功后,后續當我們分析出每一條操控藍牙設備的指令,就可以將想要發送的消息按照指定格式進行發送與BLE設備通訊,從而實現對藍牙設備的攻擊。
?
總結
? 這一小節,我們學習藍牙無線通信的基礎知識,以及對藍牙智能手環的簡單抓包分析和攻擊,初步理解了低功耗藍牙的內容。
?蛇矛實驗室成立于2020年,致力于安全研究、攻防解決方案、靶場對標場景仿真復現及技戰法設計與輸出等相關方向。團隊核心成員均由從事安全行業10余年經驗的安全專家組成,團隊目前成員涉及紅藍對抗、滲透測試、逆向破解、病毒分析、工控安全以及免殺等相關領域。
審核編輯:湯梓紅
評論
查看更多