论文阅读笔记-[Security_18] Off-Path TCP Exploit-How Wireless Routers Can Jeopardize Your Secret
摘要
- 作者发现了一种时序侧信道,其存在于各代半双工的 IEEE 802.11 或者 Wi-Fi 技术中。
- 这种设计上的错误很难被修补,不像其他漏洞。
- 可以应用于三大操作系统,macOS, Windows, Linux
- 条件是,仅需要通过无线路由器连接到互联网的设备,攻击者可连接至该设备(直接或间接)。
- 威胁是,处于路径之外的攻击者能很快篡改毫不知情的用户的 Web 缓存。
1 简介
- 网络协议栈中的侧信道导致严重的攻击漏洞,都利用到了攻击者和受害者之间的共享资源,但大部分漏洞都来自软件问题并已经被修补。
- 作者发现的漏洞根源于 IEEE 802.11 或 Wi-Fi 技术的半双工机制。例如,如果上行链路有数据传输,那么用于测量 RTT 的下行链路会有更高的延迟。
- 攻击者可以利用这一时序信道来推断 TCP 序列号和 ACK 确认号,最终实施路径外的 TCP 攻击。
2 路径外 TCP 攻击
2.1 通用威胁模型
- 典型的路径外 TCP 劫持威胁模型包括三部分,受害客户端,受害服务端,和一个路径外攻击者
- 不像中间人攻击,攻击者无法窃听客户端与服务端之间的流量,需要在客户端上植入一个应用或脚本,来观察共享状态的变化并决定如何伪造数据包。极少情况下,状态变化能被远程观察到,就不需要这种应用或脚本。在多轮推断后,攻击者便能够注入有害的并能被客户端 TCP 层接收的数据。
- 这种攻击需要两种必要的模块,一是存在有漏洞的包验证逻辑;二是共享状态必须能被攻击者观察到。
2.2 最新的入站 TCP 数据包验证逻辑
- 连接(四元组)确认
- 序列号检查
- ACK 确认号检查
2.3 以前的攻击和侧信道
- 全局 IPID 计数器,Windows 系统的曾经的漏洞,已经在 Win10 系统中被修复
- 读浏览器网页,运行有害的 Javascript 代码,也已被修复。
- 全局挑战性确认的速率限制
- 系统范围内的数据包计数器
3 Wi-Fi 时序信道
Wi-Fi 半双工的本质创造了在上下行链路中的共享资源(CSMA 协议),如果另一边在传输数据,那么这边数据的传输就会有延迟,有碰撞延迟更高。
利用该时序信道:发送探测包,探测前查询包,探测后查询包,来测量 RTT。序列号在窗口内,不发送 ACK,RTT 短,否则 RTT 长。还可以发送多个探测包,来放大 RTT 的测量效果。
实例测试:半双工机制和全双工机制对比,验证了半双工机制导致的碰撞是产生时序信道的根本原因
4 攻击概述
威胁模型
客户端连接至 Wi-Fi,用户需要被诱导去访问一个恶意网站,然后一个沙盒恶意脚本(木偶)与攻击者发起连接,以此解决 NAT 或 防火墙的问题。
攻击目标:
推断客户端到服务端的存在性
序列号,ACK 确认号推断
向连接中注入恶意数据包
总体流程
对于攻击目标 3,作者聚焦于“Web 缓存污染”攻击。接下来逐步介绍这三个攻击目标,以及他们在三大主要操作系统上的具体操作。
利用 TCP 包验证逻辑
有两个问题需要考虑,一是连接至 Wi-Fi 的客户端大都在 NAT 或防火墙后面,包验证逻辑可能有微小的改变;二是不清楚操作系统是否完全遵循 RFC 包验证逻辑的标准。
对于第一个问题,如果来了一个不与任何连接匹配的包,NAT 或防火墙会直接丢弃,反之则按正常流程走。这其实简化了连接存在性的推断过程。攻击者只需发送总会激发响应的包(例如,SYN 包),如果没有响应,那么连接不存在,反之则存在。
对于第二个问题,作者则做了详尽的调查和充分的实验,做出了归纳总结。
连接(端口号)推断
外来的与现有连接匹配的 ACK 包,如果序列号在接收窗口外,则一定会激发客户端的 ACK 包出来,对任一操作系统都如此。利用本论文第 3 节提到的方法测量时延即可。
序列号推断
对 Linux 系统,如果 10 个只含一个字节有效数据的入 ACK 数据包被客户端接收,要么产生 10 个响应(序列号在窗口外),要么由于速率限制而最多产生 1 个响应(序列号在窗口内)。
对于 macOS,如果不置任何标志位,序列号在窗口外则产生响应,序列号在窗口内则不产生响应。如果置 ACK 位,且序列号在窗口内,则 ACK < SND.UNA 时无响应,ACK > SND.MAX 时有响应。
对于 Windows 系统,将 ACK 置位后,序列号在窗口外则产生响应,反之序列号在窗口内且 ACK 在窗口外时不产生响应。
ACK 确认号推断
现假设序列号都在窗口内了。按标准来说,接收一个序列号在窗口内的,没有有效数据的包,如果 ACK 确认号在窗口外,则产生响应,如果 ACK 确认号在窗口内则不产生响应。但不同操作系统没有完全遵照标准。
Linux:ACK 号小于 SND.UNA - MAX.SND.NXT 时,回应一个 ACK(有速率限制时);ACK 号太新时(大于 SND.NXT),直接丢弃,不做响应。当没有速率限制时,攻击者可以通过二分查找来推断正确的 ACK 号。然而有速率限制时,一次与零次响应的对比不能产生足够明显的时序信道。另外,没有有效数据的窗口内 ACK 号也会没有响应,这将导致无法区分窗口内和窗口外的情况,有有效数据即可避免此情况。仅当 ACK 号在窗口内时有响应。但有有效数据会带来新的问题,让客户端误以为是服务端发来的数据,造成错误。幸运的是,Linux 有一个特殊情况可以解决上述问题:如果序列号等于 RCV.NXT - 1(表示一个 keep-alive 消息),则应该产生响应。当序列号等于 RCV.NXT - 1 时,一个窗口内的 ACK 号会使其产生响应,并且不带有效数据,相反地如果是窗口外的 ACK 则最多产生一个响应。
MacOS:对于 keep-alive 包,无论 ACK 号是多少,都产生响应,故 Linux 的方法不再适用于此。太新的 ACK 号产生响应,太旧的 ACK 号不产生响应。
Windows:ACK 确认窗口会改变。一开始,当连接空闲时,只对 SND.UNA 和 SND.NXT 的 ACK 确认号有响应,此时 SND.UNA == SND.NXT。后面确认窗口会增大,ACK 号在窗口外时不响应,在窗口内时产生响应。
5 实现
5.1 连接(四元组)推断
通用方法
每次用 30 个包来猜端口号,当猜对时,能观察到 RTT 的突然增加。如果是猜由客户端发起的任意连接,则需要暴力方法;但攻击者需要实施 Web 缓存污染攻击的话,则应当以木偶发起的连接为目标,这种情况下能采用一些优化方法。
Windows 和 macOS
采取全局顺序的端口分配策略。先让其和恶意服务端建立连接,然后即可推测下一个目标连接分配的端口号。
Linux
采用 Simple Hash-Based Port Selection 端口分配策略,对每一对远程 IP 和端口号有一个独立的本地端口分配空间。这样便无法通过某条连接来预测另一条连接至另一服务端分配的端口号。但也可以不用暴力预测端口号,因为:为同一服务端 IP 和端口号对分配的本地端口号是顺序的。因此,可以先让木偶与目标建立 n 条连接,然后每次测试端口号后 +n,算一个小优化。
NAT
一般不会对端口号进行转换,即不用担心外部端口被转换从而变得不可预测,否则将采用暴力方法或者是文献(GILAD, Y., AND HERZBERG, A. When tolerance causes weakness: the case of injection-friendly browsers. In WWW (2013).)提出来的方法。
Multiple IP addresses from a domain
需要攻击者付出两三倍的努力。
5.2 序列号推断
通用方法
按之前介绍的方法得到窗口内的序列号,然后再通过二分查找缩小范围至 RCV.NXT。
优化:增加窗口大小
为了大幅减少猜测次数的迭代次数,一种直接的方法是大幅扩大客户端的接收窗口。为此,木偶可以请求大量的大型对象。在收到足够的完整段之后,接收者将根据TCP流量控制显著增加其接收窗口大小。在我们的实验中,我们发现窗口大小通常可以扩大到约x = 500,000,与原始大小(例如65,535)形成鲜明对比。值得注意的是,根据RFC793 [4]的规定,窗口大小一旦扩大就无法缩小。类似地,通过上传数据,ACK窗口(即对等方的序列窗口)也可以扩展,尽管通常比我们所能达到的最大序列窗口大小要小得多。
5.3 TCP 劫持
本节假设攻击者通过由木偶发起的连接来进行 Web 缓存污染。
MacOS:由第 4 节所述,进行二分查找。一旦 ACK 号推断成功后,进行去同步攻击以避免服务端优先发送响应导致的竞争
Linux:利用时序侧信道来推断 ACK 号是可行的,但推断时间较长。一种代替方案是,在不知道确切的 ACK 号的情况下实施数据盲注。(1)去同步化,木偶持续向客户端请求一个对象,攻击者不断发送序列号匹配的,暴力遍历 ACK 号码的包(比利用时序信道快,因为不需要等响应),最终使得客户端与服务端失去同步。(2)数据盲注,现在只需遍历有效的 ACK 号。注意到上述两个过程各遍历了一次 ACK 号,但也只会花费几秒钟。
Windows:为了防止有效的确认窗口大小仅为一个字节,客户端必须不断发送请求以确保始终有尚未接收的数据,这增加了我们的攻击的复杂性,因为攻击者必须同步下一个预期的序列号。此外,大量的流量还会对定时侧信道引入干扰。如果一个新的TCP数据包的序列号范围与之前缓冲数据有重叠,我们发现在Windows上总是优先选择旧的数据,而在Linux上优先选择新的数据。因此,在Windows主机上缓冲的由攻击者注入的数据可能会破坏来自服务器的真实HTTP响应。后面没看懂。。。。。
5.4 其他挑战
通过设置适当的阈值来处理噪声
先发送正常的包来测量攻击者和客户端之间的 RTT,分为有响应和无响应两类,设置阈值使得有响应的前 80% 的时间都在阈值以上。但也会去除大于 3 倍标准差的异常值。
通过错误恢复来处理噪声
相对比较和双重检查。在测得窗口内序列号之后,继续测量窗口外序列号的 RTT,并将两者之差进行比较,如果结果前后不一致,那可以推断之前出了错并将步骤回滚。如果把一个窗口内的数字误认为是窗口外的数字,则没有简单的办法检测这种情况,只能将整个过程重复一遍直到找到正确的数字。
流水线
不是一次只测一个 SEQ/ACK,用流水线。
滑动 SEQ/ACK 窗口和未知的窗口大小
因为受害者连接是由木偶控制的,所以大部分时间是空闲的除非木偶发起请求。因此,攻击者能够完全知道什么时候 SEQ/ACK 窗口会滑动。初始先选一个相对较大的窗口大小 $\theta$,然后每轮迭代减半这个大小。
检测任意对象的大小
让木偶向服务端请求那个对象,计算客户端前后期待序列号之差
6 评估
实验设置
攻击者操作系统:Ubuntu 14.04
被攻击者 OS:macOS 10.13, Linux 4.14.0, Windows 10 Pro version 1709。它们也是用来学习 TCP 栈行为的 OS。浏览器用的是 Chrome 64.0 和 Firefox 58.0.1。
时序侧信道的噪声韧性
增加噪声:放 Youtube 视频;实验地点有 43 个 Wi-Fi,其中 22 个是 2.4GHz 的,6 个用的是和测试用路由器同样的信道;有 10 个以上学生在使用网络。
本地攻击的评估
受害网站可以是任何用 HTTP 传输的网页。即使用了 HTTPS 但没用 HSTS 也不行,因为向服务端发起的初始请求是用的 HTTP,服务端后面才将浏览器重定向至 HTTPS 的站点。测了不同 OS 和浏览器的成功率和平均成功时间。
远程攻击的评估
外部攻击者与受害者之间的 RTT 大于 20ms。耗时明显变长。
7 讨论
攻击可以扩展至连接至同一无线网络的其他客户端,也可以扩展至通过无线网连接的服务端(例如 IoT 设备)
8 防御
作者发现这个时序侧信道问题后,就向工作组揭露了它,也向路由器厂商报告了。
在 Wi-Fi 技术层面的防御
让 Wi-Fi 信道全双工。
在 TCP 栈方面的防卫
包验证逻辑。
ACK 号验证逻辑的一种可能改进:窗口内序列号的有数据的包,都有响应;不带数据的 ACK 包,都不响应。
序列号验证逻辑的一种可能改进:使有效和无效的序列号的响应一致。一个有效的策略是考虑限制发来的各种类型的包的 ACK 应答的速率(一次或零次响应),使其足够小到无法测量。这个方法也可以应用于连接的推断。
在应用层的防卫
HSTS 和 HTTPS 能抵挡大部分 Web 攻击,例如网页缓存污染。但这两个只能抵挡应用层的攻击(例如网页缓存污染)而不能抵挡传输层的攻击。浏览器也要做一些改进:观察到任何不正常的响应,例如不正确的格式以及更长的时间,应立即断开连接并重启。
9 相关工作
……
10 结论
……
论文评审
Overall merit
Accept
Reviewer expertise
Some familiarity
Paper summary
本论文的作者发现了一种时序侧信道,其存在于各代半双工的 IEEE 802.11 或者 Wi-Fi 技术中。这种设计上的错误很难被修补,不像其他软件上的漏洞能通过软件更新来修补。这一漏洞可以应用于三大操作系统(macOS, Windows, Linux),进行路径外的 TCP 注入攻击。条件是仅需要通过无线路由器连接到互联网的设备,攻击者可连接至该设备(直接或间接地)。处于路径外的攻击者能够对受害者实施 Web 缓存污染攻击。
Strengths
- 对如何实施攻击列出了详细的步骤,并充分解释了其背后的原理,对可能遇到的各种情况以及存在的困难和挑战也都做了详尽的总结和实验。
- 对不同操作系统和浏览器的 TCP 实现机制研究很深入,并且提出了更有针对性的更优化的攻击方法。
Weaknesses
- 文中的“客户端”和“服务端”的表述有时让人迷惑,应用更清楚的表达方式来使得指代更明确。
- 没有提出经过充分验证的且有效的防御方法。
Attack details
- 策略(目标 & 影响):
- 目标:通过无线路由器连接到互联网的设备
- 条件:攻击者能与受害者直接或间接地相连接
- 影响:Web 缓存污染
- 影响评级:中
- 目标:通过无线路由器连接到互联网的设备
- 技术手段:
- 时序侧信道攻击:攻击者利用 IEEE 802.11 和 Wi-Fi 技术的半双工特性,利用向受害客户端发送伪造 TCP 数据包后产生响应与否,从而导致 RTT 的不同,推测受害客户端和服务端之间的连接的端口号、序列号、ACK 号,最终能够实施 Web 缓存污染攻击。
- 攻击模式:利用发送伪造数据包后客户端产生响应与否导致的 RTT 不同来进行推断
- 连接存在性(端口号)推断:外来的与现有连接匹配的 ACK 包,如果序列号在接收窗口外,则一定会激发客户端的 ACK 包出来,对任一操作系统都如此。
- 序列号推断:
- 对 Linux 系统,如果 10 个只含一个字节有效数据的入 ACK 数据包被客户端接收,要么产生 10 个响应(序列号在窗口外),要么由于速率限制而最多产生 1 个响应(序列号在窗口内)。
- 对于 macOS,如果不置任何标志位,序列号在窗口外则产生响应,序列号在窗口内则不产生响应。如果置 ACK 位,且序列号在窗口内,则 ACK < SND.UNA 时无响应,ACK > SND.MAX 时有响应。
- 对于 Windows 系统,将 ACK 置位后,序列号在窗口外则产生响应,反之序列号在窗口内且 ACK 在窗口外时不产生响应。
- ACK 确认号推断:现假设序列号都在窗口内了。按标准来说,接收一个序列号在窗口内的,没有有效数据的包,如果 ACK 确认号在窗口外,则产生响应,如果 ACK 确认号在窗口内则不产生响应。但不同操作系统没有完全遵照标准。
- Linux:ACK 号小于 SND.UNA - MAX.SND.NXT 时,回应一个 ACK(有速率限制时);ACK 号太新时(大于 SND.NXT),直接丢弃,不做响应。当没有速率限制时,攻击者可以通过二分查找来推断正确的 ACK 号。然而有速率限制时,一次与零次响应的对比不能产生足够明显的时序信道。另外,没有有效数据的窗口内 ACK 号也会没有响应,这将导致无法区分窗口内和窗口外的情况,有有效数据即可避免此情况。仅当 ACK 号在窗口内时有响应。但有有效数据会带来新的问题,让客户端误以为是服务端发来的数据,造成错误。幸运的是,Linux 有一个特殊情况可以解决上述问题:如果序列号等于 RCV.NXT - 1(表示一个 keep-alive 消息),则应该产生响应。当序列号等于 RCV.NXT - 1 时,一个窗口内的 ACK 号会使其产生响应,并且不带有效数据,相反地如果是窗口外的 ACK 则最多产生一个响应。
- MacOS:对于 keep-alive 包,无论 ACK 号是多少,都产生响应,故 Linux 的方法不再适用于此。太新的 ACK 号产生响应,太旧的 ACK 号不产生响应。
- Windows:ACK 确认窗口会改变。一开始,当连接空闲时,只对 SND.UNA 和 SND.NXT 的 ACK 确认号有响应,此时 SND.UNA == SND.NXT。后面确认窗口会增大,ACK 号在窗口外时不响应,在窗口内时产生响应。
- Web 缓存污染:在完成上述三个步骤后,即可知道客户端期待的下一个序列号和 ACK 号,能实施此类攻击
- 弱点:
- TCP 包验证逻辑有漏洞,以及 Wi-Fi 的半双工特性,使得攻击者能够观察到对预测正确与否的包的响应时间的区别。
- 安全隐患:
- 任何通过无线路由器连接至网络的设备
- 连接至与被攻击客户端同一无线网络的其他客户端
- 通过无线网连接的服务端(例如 IoT 设备)
- 防御措施:
- Wi-Fi 技术层面,使其成为全双工工作模式(很难实现)
- TCP 栈方面,改进 TCP 包的验证逻辑。ACK 号验证逻辑的一种可能改进:窗口内序列号的有数据的包,都有响应;不带数据的 ACK 包,都不响应。序列号验证逻辑的一种可能改进:使有效和无效的序列号的响应一致。一个有效的策略是考虑限制发来的各种类型的包的 ACK 应答的速率(一次或零次响应),使其足够小到无法测量。这个方法也可以应用于连接的推断。
- 应用层方面:采用 HSTS 和 HTTPS 协议;浏览器对接收的包采取更严格的审查方式。
Comments for authors
这篇论文整体上写得很不错。以前我也听说过侧信道攻击,但并没有深入了解某个具体的攻击方式,觉得攻击者能够捕捉到如此微妙的信息并借此发动攻击挺不可思议。这是我第一次完整地了解了一个侧信道攻击方式:利用无线网络通信的半双工特性,结合 TCP 包验证逻辑中对各种包的响应情况不同,来测得 RTT 的区别,从而推测出受害客户端与服务端的连接里,前者预期接收的 TCP 包的端口号、序列号、ACK 号,进而攻击者能够伪造 TCP 包,最终对受害客户端发起 Web 缓存污染攻击。
读完这篇论文后给我的最深刻的印象就是内容非常详实,很有说服力。此论文做了大量的调研和实验,全文引用了许多前人所做的工作;证明了 Wi-Fi 信道的半双工特性而不是全双工是这种时序侧信道攻击漏洞的根基;详细阐述了三大不同操作系统(macOS, Windows, Linux)的 TCP 包验证逻辑,并有针对性地提出了相应的攻击方案;不仅如此,作者还不满足于仅利用时序侧信道来推断 TCP 包相关字段,还针对不同操作系统提出了更优化的方法来加快速度;并且作者也没有回避现实中可能遇到的困难和挑战,例如 NAT 或防火墙的存在,以及网络通信中的噪声干扰等,也提出了解决方案,实验也是在模拟真实的网络环境中进行的;也提出这个攻击技术可以扩展,包括连接至无线网络的服务端(如 IoT 设备)等;最后作者还提出了可能的防卫措施。
另外我也想问作者一些问题。整个攻击存在的前提之一是需要先向受害客户端注入恶意脚本,通过它来观察共享状态的变化,如果这一步不成功,攻击是否就无法开展了?这一过程其实也应该详细阐述并讲解预防方法。另外我对 5.3 节 TCP Hijacking 部分的对 Windows 系统的攻击方法阐述中,有些地方不理解:Inject 步骤中,为什么攻击者要发送 $\dfrac{2^{32}}{|wnd|}$ 数量的伪造包?为什么要加一个 offset,为什么第 $i$ 个包猜测的 ACK 号是 $i\cdot |wnd|$?这一部分我没有看懂。最后我想知道,这一漏洞到目前为止有没有被修补,以及现在的现实世界中有没有利用这种漏洞发起的攻击,如果有,规模怎么样?造成了多少损失?
文章链接
https://www.usenix.org/conference/usenixsecurity18/presentation/chen-weiteng