当前位置:首页 > 空调维修 > 文章正文

TCP 重置进击的工作事理

编辑:[db:作者] 时间:2024-08-25 06:53:52

理解 TCP 重置攻击并不须要具备深厚的网络知识功底,只须要一台条记本就可以对自己进行仿照攻击。
本文将会带你理解 TCP 重置攻击的事理,同时会帮助你理解很多关于 TCP 协议的特性。

TCP 重置进击的工作事理

本文紧张内容:

Python

下面开始剖析 TCP 重置攻击事理。

1. 伟大的 xx 长城是如何利用 TCP 重置攻击的?

这一段略过,缘故原由你懂得,感兴趣的请直接看原文。

2. TCP 重置攻击的事情事理

在 TCP 重置攻击中,攻击者通过向通信的一方或双方发送假造的,见告它们立即断开连接,从而使通信双方连接中断。
正常情形下,如果客户端收创造到达的报文段对付干系连接而言是禁绝确的,TCP 就会发送一个重置报文段,从而导致 TCP 连接的快速拆卸。

TCP 重置攻击利用这一机制,通过向通信方发送假造的重置报文段,欺骗通信双方提前关闭 TCP 连接。
如果假造的重置报文段完备逼真,吸收者就会认为它有效,并关闭 TCP 连接,防止连接被用来进一步交流信息。
做事端可以创建一个新的 TCP 连接来规复通信,但仍旧可能会被攻击者重置连接。
万幸的是,攻击者须要一定的韶光来组装和发送假造的报文,以是一样平常情形下这种攻击只对长连接有杀伤力,对付短连接而言,你还没攻击呢,人家已经完成了信息交流。

从某种意义上来说,假造 TCP 报文段是很随意马虎的,由于 TCP/IP 都没有任何内置的方法来验证做事真个身份。
有些分外的 IP 扩展协议(例如 IPSec )确实可以验证身份,但并没有被广泛利用。
客户端只能吸收报文段,并在可能的情形下利用更高等别的协议(如 TLS )来验证做事真个身份。
但这个方法对 TCP 重置包并不适用,由于 TCP 重置包是 TCP 协议本身的一部分,无法利用更高等别的协议进行验证。

只管假造 TCP 报文段很随意马虎,但假造精确的 TCP 重置报文段并完成攻击却并不随意马虎。
为了理解这项事情的难度,我们须要先理解一下 TCP 协议的事情事理。

3. TCP 协议事情事理

TCP 协议的目标是向客户端发送一份完全的数据副本。
例如,如果我的做事器通过 TCP 连接向你的打算机发送我的网站的 HTML ,你的打算机的 TCP 协议栈该当能够以我发送的形式和顺序输出 HTML 。

然而现实生活中我的 HTML 内容并不是按顺序发送的,它被分解成许多小块(称为 TCP 分组),每个小块在网络上被单独发送,并被重新组合本钱来发送的顺序。
这种重新组合后的输出被称为 TCP 字节流 。

将分组重修成字节流并不大略,由于网络是不可靠的。
TCP分组可能会被丢弃,可能不按发送的顺序到达客户端,也可能会被重复发送、报文破坏等等。
因此,TCP 协议的职责是在不可靠的网络上供应可靠的通信。
TCP 通过哀求连接双方保持密切联系,持续报告它们吸收到了哪些数据来实现可靠通信,这样做事端就能够推断出客户端尚未吸收到的数据,并重新发送丢失的数据。

为了进一步理解这个过程,我们须要理解做事端和客户端是如何利用序列号(sequence numbers)来标记和跟踪数据的。

TCP 序列号

TCP 协议的通信双方, 都必须掩护一个序列号(sequence numbers),对付客户端来说,它会利用做事真个序列号来将吸收到的数据按照发送的顺序排列。

当通信双方建立 TCP 连接时,客户端与做事端都会向对方发送一个随机的初始序列号,这个序列号标识了其发送数据流的第一个字节。
TCP 报文段包含了 TCP 头部,它是附加在报文段开头的元数据,序列号就包含在 TCP 头部中。
由于 TCP 连接是双向的,双方都可以发送数据,以是 TCP 连接的双方既是发送方也是吸收方,每一方都必须分配和管理自己的序列号。

确认应答

当吸收方收到一个 TCP 报文段时,它会向发送方返回一个 ACK 应答报文(同时将 TCP 头部的 ACK 标志位置 1),这个 ACK 号就表示吸收方期望从发送方收到的下一个字节的序列号。
发送方利用这个信息来推断吸收方已经成功吸收到了序列号为 ACK 之前的所有字节。

TCP 头部格式如下图所示:

一个确认应答报文的 TCP 头部必须包含两个部分:

ACK 标志位置位 1包含确认应答号(ACK number)

TCP 统共有 6 个标志位,下文就会讲到个中的 RST 标志位。

TCP 头部包含了多个选项,个中有一个选择确认选项( SACK ),如果利用该选项,那么当吸收方收到了某个范围内的字节而不是连续的字节时,就会发送 SACK 奉告对方。
例如,只收到了字节 1000~3000 和 4000~5000 ,但没有收到 3001~3999 。
为了大略起见,下文谈论 TCP 重置攻击时将忽略选择确认选项。

如果发送方发送了报文后在一段韶光内没有收到 ACK ,就认为报文丢失了,并重新发送报文,用相同的序列号标记。
这就意味着,如果吸收方收到了重复的报文,可以利用序列号来判断是否见过这个报文,如果见过则直接丢弃。
网络环境是错综繁芜的,每每并不是如我们期望的一样,先发送的数据包,就先到达目标主机,反而它很骚,可能会由于网络拥堵等乱七八糟的缘故原由,会使得旧的数据包,先到达目标主机。
一样平常分两种情形:

发送的数据包丢失了发送的数据包被成功吸收,但返回的 ACK 丢失了

这两种情形对发送方来说实在是一样的,发送方并不能区分是哪种情形,以是只能重新发送数据包。

只要不频繁重复发送数据,额外的开销基本可以忽略。

为假造的重置包选择序列号

构建假造的重置包时须要选择一个序列号。
吸收方可以吸收序列号不按顺序排列的报文段,但这种容忍是有限度的,如果报文段的序列号与它期望的相差甚远,就会被直接丢弃。

因此,一个成功的 TCP 重置攻击须要构建一个可信的序列号。
但什么才是可信的序列号呢?对付大多数报文段(除了重置包,即 RST 包)来说,序列号是由吸收方的吸收窗口大小决定的。

TCP 滑动窗口大小

想象一下,将一台上世纪 90 年代初的古老打算机,连接到当代千兆光纤网络。
闪电般快速的网络可以以令人瞠目结舌的速率向这台古老的打算机传送数据,速率远远超过该打算机的处理能力。
但并没有什么卵用,由于只有吸收方吸收并处理了报文,才能认为这个报文已经被收到了。

TCP 协议栈有一个缓冲区,新到达的数据被放到缓冲区中等待处理。
但缓冲区的大小是有限的,如果吸收方的处理速率跟不上发送方的发送速率,缓冲区就会被填满。
一旦缓冲区被填满,多余的数据就会被直接丢弃,也不会返回 ACK。
因此一旦吸收方的缓冲区有了空位,发送方必须重新发送数据。
也便是说,如果吸收方的处理速率跟不上,发送方的发送速率再快也没用。

缓冲区到底有多大?发送方如何才能知道什么时候可以一次发送更多的数据,什么时候该一次发送很少的数据?这就要靠 TCP 滑动窗口了。
吸收方的滑动窗口大小是指发送方无需等待确认应答,可以持续发送数据的最大值。
假设吸收方的通知布告窗口大小为 100,000 字节,那么发送方可以无需等待确认应答,持续发送 100,000 个字节。
再假设当发送方发送第 100,000 个字节时,吸收方已经发送了前 10,000 个字节的 ACK,这就意味着窗口中还有 90,000 个字节未被确认,发送方还可以再持续发送 10,000 个字节。
如果发送了 10,000 个字节的过程中没有收到任何的 ACK ,那么吸收方的滑动窗口将被填满,发送方将停滞发送新数据(可以连续发送之前丢失的数据),直到收到干系的 ACK 才可以连续发送。

TCP 连接双方会在建立连接的初始握手阶段通知布告对方自己窗口的大小,后续还可以动态调度。
TCP 缓冲区大的做事器可能会声明一个大窗口,以便最大限度提高吞吐量。
TCP 缓冲区小的做事器可能会被迫声明一个小窗口,这样做会捐躯一定的吞吐量,但为了防止吸收方的 TCP 缓冲区溢出,还是很有必要的。

换个角度来看,TCP 滑动窗口大小是对网络中可能存在的未确认数据量的硬性限定。
我们可以用它来打算发送方在某一特定时间内可能发送的最大序列号( max_seq_no ):

max_seq_no = max_acked_seq_no + window_size

个中 max_acked_seq_no 是吸收方发送的最大 ACK 号,它表示发送方知道吸收方已经成功吸收的最大序列号。
window_size 是窗口大小,它表示许可发送方最多发送的未被确认的字节。
以是发送方可以发送的最大序列号是: max_acked_seq_no + window_size 。

TCP 规范规定,吸收方该当忽略任何序列号在吸收窗口之外的数据。
例如,如果吸收方确认了所有序列号在 15,000 以下的字节,且吸收窗口大小为 30,000 ,那么接下来吸收方只能吸收序列号范围在 15,000 ~ 45,000 之间的数据。
如果一个报文段的部分数据在窗口内,另一部分数据在窗口外,那么窗口内的数据将被吸收确认,窗口外的数据将被丢弃。
把稳:这里忽略了选择确认选项,再强调一遍!

对付大多数 TCP 报文段来说,滑动窗口的规则见告了发送方自己可以吸收的序列号范围。
但对付重置报文来说,序列号的限定更加严格,这是为了抵御一种攻击叫做盲目 TCP 重置攻击( blind TCP reset attack ),下文将会阐明。

TCP 重置报文段的序列号

对付 TCP 重置报文段来说,吸收方对序列号的哀求更加严格,只有当其序列号恰好即是下一个预期的序列号时才能吸收。
连续搬出上面的例子,吸收方发送了一个确认应答,ACK 号为 15,000 。
如果接下来收到了一个重置报文,那么其序列号必须是 15,000 才能被吸收。

如果重置报文的序列号超出了吸收窗口范围,吸收方就会直接忽略该报文;如果其序列号在吸收窗口范围内,那么吸收方就会返回一个 challenge ACK ,见告发送方重置报文段的序列号是缺点的,并告之精确的序列号,发送方可以利用 challenge ACK 中的信息来重新构建和发送重置报文。

其实在 2010 年之前,TCP 重置报文段和其他报文段的序列号限定规则一样,但无法抵御盲目 TCP 重置攻击,后来才采纳这些方法施加额外的限定。

盲目 TCP 重置攻击

如果攻击者能够截获通信双方正在交流的信息,攻击者就能读取其数据包上的序列号和确认应答号,并利用这些信息得出伪装的 TCP 重置报文段的序列号。
相反,如果无法截获通信双方的信息,就无法确定重置报文段的序列号,但仍旧可以批量发出尽可能多不同序列号的重置报文,以期望猜对个中一个序列号。
这便是所谓的盲目 TCP 重置攻击( blind TCP reset attack )。

在 2010 年之前 TCP 的原始版本中,攻击者只须要猜对吸收窗口内的随便哪一个序列号即可,一样平常只需发送几万个报文段就能成功。
采纳额外限定的方法后,攻击者须要发送数以百万计的报文段才有可能猜对序列号,这险些是很难成功的。
更多细节请参考 RFC-5963

4. 仿照攻击

以下实验是在 OSX 系统中完成的,其他系统请自行测试。

现在来总结一下假造一个 TCP 重置报文要做哪些事情:

嗅探通信双方的交流信息。
截获一个 ACK 标志位置位 1 的报文段,并读取其 ACK 号。
假造一个 TCP 重置报文段( RST 标志位置为 1),其序列号即是上面截获的报文的 ACK 号。
这只是空想情形下的方案,假设信息交流的速率不是很快。
大多数情形下为了增加成功率,可以连续发送序列号不同的重置报文。
将假造的重置报文发送给通信的一方或双方,时个中止连接。

为了实验大略,我们可以利用本地打算机通过 localhost 与自己通信,然后对自己进行 TCP 重置攻击。
须要以下几个步骤:

在两个终端之间建立一个 TCP 连接。
编写一个能嗅探通信双方数据的攻击程序。
修正攻击程序,假造并发送重置报文。

下面正式开始实验。

建立 TCP 连接

可以利用 netcat 工具来建立 TCP 连接,这个工很多操作系统都预装了。
打开第一个终端窗口,运行以下命令:

$ nc -nvl 8000

这个命令会启动一个 TCP 做事,监听端口为 8000 。
接着再打开第二个终端窗口,运行以下命令:

$ nc 127.0.0.1 8000

该命令会考试测验与上面的做事建立连接,在个中一个窗口输入一些字符,就会通过 TCP 连接发送给另一个窗口并打印出来。

嗅探流量

编写一个攻击程序,利用 Python 网络库 scapy 来读取两个终端窗口之间交流的数据,并将其打印到终端上。
完全的代码参考 我的 GitHub 仓库 ,代码的核心是调用 scapy 的嗅探方法:

t = sniff( iface='lo0', lfilter=is_packet_tcp_client_to_server(localhost_ip, localhost_server_port, localhost_ip), prn=log_packet, count=50)

这段代码见告 scapy 在 lo0 网络接口上嗅探数据包,并记录所有 TCP 连接的详细信息。

iface : 见告 scapy 在 lo0 (localhost)网络接口上进行监听。
lfilter : 这是个过滤器,见告 scapy 忽略所有不属于指定的 TCP 连接(通信双方皆为 localhost ,且端口号为 8000 )的数据包。
prn : scapy 通过这个函数来操作所有符合 lfilter 规则的数据包。
上面的例子只是将数据包打印到终端,下文将会修正函数来假造重置报文。
count : scapy 函数返回之前须要嗅探的数据包数量。
发送假造的重置报文

下面开始修处死式,发送假造的 TCP 重置报文来进行 TCP 重置攻击。
根据上面的解读,只须要修正 prn 函数就行了,让其检讨数据包,提取必要参数,并利用这些参数来假造 TCP 重置报文并发送。

例如,假设该程序截获了一个从( src_ip , src_port )发往 ( dst_ip , dst_port )的报文段,该报文段的 ACK 标志位已置为 1,ACK 号为 100,000 。
攻击程序接下来要做的是:

由于假造的数据包是对截获的数据包的相应,以是假造数据包的源 IP/Port 该当是截获数据包的目的 IP/Port ,反之亦然。
将假造数据包的 RST 标志位置为 1,以表示这是一个重置报文。
将假造数据包的序列号设置为截获数据包的 ACK 号,由于这是发送方期望收到的下一个序列号。
调用 scapy 的 send 方法,将假造的数据包发送给截获数据包的发送方。

对付我的程序而言,只需将 这一行 取消注释,并注释这一行的上面一行,就可以全面攻击了。
按照步骤 1 的方法设置 TCP 连接,打开第三个窗口运行攻击程序,然后在 TCP 连接的个中一个终端输入一些字符串,你会创造 TCP 连接被中断了!

进一步实验可以连续利用攻击程序进行实验,将假造数据包的序列号加减 1 看看会发生什么,是不是确实须要和截获数据包的 ACK 号完备相同。
打开 Wireshark ,监听 lo0 网络接口,并利用过滤器 ip.src == 127.0.0.1 && ip.dst == 127.0.0.1 && tcp.port == 8000 来过滤无关数据。
你可以看到 TCP 连接的所有细节。
在连接上更快速地发送数据流,使攻击更难实行。

总的来说,TCP 重置攻击既深奥又大略,祝你实验顺利。

本站所发布的文字与图片素材为非商业目的改编或整理,版权归原作者所有,如侵权或涉及违法,请联系我们删除,如需转载请保留原文地址:http://www.baanla.com/ktwx/165189.html

XML地图 | 自定链接

Copyright 2005-20203 www.baidu.com 版权所有 | 琼ICP备2023011765号-4 | 统计代码

声明:本站所有内容均只可用于学习参考,信息与图片素材来源于互联网,如内容侵权与违规,请与本站联系,将在三个工作日内处理,联系邮箱:123456789@qq.com