作者:EnsecTeam-挽秋
公眾號:EnsecTeam

本文以如何劫持(竊取)智能家居時代設備的身份“安全憑證”為出發點,調研并分析了目前國內市場的主流產品和設備交互協議,及其所依賴身份憑證,通過介紹、分析和發現設備交互控制協議安全性,最終通過身份劫持,實現相關設備和產品的任意遠程控制。

智能家居身份和劫持危害

先通過一張簡圖來了解一下應用、智能設備和云端三者交互時攜帶的身份標識,如圖所示:

智能家居設備交互時攜帶的身份標識

從上圖了解到,智能家居身份標識通常是以下幾種情況:

  1. 賬號cookie相關,如身份Token;
  2. 用戶id:userid
  3. 設備id:deviceid
  4. 認證或加密的key

一旦用戶或設備的身份被劫持,那么至少存在如下幾方面危害:

  1. 個人信息,聊天內容等隱私敏感信息泄露
  2. 智能設備被任意控制
  3. 財產損失
  4. 隨時被監控

以智能音箱和智能插座等設備為例,至少有兩個環節設計“身份”相關:

  1. 賬號同步
  2. 設備交互操作

下面將分別介紹如何在這兩個環節進行身份劫持。

賬號同步

賬號同步是指,在智能設備在初次激活使用(或更改綁定用戶時),用戶將自己的身份信息同步給設備,并綁定設備。

一個簡化的賬號同步流程,如圖所示:

賬號同步

賬號同步通常會存在如下兩類問題:

  • 如何設備是否合法:驗證設備id還是設備key?id和key都很容易泄露偽造。
  • 賬號Token如何安全傳輸:設備此時為入網,通過藍牙、AP,還是其他何種方式傳輸賬號信息。

賬號同步時身份劫持,以廠商A音箱的配網和身份賬號同步為例,其賬號同步分為兩種方式:

  1. 直接通過UDP廣播255.255.255.255:50000,發送userid、token和wifi的ssid和wifi密碼。
  2. 將userid、token、ssid和wifi密碼等轉化成語音播放,音箱進行語音信息識別即可。

關于兩種模式的選擇:由本地sharedPreferences文件(tg_app_env.xml)中的app_connect_mode屬性值決定,其賬號同步代碼如圖所示:

廠商A音箱的賬號同步

廠商A的音箱將身份信息,通過固定“協議”的格式,在UDP255.255.255.255:50000端口進行身份信息發送,攻擊者可以監聽UDP50000端口,從而獲取用戶的userid和token,竊取身份憑據;語音發送也是按照同一套固定的“協議”格式發送。協議格式通過破解后如圖所示:

廠商A音箱的賬號信息同步格式

設備交互

設備交互是指應用、設備和云端的三者交互訪問;交互操作大體分為兩種方式:

  1. 只支持廣域網:廠商A為代表;
  2. 支持廣域網和局域網:廠商B和C為代表。

廣域網交互中應用與設備交互、設備與設備的交互方式如圖:

應用和設備廣域網交互

設備和設備廣域網交互

廠商A的智能家居接入方式:以開燈為例

第一步:廠商A的音箱-->音箱server

url:https://.com/

Payload: { Uderid, Deviceid, Accesstoken, 打開燈的語音}

第二步:廠商A的音箱sever-->第三方server

用戶需要在第三方產品server注冊并通過Oauth授權給廠商A的Server,消息格式如下:

{
 "header":{
   “namespace”:”***Genie.Iot.Device.Control",
      "name":"TurnOn",
      "messageId":"1bd5d003-31b9-476f-ad03-71d471922820",
      "payLoadVersion":1
   },
   "payload":{
       "accessToken":"access token",
       "deviceId":"34234",
       "deviceType":"XXX",
       "attribute":"powerstate",
       "value":"on",
       "extensions":{                                         
          "extension1":"",
          "extension2":""
      }
}
}

第三步:第三方server-->設備

Payload:{command: turn-on, currentValue:0 }

廠商A音箱的身份劫持

廠商A的音箱每次交互時,都會攜帶: token、userid、deviceid、action來進行,并且server會依據userid來進行身份判斷。

  1. 有了userid就可以身份劫持——遠程設備任意操作;
  2. userId是順序的,可遍歷的9位數字:比如一個userid是50*123,另一個userid則是50*397這幾位數字;
  3. userid還有其他多種方式獲得:配網時竊取、APP端上獲取;

廠商A音箱被劫持后,可以用戶查看聊天記錄,自定義問答,設置鬧鐘、話費充值、智能家居控制等等,此外音箱 “被分享”之后,宿主不能主動取消分享,只能等“攻擊者”取消分享,身份劫持危害如圖所示,中間的攻擊者可以任意查看用戶的聊天記錄:

廠商A音箱的身份劫持

如何發現這類身份劫持?

應用或設備通過攜帶4元組信息:userid、deviceid、token和action,向云端進行請求時,如下圖所示,如果云端對4元組信息校驗出現不一致的情況下,就會導致身份劫持:

  • 把userid、deviceid、token三者信息中的一種直接當成用戶身份,而不是進行嚴格的身份一致性判斷:判斷userid和token是否一致,用戶身份和設備列表是否是綁定關系。
  • 用戶身份和action判斷,存在邏輯漏洞,導致攻擊者可以進行操作提權,比如子設備提權可以操作“屬主”身份的一些權限,OTA更新等等。

4元組訪問請求

局域網交互中應用與設備交互、設備與設備的交互方式如下圖所示:

應用和設備局域網交互

設備和設備局域網交互

廠商B的設備局域網身份劫持

在同一局域網下,廠商B設備通過專有的加密UDP網絡協議——miio協議,進行通信控制。

  1. 通過廣播發送一個握手協議包,如果設備支持miio協議,那么設備就會回復自身信息:token、ip和ID。
  2. 向指定設備發送一串hello bytes獲得設備信息結構體”header”
  3. 憑借token、ID等信息構造信息結構體”header”,跟隨控制消息發送給設備,實現設備控制。

廠商B的設備局域網身份劫持交互如圖所示:

廠商B的設備局域網身份劫持交互

第一步:安裝python-miio庫,然后執行:mirobo discover --handshake 1,獲取設備IP、ID和Token信息。

第二步:發送hello bytes消息給設備54321端口,獲取設備消息結構體Header:

第三步:偽造控制消息結構體Header、消息指令cmd和checksum(Token),給設備發送;

typedef  struct{
Header,
cmd,
checksum
}Msg

控制消息結構體如圖所示:

廠商B的設備控制消息結構體

以打開智能插座為例:cmd={'id':1,'method':'set_power','params':['on']}

廠商C的局域網交互控制

廠商C為了實現智能家居生態,主推一套實現產品智能化互聯互通的協議——“***Link”,目前所有的產品都可以與APP,以及音箱進行交互控制,是一套“帶認證的密鑰協商+對稱密鑰加密”的設備操作和交互控制協議。

再介紹和認識“帶認證的密鑰協商”之前,我們先介紹一下ECDH密鑰協商及其存在的安全問題。

有兩個用戶Bob和Alice,使用ECDH密鑰協商,交互過程如圖所示:

ECDH密鑰協商

但是ECDH密鑰協商是無法防御中間人攻擊的,假設在Bob和Alice存在一個攻擊者——Attack,對Bob和Alice進行中間人攻擊,ECDH協商流程如圖所示:

ECDH密鑰協商之中間人攻擊

為了防御中間人攻擊,需要在ECDH密鑰協商過程中加入“一套身份認證機制”——EccSignKey和EccVerifyKey,EccVerifyKey提前存儲在需要協商密鑰的用戶設備上,整個“待認證的ECDH密鑰協商”交互過程如圖所示:

待認證的ECDH密鑰協商

設備和廠商C的應用(或音箱)基于***Link協議來進行交互,第三方設備制造商首先在云端通過ECC算法一對生成公私鑰:Ecc-sPrivateKey/Ecc-sPubkey,其中公鑰Ecc-sPubkey內置在設備端,用于發送隨機數到云端,進行設備的身份認證,設備認證合法后,云端下發設備后續通信加密的key:accessKey,然后應用使用ECDH密鑰協商算法協商出的密鑰,通過AES-CBC模式加密傳輸accessKey;此外設備和應用進行局域網通信時,都是通過localkey進行加解密來進行的,其中localkey就是accessKey。設備和廠商C的應用局域網交互流程如圖所示:

設備和廠商C的應用局域網通信交互

廠商C的設備局域網身份劫持

廠商C的***Link協議的交互控制的消息結構體如下所示:

以打開智能插座為例:

Packet_t=協議包頭,opt=null,Payload=LocalKey 密鑰加密

Time[時間戳]  //4字節int類型時間戳,小端在前
{
“cmd”:5,
"data":{
"streams":[{"current_value":"0","stream_id":"power"}],
"snapshot":[{"current_value":"1","stream_id":"power"}]
}

設備交互方式總結和比較

通過應用實現身份劫持

通過應用實現身份劫持,常用的方法有如下兩種:

1)通過webview JS交互接口遠程命令執行或泄露身份賬號

應用APP通過為webview @JavascriptInterface關鍵字,自定義添加身份獲取的函數,并且沒對加載url做好限制,導致身份信息遠程泄露或者遠程命令執行

2)Webview file域遠程信息泄露

應用開啟WebSettings.setAllowUniversalAccessFromFileURLs(true),并且webview對加載的url沒有任何限制,則應用APP下所有私有目錄信息都會被竊取

通過webview JS交互接口遠程命令執行或泄露身份賬號

應用掃一掃時(CaptureActivity),當CaptureActivity掃描到是“合法”url時,會調用com.***.WebViewActivity進行url加載,但是url判斷邏輯存在漏洞,導致攻擊者可以調用WebViewActivity定義的交互接口,遠程獲取用戶賬號等敏感身份信息,漏洞執行效果如下圖所示。

通過webview-JS交互接口獲取廠商C控制應用的身份

漏洞案列簡化:

if(loadurl.contains(“***”)){
//合法
} else{
//不合法
}

Webview file域遠程信息泄露

廠商A的音箱控制APP中WVWebViewActivity對外導出,并接收如下遠程uri scheme:assistant://hsend***Poc5_web_view?direct_address=url

WVWebViewActivity接受外部的url會傳入Fragment中的webview中進行加載,并且WVWebViewActivity中對webview進行了設置,開啟了JS和file文件訪問能力,并設置了WebSettings.setAllowUniversalAccessFromFileURLs(true)。

攻擊者可以將assistant偽協議中的url先通過url加載任意html,然后下載惡意html文件到本地,然后webview跳轉加載本地的惡意html文件,竊取用戶私有目錄內的身份信息。

assistant://hsend***Poc5_web_view?direct_address=http://www.test.com
assistant://hsend***Poc5_web_view?direct_address=file:///*/***.html

智能家居身份劫持漏洞總結

1. 配網泄露

2. 設備交互控制時,劫持

1)app/設備->server:廠商A為代表,userid為身份憑證,可劫持;

2)局域網控制:

  • 廠商B的局域網控制基于miio協議:token泄露,可劫持
  • 廠商C的微聯局域網控制:帶認證的密鑰協商+對稱密鑰加密(localkey),協議安全;

3. app應用存在身份穿越漏洞

Webview JS交互接口遠程命令執行或遠程信息泄露
Webview File域遠程信息克隆

參考文獻

  1. https://github.com/WeMobileDev/article/blob/master/%E5%9F%BA%E4%BA%8ETLS1.3%E7%9A%84%E5%BE%AE%E4%BF%A1%E5%AE%89%E5%85%A8%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AEmmtls%E4%BB%8B%E7%BB%8D.md
  2. https://github.com/rytilahti/python-miio
  3. http://www.jmbmsq.com/616/

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