26-Feb-2024
[これがバッファオーバーフローなんだろうか]

諸事情によりD-STAR界隈とは一切関わりたくないと思っているのですが、流石にこれは放置できない話なので日記の記事としてまとめます。

レピータ管理団体及び JARL・D-STAR委員会等が提供しているプログラム以外を接続されているユーザー の皆様へにある、以下の記述。

生存確認の要求側のパケットの例
07:46:45.668636 IP xx.x.x.xxx.60005 > xxx.xxx.xxx.xxx.50100: UDP, length 10
0x0000: 4500 0026 0fee 4000 4011 66d3 xxxx xxxx     E..&..@.@.f.....
0x0010: xxxx xxxx ea65 c3b4 0012 c429 4453 5452     .....e.....)DSTR
0x0020: 0000 7312 0000                   ..s...

に対する応答パケットが、本来であれば上記の要求に対しては赤字で示したマジックナンバーが
仕様書で示された手順(パケット毎に異なる任意の数値で、ゾーンレピータとGWとの通信で送られた
パケットの識別として使われ、この数値を返送して届いたことを認識する。)に準拠していない例です。(実際の返答パケットです。)
07:46:45.723745 IP xxx.xxx.xxx.xxx.50100 > xx.x.x.xxx.60005: UDP, length 10
0x0000: 4500 0026 888f 0000 3e11 3032 xxxx xxxx     E..&....>.02....
0x0010: xxxx xxxx c3b4 ea65 0012 825a 4453 5452     .......e...ZDSTR
0x0020: 0097 7212 0000 0000 0000 0000 0000        ..r...........

この応答例では、仕様書によれば0000を返す必要があるのですが、0097を返しています。
この値が仕様書に準拠していないため、届いた確認が取れず、次の処理に進めません。
このため、全てのxchangeの転送が出来ないことになります。また、この応答例では、これ以外にも
問題があり、本来10バイトで返答しているにもかかわらず。18バイト送ってきています。
(最後に赤で示した8バイトです。)
この手法は、バッファオーバーフローと呼ばれる典型的なハッキングの手法の
一つです。

0097の値に関しては知りませんが、クラッキングでもバッファオーバーフローでもないです。

というだけの話。ここから後は長いので、お急ぎなら話のキモとなるrunt packetをgoogleとかで調べておけば十分。

データ長に問題がないことはIPヘッダ及びUDPヘッダを読めば明白で、生存確認の要求側のマシン上でtcpdumpを実行すればこのような結果になるのも当然。証拠?コードを書かずとも、システムに含まれるコマンドだけで確認可能。

マシンを二台…ここではemeraude(192.168.0.141, Linux)とframboise(192.168.0.144, OpenBSD)を用意して、emeraude上でtcpdumpを動かしてログを取るとこんな感じ。

root@emeraude:/home/uaa# tcpdump -XX -i br0 \(udp\) and \(port 1234\)
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
09:06:55.048855 IP 192.168.0.144.2003 > 192.168.0.141.1234: UDP, length 4
        0x0000:  9673 a468 f7ff 00e0 4c66 0532 0800 4500  .s.h....Lf.2..E.
        0x0010:  0020 1cd7 0000 4011 db88 c0a8 0090 c0a8  ......@.........
        0x0020:  008d 07d3 04d2 000c ae57 6161 610a 0000  .........Waaa...
        0x0030:  0000 0000 0000 0000 0000 0000            ............
09:06:59.786391 IP 192.168.0.141.34123 > 192.168.0.144.1234: UDP, length 4
        0x0000:  00e0 4c66 0532 9673 a468 f7ff 0800 4500  ..Lf.2.s.h....E.
        0x0010:  0020 3ed7 4000 4011 7988 c0a8 008d c0a8  ..>.@.@.y.......
        0x0020:  0090 854b 04d2 000c 828b 6262 620a       ...K......bbb.

一つ目のパケットはframboiseからecho aaa | nc -u 192.168.0.141 1234でemeraudeへ送られてきたもの、二つ目はemeraudeからecho bbb | nc -u 192.168.0.144 1234でframboiseに送ったもの。

一つ目のパケットが適当そうなので分解してみると、

6+6+2+32+14=60byteで、これにFCSの4byteが付加されて合計64byte。詳細はWikipediaのイーサネットフレームの項などを参照。そして14byteのpaddingがあるにも関わらずtcpdumpの表示では"UDP, length 4"となっている点にも御注目。echo aaaないしecho bbbで3文字送っていても改行コードが付くので4byte、これは意図した通り。

生存確認の要求側のパケットの例がどのようなtcpdumpのオプションなりネットワークインタフェースなりを使ってログを取ったのかはこちらでは不明…悪意を持って伏せている可能性もありそう。何であれ、知識と経験が豊富なOM達が集うD-STAR委員会が、Ethernet上を流れる小さなIPパケットをダンプしてバッファオーバーフローと呼ばれる典型的なハッキングの手法と言うのであれば何を根拠としてそう判断したのか是非とも示して頂きたいところ。研鑽に努めよと言い放つなら、尚更。

これに加え、rpi-xchange(rpi-GW)およびxchange(CentOS)への不適切アクセスでも「意図的に行っているとは思いませんが、このアクセス方法は、典型的なハッキングの手法のバッファーオーバーフローですので、至急修正して頂くようお願いします。」という文言も引っかかる。runt packet避けの、デバイスドライバやコントローラにおける意図的な処理…例えばLinux用RTL8139のドライバ、8139too.cでのpaddingをEthernetの仕様に反してでも外せ、というのだろうか?

(おまけ)

framboise# tcpdump -XX -i re0 udp and \(port 1234\)
tcpdump: listening on re0, link-type EN10MB
09:06:55.046650 192.168.0.144.2003 > 192.168.0.141.1234: udp 4
  0000: 4500 0020 1cd7 0000 4011 0000 c0a8 0090  E.. ....@.......
  0010: c0a8 008d 07d3 04d2 000c 828b 6161 610a  ............aaa.

09:06:59.784278 192.168.0.141.34123 > 192.168.0.144.1234: udp 4 (DF)
  0000: 4500 0020 3ed7 4000 4011 7988 c0a8 008d  E.. >.@.@.y.....
  0010: c0a8 0090 854b 04d2 000c 2ede 6262 620a  .....K......bbb.
  0020: 0000 0000 0000 0000 0000 0000 0000       ..............

emeraudeだけでなくframboiseでも同時にtcpdumpを動かしてみたのですが、OpenBSDのtcpdumpって-XX非対応なんですかね…-Xと等価な動きになっています。あと、SLIP接続すれば当然ですがpaddingは無いです。MAC addressも無いですけど。

root@slackware-vm2:/home/uaa# tcpdump -XX -i sl0 \(udp\) and \(port 1234\)
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on sl0, link-type RAW (Raw IP), snapshot length 262144 bytes
12:45:07.140325 IP 192.168.200.1.4424 > 192.168.200.2.1234: UDP, length 4
        0x0000:  4500 0020 05de 0000 4011 639a c0a8 c801  E.......@.c.....
        0x0010:  c0a8 c802 1148 04d2 000c 15fb 6161 610a  .....H......aaa.
12:45:16.826180 IP 192.168.200.2.54082 > 192.168.200.1.1234: UDP, length 4
        0x0000:  4500 0020 df1d 4000 4011 4a5a c0a8 c802  E.....@.@.JZ....
        0x0010:  c0a8 c801 d342 04d2 000c 51ff 6262 620a  .....B....Q.bbb.
framboise# tcpdump -XX -i tun0 \(udp\) and \(port 1234\)
tcpdump: listening on tun0, link-type LOOP
12:45:00.394831 192.168.200.1.4424 > 192.168.200.2.1234: udp 4
  0000: 4500 0020 05de 0000 4011 639a c0a8 c801  E.. ....@.c.....
  0010: c0a8 c802 1148 04d2 000c 15fb 6161 610a  .....H......aaa.

12:45:10.092035 192.168.200.2.54082 > 192.168.200.1.1234: udp 4 (DF)
  0000: 4500 0020 df1d 4000 4011 4a5a c0a8 c802  E.. ..@.@.JZ....
  0010: c0a8 c801 d342 04d2 000c 51ff 6262 620a  .....B....Q.bbb.

シリアルポートを使用する都合上、emeraudeの代わりにOpenBox上のLinux仮想マシンを使ってしまいましたがこれは問題にならないでしょう。SLIPはLinux側は標準のslattach、OpenBSD側は拙作のsliptunで構成しています。56.1kg(14:55)

25-Feb-2024
[組み替えました]

02-Jun-2022で触れた、居間においてあるLinux機のお話。外付けのNICを取り払ってしばらくの間はオンボードのNIC(Realtek)を使っていましたが、その後BROADCOMの石が載った外付けNICを入れて使っていました。ところが最近、このマシンにSSHログインできない→BROADCOMのNICが死んだか?→オンボードのRealtekが認識されてませんね(※)、という事態があったためマシンを組み替えることにしました。

(※)このためにenp5s0として認識されていたBROADCOMのNICがenp4s0となってしまい、enp5s0向けに書いたネットワークブリッジの設定と齟齬を起こしてBROADCOMのポートで通信ができなくなります。ネットワークブリッジの使用を止めるか、UEFI setupでオンボードのRealtekを無効化してBROADCOMをenp4s0とすることで回避はできるのですが…何か気分的にやだなーって。マシンの組み替えのきっかけって、結構ふわっとした理由だったりしますよね。

流石にDDR3世代のAMDで組み直すのも…しかしIntelへ移行するにも…どちらにせよマザーボードの入手性とお値段がなあ…とオークションを覗いてみたら面白そうなマザーボード、それも未使用品が悪くないお値段で売られていたので衝動買いです。Core i3-4130も中古で買って(本当は適当なi5にしようかと思ったのですがi5-4690の件で懲りたのでi3です)、昔使っていた部品もかき集めてこんな感じ。

rouge (PC/AT)

MainboardMiTAC PH10LU (Intel Q87 chipset)
CPUIntel Core i3-4130 (at 3.4GHz)
MemoryKLLISRE KHX1866C10D3/8G (PC3-14900 DDR3 SDRAM 8GB, CL11, 1.5V) x2
VGA(unknown) Radeon M209A (AMD RADEON HD 7570, 1GB, PCIe)
NIC(unknown) BROADCOM BCM5721 (10BASE-T/100BASE-TX/1000BASE-T, PCIe)
SSDCrucial CT512MX100SSD1 (512GB, SATA3)
ODDLITEON iHAS524 (CD-R/CD-RW/CD-ROM/DVD+-R/DVD+-R DL/DVD+-RW/DVD-RAM/DVD-ROM, SATA)
OSDebian 12

PH10LU、産業用ならその辺のより頑丈そうだし長持ちするのかなーという、そんな理由です。シリアルポートは4つ(ただし2ポート分は別売りのブラケットが必要)、LANポートを2つ装備していますのでPentium G4600なOpenBSD機と入れ替えたくなってしまいますがこれは我慢。SSDは長期間使用したという理由で外していたものを持ってきているので、多分そのうち壊れるかも。

こんなマシンでもDebianをインストールして動かしてみるとなかなか良い速度で動いてくれますね。Sandy Bridgeおじさんが「まだ戦える!」と言うのも頷けます。55.6kg(21:15)

18-Feb-2024
[解せぬ…]

20240218.png

sj3のbufferモードでの一文字消去、sttyのeraseに設定されている内容を見るので^H(BS, 0x08)が設定されている場合はそれを入力する必要があります。ktermの場合はCtrl-HとBackspace共にBSを返してくるのでまっとうな動作になるのですが、xtermやmltermの場合はCtrl-HはともかくBackspaceは^?(DEL, 0x7f)を返すため、一文字消去を行おうとすると確定してしまい「んあっ?!」となります。

この目的のためだけに.bashrcに書いたstty erase ^Hを^?に変えるのもなんか嫌だなあということでこんな修正を入れてはみたものの、何故か「あいこうぐんあいかわまち」とはならずに「あい こう んあい 」と…子音を入力する箇所でブツ切りにされてしまう現象が発生するようになってしまいました。こんな動作になる理由が全く分からず、困惑しています。

コードを追加するのではなくsttyの設定を適切に行うにしても、stty erase ^Hが正しいのかstty erase ^?が正しいのかは判断がつきません。とりあえず、手近な環境でデフォルトの設定を調べてみるに…

Slackware-15.0, Debian-12.5, Vine-2.5, NetBSD-10.0-RC3, OpenBSD-current
erase = ^?
FreeBSD-14.0, DragonFlyBSD-6.4, OmniOS-r151048
erase = ^?; erase2 = ^h

erase2はともかく、stty erase ^Hの設定は今の時代に相応しくなさそうです。何故このようなものを.bashrcに入れたのかは随分昔のことなのでよく分からないのですが、おそらくBackspaceで(DELではなく)BSを返してくるktermへの対策なのではないかと想像します。違っていたとしても、The Linux keyboard and console HOWTO5.11 A better solution for Motif-using programs, like netscapeではstty erase ^Hが対策法と書かれている以上、何らかの理由はあったはず。

OpenBSDのmgはsttyの設定は参照せずDEL/BSを決め打ちにするコードになっていますから、stty erase ^?とする(デフォルトがこれなので、実際はstty erase ^Hをコメントアウトする)のが適切そうです。という訳で早速.bashrcの設定を修正し、様子を見てみることにします。55.8kg(22:20)

11-Feb-2024
[津波警報に対し「東日本大震災を思い出してください!」と言うのであれば]

「非常事態宣言があったことを思い出してください!」「三密回避を思い出してください!」「ソーシャルディスタンスを思い出してください!」程度のことは言って然るべきなのではないか…と、現状のCOVID-19/インフルエンザの流行を見て思うのであります。

まあ、スーパーマーケットで買い物をしているとあの頃そんなことがあったことなんて完全に忘れて皆様行動していますなーという感じなので、この程度は流行しても構わないというのがウィズコロナというやつなのでしょう。せめてソーシャルディスタンスくらいは今でもきちんと守れよと思いますけど。

…という話を書きたくなるくらいには、sj3に関する進捗は何一つありません。他の件もあってコードいじりどころじゃないという状況でもありまして。抱えている問題も感染症の流行も、そのうち終息すると良いんですけど。56.2kg(22:10)

04-Feb-2024
[頭を抱えることが多すぎます]

sj3(tty client)、Bufferモードでかな漢字変換の候補となるかな文字の入力を行っている際に、カーソルキー+BackspaceないしCtrl-Hを押した際の挙動が変な気がするので動きを追っているところです。原典(sj3-2.0.1.20)の時点からこうなっているようだ、というのがなんとも理解に苦しむのですが(売り物のワークステーションに搭載されていたソフトウェアだったので相応の品質があるはずなのに…?)。

不思議な挙動に加えて、擬似端末(pty)を使ったコードのデバッグをどうやるのかという問題もあります。gdbへ落とすにも、printf()で画面に表示させるにも、画面がぐちゃぐちゃになるので何が何やら…まあ誰もがこんな感じのコードを書くだろうというのを作って、シリアルポートに情報を吐かせるのを試しているところです。

とはいえ、sj3が動いているVirtualBox上の仮想マシン、どうもシリアルポートの動作が怪しい感じです。確実にこうだと言えるものは掴んでいないのですが、ボーレートの設定がうまくいかない、送信FIFOが詰まる、そんな感じの挙動に見えるような事象がありました。16450のエミュレーション+ボーレート低め(19200bps以下)なら回避できていそうなので、しばらくこの設定で使ってみることにします。

現在動作中のM17リフレクタ(mrefd)がv0.3.6とあまりにも古いので、これを現状の0.11.3に上げたいところなのですが当時と今とでだいぶ変わっているので戸惑っています。

OpenDHTなるDistributed Hash Tableネットワーク(BitTorrentで使用されている、ピアを探すための情報を保持するものとでも言えば良いのでしょうか?)ライブラリがoptional, but highly recommended…という割にPlease note that there is no easy way to uninstall OpenDHT once it's been installed.などと恐ろしいことがさらっと書かれていたりしますが、折角mrefdを入れ直すならDHTへの対応も試してみたいなと。DHT抜きでも動くっちゃ動くんですけど。

で、OpenDHTのビルドを試みたもののmsgpack-c++がOpenBSDのportsには無いので、まずはここから何とかしないといけないなーというところで手が止まっています。portsを作る練習としてC向けのmsgpack-cを5.0.0→6.0.0に上げようとしたら、msgpackc→msgpack-cの名称変更によりあちこちのportsへの影響が生じてしまいそれを直す必要も発生したという、ヤクの毛刈りになっております。

果たしてこんな調子で、物事が進むのでしょうか…55.7kg(22:40)