原文作者:Juan Carlos Jiménez

翻譯者:光棍節

原文地址:http://jcjc-dev.com/2016/06/08/reversing-huawei-4-dumping-flash/

在前三節中,我們可以得到部分的存儲數據,嗅探感興趣的數據塊以及觀察每個進程使用的資源信息等,但是我們卻無法獲取所有的存儲數據,如果PCB板上沒有了串口的話,或者wifi密碼使用的不是默認的口令呢?上述的研究意義就不大了。

本節中,我們將嘗試從Flash芯片中提取出數據,解壓后就能得到可用的數據,這種提取不依靠昂貴的設備,在之前的研究基礎上,結合Flash芯片的datasheet實現提取。

一、提取存儲內容

在第三節中,我們已經可以根據datasheet知道flash芯片的引腳信息。如圖一所示。 ? 圖一 Flash芯片部分引腳意義

我們也有Flash芯片的操作指令集,這樣我們就可以自己開發程序實現與Flash之間的SPI通信。

在上節中,我們已經測試了在啟動的過程中,CPU芯片Ralink會與Flash芯片進行通信,這個會干擾我們嘗試讀取芯片的內容,所以我們需要斷開他們之間的通信,最好是基于路由器的電路實現。

二、難道我們要拆掉Flash芯片上的焊錫

最簡單的辦法是直接斷開Flash芯片的引腳上的焊錫,這樣就會與電路完全斷開,我們就可以消除掉所有的干擾進而完全的控制芯片,但是,這樣需要額外的設備,還需要有經驗和時間,甚至可能造成芯片的損壞。

第二種方法就是能不能讓CPU芯片及其周邊所有的設備都處于無效或待機狀態。微處理器通常會有一個reset引腳,當接上低電位時就處于關閉狀態,這個引腳一般用于強制重啟設備。但是從電路板上引出CPU這個引腳的麻煩比較大。

如果僅對一個芯片供電而不對其他的芯片供電呢?我們能不能只對Flash芯片供電而不是整個電路板供電?如果只是單獨用3v的電源直接給Flash芯片供電,而不用PCB上的電源電路。這樣有可能會破壞Flash芯片,反正這個路由器便宜而且廣泛使用,當然這樣也有可能會間接的給CPU供電了。如圖二所示。 ? 圖二 直接給Flash芯片供電

在我們供電之后,我們就觀察UART串口打印的數據,雖然可以看到PCB板上有led燈亮了,但是UART卻沒有數據打印,也就是說Ralink沒有運行。盡管Ralink是關閉的,但是由于電路的影響,還是有可能會對我們讀取Flash中的內容造成影響。如果有影響的話,那只能把Flash焊出來單獨研究。

Led燈和一些靜態模塊不會和Flash芯片有數據交互的,所以對我們的分析沒有影響。接下來,我們就用一個bench電源,能夠支持足夠多的電量消耗,當然,也可以用Usb供電等解決。

三、連接Flash芯片

現在我們可以不用將Flash或者Ralink焊斷,我們可以直接連接到Flash,從而實現按塊讀取存儲單元的數據。所有的微處理器都可以實現數據的讀取,一個專用的SPI轉USB將會極大的提高效率。我們采用了一個基于FT232T的電路板,支持SPI以及其他低層次協議。如圖三所示。 ?

圖三 Flash芯片數據讀取連接示意圖

四、提取數據

我們需要一個軟件能夠讀取USB-SPI連接器上的數據,并將存儲器中的內容保存為二進制文件,開源的Flashroom能夠幫助我們解決這個問題。 在測試的過程中發現,無論是OSX和Ubuntu虛擬機上都存在問題,但是在樹莓派上能夠工作。如圖四所示。

圖四 Flash芯片內容讀取

數據已經讀取了,接下來就是分析存儲器中的數據。

五、分解二進制數據

上圖中的file能夠幫助我們大概的看一下二進制文件的格式,我們可以利用binwalk來徹底的解壓二進制數據。如圖五所示。 ? 圖五 binwalk解壓二進制數據

之前我們已經得到了這些數據相關的信息,如整個的內存映射表,結合這些,整個二進制的結構就會更加清晰。如圖六所示。

圖六 Flash存儲映射表

根據上述的地址,整個二進制文件被分成4個段,使用dd命令完成,如下所示:

1. $ dd if=spidump.bin of=bootloader.bin bs=1 count=$((0x020000))
2. ? ? 131072+0 records in
3. ? ? 131072+0 records out
4. ? ? 131072 bytes transferred in 0.215768 secs (607467 bytes/sec)
5. $ dd if=spidump.bin of=mainkernel.bin bs=1 count=$((0x13D000-0x020000)) skip=$((0x020000))
6. ? ? 1167360+0 records in
7. ? ? 1167360+0 records out
8. ? ? 1167360 bytes transferred in 1.900925 secs (614101 bytes/sec)
9. $ dd if=spidump.bin of=mainrootfs.bin bs=1 count=$((0x660000-0x13D000)) skip=$((0x13D000))
10. ? ? 5386240+0 records in
11. ? ? 5386240+0 records out
12. ? ? 5386240 bytes transferred in 9.163635 secs (587784 bytes/sec)
13. $ dd if=spidump.bin of=protect.bin bs=1 count=$((0x800000-0x660000)) skip=$((0x660000))
14. ? ? 1703936+0 records in
15. ? ? 1703936+0 records out
16. ? ? 1703936 bytes transferred in 2.743594 secs (621060 bytes/sec)

這樣我們創造了4個不同的二進制文件:

1、bootloader.bin:uboot,這個文件沒有被壓縮,因為它是最先運行的,CPU并不知道壓縮算法。 2、mainkernel.bin:Linux內核,使用的是LZMA壓縮,這是最基本的固件。 3、mainrootfs.bin:文件系統,使用的是LZMA壓縮算法的squashfs格式,里面包含了所有的二進制文件和配置文件等。 4、protect.bin:保護區域,第三節中已經遇到的。

六、提取數據

接下來詳細的分析4個段的數據。 Bootloader,binwalk分析如圖七所示。

圖七 binwalk分析bootloader.bin

其中有UImage頭,uboot根據這個頭信息來識別存儲區域。有點像Linux下的file命令,解釋第一個頭的意思。 由于bootloader前面已經有分析,此處就跳過。 Kernel,binwalk分析如圖八所示。

圖八 binwalk分析mainkernel.bin

在分析之前,我們首先需要知道采用了什么樣的壓縮算法。此處使用了嵌入式設備中普遍使用的lzma壓縮,這樣就不會有明文的string保存其中了,用strings命令后發現沒有有意義的字符串。 有很多工具能夠解壓縮lzma算法,如7z或者xz等。但是對mainkernel.bin都無效。

  1. $ xz --decompress mainkernel.bin
  2. xz: mainkernel.bin: File format not recognized

這可能是UImage頭部信息占有了最開始的64個字節,在分析中,我們跳過前面64個字節,然后看到以0x40開頭的就是lzma壓縮的開始,如圖九所示。 ? 圖九 跳過mainkernel.bin的前64個字節

再次使用xz命令解壓:

  1. $ xz --decompress mainkernel_noheader.lzma
  2. xz: mainkernel_noheader.lzma: Compressed data is corrupt

由此可見,xz已經能識別是lzma壓縮,但是并不是完全的正確格式。由于我們是嘗試解壓所有的mainkernel區域,但是并不是整個的數據區域都是有效的,查看二進制發現最后的0xff就是無效的,如圖十所示,去掉最后部分,實現了xz的解壓。 ?

圖十 分析mainkernel的格式實現xz解壓

Xz解壓成功之后,我們可以用strings命令查看其中包含的有用的字符串了,如圖十一所示。

圖十一?? ? strings查看解壓后的mainkernel.bin中的字符串

上述的字符串都我們分析wifi密碼生成算法沒有什么幫助,如Wi-Fi Easy and Secure Key Derivation 僅僅是wifi設備中的一個硬編碼字符串。

Filesystem,binwalk分析如圖十二所示。 ? 圖十二 binwalk分析mainrootfs.bin

Mainrootfs段沒有一個UImage頭,由上圖可見,采用的是squashfs文件系統,這個在嵌入式設備中經常使用,有很多的版本,讓我們看看mainrootfs.bin使用的是什么版本標志。如圖十三所示。 ? 圖十三 mainrootfs中的squashfs標志

已有腳本文件能夠實現自動化的分析squashfs。此處使用的是Firmware Modification kit中的 unsquashfs_all.sh實現解壓。如圖十四所示。

圖十四 unsquashfs_all.sh解壓mainrootfs.bin

這樣我們得到了文件系統中的所有二進制文件、配置文件以及快捷方式等。如圖十五。 ? 圖十五 文件系統目錄結構

根據第一節中的字符串,我們就可以查找感興趣的文件了,如圖十六所示。 ? 圖十六 感興趣的文件

這樣文件在挖掘路由器漏洞中將會發揮重要作用。 Protected,binwalk分析如圖十七所示。 ? 圖十七 binwalk分析protect.bin

第三節中已經分析,這塊存儲區域沒有壓縮,包含了啟動過程中所必需含有的字符串,用strings命令查看得到如圖十八所示。 ? 圖十八 strings查看protect.bin文件

這些內容與curcfg.xml很像,第三節已經分析。

七、后記

至此硬件逆向已經完成,我們得到了存儲器中所有的數據,接下來就是進一步的深挖已有的數據。當然,如果你無法從硬件中得到這些數據,你可以去官方網站上下載固件,官方提供的可能不是所有的數據,但是應該能夠滿足研究的要求。


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