Scapy生成异常TCP序列号,无法发送RST包终止Telnet连接
构造TCP RST包终止Telnet连接失败问题
问题背景
我有3台通过私有NAT互联的VirtualBox(Ubuntu16)虚拟机,其中两台已建立Telnet连接,第三台可捕获二者间的数据包。尝试生成RST包终止该连接,但操作失败。
捕获到10.0.2.14发往10.0.2.16的数据包,其ACK=6,seq=3。据此尝试构造从10.0.2.16发往10.0.2.14的RST包,代码如下:
#!/usr/bin/python3 from scapy.all import * ip = IP(src="10.0.2.16", dst="10.0.2.14") tcp = TCP(sport=23, dport=37568, flags="R", seq=6, ack=3) pkt = ip/tcp ls(pkt) send(pkt, verbose=0)
Python3输出及Wireshark捕获结果显示,生成的RST包ACK正确但SEQ错误,推测这是无法终止连接的原因。
原因分析与解决方法
1. 序列号与ACK字段的正确性校验
TCP RST包生效的核心是字段必须严格匹配对端的连接状态:
seq字段:必须等于对端(10.0.2.14)期望你(10.0.2.16)发送的下一个序列号,也就是捕获到的对端包中的ACK值(即6),这部分你的配置是正确的。但要确保捕获的是对端发送的最新数据包,如果后续对端又发送了新包,需要更新seq为新的ACK值。ack字段:必须等于对端包的seq加上该包的数据长度(如果包中携带了数据)。比如如果对端包有2字节数据,ack应该是3+2=5,而非直接使用对端的seq=3。
2. 修复Scapy自动字段干扰
Scapy默认会自动填充TCP校验和等字段,手动设置字段可能导致计算错误。可以通过显式让Scapy重新计算校验和来解决:
#!/usr/bin/python3 from scapy.all import * ip = IP(src="10.0.2.16", dst="10.0.2.14") # 显式设置chksum=0,让Scapy自动计算正确校验和 tcp = TCP(sport=23, dport=37568, flags="R", seq=6, ack=3, chksum=0) pkt = ip/tcp # 强制重新生成数据包,确保所有字段计算正确 pkt = pkt.__class__(bytes(pkt)) ls(pkt) send(pkt, verbose=0)
3. 规避VirtualBox NAT的序列号修改
VirtualBox的NAT模式会修改TCP序列号用于地址转换,可能导致你捕获到的序列号与虚拟机实际使用的不一致。建议将三台虚拟机切换为内部网络模式或桥接模式,避免NAT对连接字段的干扰。
验证方式
发送RST包后,在10.0.2.14上执行命令查看连接状态:
netstat -anp | grep 37568
同时用Wireshark捕获10.0.2.14的网卡流量,确认它是否收到RST包并触发连接终止。
内容的提问来源于stack exchange,提问作者BiotieriaA
相关产品推荐
相关产品推荐

