作者 | 绿盟科技格物实验室 高剑 g[email protected]
近年来供应链攻击频发,供应链攻击和勒索软件攻击正成为黑客谋利的重要手段,对社会危害非常巨大。供应链攻击是一种以软件开发人员和供应商为目标的威胁, 攻击者通过感染合法应用的方式分发恶意软件来访问源代码、构建过程或更新机制从而达到对开发人员和供应商进行攻击的目的。软件供应链可划分为开发、交付、运营三个大的环节,每个环节都有可能引入供应链安全风险,从而遭受攻击,上游环节的安全问题会传递到下游环节并被放大。最近被大家熟知的某金融领域使用的组件被恶意攻击者攻破后泄露了大部分机密资料,由此可见供应链的威胁离我们并不遥远。那么在工控领域内有没有类似的威胁存在呢?本文将讲述在研究工控设备时发现CodeSys Runtime多个漏洞的过程,并且针对漏洞进行了相应的技术分析,文章末尾会提出针对这些漏洞的防护建议。
本次选取了ABB的AC500系列PLC,初始的研究目标为:固件分析与研究、私有协议安全性研究。目标硬件为PM564-RP-ETH-AC,固件版本通过组态软件Automation Builder 2.4.1升级到最新版本2.8.4。
确定研究对象后,首先搭建安全测试环境,利用nmap对PM564进行扫描得到如下结果,依据长时间接触工控领域的经验,当发现如下两个网络端口时第一反应就是私有协议端口而且和CodeSys关系很大。
接下来,打开组态软件,创建工程后下装至PM564,利用wireshark抓取通信报文,查看报文数据结构,发现请求和响应报文中都携带有4f 96 05开头的19个字节的head结构,紧接着“aa aa”打头的为payload。通信过程中使用的端口为1200。那么1201端口是什么时候使用的呢?数据报文结构是什么样子呢?先保留这些问题,接下来先看看PM564的固件。
幸运的是ABB官方提供了固件下载,最新版本的固件链接地址为:
https://new.abb.com/plc/programmable-logic-controllers-plcs/ac500-eco/cpus
当下载到固件后,找到对应模块PM564的固件,固件中包含的文件如下所示,其中2_0_2文件夹为BootLoader,2_8_4文件夹为firmware,ONB_IO文件夹为onboardIO部分,RTC_BATT文件夹为RTCBattery部分。
进入到firmware文件夹后,只有一个文件Pm55xE.gza,利用010打开后文件内容如下图所示,可以发现该文件肯定是经过特殊处理的,无法利用binwalk工具获取到相关信息,至此进入到了不幸的阶段。虽然提供固件下载但是无法阅读分析,这也是工控领域常见的情形,比如Siemens提供固件下载,但是固件都是经过特殊处理的。这时可以利用《某工控设备固件提取及分析》文章中提及到的第二种方法,利用拆焊手段得到flash内部的代码进而分析固件,找到固件处理算法、分析算法、拆解下载到其余PLC模块的固件。
由于研究对象为实验室专有设备无法拆解,因此在某鱼上买到了一个性价比更高的PM554模块,直接作为拆焊对象,首先分析硬件架构,理清使用的CPU、flash等芯片。如下图所示,左边为模块的CPU,型号为MPC852T,是基于PowerPC架构的MPC860四路集成通信控制器。右边标识出的为模块的flash芯片,型号为M29W320EB,它是一个容量为4M字节的nonflash芯片。
接下来就要将flash芯片拆焊,利用编程器读取内部数据。由于该模块的物理结构复杂并不像其余PLC是多个PCB板层叠安装,而是“两山夹一川”的格局,目标芯片还在“一座山”的山腰位置,因此难度大大增加,经过不断的细心尝试,最终还是将目标芯片拆下来了,如下图所示。
之后利用编程器读取出flash芯片中的内容,经过分析flash中的内容存在字节序问题,修复字节序后放入binwalk分析如下图,从0x50010处开始即为固件部分。
剩下的工作就是将固件部分导入IDA进行分析,首先利用rbasefind方法找到起始地址,然后根据经验寻找字符串定位通信处理函数,找到1201/1200端口的功能。在此不再赘述,见下图rebase address后的IDA分析图示。
经过分析和验证发现,1201端口是为了兼容之前的组态软件版本开启的端口,使用的是以“bb bb”开头的私有协议,通过搭建Automation Builder 2.3和PM564通信环境验证了这一点,下边截图展示了1201端口的流量。
进一步分析得知报文格式如下所示,其中开头2字节为特定报文头,接下来的4个字节为长度域(大端模式),紧跟1个字节为功能码,紧随其后为N字节的数据部分。
A. 通过拆焊芯片得到了PM554固件,经过分析固件得到了该系列模块固件的处理算法。
B. 通过分析固件得知1201端口也是私有协议,以“bb bb”打头。
C. 1200端口为最新版本组态软件和设备通信的私有协议,以“4f 96 05”打头。
D. 经过分析发现模块底层采用的操作系统为Micro Digital公司的SMX,但是版本依然停留在V3.5。
既然已经获取到了1201端口和1200端口的流量和报文格式,那么利用自制的Fuzz工具,就可以很轻松的针对私有协议进行安全性测试。针对1201端口结构较为简单的私有协议开始Fuzz测试,在不到半天的时间内发现了多个拒绝服务漏洞。以下是发现漏洞的示例图,PM564的状态为ERR灯闪烁,进入严重故障模式,只有重新上电才能恢复正常状态。
通过修改poc在其余使用CodeSys Runtime的PLC上进行验证,发现也受到这些漏掉的影响,至此猜测是由CodeSys Runtime引入的漏洞。为了验证猜测,分析了固件定位到了崩溃点,该崩溃点在CodeSys Runtime内核部分。而且PM564使用的Runtime版本为已经过时的版本2.4.7.48,见下图:
为了更进一步坐实这些漏洞是由CodeSys Runtime引入的,下载了当时最新的版本(Runtime版本为2.4.7.55),搭建了对应的Fuzz测试环境,在Runtime中发现了多个漏洞,并将这些漏洞提交给了CodeSys官方。
2021年10月25日CodeSys官方发布了4份安全通告,其中包含了10个漏洞,格物实验室提交的多个漏洞被合并为3个漏洞,且都评为高危,并获得官方致谢。3个漏洞的基本情况如下所示:
-
CVE-2021-30188(CVSS3.0评分8.8): CWE-121: Stack-based Buffer Overflow
-
特制的请求报文发送至受影响的CodeSys产品中,可能引起目标的拒绝服务或者远程代码执行。
-
CVE-2021-34595(CVSS3.0评分8.1): CWE-823: Use of Out-of-range Pointer Offset
单个特制的请求报文发送至受影响的CodeSys产品中,可造成越界读或者写,进而引发拒绝服务或者本地内存被覆盖。
-
CVE-2021-34596(CVSS3.0评分8.1): CWE-824: Access of Uninitialized Pointer
单个特制的请求报文发送至受影响的CodeSys产品中,可造成访问未初始化的指针,进而引发拒绝服务。
成功利用这些漏洞,轻则导致目标产品发生拒绝服务、出现宕机等后果,重则可使目标执行恶意攻击者编制的利用代码,以此影响生产、持续潜伏、窃取敏感数据、适时发动定点攻击等。
在此,以CVE-2021-34595为例,以受影响的PM564模块作为目标做一个简单分析。
当向PM564模块的1201端口发送0x3E功能码的报文时,报文payload部分被直接使用而没有做字段校验处理。
经过一系列处理函数,最终进入到了sub_1FECC0的memcpy操作,memcpy函数的size字段是从报文的payload中直接获取到的,并进行了简单的数学计算,最终导致size字段过大超出了内存范围,进而导致崩溃。
CodeSys是全球最著名的PLC软件研发厂家德国3S(SMART,SOFTWARE,SOLUTIONS)公司发布的一款与制造商无关编程软件及工控设备内核(Runtime SDK)。
这些漏洞不仅仅影响CodeSys软件产品,还影响使用CodeSys Runtime内核的广大工控厂商,因为CodeSys作为“工控界的安卓”被广泛使用在工控设备中,据官方统计使用CodeSys解决方案的知名企业超过500家,CodeSys市场占有率为35%,其中熟知的ABB、施耐德电气SchneiderElectric、费斯托Feso、伊顿电气、博世力士乐、倍福BECKHOFF、研华科技、凌华科技ADLINK、和利时集团、汇川技术、深圳英威腾、华中数控、固高科技等都使用了CodeSys Runtime。更详细的合作客户请参见如下链接 http://www.codesys.cn/list-Partner-1.html
查看公网暴露的CodeSys 产品如下图,可以看到暴露数量不算少,尤其在土耳其暴露数量超过了1200多个。由于工控安全意识加强,很多设备都不在统计范畴内,因此这个暴露数量只是冰山一角。
1. 将受影响的产品放置于安全防护设备之后,做好网络安全的纵深防御策略。
2. 当需要进行远程访问时,尽量采用安全的VPN网络,并且做好访问控制和审计工作。
3. 关注受影响厂商的安全补丁,经过测试后升级受影响的产品以使其免受威胁。
4. 尽量减少受影响设备的私有通信端口暴露,可根据业务场景选择关闭受影响的1200/1201/2455等端口。
5. 建议使用CodeSys Runtime的工控厂商及时自查,并且积极修复,发布修复版本的固件。
本文先从工控设备研究入手,发现了私有协议的多个漏洞,后来经过在其余使用相同内核的PLC上验证也存在漏洞,进一步在CodeSys Runtime内核上进行安全测试,发现了CodeSys Runtime内核的多个漏洞,提交官方后得到了修复。通过这个事件需要意识到,在OT领域内供应链威胁早已存在,而且影响范围会越来越大,工控设备使用的内核、以太网协议栈、操作系统都很集中,比如操作系统都是用VxWorks、QNX、裁剪的Linux,以太网协议栈使用LWIP,内核使用CodeSys、Infoteam、KW等,除此之外还会使用开源代码实现应用层协议,比如Modbus、Ethernet/IP等,难免会引入更多的风险。面对这样的风险我们如何应对呢,在此笔者给出了几点建议:
1. 加强供应链产品或组件的筛查审查机制,从顶层设计解决用谁的?用哪个版本?怎么用?出了问题如何快速更新等问题。
2. 建立公司内部供应链产品或组件的风险管理机制,能够识别开发过程中恶意的变动,并触发追查和防范措施。
3. 借鉴google的SLSA供应链完整性框架,在开发过程中防范供应链威胁。
由于知识面的限制,提出以上安全防护措施供参考,更多针对供应链威胁的处理和应对措施还需群策群力,构建真正能够在前期将供应链攻击扼杀的体系,以此来保障我们业务的安全生产与运行。
原文始发于微信公众号(关键基础设施安全应急响应中心):原创 | 从研究工控设备到发现供应链威胁