1. 程式人生 > >裸奔的智慧插座:博聯Broadlink SP2/SP mini的分析、破解

裸奔的智慧插座:博聯Broadlink SP2/SP mini的分析、破解

https://www.jianshu.com/p/028b10bc3dd1

智慧裝置的聯動通常採用IFTTT的方式,但這種方式受限於官方軟體提供的功能。想要自主地靈活控制,需要有官方SDK,或知道協議細節。本文通過捕獲、分析Broadlink SP裝置(含SP2和SP mini)的協議資料,達到重放(replay)控制的效果。在這個過程中,對其安全性也有了更深入的認識。

有前人做過類似的工作,但抓包過程較為繁瑣。本文的方法比較便捷,可以很容易地進行本地和遠端的分析。這個方法也可供研究其它智慧裝置時借鑑。

在路由器上用tcpdump抓包,基本行為研究

家裡的路由器是刷了OpenWRT的,所以可以直接嘗試在路由器上用tcpdump抓包。

實驗1:不開啟任何App時,觀察插座上的活動。

命令:tcpdump -i ra0 udp and host sp3 -U -s0 -w /tmp/tmp.pcap -c 30 -vvv
(sp3是我的第3個SP型別的裝置,並不是指型號;上面的命令是抓到30個UDP包就停止)

在Wireshark中開啟抓獲的pcap檔案:

  image.png

可以看到:大約每25秒,插座會向Broadlink的伺服器(112.124.35.104)報告一次自己的狀態。可稱之為線上狀態報告。

實驗2:在4G網路下(不用Wi-Fi),開啟手機App對應的插座狀態介面

  image.png

可以看到,大約每3秒,插座會向Broadlink的伺服器(112.124.35.104)報告一次自己的開關狀態。當然,資料裡還有線上狀態報告。通過包的長度很容易區分出來。

3秒的間隔應該是App端決定的,其實是App向Broadlink伺服器詢問插座開關狀態,伺服器再來問插座的。

區域網內抓包的問題

當手機在家裡或在家外時,控制智慧插座的原理是不一樣的。手機和插座在同一個區域網內時,它們是直接通訊,不需要藉助於伺服器的。

但在無線路由器上,其實是抓不到兩個Wi-Fi裝置之間的通訊的。也許這些通訊由Wi-Fi硬體直接處理,不經過路由器的系統(驅動)。而且我試了,一方接在2.4G上,另一方接在5G上,也是一樣抓不到資料。

要抓取區域網內的兩個無線裝置的通訊,傳統的辦法是把PC變成AP,讓它們的流量經過PC,然後用抓包軟體抓取。但這需要對裝置重新部署、配置,比較折騰。

用無線網絡卡的monitor模式,使用Wi-Fi sniffer,也是一種選擇。但對於加密的無線網路,比較麻煩。而且是從資料鏈路層分析應用層的資料,略感捨近求遠。

因為無線路由器上可以抓到區域網內有線裝置和無線裝置之間的通訊,所以還有另一個選擇:把手機變成有線的!

Android模擬器Genymotion

在PC上執行Android模擬器,我們就有了一個連在有線網路上的手機了(前提當然是PC連在有線網路上),從而可以繼續在無線路由器上抓包。

Android的模擬器有不少,我一般用Genymotion。Genymotion預設不支援ARM,但有好人弄了翻譯器。新版的Genymotion好像只在Android 6.0, 5.0上有翻譯器的支援。

當然,如果App支援x86架構,或與架構無關(純Java的),也是不需要ARM翻譯器的。但Broadlink App(易控)不是這樣的。

  image.png

最後,Broadlink App能在Android 6.0的模擬器上正常執行。

  image.png

另外,在Genymotion的設定中使用網橋模式,這樣,模擬器和Broadlink裝置在同一網段。

區域網內行為研究

實驗3:在區域網內,Android模擬器上點選開/關時,在OpenWRT上用tcpdump抓包

  image.png

這些包裡有3秒一次的開關狀態包。都是QUIC協議114位元組。根據時間的週期性,可以看出哪些包是對應於開關控制的,比如上圖中的第2和第4個包。

為了重新發送這些資料包,寫了一個簡單的Python指令碼sendpcap.py,對pcap檔案進行簡單解析,主要是確定每個包的分隔,哪些是頭部,哪些是Payload,並可以傳送指定序號的一個或多個包。

實驗4:在區域網內,重新發送pcap裡的某個指定的UDP包,可以控制SP插座的開和關。

命令:sendpcap.py sp3 sp3-lan-phone-onoff.pcap 2

傳送第2個包會開啟插座。

  image.png

儘管每個包的資料不完全一樣,但這些包都可以用於控制插座。實測一年以後還有效(當然,只對於同樣網路環境下的同一個裝置)。

所以,對每個裝置採集一段樣本資料,確定哪個包是控制開的,哪個包是控制關的,就可以實現對不同插座的自主控制了。

遠端行為研究

那麼,這種重放機制對於遠端控制插座是否有效呢?

對於遠端互動,由於家裡路由器上收到的只是進入裝置的資料,而且,有些互動資料不一定會流入裝置(也許是和Broadlink伺服器互動)。所以,需要把抓包環境搭建在遠端端,抓獲遠端手機端的流出資料。

其實,在root的Android上也可以安裝tcpdump的。更好的是,Genymotion的Android已經自帶tcpdump了。

實驗5:在遠端網路上,在Android模擬器上通過tcpdump抓包

命令:tcpdump -i eth1 -U -c 300 -vvv -w xxx.pcap

  image.png

結果出乎意料,沒有任何直接指向家裡的資料流,只有和Broadlink伺服器的資料往來。

  image.png

用同樣的方法,我們可以重發這些資料包。下圖中,資料包128對應於關播座,154對應於開插座。

實驗6:在遠端網路上,通過重新發送pcap裡的某個指定的包,可以控制家中的SP插座的開和關

命令:sendpcap.py 112.124.42.42 xxx.pcap 154

  image.png

就這麼輕鬆,發一個獨立的資料包給Broadlink的伺服器就能控制家裡的插座了,沒有任何上下文,資料也不會過期(實測一天之後也可以用)。

結語

有了基於OpenWRT的無線路由器,或基於Genymotion的Android模擬器,我們便可以很容易地在路由器或Android上用tcpdump抓取Broadlink SP裝置的網路資料包,從而分析其協議。

  image.png

在區域網內控制Broadlink插座,並不需要Broadlink伺服器的參與;而遠端控制插座,則都要藉助於伺服器。

重新發送截獲的 UDP/QUIC資料包就可以控制插座。不管是SP2,還是SP mini,不管是區域網,還是遠端的,都可以。但必須用在對應環境下、對應裝置的資料包。對同一裝置,每次抓獲的資料包都不完全相同,但用任何一個都有效,且不會過期,沒有會話上下文。

可見,這個安全性是很低的,形象地說,就是“裸奔”。只要在網路上截獲發往Broadlink伺服器或SP裝置的UDP包,便很容易實現“重放攻擊”。當然,我們也可以用這一原理來自主地控制插座。比如,我曾用程控電源給鋰電池充電,當樹莓派檢測到電流或電壓達到一定值時,便從樹莓派上發UDP包關閉插座,從而徹底關閉程控電源; 當電壓過低時,便發包開啟電源充電。這些,是用手機App無法整合的。

所以,這事有兩面性:不安全,但便利。

參考

  1. broadlink的智慧插座sp2簡單分析. 沒有去驗證這篇文章中的抓包方式,只是從這篇文章得知重放攻擊的可行性。另一方面說明3年來,Broadlink的這一不安全的方式並沒有改進。
  2. 博聯易控App下載. 當前最新的版本確定可以在Genymition的Android模擬器上執行,但需要ARM翻譯器。


作者:蘿蔔頭實驗室
連結:https://www.jianshu.com/p/028b10bc3dd1
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。