作者:Yimi Hu & Light @ PwnMonkeyLabs
原文鏈接:https://mp.weixin.qq.com/s/8t8s9UOVeVht9yqkVnaG0g

1.簡介

我們在前面兩篇文章中簡單介紹了BLE協議棧,并對一款智能燈泡進行了分析。本篇中,我們選擇Yale品牌的一款智能門鎖進行安全測試,一起來研究一下這款鎖是否存在安全問題。

我們測試的智能門鎖如圖1.1所示,這款門鎖有一個可拆卸的藍牙模塊,該模塊配合Yale廠商提供的一款名為Yale Bluetooth Key的app,可以實現藍牙開鎖功能。

圖片

圖1.1 智能門鎖

首先我們需要介紹一下這款智能門鎖的使用方式。和上一篇的智能燈泡類似,正常情況下,使用門鎖前需要先在手機app中綁定門鎖,如圖1-2所示

圖片

圖1-2 綁定門鎖

綁定之后,如果門鎖在手機的藍牙通信范圍內,app就會自動向門鎖發起BLE連接,連接成功后,即可點擊開門按鈕打開門鎖,如圖1-3所示。

圖片

圖1-3 連接及解鎖

2.分析過程

2.1 App初步分析

既然智能門鎖也可以由app控制,那么我們參考上一篇的研究思路,首先查看app日志,嘗試獲取BLE通信的內容。然而當我們用Android Killer查看日志時,發現Yale Bluetooth Key這款app沒有輸出任何日志。通過對APK進行簡單的逆向分析,我們找到了關于輸出日志的部分代碼,如圖2-1所示:

圖片

圖2-1 App Log代碼

ILog類負責輸出日志,但是這個類中所有的Log函數均為空,要解決這個問題有兩個方法:一是修改app的smali代碼并重新打包;二是用Hook的方式直接打印這些Log函數的參數。本篇我們采用了第一種方法,第二種方法將后續文章中介紹。

可以使用Android Killer完成修改smali代碼并重打包等工作。將app反編譯之后,找到ILog.smali,在需要修改代碼的地方點擊鼠標右鍵即可插入代碼,如圖2-2所示,這里我們在插入Log代碼的同時,也在AndroidManifest文件里添加了android:debuggable標簽,在《耶魯智能門鎖的簡單測試(下)》會提到它的用處。

圖片

圖2-2 修改app代碼

2.2 通信數據分析

修復了日志輸出代碼之后,我們就可以看到BLE通信內容了。當門鎖在手機附近時,app會自動向門鎖發起連接,連接過程的日志如圖2-3:

圖片

圖2-3 手機連接門鎖時的日志

根據日志中的關鍵字“_72_AUTHENTICATION_EVENT”和“send 72ACK”進行代碼回溯,找到關鍵代碼如圖2-4所示:

圖片

圖2-4 Authentication數據包相關代碼

結合我們在本專題第一篇文章中介紹的Android系統BLE接口的相關知識。圖2-4的處理流程是:

a. 當回調函數onCharacteristicChanged或onCharacteristicRead被調用時,會發出一個名為“com.irevo.bluetoothkey.regnosleep.ACTION_DATA_AVAILABLE”的廣播,其中攜帶著接收到的BLE消息內容。

b. 相應的廣播接收器接收到這條廣播后,將其中的BLE消息內容取出,交由函數handleLockStatus處理,這里輸出了圖2-3的第一條日志。

c. handleLockStatus函數中輸出了圖2-3的第二條日志,BLE消息由encodeCounter函數處理完成之后,交給send72Response函數。

d. send72Response將encodeCounter的處理結果封裝為ACK幀,也就是圖2-3的第三條日志的主要內容。在send72Response函數的最后調用了writeCharacteristic將ACK幀發送給門鎖。

可以看到,這是一次完整的BLE通信的收發處理流程,結合日志中的AUTHENTICATION關鍵字,我們推測這是門鎖與手機建立BLE連接時的身份認證過程。這一過程非常簡單,門鎖向手機發送一組數據,我們暫且稱之為Authentication Request,Request經encodeCounter函數處理后得到Payload,Payload在send72Response函數中封裝成Authentication Response發送給門鎖,如果手機通過了身份認證,就可以發送控制指令控制門鎖的打開與關閉了。

接下來,我們重點分析手機如何處理Request生成Payload。encodeCounter函數的參數counterData就是門鎖發來的Authentication Request,圖2-5展示了 counterData的處理方式:counterData被分割成若干個字節,每個字節都與key1~key6中的某一個相加,相加的結果放在c1r1~c3r4中。具體過程請看圖2-5。

圖片

圖2-5 Authentication Request的處理

c1r1~c3r4最后重新拼接成字節流形式,作為encodeCounter的返回值,也就是手機返回給門鎖的Payload,如圖2-6所示。

圖片

圖2-6 Authentication Response拼接

已知Payload是由Authentication Request與key1~key6相加得到的,Request是門鎖發送來的,那么key1~key6的來源是什么呢?如圖2-7所示,encodeCounter函數首先讀取了this.keyModel.productInfo變量,然后將productInfo變量逐字節存儲到 key1~key6這些變量中。

圖片

圖2-7 Authentication Key的處理

key1~key6來源于productInfo,那productInfo是哪里來的呢?我們繼續回溯,可以發現productInfo是在門鎖與手機進行綁定時,由門鎖發送給手機的,在完成綁定后,將productInfo存儲在數據庫里,每次使用時直接讀取數據庫即可。回溯過程可以參考圖2-8。

圖2-8 productInfo的處理

上圖中,箭頭方向表示數據的流動方向。經過多次實驗可以發現,門鎖綁定不同手機時發送的productInfo是相同的,這應該是門鎖出廠時就燒錄在flash里的一組固定密鑰。

經過分析,我們可以確定以上身份認證機制中存在這樣一個問題:門鎖對手機進行身份認證的算法是加法運算,如果我們能嗅探到Authentication的Request和Response兩個數據包,就能直接通過減法運算得到productInfo,從而通過門鎖的身份認證,控制門鎖。

3.小結

本篇是我們對Yale門鎖研究的上篇,在上篇中,我們主要對Yale門鎖的app進行了分析,最終發現在門鎖與手機的BLE通信機制中存在一些問題。在接下來的下篇中,我們會引入一個USB dongle用于對BLE通信進行嗅探,并利用本篇中發現的問題,通過嗅探而來的數據,計算得到productInfo,最終實現在任意手機上進行未授權開鎖。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1529/