TCP创造并发展于1970年代~1980年代,这注定了它能工作但脆弱。
在TCP伊始,最重要的是可用,而不是高效,也不是安全,因此,在端到端TCP连接的中间,利用伪造的ACK,你很容易完成一种叫做 中间人攻击 的事情。
如果你用“TCP劫持”,“TCP中间人”,“TCP注入”等作为关键词百度或者Google,绝大部分内容都在SYN 文上做文章,诸如会话Reset,会话劫持,SYN Flood攻击等等,但实际上还有更好玩的恶作剧。
通过在中间路径上伪造ACK,你可以:
-
提前确认数据,扰乱TCP的ACK时钟,影响RTT测量。
由于数据尚未到达receiver,提前伪造的ACK可以造成sender测量的RTT偏短,误导其BDP的测量。 -
乱序确认数据,扰乱ACK到达模式,影响拥塞控制。
比方说倒序发送两个伪造的ACK,可以造成sender端burst数据引发拥塞(ABC机制可减缓)。 -
确认已经丢弃的数据,接收端空洞永无可弥补。
只要sender收到ACK,数据就会从重传队列中永久删除,但事实上这个ACK是伪造的,真正的数据已经丢失。receiver将再也无法等到这个数据。 -
确认已经丢弃的数据,伪造数据弥补空洞实现注入。
参照上面一点,既然receiver在苦等再也等不到的数据,中间人便可以伪造任意数据去填补这个空洞,实现数据注入。 -
伪造数据注入,使SSH,HTTPS等解密失败,TCP正常关闭。
参照上面两点伪造数据注入HTTPS,SSH等加密连接,会造成解密失败,从而应用程序调用close关闭连接不是Reset掉连接。
是不是更有趣呢别是最后一点,大多数时候,程序员,运维以及经理在排查TCP问题的时候,总是盯着Wireshark里显示成红色的RST 文,现在他们有能力通过IPID字段的分布以及TTL字段判断该RST是不是来自中间设备了(几年前他们还做不到…)。然而,我让连接断开的方式并没有使用过时的RST,而是注入脏数据,序列 ,IPID,TTL等均匹配,这样会很大程度扰乱程序员,运维和经理们的思路,让他们加班到头昏脑胀的时候陷入更加炼狱般的深渊。因此,在发送伪造ACK或者伪造数据的时候,你要做到:
- 伪造ACK或者伪造数据注入的时候,一定注意IPID,TTL两个IP层的字段,尽量和抓包位置看到的这两个字段匹配,这样才更逼真。比如,IPID保持单调小幅递增,TTL保持一致。
来来来,简单比划一下。
先看拓扑:
在host A上运行nc客户端:
为了模拟丢包的获取,在Midbox上模拟一个针对性的丢包,这样简化我们的实验,实际环境中,还是要通过分析ACK序列来识别丢包:
通过抓包,我当然能获取这两个nc建立连接的四元组信息,我在Midbox上执行伪造ACK的逻辑,试图确认一个已经丢失的 文,即包含”hello”的 文:
当host A输入hello之后,在Midbox执行伪造数据的逻辑:
以下就是结果:
但很不幸,我们很难在终端上部署隧道,所以大多数情况下,SD-WAN的方案并不好使。
那么只好搭建一个透明代理了。
用IP_TRANSPARENT option可以轻松构建一个TCP透明代理。
但是有比透明代理更高效简单的三层方案:
- 在lastmile转发节点为每一个路过的TCP连接cache住最大一个BDP的sequence连续的 文。
-
利用这些 文cache,实现下图的逻辑:
实际上就是实现一个超级简单的超时重传,快速重传机制。我称它为 伪中继 。
至于说实现,我觉得还是比透明代理和隧道都简单,其复杂性在nf_conntrack之下,我们可以想象用nf_conntrack的实现方式来完成这个:
- 以TCP四元组为键构建双向流量hash表。
- TCP 文到达时以四元组查询hash表,找到entry。
- 实现伪造ACK,定时器管理等逻辑。
- 基于滑动窗口保存至多一个BDP的sequence连续的数据 文。
- …
这里面有一个很有意思的点,很多擅长主机 络的看到上面这种伪中继把戏会提出很多质疑,比方说引入这么复杂的逻辑势必增加处理时延,数据结构的互斥读写的同步开销会消耗CPU进一步增加处理时延,诸如此类。
这个点就是, 我们处理的是长肥管道里的一条端到端的TCP,而不是主机收包或者发包路径。 一条TCP的RTT至少是ms级,长肥管道可达百ms级,为了应对lastmile的丢包引入的伪中继逻辑所带来的处理时延不过us级,这根本不是一个数量级上的事情。
此外,和分段隧道相比,伪中继是完全透明的,它不会损耗链路的MTU,而分段隧道至少要消耗一个TCP头/IP头的空间开销。
嗯,有个脑洞,分段隧道是不是也可以不用隧道模式,而用传输模式呢再进行再封装,而仅仅是在中间节点针对缓存的数据实施不同的CC算法。就是把上面的伪中继把戏推广到整个链路,推广到这个SD-WAN的Overlay 络,每个中转节点均对TCP数据进行缓存,在实施不同的CC算法发送数据的同时,实现超时重传逻辑和快速重传逻辑…
有点想多了。
浙江温州皮鞋湿,下雨进水不会胖。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!