作者:Light & Yimi Hu @ PwnMonkeyLabs
原文鏈接:https://mp.weixin.qq.com/s/16FE24Oi4FMkhNC5en42dg
1.簡介
上一篇文章的分析中,我們發現Yale智能門鎖的通信中存在兩個問題,本篇文章將分為兩個部分描述如何利用這兩個問題:
a. 嗅探BLE通信獲取productInfo;
b. 使用獲取的productInfo控制門鎖。
2.嗅探BLE通信,獲取productInfo
Yale門鎖的BLE通信沒有加密,所以我們通過嗅探的方式可以直接獲取Authentication Request和Authentication Response,利用這兩個數據包的Payload做減法運算即可得到productInfo。
2.1 嗅探通信
嗅探BLE通信需要有專用的硬件工具,我們使用的是CC2540 Dongle,配合TI的Packet Sniffer軟件,如圖2-1所示。

Dongle直接接到電腦的USB接口即可使用,Packet Sniffer軟件可以對Dongle進行配置,并顯示嗅探到的BLE消息。
我們在第一篇文章中介紹過,Master在Scanner狀態下,會不斷掃描并接收Slave在Advertiser狀態下發出的廣播包,廣播包的發送和接收都是在3個廣播信道上進行的,Master想要與某個掃描到的Slave建立連接時會進入Initiator狀態并向Slave發起連接請求,雙方建立連接后會在37個通信信道上以一定的規律進行調頻通信。
由于連接建立后,雙方以跳頻的方式進行通信,因此我們只能在Master和Slave建立連接時,也就是Master在Initiator狀態下發出CONNCET_REQ數據包時,就開始跟蹤雙方的通信,才有可能嗅探到所有通信內容。
因此,Dongle的工作原理如圖2-2所示,整個嗅探流程可以分為三個步驟:
a. 啟動完成后,Dongle工作在某一個廣播信道上,會嗅探所有該信道上的廣播包;
b. 當探測到CONNECT_REQ數據包時,說明該信道上有Master和Slave準備建立連接,此時Dongle會解析CONNECT_REQ數據包的內容,獲取主從設備的信息及雙方第一次跳頻通信的通信信道;
c. 此后,Dongle只會過濾步驟b中主從設備之間的通信,并跟隨雙方的跳頻,這樣雙方所有的通信都被嗅探到了。

一個Dongle只能監聽一個廣播信道的通信,而通信雙方可能會在3個廣播信道中隨機挑選一個建立通信,因此如果只有一個Dongle時,可能需要多次嘗試才能獲得需要的數據,有多個Dongle時則可以分別將它們配置為監聽不同的廣播信道,選擇Dongle并配置監聽信道的方式如圖2-3所示。

介紹完嗅探工具,我們就可以嘗試嗅探通信了。
嗅探的操作非常簡單,配置好Dongle后,點擊Packet Sniffer中的開始嗅探按鈕,就可以看到Dongle接收到的所有廣播包,如圖2-4所示。

開始嗅探后,我們在Dongle附近嘗試在app里連接門鎖,如果手機和門鎖恰好是在Dongle監聽的廣播信道上建立連接,那么就可以抓到后續手機和門鎖之間所有的BLE通信,如圖2-5所示。

圖2-5中,黃色數據包之后,手機和門鎖就已經開始跳頻通信了,可以看到Channel字段每次通信都會變化,而建立通信前的最后一個廣播包的類型就是CONNECT_REQ,Dongle是通過這個數據包來跟蹤雙方隨后的跳頻通信的。
正如上文所提到的,Dongle一次只能監聽一個廣播信道,所以我們可能需要多次重復才能嗅探到手機和門鎖的通信。
2.2 數據包分析
嗅探到通信之后,我們只要找到Authentication Request和Authentication Response即可,要定位這兩個數據包,則需要知道數據包的特征和結構。
回想上一篇文章,在生成Payload并發送Authentication Response之前,調用過一個makeACKFrame的函數,從函數名看,這個函數的作用是將Payload封裝成ACK Frame,我們就從這里著手分析。
首先我們看一下調用makeACKFrame的地方,如圖2-6所示。

調用makeACKFrame函數時傳入了4個參數,其中v2、v3分別是已經初始化好的變量,所以Authentication Response中應該有兩個固定內容的字節,v4顯然是個累加的計數器,最后一個參數arg7,我們上一篇文章中就提到了,這個參數是encodeCounter函數的返回值,也就是Authentication Response的Payload。
我們在上一篇文章中獲取到的日志,如圖2-7,send 72ACK的內容,起始字節是0x72和0xA1,而圖2-6中,參數v2和v3分別包含了HexString(72)和HexString(A1)。所以,我們可以推斷Authentication Reponse起始字節是固定的0x72A1,這一點可以作為數據包的特征。幫助我們在嗅探到的通信中尋找Authentication Response。

makeACKFrame的結果在v1中,打印Log時調用了v1.toString(),這個函數如圖2-8所示。

在toString函數中我們能直觀的看出Authentication Response的數據包結構:
a. 開始的兩個字節是event和source;
b. 第3個字節表示數據包的序號,第4個字節則是長度,我們暫時還不清楚這是數據包的長度還是Payload的長度;
c. 第5字節開始是數據包的Payload;
d. 最后一個字節是校驗,校驗算法暫時未知。
通過數據包的特征,我們在嗅探到的通信中定位到圖2-9了這樣一組數據包。

根據起始字節是0x72A1這一特征,第二個數據包應該就是Authentication Response,那么第一個數據包應該是Authentication Request,Response數據包的結構分析如圖2-10。

按照類似的方式取出Request數據包的Payload,按照上一篇文章的分析,只需要將Response的Request兩個數據包的Payload做差即可得到這個門鎖的productInfo,做差過程如圖2-11。

我們在已綁定了門鎖的手機中查看app的數據庫,其中顯示了已綁定門鎖的productInfo,如圖2-12所示。

對比圖2-11我們計算出來的結果,和2-12中數據庫里的product_info字段數值,二者前6字節是相同的,上一篇分析中在分析productInfo變量的使用時,其中也只有6個字節參與了計算,所以我們推測后兩個字節是無效字節,下一章的操作中可以看到,這兩個字節置0也能夠開啟門鎖。
3.使用計算得到的productInfo開啟門鎖
前文提到app數據庫中有product_info字段,而app在構造Authentication Response時直接使用了這個字段的數值,那么如果我們在未綁定門鎖的手機上,跳過門鎖綁定步驟,直接將門鎖的相關信息寫入到app的數據庫中會出現什么情況呢?接下來我們對這種情況進行實驗。
修改數據庫最方便的辦法就是,通過ADB將app中的數據庫(位于/data/data/com.irevo.blepack/databases目錄下)拉取到電腦上,在電腦上修改完成后再推送回app。
要操作/data目錄下指定app的文件,需要我們擁有root權限或者使用run-as指令,在未root的手機中,執行run-as + 包名,就可以直接以root權限進入該應用的沙盒中查看數據庫、xml、各種信息文件等內容。使用run-as指令,需要指定的應用處于允許debug的模式,所以我們在上一篇文章中添加Log代碼時,也在AndroidManifest.xml文件中添加了Android:debuggable = true的標簽。
在未綁定門鎖的手機中,數據庫應該是空的。空數據庫的填寫方式如圖3-1所示。除了product_info外,還有一個module_addr字段需要注意,這個字段應該填寫門鎖的藍牙地址,這個地址可以在門鎖附近,使用nRF Connect掃描周圍設備獲取。

數據庫填寫完成后,使用ADB指令推送回手機,即可使用該手機控制門鎖了。如圖3-2所示,手機最初并沒有綁定門鎖,在我們將數據庫推送進手機后,重啟app,會發現手機開始嘗試與門鎖建立連接,稍等片刻連接建立之后,就可以直接用這個手機打開門鎖了。
4.總結
我們用了兩篇文章記錄了Yale門鎖的漏洞分析及利用過程。
首先我們從Yale Bluetooth Key這款app的Log著手,定位到了app中的關鍵代碼,隨后通過對關鍵代碼的分析,發現了門鎖與手機之間的身份認證環節存在漏洞,最終通過嗅探門鎖與手機之間的BLE通信,我們利用身份認證的漏洞在未綁定門鎖的手機上打開了門鎖。
這次對智能門鎖的安全測試仍然是從BLE入手的,重點分析的是手機端的app。而智能門鎖的開鎖方式不只有藍牙這一種,之后我們會和大家分享更多的內容,大家如果有想要討論或者分享的事情,歡迎在公眾號后臺留言,或發郵件到pwn@pwnmonkey.org。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1530/
暫無評論