VxWorks固件分析方法總結
最近研究基於VxWorks系統的iot設備的固件分析方法,將學習心得記錄於此,以備將來的查詢需要。
1.VxWorks是什么?
VxWorks是美國WindRiverSystem公司(風河公司)推出的一個RTOS(實時操作系統),憑借良好的持續發展能力、高性能的內核以及友好的用戶開發環境,在嵌入式實時操作系統領域占據一席之地。自從1987年首次問世以來,VxWorks系統版本經歷了5.x,6.x到如今的7版本。VxWorks系統憑借其優秀的實時性占據着不小的市場份額,包括NASA的火星探測器、波音787客機、網絡路由器等,市場范圍跨越各種安全領域。
按照所運行的操作系統區分,嵌入式iot設備可以大致上分為基於linux和基於VxWorks的兩類。VxWorks支持幾乎所有現代市場上的嵌入式CPU架構,包括x86系列、MIPS、PowerPC、Freescale ColdFire、Intel i960、SPARC、SH-4、ARM、StrongARM以及xScale CPU。
2.如何定位VxWorks固件的加載地址
使用ida pro、ghidra等反匯編工具進行分析時,需要了解固件的加載地址,否則無法正確的分析固件。下圖所示為填寫固件加載地址前后的函數識別情況的對比,可以看出確定了固件加載地址之后函數的識別度更高。
2.1通過ELF文件頭讀取
通常固件文件會使用ELF格式進行封裝,因此可以使用readelf等工具對頭部文件進行分析,進而得到固件的加載地址。IDA pro已經集成了這個功能,可以直接分析出常見的固件的加載地址。
2.2通過分析內存中的相鄰位置
如圖所示為VxWorks固件在mips架構中的內存分布圖,可知固件加載地址與棧初始化地址相鄰,可以通過定位棧初始化地址確定固件的加載地址。
那么如何定位棧初始化地址呢?那就是尋找棧指針寄存器sp的位置。根據VxWorks官網給出的Initial Stack的說明,可知Initial Stack是usrInit()函數的初始化棧。
又因為UsrInit()是VxWorks系統引導后的運行的第一個函數,因此可以通過在ida中尋找sp寄存器首次出現的位置(此時的ida並沒有指定固件加載地址),通過sp的值確定棧初始化的值,從而確定固件的加載地址。
如果所示,sp寄存器中保存0x80000FF0,因此固件的加載地址應該是0x80001000。
2.3通過定位bss在內存中的地址
這個方法在原理上同2.2的方法一樣,但是需要一定的計算。根據UsrInit()的描述,第一個跳轉的函數就是負責初始化BBS區的函數,因此可以尋找第一個跳轉的指令的位置;還有另外一個方法確定初始化BBS區的位置,由於在系統啟動過程中VxWorks會使用bzero函數對bss區的數據進行清零,所以可以在固件中用命令grep -r bzero
查找bzero字符串出現的位置,此方法可以作為驗證。
2.4其他方法
通過焊接UART接口查看系統引導過程的串口輸出;通過查閱開發者手冊等。
3.使用符號表修復函數名
3.1尋找符號表的位置
如果固件本身已經編入了符號表,那么可以使用binwalk確定符號表的位置。
VxWorks系統的符號表按照每16個字節一組,前四個字節用0x00進行填充,第二個四字節表示符號名字符串在內存中的位置,第三個四字節表示符號在內存中的位置,最后四個字節代表符號的類型,如0x0500表示函數名。
但是如果分析固件沒有得到符號表,可能存在兩種可能:一種是固件本身就沒有編入符號表,這種情況使得函數分析變得比較困難;另一種是符號表被開發者隱藏了起來,防止固件被順利逆向。
如何尋找隱藏了的符號表還在學習中,之后會另開一篇專門介紹。
3.2修復函數名
在ida pro中,函數名的修復需要編寫腳本,用符號表中的函數名替換當前無意義的函數名。在ghidra中,加載完固件之后可以運行vxhunter腳本,將函數名替換為符號表中的函數名。
ghidra修復完函數名之后的效果,可以很明顯的看出施耐德PLC以太網模塊固件NOE77101.bin固件中所存在的后門賬戶漏洞CVE-2011-4859。