昨天刚听了轩神在HWS开的第一堂iot入门课程,今天想着找个固件来分析一下练练手
本人对于iot完全小白,参考了诸多文章来分析此固件
固件下载地址:https://github.com/ameng929/NOE77101_Firmware/blob/master/FLASH0/wwwroot/conf/exec/NOE77101.bin
固件逆向分析
固件识别与解压
binwalk 分析文件,发现是zlib压缩文件
binwalk -e 分离文件后,对分离出的文件分析
固件的符号表位于0x301E74,操作系统为VxWorks 2.5
确定CPU架构为PowerPC big endian
确定固件内存加载地址
嵌入式系统固件需要加载到内存中特定位置运行,这个特定位置就是固件加载地址
固件加载地址 = 符号表中字符串的地址 - 相应字符串在固件中的偏移
嵌入式系统固件的函数调用地址是基于固件加载地址所计算出的内存位置,而不是固件中的地址
我们找到了符号表的地址,VxWorks系列的符号表的组织规则,以16个字节为一组数据,前四个字节是0x00,之后四个字节是符号名字符串所在的内存地址,后四个是符号所在的内存地址,最后四个是符号的类型
根据符号表找到字符串附近,然后在附近找字符串,我们需要找到最后一个字符串所在的地址,因为字符串表中的最后一个字符串在符号表中第一个被引用,我们需要使用字符串在内存中的地址减去在文件中的地址就能得到内存加载地址,最后一个字符串是APP_STATION_MODBUS
内存加载地址 = 0x27656C - 0x26656C = 0x10000
修复函数名
找到符号表的结束地址:
from idaapi import * |
代码分析
VxWorks的启动代码usrInit分析
这个函数是在ram中执行的第一个函数,主要完成对bss段的清除、设置异常向量、然后调用sysHwinit()初始化硬件,VxWorks固件自身有三个section,text,data和bss,所以根据usrinit首先会处理bss段,可以找到bss段的地址进而计算出固件的加载地址(跑题了,这是根据别的文章提一句),usrKernelInit()会初始化系统内核,然后做cache相关的操作,接下来会创建第一个任务usrRoot
整个调用关系_sysinit -> usrInit -> usrKernelInit -> usrRoot -> usrAppInit
在这里发现多次调用添加账户的function,然后根据这个就能摸到多个后门账户和密码。
总结一下,还有很多地方不懂,比如这种架构的指令集,VxWorks的一些知识,一些细节问题,比如符号表的开始地址和结束地址确定,一开始是010editor中的地址,后来啥也出不来,就往后移动了四个字节,才显示出修复的函数名,idapython的用法,以及符号表中的第一项对应APP_STATION_MODBUS。
总之,听了剑锋老师的话,还是要多积累经验,毕竟当初栈溢出ret2text的时候也不懂啥是plt和got(笑
Reference
工控漏洞挖掘方法之固件逆向分析:https://paper.seebug.org/613/#22noe-771
施耐德 NOE771 后门分析:https://p1kk.github.io/2021/06/11/iot/%E6%96%BD%E8%80%90%E5%BE%B7%20NOE771/
施耐德PLC以太网模块固件NOE77101后门账户漏洞:https://blog.csdn.net/weixin_43815930/article/details/107646507
NOE77101 vxworks后门账户分析:http://www.atomsec.org/iot/noe77101-vxworks%E5%90%8E%E9%97%A8%E8%B4%A6%E6%88%B7%E5%88%86%E6%9E%90/
基于 VxWorks 的嵌入式设备固件分析方法介绍:https://paper.seebug.org/771/#1
VxWorks启动代码usrInit()函数分析:https://blog.csdn.net/yinyansiniye/article/details/41926723
Porting from IDAPython 6.x-7.3, to 7.4:https://hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml