为什么在Python中尝试TCP三次握手时系统会发送RST标志?

0 投票
1 回答
2916 浏览
提问于 2025-04-18 18:51

我想在我的Ubuntu上创建一个TCP三次握手。 我在虚拟机中使用了Kali Linux。在Kali Linux的终端(IP地址是172.16.28.130)中,我打开了一个“监听”模式的端口,以便与那台机器建立连接。

nc -l -p 1025

这是我在Ubuntu主机上运行的Python代码,

#!/usr/bin/python
from scapy.all import *
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

#if i send to broadcast address : 192.168.1.255 what will happen?
def sendPacket(src, dst):
   ip = IP(dst = dst)
   port = RandNum(1024, 65535)
   SYN = ip / TCP(sport=port, dport=1025, flags="S", seq = 42)
   SYNACK = sr1(SYN, verbose=0)

   ACK = ip / TCP(sport = SYNACK.dport, dport=80, flags="A", seq = SYNACK.ack, ack = SYNACK.seq + 1)
   send(ACK)

   print "Done!!\n"

src = '1.2.3.4'
dst = '172.16.28.130'
sendPacket(src, dst)

使用Wireshark捕获的数据包,

3      172.16.28.1   172.16.28.130   TCP   54   64865 > blackjack [SYN] Seq=0 Win=8192 Len=0

4      172.16.28.130   172.16.28.1   TCP   60   blackjack > 64865 [SYN, ACK] Seq=0 Ack=1 Win=29200 Len=0 MSS=1460

7      172.16.28.1   172.16.28.130   TCP   54   64865 > blackjack [RST] Seq=1 Win=0 Len=0

8      172.16.28.1   172.16.28.130   TCP   54   64865 > http [ACK] Seq=1 Ack=1 Win=8192 Len=0

9      172.16.28.130   172.16.28.1   TCP   60   http > 64865 [RST] Seq=1 Win=0 Len=0

在运行代码之前,我修改了IPtable,

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

当我把目标地址改为dst = "www.google.com",目标端口改为dport=80时,一切都正常。

但是现在, 1) 我可以发送SYN数据包 2) 目标系统回复了SYN和ACK数据包 3) 我的系统发送了RST 4) 我发送了ACK 5) 目标系统又回复了RST 所以我无法建立连接!! 问题: 1) 我该如何成功建立连接 2) 我的源IP是"1.2.3.4", * 但当我发送到虚拟机时,它显示的是172.16.28.1(广播IP)。这是为什么?

1 个回答

1

1) 我该如何成功建立连接

这里有个猜测。把你的 iptables 命令改成:

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

当你连接到 google.com 时,你是通过你的物理以太网设备连接的,这个设备的 IP 地址是 192.168.x.y,所以 -s 参数是匹配的。

而当你连接到 Kali 时,你是通过一个虚拟以太网设备连接的,它的地址是 172.16.x.y,所以 -s 就不匹配了。

你需要从正确的输出队列中丢弃 RST 数据包。

2) 我的源 IP 是 "1.2.3.4",但是当我发送到虚拟机时,它显示的是 172.16.28.1(广播 IP)。这是为什么呢?

首先,172.16.28.1 其实不是你的广播 IP。它是你主机上虚拟以太网设备的 IP 地址。

你的源 IP 没有出现的原因是因为你没有使用它:

ip = IP(dst = dst)

你指定了一个目的地址,但没有指定源地址。某个东西(可能是 scapy 或者主机操作系统的 IP 栈,我不太确定)为你选择了一个合理的源地址。你可以试试:

ip = IP(dst = dst, src = src)

看看会发生什么。

撰写回答