6
【編者按】本文來自烏云,作者FengGou。

0x01 前言
因為自己曾DIY過所謂的“智能硬件”,學習過程中除了接觸各種芯片、傳感器、電路知識外,也拆了不少設備分析其設計思想學以致用。再后來又接觸了如:Wi-Fi、ZigBee、Bluetooth、NFC、IR、普通射頻甚至音頻等通信技術,才發現空氣中那些形形色色的邊界,才是整個物聯安全的關鍵。
今天的內容是我在烏云內部做的技術分享,也是我以前對低功耗藍牙技術的一些接觸,整理后決定對社區公布。一來可以讓社區對神秘的藍牙技術破冰;二來也是拋磚引玉,希望能看到更多有趣的案例;三來比起那些華麗麗的show,我更喜歡分享一些實際的內容。
0x02 BLE 協議棧總覽,GAP、GATT講解
0x03 BLE嗅探
0x04 偽造BLE通信
(理論細節過于繁復,暫且略去,感興趣的童鞋可進烏云平臺原文查看)
0x05 分析BLE私有數據協議,以燈泡、跳蛋、小米手環為例
有了上面的理論基礎,要開始實戰了。我手頭上只有藍牙燈泡和小米手環,后來一個猥瑣的朋友借我個跳蛋希望幫忙分析…
YeeLight 2 代藍牙燈泡
首先這個燈泡我在分析前就敢肯定它是存在問題的,因為燈泡的操作邏輯不會過于復雜,無非是一開一關、變色等等,所以我就拿它來做個“Hello world”。
抓包燈泡的開關燈動作的value
2c2c2c3130302c2c2c2c2c2c2c2c2c2c2c2c(開)
2c2c2c302c2c2c2c2c2c2c2c2c2c2c2c2c2c(關)
看到差異了么?

0x313030 = 100 0x30 = 0 從 4bytes 開始,就是該燈泡的亮度部分,100最亮,0沒有亮度,也就是關。
2. 抓包燈泡的換顏色動作
3235352c302c302c3130302c2c2c2c2c2c2c(紅色)
302c302c3235352c3130302c2c2c2c2c2c2c(藍色)
同上道理

0x3235352c302c30 = 255,0,0
0x302c302c323535 = 0,0,255
這就是RGB的顏色格式,很簡單直接告破:)
最后看下 Handle 0x0012,來源如圖

最后,簡單的看下Bluez協議棧自帶的gatttool工具的使用方法

通過抓包分析得知操控燈泡顏色的handle是0x0012,我讀了下他的uuid為fff1,私有的。用char-write-cmd命令直接寫入我們分析好的協議,燈泡變色,然后再讀取之,數據確實成功寫入。
Demo(視頻進入烏云平臺可看)
小愛愛智能跳蛋
(這個真不是我的,某個小伙伴借給我研究的)
這個產品感覺邏輯也簡單,就是網絡遠程發送震動指令到手機,手機在通過BLE鏈接設備進行你懂、我懂、他也懂的事情,羞~

這個跳蛋有三種模式:預定義節奏的震動、隨著音樂翩翩起舞的震動以及體位交互震動。
前兩個沒啥難度,基本抓到操作重放出來就OK了,最后這個模式比較卡哇伊,玩玩它咯。
與燈泡不同的是,進入體位模式后,Master會給Slave發送一個狀態開啟這個模式。所以你盲目的發送抓到的震動操作這個蛋是不震的,因為你要先讓她進入狀態。
給 Handle 0x0013 發送 0x0811060f01010232 后,它就進入狀態了。
然后 0x3e = 震動,0x7f = 生理暴擊(你狂按手機的時候就瘋狂的震動)
這個分析很簡單,因為都是些開關類的操作沒有太多實際的含義,所以無需解開數據,直接重放就可以,我做了個發送SOS急救信號的demo。
Demo (視頻見烏云漏洞平臺)
小米手環
小米手環是明星產品,對它的分析也充滿了趣味與困難。因為從一開始我就遇到了一個認證機制,如果藍牙鏈接后不寫入一段特殊格式的數據,那你只能讀少量信息不能對手環進行操作。
我通過抓包分析GATT中的write操作,過程省略2萬字,最終定位了一個向 Handle 0x0019 進行的write操作,該Characteristic返回了個Notify,然后手環就可以隨意寫指令了(如私有協議中的震動、LED顏色變化、開啟實時步數監控等)。
不過認證怎么能叫PWN?
不過認證怎么能叫PWN?
不過認證怎么能叫PWN?
重要的事情說三遍。小米手環的認證數據分析好了,結構如下

這個簽名是最重要的部分,前面的數據都可以偽造,只要簽名過了,手環就會允許你后續的寫指令,才能做到真正的PWN。那這個簽名是咋算出來的?請看番外篇。
番外篇:小米手環認證機制分析
劍走偏鋒,通過BlueZ得到了小米手環一個完整的私有協議UUID,然后去Github搜索,希望找到官方的代碼(其實這部分通過逆向Android app相信就能得到,不過說好的劍走偏鋒么)

然后呢?duang~


似乎是個第三方SDK,目前至少不用去逆向Android APP了開心,說實話這個我還真不擅長。通過這個SDK我找到了具體認證流程的代碼:GitHub - miband-sdk-android。
從這段代碼中分析,最終寫入Characteristic的內容,來自 userInfo.getBytes(device.getAddress()
public void setUserInfo(UserInfo userInfo)
{
BluetoothDevice device = this.io.getDevice();
this.io.writeCharacteristic(Profile.UUID_CHAR_USER_INFO, userInfo.getBytes(device.getAddress()), null);
}
userInfo.getBytes 的設計在這里,做了簡單注釋
public byte[] getBytes(String mBTAddress)
{
...
ByteBuffer bf = ByteBuffer.allocate(20);
bf.put((byte) (uid & 0xff)); //uid
bf.put((byte) (uid >> 8 & 0xff));
bf.put((byte) (uid >> 16 & 0xff));
bf.put((byte) (uid >> 24 & 0xff));
bf.put(this.gender); //性別
bf.put(this.age); //年齡
bf.put(this.height); //身高
bf.put(this.weight); //體重
bf.put(this.type); //類型
if(aliasBytes.length<=10)
{
bf.put(aliasBytes);
bf.put(new byte[10-aliasBytes.length]);
}else{
bf.put(aliasBytes,0,10);
}
byte[] crcSequence = new byte[19]; //取出用戶信息的前19個字節
for (int u = 0; u < crcSequence.length; u++)
crcSequence[u] = bf.array()[u];
byte crcb = (byte) ((getCRC8(crcSequence) ^ Integer.parseInt(mBTAddress.substring(mBTAddress.length()-2), 16)) & 0xff);
bf.put(crcb); //將簽名跟前面的用戶信息拼接
return bf.array(); //最終寫入Characteristic的內容
}
這個數據與MAC地址最后兩位FC進行異或為16byte數據,在轉為2byte的hex簽名結果。用戶信息與手機端無需一致,只要簽名正確即可。這里感謝 @瘦蛟舞 的幫忙,用java程序幫我做了個接口,這樣我就能根據MAC地址任意生成有效的認證數據了。

完整代碼也不放出了,畢竟可以秒殺手環認證:)
解決了認證的難題,接下來就是壓軸大戲,如何對用戶以及產品口碑造成真正的影響。震動?改步數?LED跑馬燈?都不是,我選擇在茫茫人群中,給你寫入惡意的鬧鈴,名曰 午夜兇“鈴”。試想下,背著我那臺無線Hack設備,天天在早高峰蹭北京城鐵13號線,自動搜索身邊小米手環,然后鏈接過認證寫入鬧鈴,你們猜一個月后我能“感染”多少手環?我相信不用多久,小米手環論壇就會有用戶鬧翻天了…光說不練耍流氓,實現它。選擇設備后抓包,客戶端設置幾次鬧鈴,只要一次我就解開私有協議格式了:

一樣簡單,數據格式我畫出來。第一位說明當前的操作是鬧鈴,第二位是鬧鈴的序號,第三位鬧鈴的開關,第四位開始就是鬧鈴時間,倒數第二位是智能喚醒(就是在你淺睡眠的時候把你叫起,但是我偏不,就是要在你深度睡眠時喚醒你,木哈哈),最后一位就是鬧鈴的循環日期,0x7F就是每天。
寫好測試程序,搜索并鏈接手環通過那個“認證”獲取操作權限,再用手環LED玩個跑馬燈,最后華麗麗的寫入鬧鈴釋放鏈接。結果手機客戶端連上去發現鬧!鈴!沒!開!啟!還是默認的關閉狀態,不放棄繼續分析,我是越挫越勇的……
通過后面的分析發現,這個地方是小米手環客戶端(至少iOS客戶端)的BUG,手環開發組GG認為手環的數據只有通過客戶端進行開啟修改,所以非客戶端寫入的數據不會自動同步!也就造成了惡意鬧鈴雖然寫入成功,但客戶端看不到,認為鬧鈴沒有變化不去同步最新的狀態,但這反讓攻擊變的更加隱蔽了,嘖嘖。
看演示吧,POC代碼不放,因為細心動手的人可以通過我的分析解決一切問題,也避免真的有人直接利用代碼對小米用戶進行攻擊(因測試成功后忘記取消之前設置的午夜兇“鈴”,所以我成了第一個受害者,大半夜太酸爽了)。
Demo:(視頻略大,沒法直接上傳,感興趣的童鞋進入烏云平臺看吧)
0x06 結語
內容沒有涉及任何經典/低功耗藍牙的協議加解密、簽名、配對兒認證等安全機制,畢竟是初探,不搞那么復雜高大上變成學術文章。所以我先分享一些接地氣兒的產品和攻擊場景,希望能夠建立伙伴們對物聯網安全的興趣。
BLE在藍牙中都是很小的一部分,在物聯網汪洋大海中更是一葉扁舟,學海無涯希望路上有你。
PS:以上的內容我個人認為并不是漏洞,畢竟還得10米的攻擊范圍內,所以直接當做技術分享吧。
為照顧用戶體驗,部分內容已做精簡。欲了解更多技術細節,可進入烏云平臺查看。
雷峰網原創文章,未經授權禁止轉載。詳情見轉載須知。