CVE-2016-5696漏洞分析:TCP侧信道安全

2016-08-19 +18 611408人围观 ,发现 18 个不明物体 漏洞

*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。

* 本文原创作者:Leon不会玩QEMU,本文属FreeBuf原创奖励计划,未经许可禁止转载

在这篇文章中,我们要讨论一个最新的TCP侧信道的漏洞(CVE-2016-5696)。这个标准是在Linux 3.6版本之前提出的,并且影响众多的设备和主机。简单地说,只要是两台主机之间通过TCP协议去通信,那么就很容易遭受到一个盲目的Off-Path攻击。此外,如果这个连接存在,攻击者通过这种Off-Path攻击也可以从连接的两侧推断出这个序列号是不是正在使用,这样一来反过来,攻击者可以导致连接终止和进行数据注入攻击。

0×01 简介

其实在TCP协议设计的时候并没有考虑安全性。然而最近似乎大家都开始关心起TCP的安全性来的,比较搞笑的是,大家都在为TCP装各种各样的补丁的时候,新的安全问题也随之出现。

那什么是侧信道攻击呢?

信息论创始人香农(Shannon)对信息的定义是:“减少随机不定性的东西。”加密的本质也是打破原有的确定性,使得明文数据变为不可解读密文乱码。但是,侧信道的出现,就是越过加密算法增加的随机不定性,从其他的渠道获取数据标签,确定信息内容的。侧信道最早的实践是通过采集加密电子设备在运行过程中的时间消耗、功率消耗或者电磁辐射消耗等边缘信息的差异性进行攻击的手段。而随着研究的深入,也逐渐从加密设备延伸到计算机内部CPU、内存等之间的信息传递等方面,并在Web应用交互信息传递越来越频繁时,延伸到了网络加密数据流的破解方面。侧信道攻击对数据加密甚至加密Web流量的威胁早就被纳入了信息安全研究的范畴之中了,但是直到2010年,美国印第安纳大学王晓峰教授等人的研究发现侧信道攻击对Web应用的威胁是与生俱来的问题。

首先思考一下Web应用的特点,一个Web服务通常在一个客户端(Client)和一个服务器端(Server)之间进行,他们之前的请求与应答信息一般是通过互联网进行的,这就会把他们之间的交互数据暴漏给了攻击者。而通过这些数据,攻击者就能够推断出他们的状态转变以及触发这些转换的用户数据。更糟糕的是, Web2.0的发展使得Web应用的交互性能越来越好,尤其像Ajax这类编程技术的出现,能够让用户甚至在文本框中输入一个字母或者从一个选项列表中选择一个选项之后,就从服务器查询做出一个应答,而这些应答信息的熵一般很低,因此很容易通过枚举与对比猜测出用户的输入请求。

回归到正题,针对TCP侧信道攻击,可以进行如下的威胁建模分析:

如图1所示,偏离路径攻击是TCP攻击基于现实的一个威胁模型。有三台主机涉及:受害者的客户端,受害者服务器和攻击者。任何机器可能会在这个模型中,只要其ISP允许攻击者将数据包发送到服务器并且成功伪造成攻击者的IP即可成功。可替代地的攻击模型如图2所示,攻击者能够将数据包发送到客户端并且受害者服务器的欺骗IP地址。

Image

图1-威胁模型1

Image

图2-可替代攻击模型

In-window盲攻击:

在上述的模型下,最普通的攻击情况也就是In-window盲攻击,也就是off-path的攻击者企图将猜出来的并且可以引发数据注入和拒绝服务的序列号绑定进伪造TCP数据包来实现攻击。要想攻击得手,这个攻击者必须的知道准确这个服务器和客户端之间建立连接的四元组(也就是原目的端口、IP地址)。一旦伪造的序列号落到了窗口上,攻击者就可以去注入恶意链接或者直接重置连接。

让我们来更精确的描述一下:一个能够满足攻击条件的序列号必须要具备以下条件才能成功。

RCV.NXT SEG.SEQ RCV.NXT + RCV.WND

如果SEG.SEQ是被猜到的序列号,那么RCV.NXT就是接收方下一个想要接收的字节,RCV.WND就是下一个想要接收的窗口大小。

为了要能承载这个攻击,攻击者需要伪造一个序列号远大于正常值的数据包来让整个序列号空间爆炸。在这个序列中,数据包的序列号是一定大于他前面的一个窗口的大小。

Image

图3-ACK窗口插图

为了防止这种攻击,RFC5961提出了几点关于建议在TCP如何处理传入的数据包的修订。

(1)减少盲目利用SYN位进行重置链接的攻击:

攻击者利用强制发送TCP-SYN包对TCP链接进行强制重置,当SYN包发送的时候,TCP链接则会被重置。

在前者(预RFC5961)的Linux内核版本,传入的SYN数据包的处理过程如下:

l 如果该序列号是超出了有效的接收窗口,接收器将发送一个ACK回发送方。

l 如果该序列号是在窗口中,接收器将复位此连接。

显而易见的是,攻击者只需要一个单一的SYN数据包与在窗口序列号重置持续TCP连接。

所以,RFC5961建议在处理SYN数据包如下修改:

l 如果一个接收机看到一个输入SYN分组,忽略该序列号,发回一个ACK(称为挑战ACK)给发送者,以确认先前的连接的丢失。

l 如果数据包确实是从合法的远程端发起,它必须有真正的失去了以前的连接,然后现在正在尝试启动一个新的。收到Challenge ACK,对端会发送一个RST包具有正确的序列号(从挑战ACK包的ACK域而来),以证明以前的连接确实终止。

这样的话,如果SYN序列号是假的,就不会强制重置TCP会话。

(2)减少盲目利用ACK位进行重置链接的攻击:

攻击者可能还伪造一个RST包(其中RST标记被设定TCP包),然后注入到一个持续的TCP连接。

在预发布的RFC5961中,就像上文的SYN的情况一样,一个RST包只要能成功地为它的序列号是在窗口终止连接。

所以RFC5961建议以下变化:

l 如果序列号超出有效的接收窗口,接收器简单地丢弃该数据包。不会对该窗口进行修改。

l 如果序列号的下一个预期序号(RCV.NXT)精确匹配,那么就会连接复位。

l 如果该序列号是在窗口,但不完全匹配RCV.NXT,接收机必须发送一个Challenge ACK分组的发送者,并丢弃不可接受RST分组。

在最后的情况下,如果发送者是合法的,它发回具有正确序列号的RST分组(从Challenge ACK号码ack衍生),以重置连接。另一方面,如果RST被伪造,挑战ACK分组将不会关断攻击者可观察到的路径。因此,攻击者必须得非常幸运- 只因为只有1/2^32的序列号将被接受。(直接说概率小的可怜不行么?!)

(3)减少数据盲注攻击:

攻击者可能会通过数据盲注来实现破坏传输内容,当分组到达时,接收器首先检查序列号来确保它处在in-window状态下。另外,该ACK号码将被检查。预发布的RFC5961中,ACK号码被认为是有效的,只要它落在[SND.UNA-(2^31-1),SND.NXT]这么大一个区间内; 实际上这是ACK号空间的一半。这里,SND.UNA是第一未确认字节的序列号。 SND.NXT是将要被发送的下一个字节的序列号。

RFC 5961建议做法是[SND.UNA-MAX.SND.WND,SND.NXT]。

其中MAX.SND.WND是接收机曾经从它的对等见到的最大窗口尺寸的一个更小的有效ACK编号范围。这在图3插图的是唯一有效的ACK号码是那些不是太旧(字节被最近发送)和不是太新(接收器可以在不ACK字节还能够被寄出)的原因。其余的ACK值将是在[SND.UNA的范围 -(2^31 - 1),SND.UNA -MAX.SND.WND]区间内,表示为Challenge ACK窗口。即使这个窗口内的ACK号码仍然被认为是无效的, 该规范要求接收机响应于与这样的ACK编号的数据包,以产生传出挑战的ACK。总体来说,这更严格的ACK号检查不消除,而且有利于极大地减少了无效数据成功注入的可能性。具体地说,如果MAX.SND.WND很小(通常为大多数连接的情况下),则可以接受的ACK窗口会比ACK号空间的一半(如在图3中示出)要小得多。

(4)ACK节流(Throttling)

在一般情况下,如前面所解释的,RFC5961强制对传入的TCP分组的更严格的检查;例如,它要求RST包具有一个确切的序列号来实际重置连接,而“足够好”的窗口值仅触发一个挑战的ACK。为了减少浪费CPU和带宽资源Challenge ACK数据包的数量,一个ACK节流机构还被提出。

具体地,系统管理员可以配置可在给定的时间间隔(例如,1秒)被发送出去Challenge ACK的最大数量。

该RFC明确指出“实现应该包括一个ACK节流机制是保守的。”因此,Linux内核通过存储在所有TCP连接共享的全局变量的挑战ACK柜台忠实地执行此功能。这种方法,不幸的是,创建一个压根就不需要的副信道,如将要详细阐述。我们强调,RFC规定ACK限制仅适用于挑战ACK和不正规的ACK。这意味着它们面临的挑战的ACK计数器不大可能由合法的ACK交通的影响作为触发挑战的ACK的条件都被认为是罕见的或由于攻击。

0×02 漏洞预览

在2012年9月发布的3.6版本,Linux内核的首次实现了所有在RFC5961建议功能,这些变化全部回迁到了这个版本以及先前的版本上。一个全局系统变量sysctl_tcp_challenge_ack_limit被引入到控制每秒生成Challenge ACK的最大数量。它默认设置为100。由于此限制所有连接(可能包括与攻击者建立的连接)共享,共享状态可以被利用作为一个侧通道。

假设我们按照图 1 中的威胁模型,其基本思想是重复以下步骤︰

1) 发送伪造包用来测试链接(用一个具体的四个元组),

2) 创建一个超过sysctl_tcp_challenge_ack_limit限制的TCP链接,即通过常规的连接从攻击者创建到服务器并故意触发允许每秒最大的ChallengeACK的数量。

3) 算Challenge ACK在该连接收到的确认实际的数。如果这个数字小于系统限制,通过连接下测试,作为对伪造的数据包作出反应必须有发送Challenge ACK。

根据步骤1发送伪造类型的数据包,Off-Path的攻击者可以推断出以下几点:

1) 如果存在由其四个元组指定连接

2) 下一个预期的服务器 (或客户端)上的序列编号 (RCV.NXT)

3) 下一个预期的服务器 (或客户端) 上的ACK 编号 (SND.UNA)。

这就有意思了,这样的话前面的前三个攻击都可以触发了。然后我们精心构造一个看看。

计算用来连接的四元组: 图4显示了一个关断路径攻击者可以发送(i)存在下,或(ii)不存在正在进行的连接的情况下,区分数据包的序列。在这两种情况下,攻击者发送的分组的顺序相同。虚线代表与欺骗性IP地址的数据包。 在

该图中,初始SYN-ACK分组被伪造,以便它似乎来自客户端。为Challenge ACK的可发出(最初100个数据包)时,计数器跟踪和描绘的服务器的时间轴上。

图片 1.png

图4-四元组连接测试

我们的期望是最初欺骗SYN-ACK分组将击中对应于客户端和服务器之间的有效连接一个正确的四元组。在这种情况下(图4的左侧)的服务器将是一个Challenge ACK2(按照对策建议防范Blind SYN数据包注入,这个在后面会有说明)答复。同时,这会从100这一全局的Challenge ACK数减少到99.在那里的欺骗性SYN-ACK不打正确的四元组(上图右)的情况下,服务器将简单地回复一个RST回相应的客户机(每个TCP标准)。

然后,攻击者会发送100个非欺骗IN-WindowRST包用尽Challenge ACK计数(这种行为我们在前面有详细描述)。在活动的连接的情况下,由于挑战的ACK计数为99,攻击者现在可以观察只有99挑战的ACK。在没有连接的情况下,攻击者可以观察100在挑战ACK的数量的差异,从而有效的泄漏有关测试四元组是否对应于活动连接与否的信息。

推算序列号:假设攻击者已经确定对应于该客户机和服务器之间的有效连接一个四元组,偏离路径攻击者现在需要猜测由服务器认为可接受的有效序列号。图 – URE5示出了攻击者可以发送的(i)该情况之间进行区分的分组的在窗口和(ii)外的窗口序列号的序列。在那里的欺骗性RST分组具有在窗口序列号(而不是下一个预期的序列号),如每对策提出了抵御Blind RST分组注射如在前面(2)中描述,一个Challenge ACK被触发,并且第一壳体这减少了从100到99的全局ACK Request计数在将序列号落在窗口之外的第二情况下,没有Challenge ACK将生成(全局的Challenge ACK计数保持在100)。

以连接推论类似,攻击者现在将派遣100名非欺骗的窗口RST包用尽Challenge ACK计数。再一次,根据有多少接收Challenge ACK,攻击者能知道在欺骗性RST猜测的序列号,是在此窗口或外的窗口。

图片 1.png

图5-序列号测试

ACK序列推断:活动连接的一个在窗的序列号被识别后,攻击者现在需要猜测由该服务器认为可接受有效的ACK号码。图6显示了攻击者可以发送来区分的挑战的ACK窗口和(ii)其它的ACK编号(ⅰ)的ACK的情况下,分组的序列。在欺骗性ACK分组具有Challenge ACK窗口(但具有在窗口序列号)的ACK编号第一种情况下,服务器将具有Challenge ACK应答,根据该对策提出了抵御盲数据包注入(在前面有描述)。按照与之前相同的方法,如果该猜测ACK号落在挑战ACK窗口的攻击者可以推断。如将在后面描述的那样,这有助于攻击最终识别服务器上SND.NXT。

图片 1.png

图6-ACK序列号测试

值得注意的是,一旦双方的顺序号和ACK号由服务器上可接受的被推断,攻击者能够确定由客户端上可接受的顺序号和ACK号为好。这是因为RCV.NXT和SND.NXT服务器上基本上等同于SND.NXT和RCV.NXT在客户端[25,18]上。在实践中,如果受害者连接具有正在进行的信息流,推断序列和ACK号可能会改变作为攻击正在进行。我们§6讨论了这样的情况。

另一种推理序列号的方法:

在某些情况下,大量的在一个短的时间内观察到的RST包的可以考虑AB-正常。防火墙甚至可能对每个连接速率限制RST包。为了缓解这一点,其实是可以与ACK包,这很可能会留在雷达之下RST更换包。正如图3所示,当ACK号是在挑战ACK窗口而序列号是IN-窗口一个挑战的ACK将被发送。由于挑战ACK窗口空间是号码ack空间的整个4G的至少1/4,可以发送4个包与ACK号码0,1G,2G和3G分别与至少一个分组将触发一个挑战的ACK如果猜测的序列号是在窗口。要明白为什么挑战ACK窗口至少是这么大,我们首先指出,最大接收窗口的大小为1G的TCP窗口缩放。

选项​​(RFC 7323),这意味着SND.MAX.WIN不能超过1G大。因此,根据在上文中描述的挑战的ACK窗口的定义,它是至少1G为好。鉴于此,对于前面的序列号发送推断每欺骗RST包由四个ACK包,这是效率较低,但仍然是有效的放置重。我们已经实施和测试序列号推断这种替代方法。然而,为了简化说明,我们假定使用与在后续部分RST包原始序列号推断。

参考文档:http://www.cs.ucr.edu/~zhiyunq/pub/sec16_TCP_pure_offpath.pdf

* 本文原创作者:Leon不会玩QEMU,本文属FreeBuf原创奖励计划,未经许可禁止转载

相关推荐

这些评论亮了

  • 周鸿祎 回复
    赞+1
    )15( 亮了
  • YIZ 回复
    表示支持原创翻译,但是,
    翻译不写上原文链接吗?
    还有最后一段翻译完之后有自己读过一遍吗囧
    )10( 亮了
  • 周鸿祎 回复
    假装能看懂
    )8( 亮了
  • 周鸿祎 回复
    )7( 亮了
发表评论

已有 18 条评论

取消
Loading...
Leon不会玩QEMU

某信息安全公司信息安全工程师一枚,专注云计算安全

3 文章数 13 评论数

特别推荐

推荐关注

活动预告

填写个人信息

姓名
电话
邮箱
公司
行业
职位
css.php