施耐德NOE77101後門漏洞分析

unr4v31發表於2022-02-24

韌體下載地址:

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檔案,在開啟時設定架構:

Image.png

然後要求設定RAM和ROM,其實就是設定載入基地址:

Image.png

Image.png

Image.png

在IDA中無法識別出任何函式,需要在程式開頭位置按一下 “c” 鍵,就可以顯示部分函式,但沒有解析出所有的函式:

Image.png

Image.png

此時可以通過三種方式獲得載入基地址:

  • 通過跳轉表獲得基地址、通過字串引用獲得基地址

韌體安全之載入地址分析 – 綠盟科技技術部落格

  • 使用IDA的Vxhunter外掛

vxhunter/firmware_tools at master · PAGalaxyLab/vxhunter

這裡為了方便選擇Vxhunter外掛,選擇python版本下載後複製到plugin資料夾下,然後執行外掛:

Image.png

得到載入地址是0x10000:

Image.png

然後發現依然沒有解析函式,此時需要恢復函式名稱。使用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即起始位置:

Image.png

符號表每0x10為一組,一直找到結束的位置0x3293a4:

Image.png

然後執行IDA指令碼:

Image.png

最後恢復完成:

Image.png

usrAppInit函式中發現多處loginUserAdd新增使用者,這些字串即後門賬號和密碼:

Image.png

總結

此韌體分析關鍵點在於確定程式基地址和如何恢復符號資訊,只要恢復了符號資訊就和閱讀原始碼無異了。

References

韌體符號表恢復

https://bbs.pediy.com/thread-266803-1.htm

韌體安全之載入地址分析 – 綠盟科技技術部落格

施耐德PLC乙太網模組後門賬戶解密 – 燈塔實驗室

https://p1kk.github.io/2021/06/11/iot/施耐德 NOE771/

相關文章