老规矩,首先在官网下载NOE77101固件,要说明NOE77101固件与之前分析的TP-Link SR20固件有着很大的差别,SR20固件使用了linux内核,而NOE77101则使用了VxWorks内核(不了解VxWorks 的看这里),前者是家用路由器固件,后者是施耐德PLC以太网模块固件。
下载好后解压,在./FLASH0/wwwroot/conf/exec
目录下会有一个NOE77101.bin文件
使用binwalk分析并导出目录,进入_NOE77101.bin.extracted目录,可以看到217、217.zlib两个文件,在逆向vxworks固件前首先要先找出固件的内存加载地址否则将会导致ida无法解析出函数。
在找加载地址前先我们要用binwalk找到符号表的位置还要找出他的硬件架构和大小端格式。首先使用binwalk 217
指令查看符号表地址,如下
然后使用binwalk -A 217
指令查看硬件架构与大小端格式
由此可知,符号表地址为0X31EED4,cpu架构为PowerPC,big endian意为大端有效。
f符号表内容
可以看到符号表的真正起始地址是31EEC4,这里还要说明一下,符号表是有固定格式的,每十六个字节一条,开头四个字节使用0来填充,第二段四个字节是符号名字字符串在内存中的所在地址,第三段四字节表示符号在内存中的位置,最后四个字节代表符号的类型,如0x0500表示函数名。
然后我们还需要找到最后一个字符串所在的地址,因为字符串表中的最后一个字符串在符号表中第一个被引用,我们需要使用字符在内存中的地址-在文件中的地址
就能获得内存加载地址,而我们刚刚得到了符号表中的第一条记录,符号表中的第一条记录对应字符串表中的最后一个字符串,所以我们还需要找到字符串表中的最后一个字符串。
最后一个字符串是APP_STATION_MODBUS,地址是298BD8,现在拿符号表中第一条记录的第二段四个字节
2A8BD8-298BD8
最后得出10000。
现在使用ida打开217.
注意处理器类型。
z这里注意ROM起始地址和加载地址的填写,之后一路默认。
现在我们还是无法获取到函数,所以我们还需要使用py脚本辅助来帮我们修正函数名,在写脚本之前,我们先去获取一下符号表的结束地址,之后在修正函数名时需要用到。
结束地址是348114
from idaapi import *
from idc import *
loadaddress = 0x10000 #加载地址
eaStart = 0x31eec4 + loadaddress#符号表起始地址
eaEnd = 0x348114 + loadaddress#符号表结束地址
ea = eaStart
eaEnd = eaEnd
while ea < eaEnd:
create_strlit(Dword(ea), BADADDR)
#获取名称字符串,Dword为双字类型一个字等于两个字节,双字则是四个字节
sName = get_strlit_contents(Dword(ea))
print sName
#如果函数名不为空
if sName:
#获取函数地址
eaFunc = Dword(ea + 4)
#重命名地址,将函数地址与函数名对应
MakeName(eaFunc, sName)
#分析指定地址代码区
MakeCode(eaFunc)
#设置函数始末地址
MakeFunction(eaFunc, BADADDR)
#每次叠加16字节,每条符号表记录占16个字节
ea = ea + 16
r然后在ida中选择文件->脚本文件,将写好保存好的文件导入。
即可得到所有函数
接下来我们要找到后门账户存储的位置,所以我们需要关注用户账户的一些操作函数。
从_sysInit函数开始走流程,接下来是usrInit,可以大致猜测usrInit函数为用户初始化函数,因为我穷买不起正版,所以智能多花点时间去查手册看汇编代码了。
最后找到一个可疑函数loginUsrAdd,查看他的调用者
可以看到有很多调用者,先来看看FTP_User_Add如何调用
注意看函数调用上面的lis,addi两条指令,他有点类似于intel x86架构处理器下的传参指令push,这两个重复的lis,addi调用也是在传参,点进去,我们就能看到相应的后门账户
除了FTP_User_Add还有usrAppInit和usrSecurity函数都可以查找到对应调用并根据调用找到后门账户
usrSecurity处的调用
usrAppInit处的调用
总体来讲VxWorks内核的固件分析起来还是有点麻烦啊…