0

低レベルのネットワークは非常に興味深いものだと常々思っていたので、生のソケットの使用について自分自身を教育してきました。ここでの目標は、未加工のソケットを使用して TCP を完全に再実装することではなく、自分で (カーネルをバイパスして) 3way ハンドシェイクを行う方法を学ぶことです。

私の例では、ユーザー提供の送信元アドレスと宛先アドレスを含む IP ヘッダーを作成し、プロトコルに TCP を入力し、任意の 16 ビット ID を作成し、バージョンを 4、長さを 5、およびフラグを設定する小さなプログラムを作成しました。 2 に (フラグメント化しないでください)。IP ヘッダーは、それが作成するすべてのパケットに対してこれを行います (実際、アドレスと ident を除いて、既知の正常な TCP SYN パケットとすべて同じビットを持っています)。次に、ユーザーが指定したポート、ランダムなシーケンス番号、0 ACK、オフセット 5 (オプションを除く)、フラグ 2 (SYN)、および任意のウィンドウ サイズ (私は 32792 を使用しています) を使用して TCP ヘッダーを作成します。おそらくそのうちの 1 つが私の努力を妨害しているのではないかと期待して、さまざまな程度の TCP オプションを試してみました。

このプログラムは Python で書かれており、アドレス ファミリ AF_INET の raw ソケットとプロトコル IPPROTO_RAW を使用しています (ただし、IPPROTO_TCP も試しました)。そこで、wireshark を起動し、TCP 接続を待機しているユーザー アプリケーションに SYN を送信しました。Wireshark は SYN を表示し、パケットに関連するエラーを表示しませんが、それで話は終わりです... SYN/ACK も RST も何もありません。syslog にエラーはなく、ユーザー アプリケーションには何も表示されず、iptables のチェックにより、ファイアウォール ルールがないことが確認されました。これまでのすべてのテストはすべて同じアドレス「127.0.0.1」で行われており、これらの最初の応答で偽装されたのは送信元ポートだけであることに注意してください。これを slackware 14.0 (VM で実行) でテストしてきました。

奇妙な部分は、クライアント ユーザー アプリケーション (つまり、私が対象としていた単純なサーバーへのクライアント) を起動し、tcp ソケット経由で接続すると、パケットと数バイトだけ異なる初期 SYN が表示されることです: tcp.s_port, tcp.チェックサム、ip.checksum、ip.identification。それでもすぐに、サーバーはクライアントの SYN に SYN/ACK で応答します。手作りのパケットがどこに落ちているのか、一生わかりません。これをデバッグするために、TCP タイムスタンプとウィンドウ サイズをオフにしました。誰かが私を妨げているかもしれないものに光を当てることができますか

更新 コードはここにあります: http://pastebin.com/2aHWYGxb#
TCP チェックサム計算についてもう少し読んで、これに出くわしました: http://www.tcpipguide.com/free/t_TCPChecksumCalculationandtheTCPPseudoHeader-2.htm
を説明します今まで見たことのない方法ですが、今はこのようになっているのではないでしょうか? 確かではありませんが、私は今それに取り組んでいます。

上記の記事に従い、疑似ヘッダー、tcp ヘッダー (チェックサムに 0 を使用) で計算されるチェックサム関数を再実装し、ペイロードに改善は見られません。変更されたコードは、pastebin のリンク
にあります。

さらに調べてみると、チェックサム関数を半分ではなくバイトで操作していて、シフト操作を忘れていたことがわかりました。今はすべて機能しています。助けてくれた人に感謝します。

4

0 に答える 0