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スタックによって処理される前に、サーバーの応答をユーザースペースにリダイレクトします。したがって、厄介なTCPRSTは生成されません。DivertSend()はパケットを挿入します。
これがWinDivertとWinPCAPの主な違いです。後者は単なるパケットスニファですが、前者はトラフィックを傍受/フィルタリング/ブロックできます。
WinDivertはCで記述されているため、独自の.NETラッパーを作成する必要があります。
(通常の開示:WinDivertは私のプロジェクトです)。
基本的に、問題はscapy
ユーザー空間で実行され、Windows カーネルが最初に SYN-ACK を受信することです。scapy で何かを行う前に、問題のポート番号でソケットが開いていないため、Windows カーネルは TCP RST を送信します。
(Linuxでの)典型的な解決策は、スクリプトの実行中にカーネルがそのTCPポート(12456)でRSTパケットを受信しないようにファイアウォールを設定することです...問題は、Windowsファイアウォールがこれほど細かくすることを許可していないと思うことです(つまり、TCP フラグを調べて) パケット ドロップを調べます。
おそらく最も簡単な解決策は、Linux VM でこれを行いiptables
、RST ドロップを実装するために使用することです。
独自の TCP-over-IP-over-Ethernet パケットを作成してサーバーに送信するのではなく、Boring Old Winsock を使用してサーバーへの TCP 接続を確立するか、Windows インターネット プロトコル スタックに SYN を無視するよう説得するサーバーから取得した +ACK (および後続のすべてのパケット)。サーバーからの SYN+ACK が表示されないようにします。192.168.1.3:12456 から 192.168 への TCP 接続をセットアップしようとするプロセスがないことに注意してください。 1.1:80 を標準のカーネル内ネットワーク スタックを使用して (つまり、Boring Old Winsock を使用してセットアップしようとした人は誰もいません)、RST を返信して、マシンのポート 12456 でリッスンしている人がいないことをサーバーに伝えます。
WinDivertを使用して後者を実行できる場合があります。それ自体には .NET ラッパーがないように見えるため、退屈な古いアンマネージド C や退屈な古いアンマネージド C++ ではなく .NET を使用する場合は、ラッパーを探す必要があるかもしれません。