假如TCP程序A和B之间存在TCP连接,并且它的源IP地址/端口和目的IP地址/端口都被攻击者知道,现在攻击者想要向A发送一个TCP Reset数据包来结束这个TCP连接。
现在,我们假设,对于 A,它的 TCP 堆栈刚刚发送了一个序列号为 1000、确认号为 5000 的 TCP Ack 数据包。
Reset报文上的序列号和确认号有什么要求吗?
如果Reset数据包使用seq: 5000 and ack:1000
,那么它一定会被A的TCP协议栈接受,从而在A上结束TCP连接。
以下组合怎么样?
1 seq: 5000, ack_seq: 0
2 seq: 5000, ack_seq: 999 ( this ack_seq is obsolete, namely <1000)
3 seq: 5000, ack_seq: 1002 ( this ack_seq is proactive, namely >1000)
4 seq: 5001, ack_seq: 1000 ( the seq is not consistent)
5 seq: 5001, ack_seq: 999 ( both seq and ack_seq are not consistent)
在我看来,1
终止连接就可以了吗?
答案1
在这种情况下,您已建立连接。这意味着组合 1 不起作用。
RFC793第 15 页对 ACK 编号进行了如下说明:
确认号:32位
如果设置了 ACK 控制位,则该字段包含该段发送方期望接收的下一个序列号的值。 一旦建立连接,就会发送此信息。
因此,您仍然需要随 RST 包发送 ACK 编号来终止连接。但这似乎也适用于未建立连接和已关闭的端口。如果您向已关闭的端口发送 SYN 数据包,则另一端将使用 RST、ACK 包进行响应。
您可以使用 wireshark 对此进行分析。
答案2
根据 RFC793 第 69 页,当一个段到达处于 LISTEN 以外状态的连接时,首先检查序列号是否落入接收方窗口内,如果不在,则将其丢弃。