固件下载地址:
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.binDECIMAL HEXADECIMAL DESCRIPTION--------------------------------------------------------------------------------901 0x385 Zlib compressed data, default compression用binwalk提取文件内容,binwalk会自动解压文件,得到文件夹 _NOE77101.bin.extracted:
? exec binwalk -e NOE77101.binDECIMAL HEXADECIMAL DESCRIPTION--------------------------------------------------------------------------------901 0x385 Zlib compressed data, default compression? exec lsNOE77101.bin _NOE77101.bin.extracted kerVerbinwalk自动提取了文件到_NOE77101.bin.extracted目录下,并对其进行解压。此时文件夹下就有两个文件,一个zlib和一个被解压出来的:
? _NOE77101.bin.extracted ls385 385.zlib然后再用binwalk查看385文件:
? _NOE77101.bin.extracted binwalk 385DECIMAL HEXADECIMAL DESCRIPTION--------------------------------------------------------------------------------2054252 0x1F586C EST flat binary2088936 0x1FDFE8 HTML document header2108532 0x202C74 HTML document footer2110048 0x203260 HTML document header2115564 0x2047EC HTML document footer2119528 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 table2192580 0x2174C4 Base64 standard index table2211604 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 epilogue2045968 0x1F3810 PowerPC big endian instructions, function prologue2046180 0x1F38E4 PowerPC big endian instructions, function epilogue3150948 0x301464 PowerPC big endian instructions, function epilogue之后用IDA打开385文件,在打开时设置架构:

然后要求设置RAM和ROM,其实就是设置加载基地址:



在IDA中无法识别出任何函数,需要在程序开头位置按一下 “c” 键,就可以显示部分函数,但没有解析出所有的函数:


此时可以通过三种方式获得加载基地址:
固件安全之加载地址分析 – 绿盟科技技术博客
vxhunter/firmware_tools at master · PAGalaxyLab/vxhunter
这里为了方便选择Vxhunter插件,选择python版本下载后复制到plugin文件夹下,然后运行插件:

得到加载地址是0x10000:

然后发现依然没有解析函数,此时需要恢复函数名称。使用IDA脚本:
#coding=utf-8from 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_starteaEnd = symbol_table_endwhile 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添加用户,这些字符串即后门账号和密码:

此固件分析关键点在于确定程序基地址和如何恢复符号信息,只要恢复了符号信息就和阅读源码无异了。
固件符号表恢复
https://bbs.pediy.com/thread-266803-1.htm
固件安全之加载地址分析 – 绿盟科技技术博客
施耐德PLC以太网模块后门账户解密 – 灯塔实验室
https://p1kk.github.io/2021/06/11/iot/施耐德 NOE771/