うさちゃんと一緒(7) TCPパケットをオウム返しでtelnet、Rabbit4000

Joseph Halfmoon

前回はUDPでしたが、今回はTCPのパケットをうさちゃん(Rabbit4000)にオウム返ししてもらいます。使うポートは23。telnetであります。Scapyも使ってみますが、TCPは3wayハンドシェイクしないといけないので本来の telnet コマンドにご登場願う、と。あれtelnetインストールしてなかった?

※「うさちゃんと一緒」投稿順indexはこちら

※Ethernetの通信の一方は、Raspberry Pi 3 model B+(Raspberry Pi OS機)上で、Scapy(Python上で任意のパケットを最下層から構築可能なモジュール)を使用して行っています。

※Ethernet通信のもう一方として、「最強のZ80後継機」Rabbit4000を使用しています。開発環境はDynamic C 10.72Eを使用しています。

今回Raspberry Pi 4 model B機からTCPパケットをうさちゃんに投げます。しかし、telnet 起動しようとしてRaspberry Pi OS上にインストールしてないことに気づきました。そだね、ssh でリモートログインすることはままあれど素の(暗号化されてない)telnetを使うことはもはやなかったです。今後は、うさちゃん相手の「練習」にtelnet使うことが多いと思うのでインストール

Rabbit4000側(対向機)のソフト

毎度のことながら今のところ自分で書く必要がありませぬ。DynamicC 10.72 の充実のサンプルプログラムの中から以下を選択しました。

ECHO.C

上記のソースの#define TCPCONFIG 行の後に前回同様うさちゃんの「静的」IPアドレスを記述追加するのみであります。

#define TCPCONFIG		1
#define _PRIMARY_STATIC_IP  "192.168.2.59"
#define _PRIMARY_NETMASK    "255.255.255.0"
#define MY_GATEWAY          "192.168.2.1"
#define MY_NAMESERVER       "192.168.2.1"

これにより、うさちゃんは、TCPパケットが到来すると

    • TCPパケットに積まれているペイロードを標準出力に表示
    • 到来したTCPパケットのソース、デスティネーションを交換して(ペイロードは同じまま)TCPパケットを送信

という「オウム返し」ECHO動作をすることになります。待ち受けるポートは23番。telnetが使っているウエルノウンポートです。

なお、TCPの場合 3WAYハンドシェイクとて SYN, ACK フラグの操作を行うパケットの交換が必要になりますが、その辺はうさちゃんのライブラリで始末してくれているみたい。

3Wayハンドシェイク考えずScapyでパケットを投げつけてみる

まずは、Scapyを使って何のハンドシェイクも無しにTCPパケットをうさちゃんに投げつけてみたいと思います。前回ハンドシェイク不要なUDP ECHOではこれで実験できました(その後問題あったケド。)でも今回は最初から問題出る筈。

Scapyで送った操作はこんな感じ。

data="ABCD"
pkt=IP(dst="192.168.2.59")/TCP(dport=23)/Raw(load=data)
ans,unans=sr(pkt)

念のため、組み立てたpktの中身を見てみます。指定していないところはScapyが勝手に補ってくれているもの。

pkt

上みると、デスティネーションはtelnetになっているのに、ソースはftp dataだと。その上、ハンドシェイクも無しにペイロード積んでしまっているし。まあボロボロなパケットであります。

上記を送信してみた結果が以下に。一応うさちゃんからはTCPハンドシェイクのお返事が返ってきているみたい。

ans

その時の様子を wireshark で観察したものが以下に。青色で選択状態にあるのが、Scapyから送った「トートツ」で「ボロボロ」なTCPパケット。灰色がうさちゃんの 3wayハンドシェイクの2番目になるはずの SYN, ACKパケット。そして不吉な赤色が、突然パケットを「返信」されたラズパイ4のftp dataポートが理解できないパケットにたいして、RSTと拒否っているもの。

wireshark000

そのようすを内部に踏み込んで観察すると以下です。最初のパケットにはSYNフラグ立ってました。しかしハンドシェイクのパケットにはありえないペイロードがのっちゃってます。というか載せたのは私か。

pkt7461

それに対してうさちゃんからのお返事が以下に。SYN、ACKとなっているのでハンドシェイクしようとしているのが分かります。この部分ではまだTCPパケットに対する「オウム返し」は発動せず、うさちゃんのファームの方でハンドシェイクを試みている状態のようです。

pkt7462

最後、ラズパイ4側が拒否っているパケットが以下に。Scapyからの最初の送信パケットで送り元がftp data(ポート20番)になっていたので、そちらに上記のSYN, ACKが届いてしまい「身に覚えのない」20番ポートが知らん、RSTだと。切断してるみたいです。

pkt7465

素のtelnet相手にオウム返し

ハンドシェイクをして通信を始めるのであれば うさちゃん上の「オウム返し」はそれらしく動作するみたいです。急遽ラズパイ4上にインストールした昔ながらのtelnetをつかってうさちゃんに接続してみます。

    • a と一文字入力すると(ローカルエコーがあるのでaと表示されます)
    • となりに a と返ってきます
    • bとうってもcとうっても同じ文字が返ってきます。

ECHOしてますね。

telnet

その様子を wireshark で観察したものが以下に。

wireshark001

最初にTCPのパケットが3つあるのが

    1. ラズパイ4からうさちゃんへのSYN
    2. うさちゃんからラズパイ4へのSYN、ACK
    3. ラズパイ4からうさちゃんへのACK

これで3Wayハンドシェークができたようです。その後TELNETのパケットがいくつもやりとりされていますが、これはTELNETの通信条件を双方でネゴしているみたいです。ただ、うさちゃんに今回書き込んであるソフトウエアは、相手から言われたものをそのままオウム返しにしているだけなのでまったく「理解」しておりません。でもなんとかなってしまうのね。。。

実際にラズパイ4からうさちゃんに最初の「a」が送られているパケットが以下です。

sendA

これに対するうさちゃんからの返信がこちら。送られた一文字「a」が送りかええされております。

rcvA

ちゃんとECHOしてますな。

なお、うさちゃん側のStdioを眺めたものが以下に。

途中、ABCDConnection closed…とある行の頭のABCDとある部分は、最初にScapyから送ったボロボロパケットに載っていたペイロードです。TCPのハンドシェーク上では問題なペイロードですが、ちゃんと届いてはいるようです。

また、下の方に黒四角や記号が並んでいるのはtelnetが通信条件などをネゴしているときに送られてきている数値じゃないかと思います。うさちゃん側の実験ソフト(私も)はtelnetのことなど分からないので画面に垂れ流し。その後に abc と書かれているところが、telnetからペイロードとして送られてきた文字ですな。

ま、うさちゃん側にはデータは正しく届いておる、と。

RabbitSTDIO

UDP、TCPとトランスポート層での実験はひとまずできたことにして、次回はもすこし上?大丈夫か?

うさちゃんと一緒(6) Scapyから送ったUDPパケットをオウム返し、Rabbit4000 へ戻る

うさちゃんと一緒(8) HTTP clientでNode-REDとお話、Rabbit4000 へ進む