一、背景
近日,JSOF研究实验室在研究过程中发现Treck TCP/IP协议栈存在一系列的安全问题,命名为Ripple20,成功利用这些漏洞可能允许远程执行代码或暴露敏感信息。全部的技术细节将会在今年的BlackHat USA 2020中进行发布。
目前证实此漏洞广泛影响物联网设备,涉及众多厂商,包括HP、Schneider Electric、Intel、Rockwell Automation、Caterpillar、Baxter等供应商,涉及医疗、航空、运输、家用设备、企业、能源(石油、天然气)、电信、零售业等行业。
二、漏洞及分析
2.1 Treck协议栈介绍
高性能嵌入式系统是推动当今快速增长的市场创新,也是高增长应用的关键技术。自1997年以来,Treck一直专注于设计、分发和支持实时嵌入式系统的Internet协议。Treck TCP /IP协议栈是专为嵌入式系统而设计的高性能协议栈,广泛应用于嵌入式设备和物联网设备。
Treck TCP/IP具有高性能、可伸缩和可配置的特点,能轻松集成到任何环境中,而无论处理器,商用RTOS,专有RTOS还是其他的RTOS,通过内核、计时器、驱动程序和套接字的API接口,Treck TCP/IP可以轻松集成到各种嵌入式产品中。
2.2 Treck协议栈分析
Treck TCP/IP堆栈中的数据包由一个名为tsPacket的结构表示。每个包都与一个数据缓冲区相关联,该数据缓冲区保存了从接口驱动程序到达的原始数据。tsPacket结构还保存另一个称为ttUserPacket的重要结构,以及指向tsSharedData结构的指针,该结构包括网络协议栈处理数据包时所需的信息。
协议栈中的一个常见模式是在协议栈的层之间移动时调整指针。例如,如果数据包是一个ICMP回显请求包(ping),它将由三层组成:Ethernet、IPv4、ICMP。在这种情况下,当处理Ethernet层(在函数tfEtherRecv中)时,指针指向Ethernet报头的开始,然后在移动到下一层之前,使用以下代码对其进行调整:
pkt->pktuLinkDataPtr = pkt->pktuLinkDataPtr + 0xe;
pkt->pktuLinkDataLength = pkt->pktuLinkDataLength - 0xe;
pkt->pktuChainDataLength = pkt->pktuChainDataLength - 0xe;
在本例中,0xe(十进制14)是Ethernet报头(6 (目标 MAC地址) + 6 (源MAC地址) + 2 (下一层EtherType))的大小。
当tfEtherRecv完成包处理时,它使用表示下一层协议的EtherType字段将包转发至下一层进行处理。受支持的EtherType有ARP、IPv4和IPv6。
下图是 tsUserPacket 结构的示意图:
Treck协议栈会在tfIpReassemblePacket中处理分片的重组,这个过程被tfIpIncomingPacket调用。每当收到发往设备的IP分片时,就会调用这个过程。如果有缺失的分片,该函数将返回NULL。反之,如果所有的分片都到达了,协议栈就会使用pktuLinkNextPtr 字段将分片链接在一起,并将数据包传递到下一层进行处理。这里的 “重组 “一词并不是指将数据包复制到一个连续的内存块中,而是简单地将它们以链表的方式链在一起。
2.3 漏洞产生分析
当协议栈处理外部分片时,它将使用tsUserPacket结构中的pktuLinkNextPtr字段链接它们。当函数tfIpIncomingPacket处理内部IP数据包(由于protocol = 4)时,会处理进入的分片数据(内部IP数据包由链接在一起的两个tsPacket结构表示),同时也将会调用到存在漏洞的流程。
内部IP数据包通过了IP标头完整性检查,因为仅考虑了tsUserPacket的pktuChainDataLength字段,而没有考虑pktuLinkDataLength。 内部IP数据包的总长度(32)小于链数据长度(1000 + 8 + 20 = 1028),因此Treck协议栈将尝试不正确地截断数据包,方法是将字段pktuLinkDataLength和pktuChainDataLength设置为相同的值,即IP总长度(示例中为32)。这就导致了内部IP包由两个tsPacket结构连接在一起表示的情况。但它们的总cusize大于pktuChainDataLength 字段的值(截断后,pktuChainDataLength字段等于32字节,而不是1028字节)。
下图是以上描述的示例包结构:
如果应用程序正在侦听任何UDP端口,那么一个UDP数据包将会被传递到这个端口的套接字处理函数tfSocketIncomingPacket,将该数据包附加到套接字接收队列(之后由应用程序层轮询)。在研究中发现当UDP数据包的套接字接收队列为非空,并且有新数据包到达时,包含堆溢出的数据流是可以实现的。
测试将一个数据包链接具有较小的缓冲区,这里sizeOfPacketBuffer相对较小(大约10字节多一点),当数据包到达程序流时,pkt-> pktuChainDataLength等于4(截断后为32,然后在处理IP层时递减20(IP报头的大小),然后再递减8(UDP报头的大小))。因此4 * 4-16小于size0fPacketBuffer,于是通过了检查。
需要确保UDP数据包的接收队列是非空的(否则无法到达此流程)。以足够快的速度将多个UDP数据包发送到同一端口,在到达发生溢出的位置tfSocketIncomingPacket之前,数据包会经过tfUdpIncomingPacket进行与UDP相关的安全性检查。确保UDP长度字段等于pktuChainDataLength字段减去内部IP报头的大小即可。
总之,如果受影响的设备上有一个UDP端口在监听,则可以快速发送数据包,使Socket接收队列非空,同时发送一个分片化的UDP数据包,将触发漏洞。
三、安全建议
3.1 设备生产商
针对代码资产进行核查,看是否使用了Treck的相关代码,并从源代码中查看软件版本是否为受影响的版本(版本号小于6.0.1.67)。
针对二进制库文件,可以使用如下命令查看库文件的版本,确定是否使用了受影响的版本。
strings 驱动名称 | grep -e "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
针对第三方库的引入建立安全评估流程。
3.2 设备使用商
针对物联网设备,禁止IP_IN_IP的访问,即类似VPN方式的数据访问。
如果使用的防护设备可以自定义规则,则可以添加如下规则:
#IP-in-IP tunnel with fragments
alert ip any any -> any any (msg:"VU#257161:CVE-2020-11896 Fragments inside IP-in-IP tunnel"; ip_proto:4; fragbits:M; rev:1;)
随时关注设备厂商的软件更新公告,即时更新系统到最新版本。
限制物联网设备访问权限与访问范围。
3.3 安全厂商
防护类增加如下规则,并需要和设备资产进行关联(是否物联网设备),精确进行防护,减少误报。
#IP-in-IP tunnel with fragments
alert ip any any -> any any (msg:"VU#257161:CVE-2020-11896 Fragments inside IP-in-IP tunnel"; ip_proto:4; fragbits:M; rev:1;)
检测类设备
目前确认受影响的厂商为:
- Aruba Networks
- Baxter US
- B. Braun
- CareStream
- Caterpillar
- Cisco
- Digi International
- Green Hills Software
- Hewlett Packard Enterprise
- HP Inc.
- Rockwell Automation
- Schneider Electric
- Teradici
- Treck
- Xerox
- Zuken Elmic
详细的设备型号还需要进一步确认。
四、产品解决方案
4.1 NTI情报关联
绿盟科技威胁情报中心第一时间收录了此次漏洞的详细信息,包括漏洞成因、受影响的产品版本和解决方案等。漏洞CPE字段包括了可机读的影响产品字段,可以于用户本地资产管理库进行关联,从而识别是否存在有影响的设备。
4.2 物联网准入网关
绿盟科技物联网准入网关,可以对物联网设备进行主动探测发现,形成物联网设备资产库,并能通过对流量进行分析,形成攻击画像。
本次升级Treck漏洞指纹库后,可以主动探测内网使用Treck协议栈的物联网设备,并对这类设备产生告警。
针对发现有Treck漏洞的设备,如果发生攻击行为,物联网准入网关,还可以对设备进行网络阻断。