我试图使用Pcap.Net打开一个TCP连接。
我正在发送以下包:
服务器正在响应:
之后,Windows自己发送重置数据包:
为什么会发生这种情况,我该如何阻止这种行为?
我在Windows 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是我的项目)。
本质上,问题是scapy
在用户空间中运行,而windows内核将首先收到SYN-ACK。 你的Windows内核将发送一个TCP RST,因为在你有机会用scapy做任何事情之前,它没有在有问题的端口号上打开一个套接字。
典型的解决方案(在Linux中)是在运行脚本时防止内核在TCP端口(12456)上接收RST数据包…问题是,我不认为Windows防火墙允许你成为这种粒度(即查看TCP标志)丢包。
也许最简单的解决方案是在linux虚拟机下执行此操作,并使用iptables
来实现RST丢弃。
通过使用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 ++,你可能需要寻找一个。