mailto:wangkai0351@gmail.comhtml
【未经赞成禁止转载】架构
[1]感谢灯塔实验室技术专家于2015年撰写的技术文章《施耐德PLC以太网模块固件后门引起的血案》tcp
[2]感谢威努特公司的技术专家于2018年撰写的技术文章《工控漏洞挖掘方法之固件逆向分析》操作系统
https://paper.seebug.org/613/code
[3]感谢平安科技银河实验室和支付宝光年实验室的技术专家于2018年发布的针对VxWorks设备的分析工具VxHunterhtm
https://www.4hou.com/info/17114.htmlblog
[4]感谢平安科技银河实验室的技术专家于2019年撰写的技术文章《基于 VxWorks 的嵌入式设备固件分析方法介绍》ip
本固件文件的获取方式是从厂家官网得到的,不须要注册用户账户,不须要赞成任何用户协议。
下载的固件文件是一个压缩包,解压后获得A.bin文件。
使用binwalk分析A.bin文件。
信息搜集:
a)该PLC CPU模块的主控芯片架构是ARM920,芯片型号是ATMEL AT91RM9200。
b)该PLC CPU模块固件的操做系统是VxWorks,其中,
VxWorks WIND kernel version = 2.10
VxWorks operating system version = 6.4。
更详细的版本号参考结构体逆向后结果
struct vxWorksVersion{
vxWorksVersionMaint
vxWorksVersionMajor
vxWorksVersionMinor}
c)该PLC CPU模块固件是包含函数名表的。
0x05 | 函数名 |
0x07 | |
0x09 |
总结上图中出现过的两类地址,罗列到下表,同时考虑是小端存储(地址大的数据在前),转换成大端(方便人看)。
符号字符串所在的绝对存储地址 | 大端(0x) | 符号所在的存储地址 | 大端(0x) |
---|---|---|---|
20 67 34 20 | 20346720 | 30 dc 17 20 | 2017dc30 |
2c 67 34 20 | 2034672c | 3c c2 15 20 | 2015c23c |
48 67 34 20 | 20346748 | 64 c4 15 20 | 2015c464 |
58 67 34 20 | 20346758 | a8 c4 15 20 | 2015c4a8 |
6c 67 34 20 | 2034676c | ec c4 15 20 | 2015c4ec |
下面的任务有两个,依次是
1)计算加载地址(偏移地址)
$$
加载地址 = 符号表中字符串的绝对地址 - 相应字符串在固件中的偏移
$$
2)修复函数名表
咱们先解决第一个问题,咱们有不少种方法去逆向推断出来加载地址(偏移地址)。我我的比较推崇的是,由表及里的逆向推断方法,从加载地址的定义概念出发。
由上表能够延伸一下
函数字符串编号 | 函数名字符串的绝对存储地址(大端0x) | 绝对存储地址误差(0x) | |
---|---|---|---|
1 | 20346720 | —— | |
2 | 2034672c | 2034672c-20346720=c | |
3 | 20346748 | 20346748-2034672c=28 | |
4 | 20346758 | 20346758-20346748=10 | |
5 | 2034676c | 2034676c-20346758=14 |
由于
函数名字符串N+1的绝对存储地址-函数名字符串N的绝对存储地址=函数名字符串N+1的相对存储地址-函数名字符串N的相对存储地址
所以,咱们就寻找连续的5个函数名字符串,使得其相对存储地址误差等于上表罗列的绝对存储地址误差。
参考如下的函数名相对存储地址示例
00390310 73 74 72 63 68 72 00 00 73 74 72 63 6d 70 00 00 |strchr..strcmp..| 00390320 73 74 72 63 6d 70 63 69 00 00 00 00 73 74 72 63 |strcmpci....strc| 00390330 6f 6c 6c 00 73 74 72 63 70 79 00 00 73 74 72 63 |oll.strcpy..strc| 00390340 73 70 6e 00 73 74 72 65 72 72 6f 72 5f 72 00 00 |spn.strerror_r..| 00390350 73 74 72 46 72 65 65 00 73 74 72 66 74 69 6d 65 |strFree.strftime|
能够看出,存储函数名的时候有对齐规则。
函数字符串编号 | 函数名 | 函数名字符串的相对存储地址(0x) | 相对存储地址误差(0x) |
---|---|---|---|
1 | strchr | 00390310 | |
2 | strcmp | 00390318 | 00390318-00390310=8 |
3 | strcmpci | 00390320 | 00390320-00390318=8 |
4 | strcoll | 0039032c | 0039032c-00390320=c |
5 | strcpy | 00390334 | 00390334-0039032c=8 |
从上表看出,这5个函数的相对存储地址误差和表()中绝对存储地址误差对不上,所以,这5个函数也就不是表()中对应的函数,本次匹配宣告失败,可是,咱们编写程序自动实现循环匹配,看有没有能匹配上的(若是函符号表对应没有问题,那么最后确定是能够匹配成功的)。
这些
详细内容稍后奉上。 本版本中的tcp/ip协议栈并非IPNET协议栈,所以不受URGENT/11的影响。具体说明,本设备的vxworks OS中使用的是BSD的tcp/ip协议栈,system call的API以下。 bsdAccept bsdConnect bsdConnectWithTimeout bsdGetpeername bsdGetsockname bsdGetsockopt bsdRecv bsdRecvfrom bsdRecvmsg bsdSend bsdSendmsg bsdSendto bsdSetsockopt bsdShutdown bsdSockDefaultConfigParams bsdSockFunc bsdSockInstInit bsdSockLibInit bsdZbufSockRtn