查看原文
其他

Schneider IGSS远程溢出漏洞分析

启明星辰 ADLab 2022-12-23

更多安全资讯和分析文章请关注启明星辰ADLab微信公众号及官方网站(adlab.venustech.com.cn)











01

前言

近期,启明星辰ADLab对Schneider  SCADA(Interactive Graphical SCADA System,简称IGSS)的漏洞补丁进行了深入分析,发现这些补丁并没有从根源上修复多个高危缓冲区溢出漏洞,导致IGSS仍可以被远程溢出。ADLab研究员对这些高危漏洞进行了详细分析和实际验证,并及时协助厂商进行了修复


02

漏洞基本信息

根据schneider的漏洞公告[1],这些高危漏洞的基本信息如下:

受影响的产品:V15.0.0.22170 and prior

  • CVE-2022-32522,缓冲区溢出
  • CVE-2022-32523,缓冲区溢出
  • CVE-2022-32524,缓冲区溢出
  • CVE-2022-32525,缓冲区溢出
  • CVE-2022-32526,缓冲区溢出
  • CVE-2022-32527,缓冲区溢出
  • CVE-2022-32529,缓冲区溢出
触发方式:网络
CVSS v3评分:  9.8

03

漏洞分析与验证

V15.0.0.22020是2022年IGSS首个发布补丁的版本,其补丁[2]修复了多个缓冲区溢出漏洞,本文以该版本为分析起点。

3.1 报文处理过程

IGSS在创建socket并设置监听等一系列初始化操作后,转入如下的代码,即等待连接事件并进入sub_4B3090:

第一个红框中,传入sub_4B3090的第一个参数 a1为一个中间缓存区,用来存放IGSS在执行具体功能过程中产生的中间量;第二个参数 1则是该函数的状态量。sub_4B3090内部是一个嵌套式的switch结构,根据输入的参数来决定具体的执行分支。

sub_4B3090函数如下图所示,程序最终会在此处通过WSARecv接收用户传入的数据:

结合上述代码分析,IGSS对接收数据的格式要求如下:

  • 接收数据的大小不能大于0x1000
  • 0 – 2字节的内容为数据的总长度
  • 2 - 4字节的内容必须为1
  • 6 - 10字节的内容为opcde(用于接下来的功能分支)

因此,通过网络只需要发送满足该格式的数据包后就可以请求IGSS执行相应代码。

3.2 初始漏洞分析

运行一个初始漏洞的POC,靶机IGSS崩溃,windbg给出如下崩溃信息:

通过IDA定位到崩溃点,位于程序的Request LOG功能的memcpy代码处,如下所示。

经过逆向分析得知,该处函数的作用是用于处理报文分片的拼接处理,即:在实际接收数据包的过程当中,若接收的数据包并不是一次发送完全,就会继续接收数据;每接收一次后续数据,就会调用该函数将新报文的内容拼接到现有报文的尾部。

分析报文的数据结构得知,该函数要处理的数据有如下图的结构:即18字节的头文件, 18字节的“数据块头”用来存储 “数据块”数量信息,最后是具体的数据块内容(每个数据块的大小为12字节):

预期的拼接逻辑如下,发送端发送了如下的两个数据包B1和B2 :

IGSS通过sub_4A6390进行如下操作:首先realloc申请了12*B2_len长度的缓冲区来扩展B1,接下来使用memcpy将B2数据块的内容拷贝在原B1数据的末尾。

但是,IGSS没有正确校验报文B1的数据结构,导致上文的初始漏洞POC触发了靶机IGSS的拼接漏洞,逻辑如下:

即第一次发送的数据包不存在数据块(B1_len = 0,B2_len = 1),当IGSS执行到sub_4A6390函数则会发生如下图所示情况:

其中,中间蓝色部分是realloc函数申请的12*B2_len长度的缓冲区,这里的B2_len设置成1也就是12字节,所以扩展后存放B1数据所申请的缓冲区大小为30(18+12)字节。经过分析,memcpy的参数*(v8+4)指向了B1缓冲区的开头,而*(*(v8+4)+18)指的是B1的B1_len的长度。由于B1_len = 0,所以memcpy第一个参数的值为:*(v8+4)+36。显然,*(v8+4)+36所指向的地址已经超出了B1缓冲区30字节,因此就造成非法地址写入,导致IGSS崩溃。

3.3 补丁绕过分析

为了修复此类漏洞,施耐德官方发布了V15.0.0.22082来进行修复,其核心是sub_4B40E0函数处,也就是上文所述在检验数据包头部的地方:

分析sub_4B8EE0可知,其是根据不同的opcode来限制每个数据包的长度,上述漏洞的opcode为1,进入case 1随后赋值48给v2之后将v2返回给上图中的v3,接下来判断v88[1051]是否小于v3,v88[1051]实际上存储的是数据包的长度,也就是说此处理论上规定了数据包的大小必须大于48字节(也就是18字节的数据包头部,18字节的数据块头部,加上至少1个数据块12字节的大小总共48字节)来限制上述因为不存在数据块而导致的溢出情况,否则程序会直接返回0:

打过补丁后,初始的漏洞POC就不再有效了。但是,通过对比分析数据拼接的逻辑和补丁代码,ADLab研究员发现初始补丁只是修复了初始POC对应的漏洞利用方式,并没有彻底修复漏洞。

3.4 最新补丁分析

启明星辰ADLab第一时间向施耐德报告了初始补丁绕过问题,官方在新版本(v15.0.0.22214)再次修复了该漏洞。经过分析,最新补丁彻底修复了这批漏洞。补丁存在于sub_4B42D0:

sub_4BA7E0的伪代码如下图所示。同样是按照Opcode选择分支,以case 1为例,不再像之前的版本一样将块的长度限制成最小48字节,而是限制成最小0xA3A字节的大小,也就是数据块的数量要求最少215(0xd7)个,最后将计算后的数据块大小返回赋值给上图红框中的v3,之后再与v88[1051]作比较,即整个数据包的长度最小要等于0xA3A,最新的补丁就限制了B1不能存在声明的数据块数量和实际数据包长度不匹配的情况:

 

还有一处补丁代码是限制Size(第二次发送数据包的数据块大小)不能大于4060字节,也就是每次发送数据包长度的最大值4096 -数据包头部和数据块头部总大小18+18(36)共4060字节,至此该漏洞被修复:


04

修复建议

经过ADLab研究员的分析和验证,上述高危漏洞都可以通过网络进行无条件的远程触发,具有很大的危害性。目前官方已经发布了补丁,强烈建议使用IGGS的工业用户立即升级版本到15.0.0.22171及以上。

针对工业控制系统,CISA提供了如下的通用建议:

  • 尽量减少在公网暴露工控设备或者系统;
  • 将控制系统网络和远程设备置于防火墙之后,并和办公网络隔离;
  • 当需要远程访问时,采用类型VPN的安全访问方式。


参考链接:

[1]SEVD-2022-165-01, IGSS Data Server (15.0.0.22139 and prior) https://download.schneider-electric.com/files?p_Doc_Ref=SEVD-2022-165-01[2] SEVD-2022-039-01, IGSS Data Server (15.0.0.22020 and prior) https://download.schneider-electric.com/files?p_Doc_Ref=SEVD-2022-039-01 






启明星辰积极防御实验室(ADLab)





ADLab成立于1999年,是中国安全行业最早成立的攻防技术研究实验室之一,微软MAPP计划核心成员,“黑雀攻击”概念首推者。截止目前,ADLab已通过CVE累计发布安全漏洞近1100个,通过 CNVD/CNNVD累计发布安全漏洞2000余个,持续保持国际网络安全领域一流水准。实验室研究方向涵盖操作系统与应用系统安全研究、移动智能终端安全研究、物联网智能设备安全研究、Web安全研究、工控系统安全研究、云安全研究。研究成果应用于产品核心技术研究、国家重点科技项目攻关、专业安全服务等。






您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存