作者:Yimi Hu & Light @ PwnMonkeyLab
原文鏈接:https://mp.weixin.qq.com/s/22kNqVtPDqObC3MslaxYdQ
簡介
本篇是關于海康螢石智能網關分析的第4篇,應該也是關于海康螢石智能網關的最后一篇,原計劃是再多分享點內容,但鑒于胖猴實驗室和海康的良好關系,把海康螢石的網關設備分享得非常透徹也不太好。其實,在此前的3篇文章中,我們已經完成了固件編輯和重打包,通過telnet登陸固件系統,以及使用gdbserver調試程序,在此基礎之上,相信讀者完全可以對設備固件進行獨立分析了。
在這海康螢石智能網關的最后一篇文章中,我們就把上次的遺留問題處理了,即設備的認證方式以及加密密鑰生成方法。
程序分析
2.1 概述
在上一篇的結尾部分,我們已經具備了調試能力,可以調試固件中的davinci程序以及libmicrokernel.so.1等動態連接庫。為了節約篇幅,在本篇中我們先將一些分析結論與各位分享,然后再詳細調試其中的某個細節。
在海康螢石的智能網關中,完整的通信流程涉及到3個密鑰,分別是share key、master key以及session key。顧名思義,share key是智能網關與litedev服務器(與之對應的另一個服務器是MQTT服務器)共有的密鑰,由設備序列號等常量經過多次MD5運算得到,每個智能網關設備的share key都是獨一無二的,;master key是智能網關與litedev服務器經過密鑰協商而來,用于加密傳輸session key,關于master key的密鑰協商過程就是本篇分析的重點內容;最后session key是智能網關與MQTT服務器通信時使用的加密密鑰,該密鑰由litedev服務器直接下發給智能網關。
以上三個密鑰在使用過程中,share key是與設備綁定,且固定不變的,一旦獲取了share key,就可以完成所有的認證過程,最終被海康螢石認定為合法的網關設備;使用者通過手機app綁定智能網關時,會經過密鑰協商生成master key,每綁定一次會就更新一次;最后的session key則每次運行davinci程序時,都會更新,這也意味著每次重啟網關都會更新session key。三個不同級別的密鑰,三個不同的密鑰生存周期。
在對海康螢石智能網關的密鑰體系有所了解之后,我們就可以聚焦到某些細節上,下面來著重看一下master key和share key的生成過程。
2.2 master key生成
2.2.1 認證細節分析
為了觸發智能網關的密鑰協商流程,我們需要先刪除當前的master key,具體講就是刪除 “/cfg/dev_masterkey”文件,如下圖所示:

刪除當前master key之后,繼續按照上一篇所述的方法啟動調試器,并在上一篇結尾時提到的send_authentication_i函數下斷點,等到程序中斷到調試器中,如下圖所示:

通過逆向分析該函數,可以獲知它調用的common_serialize和authentication_i_serialize用于構造將要發送的數據。我們在common_serialize函數之前下斷點,然后用gdb命令查看待發送數據的內容(本次調試時,地址為0x007d2dd0),如下圖所示:

在上圖中,可以看到待發送數據內容還是空的。待函數common_serialize執行完畢之后,重新打印該地址的數據,如下圖所示:

該地址的前幾個字節已經被賦值了。繼續調試該程序,在authentication_i_serialize函數之后下斷點,待程序中斷時,重新打印該內存處的數據,如下圖所示:

可以觀察到,authentication_i_serialize函數執行完畢之后,待發送數據基本構造完畢。我們對比一下本次發送數據和之前我們通過wireshark抓包獲取的發送數據,如下圖所示:

可以看到,本次構造的發送數據與之前的抓包結果是有一小部分相同的,而不同的這部分應該就是海康螢石智能網關密鑰協商的關鍵部分。
為了找到產生不同的原因,我們來重點逆向authentication_i_serialize函數,可以在該函數中發現其調用了一個簽名函數digital_sign_serialize函數:

在該簽名函數之前和之后下斷點,可以觀察到需要簽名的數據以及簽名結果。結合之前用gdb調試send_authentication_i時獲得的發送數據,就可以分析出發送的數據格式如下:

其中,dev_subserial是設備序列號;random_1是1字節隨機數,每次密鑰協商時都是不同的。由于random_1字節的不同,導致了digital_sign不同,所以總共有33(1+32)字節是每次通信都不同的。經過本次通信,智能網關將random_1參數上傳至litedev服務器。
通過類似的分析方法,就可以獲知認證過程中的其他3個函數的作用,這3個函數分別是:wait_authentication_ii、send_authentication_iii以及wait_authentication_iv。加上send_authentication_i函數,網關和服務器之間總共同步了4個隨機數。
2.2.2 認證完整過程
在上述的分析過程中,可以發現一個名為lbs_affair的結構體貫穿了整個認證過程,4個隨機數也保存在結構體之中,該結構體的內容如下:
00000000 lbs_affair struct
00000000 random_1: .byte
00000001 random_2: .byte
00000002 random_3: .byte
00000003 random_4: .byte
00000004 dev_subserial: .byte 16
00000014 master_key: .byte 16
00000024 dev_id: .byte 32
00000044 session_key: .byte 16
00000054 share_key: .byte 32
00000074 share_key_len: .half
00000076 .byte
00000077 .byte
00000078 global_out_packet: lbs_packet
0000008C global_in_packet: lbs_packet
000000A0 lbs_net_work: .word
000000A4 lbs_affair ends
其中,random_1和random_3由智能網關生成,發送給服務器;random_2和randon_4由服務器生成,發送給智能網關。
通過這4個隨機數以及share key就可以生成master key了,并進一步由master key獲取session key。其master key的生成算法比較簡單,可以在generate_masterkey函數中找到,如下圖所示:

根據圖中紅框標出的偏移可以知道,master key的生成過程就是將random_1、random_2、random_3、random_4和share_key拼湊在一起,然后調用sha512函數,其hash結果就是最終的master key了。
繼續分析其固件的后續內容可以發現以master key作為密鑰,使用aes cbc算法解密session key相關的代碼段,這里就不截圖了。獲取session key之后,通信數據的加密密鑰就完全切換為session key,不再使用master key了。
2.3 share key生成
相比于master key的生成過程,share key的生成無疑簡單了很多。可以在generate_sharekey函數中找到關于share key的各種運算,通過閱讀IDA反匯編后的代碼,可以確認share key是通過對dev_subserial和dev_verification_code以及一個固定的鹽進行多次MD5而得到,其中dev_verification_code是設備的認證碼,該認證碼被貼在海康螢石智能網關背面的標簽上。在md5運算過程中,固定的鹽值如下圖所示:

上圖中,“ 88075998”是海康的聯系電話,在此處,“www.88075998.com”作為鹽參與了第二次MD5運算中。
小結
到此,關于海康螢石系列的四篇文章就結束了。在前3篇文章中,我們分別解決了開啟uart串口、提取flash內容、固件重打包、gdb調試等問題;而在最后1篇中,我們分析了海康螢石的密鑰體系,雖然寫的有些模糊,但基本上涵蓋了所有關鍵點,很多海康和螢石的其他IoT設備也使用了類似的密鑰體系,本篇分析可以提供一個借鑒。其實關于海康螢石智能網關還有很多可以寫的內容,但實在不適合在這里公開的與大家分享,還是等有機會私下交流吧。
在筆者分析海康螢石智能網關時,Ghidra尚未發布且IDA尚不支持mips decompiler,但在寫本文時已經出現了很多好用的工具,合理利用這些工具可以大幅度減少分析工作量。最后,希望本篇文章能給各位讀者帶來一些收獲。在本專題的后續文章中,我們還會繼續分享其他的研究案例,敬請期待。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/1539/
暫無評論