系列文章請點擊文末「閱讀原文」查看
1.簡介本篇是關於海康螢石智能網關分析的第3篇,在上一篇中,我們完成了固件編輯和重打包工作。在我們自己修改的固件中,海康螢石的智能網關上電啟動之後會運行telnetd,此後我們只要通過telnet遠程連接網關即可使用shell,不需要再連接不穩定的串口了。
繼續上一篇的內容,我們從本篇開始分析智能網關裡面的關鍵應用,研究一下智能網關到底與伺服器通信了什麼內容。
2. 程序逆向分析2.1 預處理
在海康螢石智能網關中執行ps指令,查看所有正在運行的程序,通過簡單的排除法,就可以確定我們要分析主程序是:』/dav/davinci』(達文西?達文西?),如下圖所示:
圖2-1 固件中運行的所有進程
通過逆向分析davinci程序,我們可以發現該程序是有運行日誌的,只是把不重要的日誌屏蔽了(debug、verbose等),只輸出了較為嚴重的日誌內容(fatal、error等)。那麼我們修改幾條指令,使其跳過對日誌嚴重程度的判斷,如下圖:
圖2-2 patch日誌輸出代碼
除了輸出日誌的函數需要patch之外,還有另一個函數也需要做一些調整。davinci在啟動之後,初始化了一個線程操作看門狗,該線程會不斷向/dev/watchdog進行寫操作。如果一段時間內/dev/watchdog沒有收到任何數據,那麼整個設備就會重啟。由於我們計劃調試davinci程序,如果在調試過程中,觸發斷點導致看門狗線程掛起,那麼整個系統就會重啟。為此,我們先把該線程patch掉,然後再弄一個寫入/dev/watchdog的小腳本,用以專門餵狗防止重啟。相關位置的代碼截圖如下:
圖2-2 patch watchdog相關代碼
餵狗的小腳本內容如下:
圖2-3 餵狗小腳本
相信腳本內容一眼就能夠看懂,所以我們不做太多的解釋了。此外,還有個guard.sh也是用於檢測davinci程序是否運行的,但它不影響我們的操作,所以就不討論該腳本了,有興趣的讀者可以去看看。
完成上述操作之後,就可以把被patch的davinci上傳至海康螢石的智能網關,此處我們不再採用燒錄固件的方法,因為過於麻煩。通過翻閱該設備的文件系統,可以在設備中發現tftp程序,這是一個使用tftp協議傳輸文件的程序,可以用它從tftpd伺服器上傳或下載文件。我們使用從這個連結下載到的tftpd程序:http://tftpd32.jounin.net/tftpd64_download.html,運行後,調整tftpd伺服器的文件目錄和監聽網卡,如下圖:
圖2-4 配置tftpd程序
上圖中,被patch的davinci程序就在紅框標識的目錄中。然後在智能網關設備中使用tftp程序獲取相關文件即可,相關命令截圖如下:
圖2-5 使用tftp下載文件
待相關文件下載到海康螢石的設備中之後,就可以運行FeedWatchdog.sh腳本開始餵狗,然後終止原本的davinci進程,接著刪除/home/pidfile文件,該文件相當於互斥體,用於控制davinci僅運行了一次,最後啟動我們自己的davinci_1進程,相關命令如下:
圖2-6 啟動patch之後的davinci進程
待程序運行一段時間之後,就可以查看程序的運行日誌,然後通過日誌分析程序的各種行為。
2.2 日誌分析
待程序運行一段時間之後,就會在『/applog/devlog』目錄下生成日誌文件,每個文件500KB左右,如下圖所示:
圖2-7 程序運行時生成的日誌
用tftp程序將日誌取回,然後打開程序日誌,在日誌中搜索litedev.ys7.com,這個地址是智能網關上電之後第一個訪問的地址,我們在本專題第9篇,也就是分析海康螢石智能網關的第一篇中介紹過。搜索結果如下圖:
圖2-8 與litedev.ys7.com有關的日誌
上圖中,我們可以看到由litedev.ys7.com解析而來的ip地址:115.231.107.14,這與我們用wireshark抓包時得到的結果是相同的。
繼續翻看日誌,在距離圖2-8不遠的地方,可以看到另一條日誌,看起來像是與海康螢石MQTT伺服器相關的日誌內容,截圖如下:
圖2-9 與MQTT伺服器有關的日誌
從圖中,我們可以看到另一個ip地址:101.71.30.172,該地址同樣與我們wireshark抓包的結果吻合。MQTT通信協議是構建於TCP/IP協議之上的一種輕量級通信協議,經常出現在IoT設備系統中設備端與雲端的通信過程中。
結合這兩條日誌內容和wireshark的抓包結果,我們可以進一步確認設備的工作流程:與litedev.ys7.com通信,獲取了MQTT伺服器的地址;然後與MQTT伺服器通信,實現設備的邏輯功能。
在圖2-8和圖2-9中,我們分別用紅框標識了一個關鍵字符串。在海康螢石智能網關的文件系統中,二進位搜索其中一個字符串「lbs_connect」,確認該字符串出現在libmicrokernel.so.1中。用IDA加載該so文件,可以發現此動態連結庫中,有一個函數名字即為lbs_connect,查找該函數的交叉引用,可以看到有多處代碼調用了此函數,我們隨便找一處點開看下,如下圖所示:
圖2-10 調用lbs_connect函數
可以看到在lbs_connect函數返回成功之後,就會調用send_authentication_i函數。這個函數看起來就是加密和認證相關的函數。
3. 程序調試找到了關鍵點之後,就需要進一步分析這些函數的功能和作用了。在本專題之前的文章中,我們都是純靜態分析,所以在本篇中,我們就不再單純地進行靜態分析,而是想辦法調試一下這個程序。
對於嵌入式Linux作業系統,我們通常選用gdb和gdbserver作為調試工具。gdb是一個應用非常廣泛的調試器,在以後的文章中也會反覆出現,其全稱是GNU Project Debugger,其官網是https://www.gnu.org/software/gdb/;gdbserver是gdb的一部分,常用於解決交叉編譯環境下的遠程調試問題。我們可以直接在設備上使用gdb進行本地調試,但gdb程序體積比較大,而且直接在設備上運行gdb會有很多不方便的地方,所以我們選擇通過gdbserver進行遠程調試。為了完成調試工作,我們首先需要一個可以運行在海康螢石智能網關設備上的gdbserver程序。
在此前關於海康螢石智能網關分析的第二篇文章中,我們下載了MT7688 SDK相關的資料。在進一步翻閱相關的資料之後,我們發現官方MT7688開發板是內置了gdbserver程序。因此,我們下載了官方提供的固件包,並用binwalk提取了固件內容,最後找到了gdbserver程序。但此gdbserver程序運行之後沒有任何輸出,推測是官方定製了gdbserver的代碼,導致我們無法使用該程序調試,截圖如下:
圖3-1 官方gdbserver無法使用
所以,就只能去找一找有沒有其他可以正常運行在海康螢石智能網關中的gdbserver程序了,畢竟自己編譯一個有點太麻煩了。幸運的是,在rapid7官方github帳戶上有一些已經編譯好的gdbserver程序,連結如下:https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver, 我們選擇下載mipsle版本的gdbserver。截圖如下:
圖3-2 rapid7官方github頁面中的embedded-tools倉庫
下載完畢之後,通過tftp下載至海康螢石智能網關的設備中,並嘗試執行此程序。截圖如下:
圖3-3 執行gdbserver.mipsle程序
程序沒有報錯,看來是可以順利執行的。接下來就用此程序開始調試吧。
首先,使用 gdbserver啟動davinci。如果直接用 gdbserver附加davinci進程,很可能會錯過davinci程序與伺服器通信的認證過程。所以我們直接使用gdbserver啟動程序,這樣一來,在遠程調試器連接之前,davinci程序將處於掛起狀態。命令如下:
圖3-4 通過gdbserver啟動程序
此時,gdbserver就開始監聽23946埠,等待遠程調試器的連接。
接下來,我們可以選擇gdb或IDA作為遠程調試器連接gdbserver。IDA提供圖形界面,可以幫助我們理解程序的邏輯;但gdb要更穩定,可以有效避免IDA調試時出現的奇怪錯誤。我們這裡直接選擇gdb作為遠程調試器,在後續的文章中會有介紹用IDA作為調試器的例子。
由於我們需要調試的是MIPS指令集的程序,而gdb默認情況下,僅支持調試與當前環境採用相同指令集的程序(i386),所以我們需要安裝可以調試MIPS指令集的gdb程序。安裝方法比較簡單,直接輸入sudo apt install gdb-multiarch即可。還可以給gdb程序加一個pwndbg插件,用於輔助我們的調試工作,該插件的官方地址是:https://github.com/pwndbg/pwndbg,只需要下載下來,然後運行./setup.sh即可。此插件並非必需品,但是推薦裝上。
完成gdb的配置工作之後,就可以使用gdb連接gdbserver開始遠程調試了。gdb的調試命令非常多,可以直接搜索到很多整理好的常用命令,在這裡,我們就遇見什麼指令就解釋什麼指令吧。運行gdb-multiarch,截圖如下:
圖3-5 運行gdb-multiarch程序
上圖中,我們分別設置architecture為MIPS,讀取davinci的符號文件,在main函數設置斷點,並連接遠程的gdbserver,關鍵位置已用綠框圈出。然後,我們用快捷鍵c(continue),讓程序開始執行,截圖如下:
圖3-6 程序運行到main時中斷
上圖中,紅框部分表示觸發了main函數中的斷點。此時,我們加載libmicrokernel.so.1的符號文件,同樣用file命令,就不截圖了。然後,我們在lbs_connect函數下個斷點,並繼續執行程序,如下圖:
圖3-7 在lbs_connect函數下斷點
稍等片刻,就會看到程序斷在lbs_connect函數中,等待我們的調試命令,截圖如下:
圖3-8 程序命中lbs_connect斷點
從圖中可以看到,程序是從lbs_redirect調用過來的,可以在外層函數下斷點,繼續調試,幫助我們理解程序的邏輯,但是本篇內容先到此為止。
4. 小結從本篇起,我們開始分析海康螢石智能網關的固件程序。在我們的分析過程中,程序的日誌給我們提供了很多幫助。藉助日誌的輸出內容,我們很快定位到了通信加密相關的代碼。接著為了進一步研究設備是如何認證和加密的,我們嘗試使用gdb和gdbserver調試固件中的程序。關於進一步的分析內容將在下一篇分析中展開討論。
作者:Yimi Hu & Light @ PwnMonkeyLabs