TCP 中間変更と確認番号

TCP 中間変更と確認番号

個人的な目的のために、HTTPヘッダーに追加情報を追加する必要があります(これはHTTPサーバー側のアプリによって処理されます)。基本的な考え方は、受信したパケットを変更し、宛先に送信し、応答を気にしないことです。トラフィックパスの非常に単純化されたスキームは次のとおりです。

+---+       +------+        +---+
|   +<<-----o MDFY +<<------o   |
| R |       +------+        | S |
| C |                       | N |
| V |                       | D |
|   o--------------------->>+   |
+---+                       +---+

この問題は TCP SEQ/ACK 番号に関連しています。TCP ハンドシェイク後、送信側は 4 バイト長のパケットを送信し、これが Modifier に到達して長さが 22 に変更され、その後パケットが受信側に到達して ACK 番号 +23 を送信しますが、送信側は +5 を期待します。これにより送信側は混乱し、セッションが同期されなくなります。たとえば、テストのために netcat を試したときに、この現象が見られます。変更されていないパケットの場合、データ交換後すぐにセッションが閉じますが、変更されたパケットの場合、セッションは長時間無効になります (実際には、Ctrl + C を押して停止します)。

この状況に対処する簡単な方法は見当たりません。途中で変更されると、送信者はシーケンス番号の変更について何も知らず、自分の番号に頼るため、セッション全体を Modifier で処理する必要があるようです。これを行うと、すべてのセッションの状態を維持し、両側から来るすべてのパケットを変更して SEQ/ACK 番号を維持する必要があるため、パフォーマンスに大きな影響を与え、複雑さが増します。

独自の DPI を記述する以外に方法はないのでしょうか? :-) あらゆる知識、アイデア、提案をいただければ幸いです。

ありがとう。

答え1

私が見つけた唯一のより簡単なオプションは、透過プロキシを使用することです。

この場合、クライアントは宛先サーバーにリクエストを送信します。プロキシ サーバーはリクエストをキャプチャし、ヘッダーを追加して宛先サーバーへの別のリクエストを作成します。宛先サーバーはプロキシに応答を返し、プロキシはそれをクライアントに返します。

ここでの欠点は、サーバーがクライアントの元の IP アドレスではなく、プロキシの IP アドレスを認識することです。

次に、TCP レベルの MITM アプローチの場合、必要な機能を実装するツールキットが存在する可能性があり、完全な実装は必要ありません。

答え2

これは、ある種の中途半端な NAT のように見えます。問題は、まさにそれが中途半端であることです。

TCPパケットフローの片方向のみをMITMすることはできません。このような状況に対処するには、両方のフローを処理する必要があります(標準NATは通常、送信元と宛先のアドレス/ポートのみを考慮しますが、原理は同じです。転送中にパケットを改変し、この改変が両方のエンドポイントに対して透過的になるようにするには、すべて右)。

すべてを考慮し始めると、すぐに本格的な NAT が完成します。車輪の再発明は必要ありません。パケットを好きなように加工できる実装が数多くあります。

実際に利用可能なオプションは、もちろん、使用しているオペレーティング システムとルーティング/ファイアウォール ソフトウェアによって異なります。

関連情報