你需要了解的关于TCP\"SACK Panic\"的内容

・6 分钟阅读

netflix发现了几个在Linux (在某些情况下freebsd )处理"选择性TCP确认(SACK )"选项[1]的漏洞,最关键的漏洞可能导致kernel panic,导致系统无反应,修补此漏洞非常重要,一旦漏洞被发布,漏洞就可以用来关闭公开的服务器,或者客户端连接到恶意服务。

脆弱性概述
书钉受影响的操作系统Description/Impact
CVE-2019-11477Linux > 2.6.29SACK处理整数溢出导致,
CVE-2019-11478Linux < 4.14.127SACK缓慢或过量的资源使用
CVE-2019-5599FreeBSDrack send map sack slowness
CVE-2019-11479Linux (所有版本)资源消耗不足导致的过度资源消耗

如果你使用的是当前的Linux系统,启用了选择性确认(常见的默认设置),并且使用具有TCP Segment Offload的网卡(同样是现代服务器中的常见默认设置),则你很容易受到攻击,已提供修补程序,或者你可以禁用SACK 。

Netflix在它咨询中包含了Linux内核的补丁,以下Linux内核版本包括补丁: 4.4.182,4.9.182,4.14.127,4.19.52,5.1.11.

什么是SACK?

每个连接到网络的主机都可以发送特定大小为("MTU")的数据包,这个大小取决于所用的网络技术,对于以太网,典型的大小为1500字节,但以太网的容量可达到9,000. 此空间中的某些用于header,使用标准20字节IP头和20字节TCP头,TCP数据包通常可以包含最多1,460个数据("最大段大小"" )字节,TCP将分割数据流到足够小的段,主机以最大段大小相互通信,以减少碎片的破坏机会。

为了在TCP连接中订购数据包,每个字节被分配一个序列号,TCP头将列出包中第一个字节的序列号,接收方将通过通信下一个序列号来确认它接收到的序列号。

只承认完整的部分会导致一些低效率,接收方无法与已收到某些订单数据的发件人通信,相反,它将继续承认它收到的最后一组是完整的细分段。

为了避免这种低效,引入了SACK ,它允许接收方通知发送方已收到无序段,"I我收到了序列号10,然后期望11,但是,我也收到了20-30",这样,发送者知道只重发11-19,并且下一个31继续。

什么是TCP Segment Offload?

TCP Segment Offload是当前大多数网卡中包含的一项功能,为了减少工作,CPU必须进行缓冲和重组TCP段,网卡将负责一些TCP处理,在这种情况下,操作系统将接收超过网络MTU的大型"数据包"

什么是TCP sack"?

操作系统需要将数据存储到(并且确认)或接收到,Linux使用一个称为"缓冲区缓冲区"的数据结构来执行这样的操作,在Linux中,此套接字缓冲区最多可容纳17个段,当发送和确认数据包时,数据从结构中删除,或者某些数据可能会被合并,在某些情况下,移动数据可能会导致存储超过17个部分,而且这又导致了a。

我该怎么做才能防止这种情况发生?

1.禁用SACK

你可以暂时禁用SACK而不用重新启动,以root运行:

setenforce 0
echo 0 >  /proc/sys/net/ipv4/tcp_sack

第一行只有在使用SELinux时才是必要的,因为它可能会阻止第二个语句。

要使此更改永久化,请将以下内容添加到/etc/sysctl.conf (或者作为/etc/sysctl.d中的新文件):

net.ipv4.tcp_sack = 0
net.ipv4.tcp_dsack = 0
net.ipv4.tcp_fack = 0

运行"sysctl -p",无需重新启动(同样,你可能需要禁用SELinux )即可应用更改。

2.防火墙规则

利用此方法需要非常小的最大段大小设置,你可以阻止在iptables中转发小MSS的数据包:

iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

根据RFC 879,TCP要求MTU至少为576,导致最小MSS为536.

我怎么知道我很脆弱

3.查找易受攻击的系统

没有简单的扫描工具来找到脆弱的系统,到目前为止,还没有可用于查找易受攻击系统的PoC漏洞,作为一个快速测试,你可以查找支持SACK (运行Linux )的系统,下面的tcpdump命令可能会帮助:

tcpdump -i eth0 -n 'ip[8]<65 and tcp[13]&0x2f=2'  | grep 'sackOK'

此命令将帮助识别设置了TTL小于65的SYN或SYN-ACK标志的系统(这个帮助仅限在Linux系统里有用)。 SackOK选项没有简单的过滤器,因为它可能出现在不同的位置,所以,我用"grep"欺骗了一下,

你可以在Linux上使用ethtool"命令来查看是否启用了TCP offloading(ethtool -k interface_name ),[感谢Alan通过Twitter指出这一点。

供应商声明/补丁

Redhat :https://www.helplib.cn/anquan/article_178517
Ubuntu :https://usn.ubuntu.com/4017-1/
Debian :https://www.debian.org/security/2019/dsa-4465
SUSE :https://www.suse.com/de-de/support/kb/doc/?id=7023928
Cloudflare :https://twitter.com/jgrahamc/status/1140724787242819585
Amazon :https://aws.amazon.com/security/security-bulletins/AWS-2019-005/

[1] https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001.md

Hrh profile image