使用Scapy的不需要的RST TCP数据包

use*_*093 22 python networking tcp scapy

为了了解TCP是如何工作的,我试图建立自己的TCP SYN/SYN-ACK/ACK(基于教程:http://www.thice.nl/creating-ack-get-packets-with-scapy/).

问题是,只要我的计算机从服务器接收到SYN-ACK,它就会生成一个停止连接过程的RST数据包.

我尝试了OS X Lion和Ubuntu 10.10 Maverick Meerkat,都重置了连接.我发现了这个:http://lkml.indiana.edu/hypermail/linux/net/0404.2/0021.html,我不知道是不是这个原因.

有谁能告诉我可能是什么原因?以及如何避免这个问题?

谢谢.

Mik*_*ton 27

你引用的文章很清楚......

由于您没有完成完整的TCP握手,您的操作系统可能会尝试控制并可以开始发送RST(重置)数据包,为避免这种情况,我们可以使用iptables:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.20 -j DROP
Run Code Online (Sandbox Code Playgroud)

本质上,问题是scapy在用户空间中运行,并且linux内核将首先接收SYN-ACK.内核将发送一个RST,因为在你有机会做任何事情之前,它不会在有问题的端口号上打开套接字scapy.

解决方案(正如博客所提到的)是防火墙内核发送RST数据包.

  • 有没有IPTables的解决方案?我真的无法在我的机器上更改iptables配置.除此之外,我还想从我的实现中发送RST(为测试目的创建自己的TCP流) (6认同)

Dav*_*zer 6

其他答案中引用的博客文章并不完全正确。这不仅是因为您没有完成三向握手,而是内核的 IP 堆栈不知道发生了连接。当它收到 时SYN-ACK,它会发送一个,RST-ACK因为它是意外的。接收第一个或最后一个真的不进入它。接收的堆栈SYN-ACK是问题。

使用 IPTables 丢弃出站RST数据包是一种常见且有效的方法,但有时您需要RST从 Scapy发送一个。一种更复杂但非常可行的方法是降低,使用不同于主机的 MAC 生成和响应 ARP。这使您能够在不受主机干扰的情况下发送和接收任何内容。

显然,这是更多的努力。就个人而言,RST当我真正需要自己发送一个时,我只采用这种方法(而不是丢弃方法)RST


小智 5

我没有非 iptables 的答案,但可以解决重置问题。与其尝试过滤过滤器表中的传出重置,不如过滤原始表中来自目标的所有传入数据包。这甚至可以防止来自目标的返回数据包被内核处理,尽管 scapy 仍然可以看到它们。我使用了以下语法:

iptables -t raw -A PREROUTING -p tcp --dport <source port I use for scapy traffic> -j DROP
Run Code Online (Sandbox Code Playgroud)

这个解决方案确实迫使我为我的流量使用相同的源端口;随意使用您自己的 iptables-fu 来识别目标的返回数据包。