6

我正在尝试使用 Pcap.Net 打开一个 tcp 连接。

我正在发送以下包裹:

同步包

服务器响应:

同步确认

之后,Windows 会自行发送重置数据包:

RST

为什么会发生这种情况,如何阻止这种行为?

我在 Windows 7 上这样做

4

3 回答 3

7

正如哈里斯先生所说,你可以使用WinDivert来做你想做的事。例如,只是进行 TCP 握手,您可以编写如下内容:

// TCP handshake using WinDivert:
HANDLE handle = DivertOpen("inbound && tcp.SrcPort == 80 && tcp.Syn && tcp.Ack", 0, 0, 0);
DivertSend(handle, synPacket, sizeof(synPacket), dstAddr, NULL);
...
DivertRecv(handle, synAckPacket, sizeof(synAckPacket), &srcAddr, &length);
...
DivertSend(handle, ackPacket, sizeof(ackPacket), dstAddr, NULL);
...

DivertRecv() 函数将服务器响应重定向到用户空间,然后由 Windows TCP/IP 堆栈处理。所以不会产生讨厌的 TCP RST。DivertSend() 注入数据包。

这是 WinDivert 和 WinPCAP 之间的主要区别。后者只是一个数据包嗅探器,而前者可以拦截/过滤/阻止流量。

WinDivert 是用 C 语言编写的,因此您需要编写自己的 .NET 包装器。

(通常披露:WinDivert 是我的项目)。

于 2012-10-30T08:31:12.430 回答
4

本质上,问题是scapy在用户空间运行,windows内核会先收到SYN-ACK。您的 Windows 内核将发送 TCP RST,因为在您有机会对 scapy 执行任何操作之前,它不会在相关端口号上打开套接字。

典型的解决方案(在 linux 中)是在运行脚本时阻止内核在该 TCP 端口(12456)上接收 RST 数据包...问题是我认为 Windows 防火墙不允许您如此精细(即查看 TCP 标志)是否有丢包。

也许最简单的解决方案是在 linux VM 下执行此操作并用于iptables实现 RST drop。

于 2012-10-22T12:42:44.797 回答
2

通过使用 Boring Old Winsock 与服务器建立 TCP 连接,而不是构建您自己的 TCP-over-IP-over-Ethernet 数据包并将它们发送到服务器,或者以某种方式说服 Windows Internet 协议栈忽略 SYN +ACK(以及所有后续数据包)从服务器获得,因此它看不到来自服务器的 SYN+ACK,请注意没有进程尝试建立从 192.168.1.3:12456 到 192.168 的 TCP 连接。 1.1:80 使用标准的内核内网络堆栈(即,没有人尝试使用 Boring Old Winsock 设置它),并返回一个 RST 告诉服务器在机器上的端口 12456 上没有人在监听。

您也许可以使用WinDivert来完成后者。它本身似乎没有 .NET 包装器,因此如果您要使用 .NET 而不是 Boring Old Unmanaged C 或 Boring Old Unmanaged C++,您可能需要寻找一个。

于 2012-10-22T09:34:20.047 回答