IoT設備獲取本地shell權限并進行軟件調試
1、簡介
筆者近期研究了一些智能家居設備,這些設備開放端口較少,網絡側基本無法獲取調試權限。本地獲取設備的調試權限,在當前的攻防形態下,就變成了一個重要步驟。本文主要記錄通過串口、固件篡改獲取本地權限的過程。
如下圖所示的設備,位置1為flash芯片,位置2為串口調試接口。使用串口線進行串口探測,將主板上的接口一一引出,再使用萬用表測試電平,最后判定其串口線序,這一步許多道友都分享了,這里不再贅述。接下來主要介紹記錄獲取本地shell權限和調試環境的過程。

圖 1 設備主板flash和串口位置
2、本地權限獲取
本節主要介紹3個步驟,分別是串口探測、讀取固件、更改固件。這三個步驟的實驗可使設備運行更改后的固件,并成功執行本地shell和telnetd服務。
2.1 串口探測
使用串口線連接到設備后,顯示(none)login,需要進行登錄。因為不知道密碼,暫時無法獲取本地root權限。

圖 2 本地提示登錄
嘗試更改uboot啟動參數時,uboot設置了密碼。

圖 3 進圖uboot命令行之前提示輸入密碼
嘗試把uboot提取出來后,發現一個密碼,但是輸入到uboot中,無法登錄,暫時沒辦法短時間內通過uboot啟動我們指定的固件。

圖 4 uboot逆向后硬編碼的某字符串
綜上,在串口上直接獲取本地權限比較困難,逆向完uboot需要的時間成本較大,決定改flash上的固件獲取權限。
2.2 讀取固件
硬件上使用Norflash,硬件上處理固件相對容易。本次使用工具如下:
? Xgpro T56編程器
? Putty
? USB轉TTL線
? 拆焊臺
使用編程器將固件讀取后,可直接使用binwalk解壓到文件系統,進而進行固件的靜態分析。

圖 5 binwalk輸出的固件結構
Binwalk的結構看起來有些識別誤差,我們查看F40000附近后,可確定0x440000-0xF40000處為JFFS2文件系統分區(而非0xF400D4)。

圖 6 固件0xF40000位置
使用dd命令分割固件,將該區域的文件系統文件使用binwalk解壓后,可得到以下文件系統內容。

圖 7 JFFS文件系統內容
使用binwalk解壓整個固件,可得到根文件系統目錄,如下所示:

圖 8 根文件系統結構
在根文件系統下搜索”boot.sh”,確定boot.sh會在開機啟動。

圖 9 開機啟動boot.sh
也就是說,JFFS2文件系統作為一個MTD分區被加載到內存后,進行了掛載,并在啟動腳本”S90init”中啟動。我們只需要更改該腳本,并啟動telnetd和串口shell即可。
2.3 更改固件
由以上實驗可知,更改boot.sh即可執行本地命令。在boot.sh中增加如下所示內容。

圖 10 固件更改內容
下面重新打包固件。主要步驟如下:
? 將被更改的固件目錄重新打包為相同格式的文件系統rootfs.jffs2。
? 制作全“ff”的文件系統out1024.bin。
? 將rootfs.jffs2填充到out1024.img中。
? 將out1024.img填充到原固件中。
分別對應下列命令:

圖 11 更改固件對應的命令
使用編程器進行固件燒錄,這里不再贅述編程器的使用過程。再次啟動設備后,發現設備啟動了更改后的腳本:

圖 12 更改后的固件生效
telnet也連接shell成功:

圖 13 連接telnet shell成功
3、調試環境
本節介紹兩個方面的內容,分別是NFS服務的搭建流程和交叉編譯環境的搭建流程,通過這兩個流程,我們實現了拓展本地運行存儲空間,并建立了軟件進程的調試環境。
3.1 NFS服務
本地拿了權限,但是設備沒有太多的空間供我們使用,具體如下所示。、

圖 14 設備自身空間使用情況
查看/proc/filesystems確認設備具備NFS服務掛載的模塊,使用NFS服務外部硬盤到本地執行gdbserver或者tcpdump是一個比較好的選擇。

圖 15 filesystems文件內容
本地搭建好NFS服務后,讓服務主機與設備在一個子網中,可遠程掛載NFS服務到本地,解決了本地空間不足的問題。具體如下。

圖 16 掛載遠程硬盤成功

圖 17 掛載遠程硬盤拓展容量
3.2 交叉編譯環境
3.2.1 確定交叉編譯器
全盤搜索“arm-”可得到以下信息,確定交叉編譯工具為arm-none-linux-gnueabi-4.4.0_ARMv5TE,具體如下圖所示。在網上可找到其下載地址。

圖 18 確定交叉編譯器

圖 19 網上搜索到交叉編譯器鏈接
構建交叉編譯環境的過程就是解壓、添加PATH到系統中的過程,這里不再贅述,接下來嘗試編譯gdbserver。
3.2.2 交叉編譯gdbserver
由圖 網上搜索到交叉編譯器鏈接 可知,交叉編譯器的版本可追溯到2012年8月份。這里選定2013年左右的gdb-7.6.1進行編譯,出錯的概率會小些。
Gdb依賴的termcap庫不在交叉編譯環境中,下載termcap-1.3.1.tar.gz并交叉編譯后,將編譯生成的libtermcap.a復制到交叉編譯環境的lib目錄下即可編譯gdbserver成功。編譯gdbserver的命令如下:
./configure --host=arm-none-linux-gnueabi --target=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc
這一條命令分別在gdb根目錄下和gdb/gdbserver目錄下運行,即可生成交叉編譯后的gdb和gdbserver。將編譯后的文件復制到nfs共享目錄下:

圖 20 復制gdb和gdbserver到共享目錄下

圖 21 在設備上執行gdbserver和gdb成功

圖 22 gdbserver attach進程成功

圖 23 建立調試連接
最后建立連接的時候暫時出現了一些問題。看門狗給把進程關掉了,后面的調試還要繞過看門狗,這里不再贅述。

圖 24 看門狗kill了調試進程
4、總結
本文通過記錄智能家居設備的部分研究過程,向讀者分享了嵌入式產品簡單的固件分析、固件篡改、調試環境的建立流程。希望對各位讀者的安全研究有幫助。
由于現有設備的特殊性,這些方法只是達到階段目標的可行方式之一。比如燒錄固件,也可以通過uboot的tftp功能燒錄,還可以通過uboot加載DIY的固件等等,這些功能比較簡單,但歸根結底還是向flash中寫入數據,并將flash區域中的數據讀取到內存空間后進行啟動的過程,單獨成文的必要性不大,有興趣的同學可以單獨溝通。