[工控安全][原创]某PLC设备CPU模块固件逆向分析(一)

某PLC设备CPU模块固件逆向分析(一)

mailto:wangkai0351@gmail.comhtml

【未经赞成禁止转载】架构

[1]感谢灯塔实验室技术专家于2015年撰写的技术文章《施耐德PLC以太网模块固件后门引起的血案》tcp

https://mp.weixin.qq.com/s?__biz=MzA5OTMwMzY1NQ==&mid=207033762&idx=1&sn=e629b1db9f43937cba6d5707c707450d&scene=23&srcid=11052lU6PwhrrCHsh1r5goGp#rd函数

https://mp.weixin.qq.com/s?__biz=MzA5OTMwMzY1NQ==&mid=207094710&idx=1&sn=13fc594d15729bd7e001a48b90d827c4&mpshare=1&scene=1&srcid=0127j51fr0di9oxfYbQm1o0X#rd工具

[2]感谢威努特公司的技术专家于2018年撰写的技术文章《工控漏洞挖掘方法之固件逆向分析》操作系统

https://paper.seebug.org/613/code

[3]感谢平安科技银河实验室和支付宝光年实验室的技术专家于2018年发布的针对VxWorks设备的分析工具VxHunterhtm

https://www.4hou.com/info/17114.htmlblog

[4]感谢平安科技银河实验室的技术专家于2019年撰写的技术文章《基于 VxWorks 的嵌入式设备固件分析方法介绍》ip

https://paper.seebug.org/771/

正文

1.固件文件获取

本固件文件的获取方式是从厂家官网得到的,不须要注册用户账户,不须要赞成任何用户协议。

2.固件原始文件解包

下载的固件文件是一个压缩包,解压后获得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模块固件是包含函数名表的。

3.逆向反汇编

3.1 肯定加载偏移地址

3.2 拖进IDA pro

3.3 修复符号表

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个函数也就不是表()中对应的函数,本次匹配宣告失败,可是,咱们编写程序自动实现循环匹配,看有没有能匹配上的(若是函符号表对应没有问题,那么最后确定是能够匹配成功的)。

4.看几个已经有cve的函数

这些

详细内容稍后奉上。 本版本中的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

相关文章
相关标签/搜索