一. 摘要
工业控制系统(ICS)在全球的关键基础设施中发挥着至关重要的作用,包括电力、水务、化工、交通以及其他重要工业领域。然而,随着数字化趋势的发展,工业控制系统也成为了潜在的网络攻击目标,面临着日益严重的安全威胁。近些年涌现了层出不穷的网络攻击事件表明工业控制系统正在遭受新的网络攻击手法的威胁,包括但不限于勒索软件、远程访问木马、恶意物理渗透等。攻击瞄准了工业控制系统的独有脆弱性,如设备间通讯的未加密,公网暴露关键资产,以及对实时运行环境的依赖性,这些都使得工控系统在当前的网络攻击环境下风险加剧。
作为工业控制系统的“大脑”,控制器更易受到恶意攻击者的关注,一旦进入生产网络后想要达到更具影响力的攻击效果大多情况下都要对控制器进行篡改逻辑攻击、篡改寄存器值攻击、精准点位攻击或者毁瘫式攻击等手段。因此在攻击发生之前,就控制器的安全性进行研究,将风险点逐一加固或者优化相关设计显得尤为重要。本文尝试以西门子PLC为例,从固件分析角度出发讲解对该方向内容的研究方法和相关技术,并且在阐述过程中配合大量的实操类说明,可以更方便相关研究人员复现实验内容。
二. 研究现状
工业控制器的研究可以分为多个方向,包括但不限与控制器硬件架构研究、软件架构研究、通信协议研究、Runtime内核研究、特殊算法及指令研究、操作系统研究、工程文件编译及格式研究等等,针对这些方向再次从实现原理、脆弱性、攻击面、攻击战法、加固方法等维度对每个方向进行详细剖析,通过“矩阵方式”网格化覆盖研究内容才可初步对某一款控制器有所理解和掌握。如下图为矩阵方式研究内容,每个交叉点都为一个细分研究领域。
实现原理 |
攻击面分析 |
脆弱性分析(漏洞) |
攻击战法 |
加固方法 |
硬件架构研究 |
||||
软件架构研究 |
||||
操作系统研究 |
||||
通信协议研究 |
||||
Runtime内核研究 |
||||
工程文件编译研究 |
||||
工程文件格式研究 |
||||
特殊算法库研究 |
||||
固件文件分析研究 |
||||
………… |
目前对于全球流行的工业控制器能够覆盖所有研究方向的文章很少见,最多也是在某一个研究方向上进行详细分析。西门子工业控制器在全球较为流行,因此针对西门子PLC控制器的研究成果也更多,比如对西门子S7CommPlus通信协议的研究从2015年至今从未中断,在BlackHat上出现了《The spear to break the security wall of S7CommPlus》、《Rogue7: Rogue Engineering-Station attacks on S7-Simatic PLCs》等,笔者在BlackHat 2022会议上也针对西门子最新版本的S7CommPlus_TLS协议做了题为《Fuzzing and Breaking Security Functions of SIMATIC PLCs》的成果分享。
但是在西门子PLC控制器固件文件分析理论和实践相结合的领域中缺乏相关技术研究,本文以西门子小型PLC为研究对象,着眼于固件文件分析研究方向,从固件获取、固件解压、函数识别、实战分析等多个技术角度出发阐述工控安全研究工作中固件文件分析研究的详细过程。
三. 固件获取
笔者在KCON 2022议题《解锁工控设备固件提取的各类方法》[1]中已经对S7-1200系列PLC固件获取做了详细的介绍,基本思路是利用CVE-2019-13945漏洞,搭建漏洞利用环境,利用UART特殊访问功能将内存片区dump后从中分离固件。
本文利用另外一种思路,直接从西门子官网下载S7-1200或者S7-200 SAMRT的固件,通过对固件文件分析,直接编写解压缩程序获得可分析的固件文件。S7-1200系列PLC固件下载需要注册授权,详细下载页面如下[2]。
S7-200 SAMRT固件下载页面如下所示[3]。
随意选择两个系列中的CPU模块下载对应的固件,下载后可以浏览其中的文件结构。我们下载了6ES7_215-1AG40-0XB0_V04.06.00的固件,在文件夹中存在S7_JOB.S7S和FW文件夹。
FW文件夹中有一个.upd文件,如下所示。
S7-200 SAMRT系列CPU模块固件文件和S7-1200系列类似,不过其中的.upd文件大小明显小于S7-200 SAMRT的固件。
四. 固件文件格式分析
任意选取一个upd文件解读其文件格式,固件由3大块组成,第一块为固件头信息,说明了固件的基本信息:固件组成部分(红色框体),固件版本号(黄色框体),固件名称(绿色框体),总共0X2C字节。
第二块为固件目录信息,展示了固件的数据名称、大小、校验内容。具体格式为4字节size+4字节CRC32校验字段+6字节名称字段,如下所示红色框体内为第一个固件数据部分的大小0x20,黄色框体为CRC32校验,绿色字体为名称BG_ABL;紧接着白色框体为第二部分的大小0xeb5372,蓝色框体为CRC32校验,绿色字体为名称A00000,同理可得出还有另外2部分内容,名称分别为B00000,FW_SIG。
第三块为固件数据部分,展示了每个部分固件的详细数据,其中由每个部分的6字节名称开头。比如第一部分BG_ABL的数据如下所示,红色框体为固件部分名称,黄色框体内为具体数据。
接下来的很大部分为A00000详细数据,如下所示
经过查阅相关资料得到该部分采用了LZP3压缩算法,经过查阅资料找到了LZP3压缩算法的C代码实现,测试后发现该C代码仅适用于S7-1200固件,经过笔者修改已经支持了西门子S7-200 SMART固件。由于C代码适用性灵活性不高,因此我们利用python语言重写该部分代码,并且做成了方便易用的小工具,如下图所示,在以后的研究中可以对S7-1200和S7-200 SAMRT系列新发布的固件(只要该压缩算法不改变)进行快速解压缩,以执行后续的相关分析。
解压缩后的固件文件中有明显完整的明文信息,如下所示
五. 固件初步分析
本文中我们以S7-200 SAMRT系列SR20控制器模块固件版本V2.7.0为例做分析示例。
1.使用binwalk分析SR20-V270.BIN文件,查看文件构成。如下所示,可知文件中有gzip压缩文件
全部解压缩后查看0x380208后续的几个压缩文件内容,其中包含有web功能相关的配置文件,如下所示为0x380208开始解压缩文件的内容,其中包含了web读取内容的地址映射关系。
由于存在诸多gzip文件,因此会在后续的IDA分析中存在多段识别不是很优雅的数据段,我们在分析过程中需要注意该问题。
2.导入IDA进行分析
首先需要确定架构,利用binwalk –A,如下所示显示未ARM 大端。
获知处理器架构后还需要确定加载基地址,导入IDA后我们先使用默认的0地址加载,加载完成后先做头部分析,得知从0x40后为ARM的中断向量入口,该部分数据可不作为分析部分。
那么就可以利用rbasefind工具寻找加载基地址再减去0x40得到真正的加载基地址,利用rbasefind工具,如下所示显示加载基地址为0x00038000
根据上述思路算得加载基地址为0x00037FC0,此时在IDA中修改加载基地址为0x00037FC0
基于以上步骤IDA分析完成后可以识别大部分函数,但是还有部分未被识别,只有9045个函数,并且很多的函数没有被创建。
经过分析大部分未被识别的函数都是以“PUSH”字符打头,因此我们利用python脚本来解决push部分没有被创建为新函数,脚本如下。注意此处我们识别到gzip压缩文件的前半部分,不涉及后边的web相关内容。
import idaapi import idautils staradd=0x38000 offset=0x308208 for addr in range(staradd, staradd+offset): if idc.print_insn_mnem(addr) == 'PUSH': idaapi.add_func(addr) |
执行完脚本后分析出的函数增加了许多达到了10082个,如下所示
随后又发现新的问题,还是有固件数据没有被识别代码部分,如下所示需要手动按C才能转化为代码。
按照同样的思路我们编写脚本来处理未能被识别为代码的部分。
import idaapi import idautils staradd=0x38000 offset=0x308208 for addr in range(staradd, staradd+offset): # 如果当前字节是数据 if ida_bytes.is_unknown(ida_bytes.get_flags(addr)): # 将当前字节转换为代码 idc.create_insn(addr) |
执行完成后识别的函数进一步增多,且未被识别为代码段的部分已经被识别为PUSH函数
执行完此步骤后还需再次创建刚才被识别出的函数,同样用脚本处理即可,经过处理后的完整结果如下,此时识别出的函数已达到12439个。
通过以上几个步骤处理后识别的函数越来越多,函数越多对后续的分析越有利,但是还存在以下问题:
A.未能识别出不以“PUSH”打头的函数;
B.误将部分数据段强制转换成了代码段;
C.没有分析web部分的引用或者代码;
但是抓住主要矛盾,在详细分析过程中再次解决上述问题,毕竟现在识别到的函数已经不少了。由于之前分析过S7-1200系列PLC的固件,相较于S7-1200固件S7-200 SAMRT固件中缺少明显的段信息和相关定位,因此想要快速分析利用这种手法就显得很暴力而缺乏了精细感,在S7-1200固件中会有明显的secinfo信息定义固件各个部分的分布,包括.text、.rodat、.bss等,根据这些精准信息再配合该文中提及的脚本自动化方法将会事半功倍。
六. 分析实战
1.定位S7COM通信协议处理部分
工控安全研究中通常会将通信协议作为首选研究项,因为通信协议较为复杂问题点较多存在漏洞后执行可以远程攻击。定位到S7COM协议处理部分也有很多思路,比如从密码保护授权出发、从协议内容中特殊字符出发、从switch分支出发等等。本次我们从协议内容中出现的特殊字符出发寻找通信处理部分,先看以下报文,该报文时上传请求报文,其中请求了文件名为DB57005的块。
0A57005较为特殊,我们在IDA中搜索“0A57007”特殊字符,有如下结果。
再次向上查找引用函数,找到如下部分,从结构上看大概率是通信处理函数。
仔细分析后发现每个函数中都有通信响应报文报错码以及异常处理部分,那么可以确认该部分就是通信协议的核心处理部分,结合报文分析可以构造出更多有意思的请求报文。
此处分享几个有趣的通信指令功能。
A.停止模式下恢复出厂设置
当发送如下报文时,PLC恢复至出厂状态但配置的网络参数保留,适用于不想删除通讯等配置参数但是想清除工程文件和数据的场景。
对应的处理代码为分支为0x26,内部部分处理代码如下所示
B.非JOB服务启动PLC通信指令
一般而言要运行PLC都是在JOB服务中,但是在0x27处理函数中实现了非JOB服务的PLC启动功能,发送如下所示的请求报文可以将PLC重新RUN起来,PLC接收到该报文后不做响应直接执行动作。
对应的处理函数如下所示
对通信协议处理部分还可以做更深层次的分析,逐个查看指令功能码函数会发现更多的“新大陆”,同时还可以作为协议漏洞发现后的根因定位。当然,也可以以此作为先验知识库获得更多的样本对S7-200 SAMRT做基于变异的模糊测试工作等等。
2.分析外设接口信息开展Qemu仿真工作
QEMU(Quick EMUlator)是一个开源的系统仿真器和虚拟机管理器,可以模拟多种处理器体系结构、操作系统和设备,并且支持跨平台运行。在嵌入式系统开发中,QEMU可用于仿真嵌入式设备以及测试嵌入式软件。PLC作为特殊的嵌入式设备,生态较为封闭源代码更难获取,要想研究漏洞的详细细节可谓挑战重重,因此利用QEMU仿真PLC的固件功能给研究人员带来了更多的福音,但是由于PLC的外部依赖更多,想要完全仿真出所有功能是不现实的,只能对某一部分功能进行仿真,本文也是从固件分析的角度去阐述如何从固件中找到仿真所需要的信息。
要想在QEMU上进行PLC固件仿真首先需要了解PLC的架构,从公开的一些资料中可以得知西门子小型PLC中采用的芯片处理器为ARM Cortex‑R4,但是在QEMU的仿真架构中没有来源支持该架构的框架,那么就需要另辟蹊径经过查阅资料发现Xilinx公司正在单独开发的一个开源框架,在支持列表中有一款Xilinx ZynqMP ZCU1285。之所以选择该板卡是因为该板卡中的ARM处理器为Cortex‑R5F,其最接近我们要仿真的Cortex‑R4处理器。
接下来就需要处理外设资源内存映射的问题了,因为PLC的固件代码和外设寄存器等都可能通过特定的地址空间进行访问,而这些地址空间需要被正确地映射到物理存储器和设备上。如果缺少内存映射表,可能会导致QEMU模拟器无法正确地访问相关区域,从而影响仿真结果,因此必须从固件中分析出PLC的内存映射表。
在ARM V7架构中肯定会有定时器等硬件资源,那么我们从timer资源出发在固件中寻找线索,在strings中搜索可得到如下结果,很明显这就是我们想找的。
经过定位到对应位置并在上下文中查找和处理,得到了整个内存映射表,包含很多硬件资源和相应的寄存器
经过整理后见下表所示,表格中仅呈现了部分外设资源的信息。至此完成了仿真前的内存映射信息确认。
名称 |
范围 |
长度 |
Itcm |
0~ 0x8000 |
0x8000 |
ddram |
0x8000~0x02000000 |
0x1FF8000 |
configured_dtcm |
0x10010000~0x10014000 |
0x4000 |
internal_ram0 |
0x10030000~0x10040000 |
0x10000 |
internal_ram1 |
0x10040000~0x10050000 |
0x10000 |
MAP3_PWRSTK |
0xFFFB0000~0x FFFB003C |
0x3C |
MAP3_SPI0 |
0xFFFB1000~0xFFFB1018 |
0x18 |
MAP3_SPI1 |
0xFFFB2000~0xFFFB2018 |
0x18 |
MAP3_I2C0 |
0xFFFB3000~0xFFFB306C |
0x6C |
MAP3_I2C1 |
0xFFFB4000~0xFFFB406C |
0x6C |
MAP3_I2C2 |
0xFFFB5000~0xFFFB506C |
0x6C |
MAP3_ADC |
0xFFFB6000~0xFFFB6024 |
0x24 |
MAP3_UART0 |
0xFFFB7000~0xFFFB709C |
0x9C |
MAP3_UART1 |
0xFFFB8000~0xFFFB809C |
0x9C |
MAP3_INPUTS |
0xFFFB9000~0xFFFB9400 |
0x400 |
MAP3_OUTPUTS |
0xFFFBA000~0xFFFBA218 |
0x218 |
MAP3_TIMERS |
0xFFFBB000~0xFFFBB15C |
0x15C |
MAP3_BOOL_HELPER |
0xFFFA0000~0xFFFA4000 |
0x4000 |
西门子小型PLC的启动一般先加载BootLoader然后从BootLoader启动固件程序。因此第一步需要模拟BootLoader,接下来的工作就是配置QEMU的相关设备树文件、调整字节序、配置外设内存寄存器映射地址文件等,该部分不属于本文讨论的范畴,不再赘述。通过以上分析主要想展示如何在固件中寻找外设相关信息,确认该信息后可以为QEMU仿真做铺垫工作,当然分析清楚外设信息后也有助于理解固件文件,比如下边一段伪代码,0xFFFBB110寄存器中存放着当前的tick。
3.组件使用分析
西门子小型PLC的固件中使用了相关公共组件,该部分针对使用的组件做一梳理。首先查看TCP协议栈使用情况,在strings中搜索得到如下结果,因此可获知S7-200 SMART系列采用了NicheStack TCP/IP V3.1版本,从使用的版本分析该协议栈受INFRA:HALT系列漏洞[4][5]影响。
接下来分析使用的ACE库,ACE库(Adaptive Communication Environment)是一个跨平台的C++网络编程框架,提供了许多通用的网络编程模块,例如套接字、事件处理、线程池、进程间通信、异步IO、协议编解码等,西门子PLC中也使用了这种技术将上层的通用操作归一化处理便于开发和移植,在strings中可以看到其使用了ACE6.0.1。
具体的映射结果如下所示,显示了ACE_Asynch_Write_File类及其包含的成员函数sub_152588、sub_152618、sub_152620等。
通过搜索与ACE Write File同版本的源码对比可进一步分析出各个成员函数的名称。通过对比ACE库的源码得知,西门子对该库进行了定制化的修改,如下所示。
最后对西门子S7-200 SAMRT实现的指令集进行分析,组态软件将调用的工程文件编译为特定代码下装至PLC,PLC接收到特定码流后再进行解析。解析后在指令对应的函数中执行相关操作。指令处理函数如下所示,该处存放了244条指令函数。
以下以TCON指令处理函数为例做以呈现,详细的分析必须依赖于工程文件联调分析和动态分析才能梳理具体指令处理的流程,深入的研究内容在此不再赘述。
七. 总结
本文以西门子小型PLC的固件文件作为研究对象,从固件获取、固件解压缩、基地址定位、函数修复、实战分析等多个角度对工控安全研究中的固件文件分析工作做了全方位阐述,其中涉及到的知识点较多也是目前国内鲜有公开的技术点,具有较高的技术参考价值。囿于篇幅部分有趣的技术点未能展开说明。由于水平有限,web实现部分的代码没有做详细分析、限于资源或者技术没能命名函数或者修复符号表等,因此该部分还有待于后续研究人员进行更多的分享。
八. 相关链接:
[1]:https://github.com/knownsec/KCon/blob/b6038b4f8768ab41836973e81cb0dd156bd50d64/2022/%E8%A7%A3%E9%94%81%E5%B7%A5%E6%8E%A7%E8%AE%BE%E5%A4%87%E5%9B%BA%E4%BB%B6%E6%8F%90%E5%8F%96%E7%9A%84%E5%90%84%E7%B1%BB%E6%96%B9%E6%B3%95%E3%80%90KCon2022%E3%80%91.pdf
[2]:https://www.ad.siemens.com.cn/productportal/Prods/S7-1200_PLC_EASY_PLUS/01-resource/08-online_download.htm#firm
[3]:https://support.industry.siemens.com/cs/document/109765009/s7-200-smart-cpu-%E5%9B%BA%E4%BB%B6%E4%B8%8B%E8%BD%BD?dti=0&lc=zh-CN
[4]:https://jfrog.com/blog/infrahalt-14-new-security-vulnerabilities-found-in-nichestack/
[5]: https://www.hcc-embedded.com/support/security-advisories
结束
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新
原文始发于微信公众号(ChaMd5安全团队):西门子PLC固件分析技术研究
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论