作者:威努特工控安全
公众号:威努特工控安全
工控漏洞挖掘方法有很多种,常见的方法包括:基于工控协议的模糊测试漏洞挖掘方法、基于固件逆向分析的漏洞挖掘方法、基于工控软件ActiveX控件的漏洞挖掘方法、基于VxWorks操作系统的漏洞挖掘方法等。
本文将重点论述固件逆向分析方法,同时结合实际案例来讲解逆向分析过程中遇到的关键问题及解决方法。
固件逆向分析方法是在不对嵌入式系统进行实际运行的情况下,通过对固件文件进行逆向解析,分析固件中各代码模块的调用关系及代码内容,从而发现嵌入式系统中可能存在的漏洞及后门的一种技术手段。
在固件逆向分析的过程中,将会涉及到固件的识别和解压、固件的静态分析等技术。
固件的识别和解压,可以借用一些成熟的工具软件,如:Binwalk、BAT(Binary Analysis Toolkit)等。Binwalk和BAT均为比较流行的固件映像提取和分析工具。Binwalk以MIT License发布,BAT以GPL License发布。它们支持的固件映像解压格式对比表如下:
对于常见的嵌入式设备固件可以使用Binwalk或BAT来解压并提取固件文件。对于无法自动解压的固件,可以尝试以下方法分析:
固件解压之后的分析主要集中在对常见漏洞入口进行针对性的静态分析,包括:密码、默认开启的服务、端口、配置文件等。
分析方法如下:
1)尝试提取文件中包含的明码字段是否存在硬编码密码等。
2)发掘固件的关联性,包括分析固件作者、库使用、目录结构、配置文件关键字、定制默认密码等信息。
3)对二进制可执行文件进行反汇编分析,可以借用一些成熟的工具软件,如:IDA Pro、Capstone等。对特定的嵌入式系统(如VxWorks)的登录模块进行反汇编分析,获取其登录密码的哈希算法等信息。
IDA Pro是应用最广泛的静态反汇编工具,它支持对大量的CPU架构进行逆向分析,包括X86、MIPS、PowerPC及Arm等。
Capstone是一个反汇编框架,它支持多种平台,能够运行在Windows、Mac OS X、Linux、 FreeBSD、OpenBSD和Solaris中。Capstone可反汇编ARM、ARM64 (ARMv8)、MIPS、PPC和X86架构下的应用。
4)如果发现包含密码哈希的文件,可考虑使用John the Ripper或Hash Suite等工具进行暴力破解。前者有版本支持GPU加速(支持CUDA和OpenCL)。使用暴力破解工具可以利用前述步骤中提取的关键字,显著加快运行效率。
本文将针对施耐德NOE 771固件进行逆向分析,NOE 771是施耐德Quantum系列PLC的以太网模块,Quantum系列PLC是施耐德的高端PLC,应用在我国核心能源调度网络系统中,如:西气东输的区域子段SCADA系统。
在分析过程中,我们将重点论述固件的识别和解压、固件加载地址提取和固件反汇编代码中的函数名修复等关键技术。
1)固件升级包的获取
我们可以从施耐德官方网站下载固件升级包,从该升级包中提取固件文件。NOE 771的固件文件名为NOE77101.bin。
2)固件的识别和解压
首先,使用Binwalk来确认该文件的压缩类型,发现为zlib类型,如图1所示。
其次,使用Binwalk提取zlib压缩的文件,如图2所示。解压后的文件385存储在_NOE77101.bin.extracted
目录中,并以文件在固件升级包中的起始位置来命名。
接着,使用Binwalk对385文件进行分析,发现固件中的一些路径名、操作系统版本和符号表地址等关键信息。该固件的操作系统版本是VxWorks 2.5,可以结合VxWorks的源码来进行逆向分析。该固件的符号表地址如图4所示,符号表可以用来修复反汇编代码中的函数名,详见2.1.3节论述。
由于嵌入式系统的固件需要加载到内存中的特定位置进行运行,这个特定的位置叫做固件加载地址(base address)。
嵌入式系统固件的函数调用地址是基于固件加载地址所计算出的内存位置,而不是固件中的偏移量位置。
因此,为了使反汇编工具软件(如IDA Pro)能够正确的分析函数调用关系,我们需要分析出固件加载地址,否则所有的函数调用关系都将是错误的。
针对使用ELF封装的固件文件,在ELF文件的头部有特定的数据位记录了该固件的加载地址,因此我们可以直接读取ELF文件头,从而直接获取到固件的加载地址。
如果固件没有使用任何封装,那么就需要对固件的代码进行逆向,从而分析出固件的加载地址。这个方法比较复杂,针对不同的嵌入式系统及CPU架构都有区别。
针对NOE771的固件,我们将通过分析固件头部的代码调用来大致猜测固件的加载地址。
1)获取CPU架构,选择正确的反汇编引擎
首先,使用Binwalk - A命令来获取目标固件的CPU架构等信息,该信息有助于选择正确的反汇编引擎,如图5所示目标固件的CPU架构为PowerPC big endian。
其次,使用IDA Pro加载PowerPC big endian架构的反汇编引擎进行分析。
2)分析固件加载地址,进行正确的反汇编
当未修改固件加载地址时,IDA Pro仅仅分析出了极少数的函数,如图7所示。
通过对固件头上的代码进行分析后(往往很耗时),可以发现在0x09f8的位置有一段非常可疑的函数调用。该函数调用地址为一个偏移量0x339AB8+一个绝对地址0x10000,有相当大的可能0x10000就是我们所需要的固件加载地址。
现在我们需要验证0x10000是否是我们真正的固件加载地址。重新使用IDA Pro加载固件文件,并按照下图进行配置。配置完成后,IDA Pro能够正常的分析固件的函数调用关系。
上一节,IDA Pro虽然成功分析出了函数的调用关系,但是尚无法自动识别出函数名,这对我们的进一步分析造成了很大的阻碍。
因此,我们需要查看固件是否包含了符号表。如包含了符号表,就可以利用符号表中的内容,来修复IDA Pro中所显示的函数名。
1)获取符号表在固件中的位置
VxWorks系统的符号表包含了函数及函数名的对应关系,因此我们的第一步是要找到符号表在固件中的位置。之前使用Binwalk分析固件时,已经发现了固件中的符号表位置为0x301E74。
2)确定符号表的起始及结束地址
在获取了符号表在固件中的位置后,我们可以使用16进制编辑器对固件进行查看,从而确认Binwalk分析出的地址是否正确。
VxWorks系列的字节排序有独特的格式,以16个字节为一组数据,前4个字节是函数名的内存地址,后4个字节是函数的内存位置,然后以另4个特征字节数据+4个字节0x00结尾。
通过查看Binwalk分析出的地址位置可见,这个地址的确是符号表,0x27655C是函数名所在的内存地址,0x1FF058是函数的内存位置。
由于符号表有自己的特征,因此能够通过遍历的方式快速的锁定符号表的起始及结束地址。我们所测试的固件的符号表起始地址为0x301e64+0x10000,结束地址为0x3293a4+0x10000。
3)编写脚本插件修复函数名
在得到了符号表的位置后,我们需要使用IDA Pro的API来修复函数名,这里将使用如下的Python脚本。
4)运行脚本插件修复反汇编代码中的函数名
在IDA Pro中运行Python脚本,如下图所示。
脚本执行完毕后,IDA Pro中的函数名,如下图所示。
在固件逆向分析完毕后,可以通过查看固件的服务加载过程,来查看初始化时所添加的账号等信息。
查看usrAppInit函数,可以发现大量的loginUserAddd调用,如图15所示。同时可以发现多个后门账号,如图16所示。
基于固件逆向分析的漏洞挖掘方法可以发现隐藏较深的软件后门漏洞,是一种非常实用的漏洞挖掘方法。在工业控制领域,存在着数量庞大的嵌入式系统,这些系统大多采用固件升级的方式更新,多数固件只压缩未加密,多数固件采用VxWorks系统,因此本文论述的固件逆向分析方法具有普遍的通用性,建议感兴趣者多加尝试,会有效的发现各类安全漏洞。