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

时间:2012-01-30 00:15:17

标签: 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,我不知道是不是这个原因。

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

谢谢。

3 个答案:

答案 0 :(得分:25)

你引用的文章非常清楚......

  

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

iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.20 -j DROP

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

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

答案 1 :(得分:4)

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

iptables -t raw -A PREROUTING -p tcp --dport <source port I use for scapy traffic> -j DROP

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

答案 2 :(得分:4)

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

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

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