韌體下載地址:
GitHub - ameng929/NOE77101_Firmware
檔案目錄結構,這裡只列出了一些主要的檔案資訊:
├── bin
├── ftp
├── fw
├── rdt
├── webloader.ini
└── wwwroot
├── SchneiderTFE.zip
├── cgi-bin
├── classes
├── conf
│ ├── Gcnftcop.sys
│ ├── bootp
│ ├── dhcp
│ ├── diag
│ │ └── chkdsk.out
│ ├── exec
│ │ ├── NOE77101.bin
│ │ └── kerVer
│ ...
├── html
│ ├── config.js
│ ...
├── rdt
│ └── rdt.zip
└── secure
注意到 wwwroot/conf/exec 目錄下有一個檔案 NOE77101.bin ,這就是要分析的韌體檔案。使用binwalk
命令檢視檔案內容,是一個Zlib型別的壓縮檔案:
➜ exec binwalk NOE77101.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
901 0x385 Zlib compressed data, default compression
用binwalk
提取檔案內容,binwalk
會自動解壓檔案,得到資料夾 _NOE77101.bin.extracted:
➜ exec binwalk -e NOE77101.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
901 0x385 Zlib compressed data, default compression
➜ exec ls
NOE77101.bin _NOE77101.bin.extracted kerVer
binwalk
自動提取了檔案到_NOE77101.bin.extracted目錄下,並對其進行解壓。此時資料夾下就有兩個檔案,一個zlib和一個被解壓出來的:
➜ _NOE77101.bin.extracted ls
385 385.zlib
然後再用binwalk
檢視385檔案:
➜ _NOE77101.bin.extracted binwalk 385
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
2054252 0x1F586C EST flat binary
2088936 0x1FDFE8 HTML document header
2108532 0x202C74 HTML document footer
2110048 0x203260 HTML document header
2115564 0x2047EC HTML document footer
2119528 0x205768 XML document, version: "1.0"
2119796 0x205874 XML document, version: "1.0"
2119912 0x2058E8 XML document, version: "1.0"
2192512 0x217480 Base64 standard index table
2192580 0x2174C4 Base64 standard index table
2211604 0x21BF14 VxWorks WIND kernel version "2.5"
2225264 0x21F470 Copyright string: "Copyright Wind River Systems, Inc., 1984-2000"
2321952 0x236E20 Copyright string: "copyright_wind_river"
3118988 0x2F978C Copyright string: "Copyright, Real-Time Innovations, Inc., 1991. All rights reserved."
3126628 0x2FB564 Copyright string: "Copyright 1984-1996 Wind River Systems, Inc."
3153524 0x301E74 VxWorks symbol table, big endian, first entry: [type: function, code address: 0x1FF058, symbol address: 0x27655C]
得知檔案是VxWorks韌體,符號表位置在0x301E74處,稍後會用到。
然後使用binwalk
檢視架構,得知是PowerPC big endian:
➜ _NOE77101.bin.extracted binwalk -A 385
....
2045960 0x1F3808 PowerPC big endian instructions, function epilogue
2045968 0x1F3810 PowerPC big endian instructions, function prologue
2046180 0x1F38E4 PowerPC big endian instructions, function epilogue
3150948 0x301464 PowerPC big endian instructions, function epilogue
之後用IDA開啟385檔案,在開啟時設定架構:
然後要求設定RAM和ROM,其實就是設定載入基地址:
在IDA中無法識別出任何函式,需要在程式開頭位置按一下 “c” 鍵,就可以顯示部分函式,但沒有解析出所有的函式:
此時可以通過三種方式獲得載入基地址:
- 通過跳轉表獲得基地址、通過字串引用獲得基地址
- 使用IDA的Vxhunter外掛
vxhunter/firmware_tools at master · PAGalaxyLab/vxhunter
這裡為了方便選擇Vxhunter外掛,選擇python版本下載後複製到plugin資料夾下,然後執行外掛:
得到載入地址是0x10000:
然後發現依然沒有解析函式,此時需要恢復函式名稱。使用IDA指令碼:
#coding=utf-8
from idaapi import *
from idc import *
symbol_interval = 16 #符號表間隔
load_address = 0x10000 #韌體記憶體載入基址
symbol_table_start = 0x31eec4 + load_address #符號表起始地址
symbol_table_end = 0x348114 + load_address #符號表結束地址
ea = symbol_table_start
eaEnd = symbol_table_end
while ea < eaEnd:
offset = 0 #4個位元組為一組資料
#將函式名指標位置的資料轉換為字串
create_strlit(get_wide_dword(ea-offset), BADADDR)
#將函式名賦值給變數sName
sName = get_strlit_contents(get_wide_dword(ea))
print(sName)
if sName:
#開始修復函式名
eaFunc = get_wide_dword(ea - offset +4)
set_name(eaFunc, sName)
create_insn(eaFunc)
ida_funcs.add_func(eaFunc, BADADDR)
ea += symbol_interval
程式碼中的符號表起始地址和符號表結束地址需要手動修改一下,可以在16進位制編輯器中檢視。在binwalk分析的時候得到符號表地址為0x301E74,然後在檔案中找到這個位置,0x301E74即起始位置:
符號表每0x10為一組,一直找到結束的位置0x3293a4:
然後執行IDA指令碼:
最後恢復完成:
在usrAppInit
函式中發現多處loginUserAdd
新增使用者,這些字串即後門賬號和密碼:
總結
此韌體分析關鍵點在於確定程式基地址和如何恢復符號資訊,只要恢復了符號資訊就和閱讀原始碼無異了。