AMNESIA33:开源TCP/IP协议栈系列误差剖析与验证
宣布时间 2020-12-14前言
近期,外洋清静研究职员在多个被普遍使用的开源TCP/IP协议栈发明了多个误差,这一系列误差统称为AMNESIA33。这些误差普遍保存于嵌入式和物联网装备中,影响了多个行业领域(包括医疗、运输、能源、电信、工业控制、零售和商业等),现在已知规模内涉及了超150家供应商以及数以百万计的装备。与URGEN11和Ripple20差别的是,AMNESIA33影响的是多个开源TCP/IP协议栈,因此这些误差可以悄无声息地影响到无数个代码库、开发团队与各个公司的产品。现在已知的误差涉及到了智能家居、工厂PLC、SCADA装备与工控交流机,电力监控等装备。
这些误差保存于uIP、FNET、picoTCP和Nut/Net等开源协议栈上,影响TCP/IP协议栈的多个组件,包括DNS、IPv6、IPv4、TCP、ICMP、LLMNR和mDNS等。其中包括多个严重误差,它们的CVE编号划分为CVE-2020-17437、CVE-2020-17443、CVE-2020-24338、CVE-2020-24336、CVE-2020-25111。
CVE-2020-17437(CVSS评分8.2)、CVE-2020-17443(CVSS评分8.2)可导致装备拒绝服务。CVE-2020-24338、CVE-2020-24336、CVE-2020-25111(这三个CVSS评分均为9.8)都可导致远程代码执行(RCE)。其它28个误差的严重水平各异,CVSS评分划分从4到8.2。
由于IoT、OT、IT装备供应链的特征,误差影响的装备众多,影响规模广且一连时间长,误差修复的实验较难题。同时,由于uIP、picoTCP开源协议栈已经不再维护,以是部分误差没有补丁,许多产品只能寻找替换手艺计划或者是增添提防步伐。
关于这些误差的提防缓解步伐,我们建议接纳如下几个步伐:
● 设置内网装备的DNS服务器为内网DNS服务器。
● 使用漏扫产品识别出接纳问题协议栈的装备资产,对组织内可能保存问题的IoT、OT和IT装备举行危害评估。
● 防火墙及IPS产品加入AMNESIA33误差攻击识别特征,监控恶意流量。
● 尽可能更新相关受影响协议栈到最新版本。
下表是部分已经修复的协议栈及版本:
TCP/IP协议栈 | 修复版本 |
FNET | 4.70及以上 |
uIP-Contiki-NG | 4.6.0及以上 |
Nut/Net | 5.1及以上 |
CISA同盟分享了13个涉及到AMNESIA33误差的公司的产品修复建议,包括了Microchip、Siemens等公司的产品,详见参考链接[5]。
1、DNS协议剖析
DNS的请求和响应的基本单位是DNS报文(Message)。请求和响应的DNS报文结构是完全相同的,每个报文都由以下五段(Section)组成:

DNS Header是每个DNS报文都必需拥有的一部分,它的长度牢靠为12个字节。Question部分存放的是向服务器盘问的域名数据,一样平常情形下它只有一条Entry。每个Entry的名堂是相同的,如下所示:

QNAME是由labels序列组成的域名。QNAME的名堂使用DNS标准名称体现法。这个字段是变长的,因此有可能泛起奇数个字节,但不举行补齐。DNS使用一种标准名堂对域名举行编码。它由一系列的label(和域名中用.支解的label差别)组成。每个label首字节的高两位用于体现label的类型。RFC1035中分派了四个内里的两个,划分是:00体现的通俗label,11(0xC0)体现的压缩label。
Answer、Authority和Additional三个段的名堂是完全相同的,都是由零至多条Resource Record(资源纪录)组成。这些资源纪录由于差别的用途而被脱离存放。Answer对应盘问请求中的Question,Question中的请求盘问效果会在Answer中给出,若是一个响应报文的Answer为空,说明这次盘问没有直接获得效果。
RR(Resource Record)资源纪录是DNS系统中很是主要的一部分,它拥有一个变长的结构,详细名堂如下:

● NAME:它指定该条纪录对应的是哪个域名,名堂使用DNS标准名称体现法
● TYPE:资源纪录的类型。
● CLASS:对应Question的QCLASS,指定请求的类型,常用值为IN,值为0x001。
● TTL(Time To Live)资源的有用期:体现你可以将该条RR缓存TLL秒,TTL为0体现该RR不可被缓存。TTL是一个4字节有符号数,可是只使用它大于即是0的部分。
● RDLENGTH:一个两字节非负整数,用于指定RDATA部分的长度(字节数)。
● RDATA:体现一个长度和结构都可变的字段,它的详细结构取决于TYPE字段指定的资源类型。
DNS响应包如下图所示:

从上图中可知,该Answers区段中保存9个资源纪录,红框中体现的是主机地址(A类型)资源纪录。
域标签label在DNS数据包里被编码,每个通俗标签的第一个字节代表这个标签的长度,剩下的字母数字字符为标签自己(一些特殊字符也是可以的),可是最终最后的字符一定是以空字节最后(即0x00),用来体现域名的竣事。举个例子,如下图所示,域标签第一个字符是0x03,这代表第一个标签长度为3(即0x77 0x77 0x77 == “www”),同理,0x62 0x61 0x690x64 0x75 == “baidu”,最后可以看到以0x00最后。

2、TCP紧迫模式
为了发送主要协议数据,TCP提供了一种称为紧迫模式(urgentmode)的机制,TCP协议在数据段中设置URG位,体现进入紧迫模式。通过设置紧迫模式,发送方可以在发送行列中优先发送这部分的数据,并且不必在发送行列中排队,而吸收方可以对紧迫模式接纳特殊的处置惩罚。这种方法数据禁止易接受被壅闭,服务器端程序会优先接受这些紧迫的数据,而不必举行排队处置惩罚。在TCP报文中界说了两个字段来标示紧迫模式,一个URG标记,该标记体现报文中有紧迫数据,另一个标记是紧迫指针,它标示紧迫数据在传输数据中偏移位置。如下图所示:

下面我们对几个CVSS评分较高的误差举行剖析:
1、CVE-2020-17437
CVE-2020-17437保存于uIP协议栈的uip.c文件的uip_process函数中,该函数主要是处置惩罚ip/tcp报文,下图是uIP协议栈对TCP报文中带有TCP_URG紧迫指针标识时的处置惩罚代码,若是编译时设置了UIP_URGDATA,则程序会走到下面的if分支,对紧迫指针数据举行专门处置惩罚。
可是在默认情形下,UIP_URGDATA并没有设置。代码会进入到else分支,程序会跳过处置惩罚紧迫指针数据,并修改uip_len的数值。程序在修改uip_len的时间并没有判断紧迫指针的值,当uip_len的值特殊小,而紧迫指针的值urgp特殊大时,就会引起整数溢出,导致装备重启或者是越界读写。

2、CVE-2020-24338
该误差泛起在picoTCP/IP协议栈中剖析域名label的pico_dns_decompress_name()函数中,该函数详细实现如下代码所示:

第95、96行初始化iterator,name指向待解压缩的labels,dest_iterator指向存放解压出来的labels的缓冲区,巨细为256字节。第97行最先为while循环,读取到字符串最后空字节退出。第98行,通过iterator&0xC0判断label类型,若是为压缩label,则通过packet定位到通俗label所在的位置,若是为通俗label直接进入else代码块中,第107行,挪用memcpy将通俗label拷贝到dest_iterator中。我们知道dest_iterator缓冲区巨细只有256字节,而while循环退出条件为读到字符串最后空字节,因此当name长度凌驾256字节时,导致dest_iterator缓冲区溢出。
3、CVE-2020-24336
该误差泛起在contiki协议栈中的ip64_dns64_4to6()中,该函数功效是将ipv4类型的DNS数据包转换成ipv6类型的DNS数据包,要害代码如下:

遍历Answer区段并更新到ipv6类型的Answer区段中。从第209行最先转换资源纪录,详细实现代码如下所示:

首先判断TYPE是否是DNS_TYPE_A,DNS_TYPE_A体现该资源纪录为ipv4主机地址,然后将对应区段拷贝到acopy中。第220行,从资源纪录中直接取RDLENGTH,前文已先容,该区段表征RDATA的长度。第227行,判断len长度是否即是4,这里正常情形,len应该为4,由于ipv4地址长度为4个字节。若是len不即是4,则进入else语句中,直接挪用memcpy举行RDATA数据拷贝。这里是保存问题的,Ipv4主机地址长度不即是4,并没有验证主机地址的合理性并且len最大为0xFFFF,直接拷贝可能导致缓冲区溢出。
4、CVE-2020-25111
在使用Nut/Net协议栈的装备中,NutDnsGetResourceAll()是处置惩罚DNS请求的函数,其中处置惩罚DNS回复的函数是DecodeDnsQuestion(),处置惩罚域标签的函数是ScanName(),误差就泛起在ScanName()函数中。如下图所示,cp为指向域名第一个字节的指针(即第一个域标签的长度字节),*npp为即将被剖析的域名buffer,通过strlen()将整个域名长度赋值给rc,然后基于rc分派*npp buffer,之后通过一个while,循环处置惩罚每一个label。问题显而易见,cp是攻击者可控的,由此可以控制*npp的巨细。而关于标签的长度,即len变量,直接从数据包中获得,并没有做任何界线检查,然后通过while循环处置惩罚。因此可以对len设置恣意的值,即攻击者对*npp buffer可控的长度。由此可以在堆中造成越界写,这可导致远程代码执行(RCE)。

5、CVE-2020-17443
CVE-2020-17443保存于PicoTCP协议栈pico_icmp6.c文件中。问题代码位于pico_icmp6_send_echoreply()函数中,该函数的主要功效是回复ICMPv6应答数据包以响应对端的ICMPv6Echo(ping)请求。

我们可以看到,第68行,replay结构的缓冲巨细基于echo的报文中transport_len变量。在第84行,程序从echo->payload向reply->payload地址复制了长度为echo->transport_len- 8巨细的数据。
注重,若是echo->transport_len小于 8,echo->transport_len - 8会导致整数溢出,memcpy操作会导致缓冲区溢出。
在PicoTCP协议栈攻击者通过结构恶意的ICMPv6数据包,这个恶意的数据包ICMP报头小于8,会导致装备重启或拒绝服务。
误差验证
误差验证视频请审查ADLab公众号
参考链接:
[1] https://www.forescout.com/research-labs/amnesia33/[2]https://www.securityweek.com/amnesia33-vulnerabilities-tcpip-stacks-expose-millions-devices-attacks
[3] https://www.zdnet.com/article/amnesia33-vulnerabilities-impact-millions-of-smart-and-industrial-devices/
[4] https://tools.ietf.org/html/rfc1035
[5] https://us-cert.cisa.gov/ics/advisories/icsa-20-343-01
尊龙凯官网入口起劲防御实验室(ADLab)
ADLab建设于1999年,是中国清静行业最早建设的攻防手艺研究实验室之一,微软MAPP妄想焦点成员,“黑雀攻击”看法首推者。阻止现在,ADLab已通过CVE累计宣布清静误差近1100个,通过 CNVD/CNNVD累计宣布清静误差900余个,一连坚持国际网络清静领域一流水准。实验室研究偏向涵盖操作系统与应用系统清静研究、移动智能终端清静研究、物联网智能装备清静研究、Web清静研究、工控系统清静研究、云清静研究。研究效果应用于产品焦点手艺研究、国家重点科技项目攻关、专业清静服务等。



京公网安备11010802024551号