セキュリティ
32年前のバグがTelnetサーバーに侵入
A 32-Year-Old Bug Walks into a Telnet Server (labs.watchtowr.com)
要約
GNU inetutilsのTelnetdに存在する、1994年(32年前)に発見されたバッファオーバーフローの脆弱性CVE-2026-32746について解説しています。この脆弱性はLINEMODE SLCネゴシエーションハンドラに存在し、認証なしでリモートからのコード実行を可能にする可能性があります。多くのLinuxディストリビューションを含む広範なシステムに影響を与え、2005年には同様の脆弱性がクライアント側でも発見されていました。
全文翻訳
はるか昔、バイナリ脆弱性緩和策がなく、Unixがまだ地球を闊歩していた時代に、認証前のTelnetd脆弱性が存在しました。この脆弱性はあまりにも古く(1994年まで遡る)、あなたよりも古いかもしれません。その時代を比較のために言うと、記念碑的な映画『ハッカーズ』が公開されたのと同じ年に誕生しました。RISCがまだ遠い夢だった時代です。考えてみれば、ゼロクール自身が生み出した産物だったのかもしれません?
いずれにせよ。最近、この脆弱性は無残に終焉を迎えました。
これは何を見ているのか?
Telnetに慣れていないとしても、問題ありません。Telnetは、TCP/IPを介してリモートサーバーと通信するためのコマンドラインインターフェースを提供するネットワークプロトコルです。言い換えれば、サービスとしてのリモートコード実行です。典型的なセットアップには認証の壁があり、システムシェルにアクセスする前にログインが必要になります。また、プレーンテキストで動作するため、ネットワーク経由でユーザー名とパスワードが平文で送信されます。現代ではSSHが事実上の代替手段となっており、Telnetはますます一般的でなくなっています。
CVE-2026-32746とは?
DREAM Security Research Teamによって発見されたCVE-2026-32746は、攻撃者が約400バイトの隣接する変数を破損できるBSSベースのバッファオーバーフローです。これはLINEMODE SLC(Set Linemode Characters)ネゴシエーションハンドラに存在します。厳密にはGNU inetutilsのみに影響しますが、多くのベンダーがTelnetdの実装を同じコードに基づいており、影響範囲は広大で推定が困難です。これには、すべての主要なLinuxディストリビューション(確認済み)が含まれます。
このような脆弱性があるにもかかわらず、インターネットが興奮で爆発するとは予想していませんでした。しかし、良い分析がないまま1週間近くが経過しました。私たちが到達したところを公開するのが良いと考えました。
いくつかを取り上げます。脆弱性をどのように特定したか、攻撃者が(どのような状況下で)何ができるようになるか、そしてこの特定の脆弱性が、あなたが考えるよりもエクスプロイトにとってパンドラの箱である理由について話します。
しかし、まず明白な質問から始めましょう。それは、レガシーテクノロジーが存在しない魔法のユニコーンの国に住むすべての人々の唇にあるはずです。なぜそもそもTelnetを使うのか?!
何が影響を受けるのか?
これは難しい問題です。パッチはinetutils-telnetdに適用されましたが、多くのフォークが存在し、長年にわたって変更が加えられ、この脆弱性がシステムからシステムへとコピー&ペーストされています。
少なくとも以下のシステムでこのCVEを特定しました。
inetutils-telnetd自体
Ubuntu
Debian
FreeBSD 13 / FreeBSD 15 Port
NetBSD 10.1
Citrix NetScaler
Apple Mac Tahoe
Haiku
TrueNAS Core
uCLinux
libmtev
DragonFlyBSD
2026年ですが、なぜTelnet?MCPはどこに?
Telnetは古くから存在します。皆さんの多くは画面に向かって叫んでいるでしょう。「そんなに安全でないプロトコルを誰が使うんだ?!」
驚くかもしれませんが、古参のTelnetは、驚くほど多様な理由で、本番システムにまだ非常に多く存在しています。ベンダーがサポートしているのがそれだけかもしれません(「このCNCマシンは、壊れたら1分あたりX千ドルのダウンタイムが発生します。そして、あなたは…何を追加したいのですか?!SSHクライアント?!おい、それは8ビットマイクロコントローラで動作するんだ!」)。移行が技術的に不可能な深い理由があるのかもしれません。
事実はこうです。主要なディストリビューションのすべてのリポジトリに強く存在していることが証拠です。真に時の試練に耐えました。
Telnetに脆弱性がある?!TelnetはNetcatと同じようなものではないのか?
読者の中には、Telnetがプロトコルレベルでは単なるTCPストリームに過ぎないと誤解している人もいるかもしれません。実際、一部の実装はその通りです。TCPソケットがシェルに接続されています。シンプルで、壊すのは不可能(?)です。
しかし、そうではありません。Telnetはさまざまな機能をサポートしています。ターミナル制御(エコーをオンにしたい?オフにしたい?)、クライアントウィンドウサイズのネゴシエーション、認証、さらには暗号化です。これらのすべての機能にわたってエンタープライズセキュリティを維持する責任を負っている、哀れな魂がどこかにいると確信しています。
誰もが知っているように、「機能が多い」ということは「攻撃対象領域が多い」ということです。CVE-2020-24061を覚えていますか?そのバグでは、サーバーと環境変数を共有することを意図したTelnetプロトコルの機能がRCEに悪用される可能性がありました。非常に痛いバグで、今日の脆弱性ほど広範囲ではありませんでしたが、エクスプロイトはかなり容易でした。
この特定の脆弱性は、Telnetプロトコルの「LINEMODE」機能に存在します。RFC 1184によると:ローカル側で編集が有効になっているLinemodeでは、ネットワークトラフィックは、入力された文字ごとのパケット数ではなく、コマンドラインごとのパケット数に削減されます。これは、ユーザーがコマンドラインを入力している間はローカルで応答が得られ、コマンドが入力された後にのみネットワーク遅延が発生するため、長遅延ネットワークに非常に役立ちます。また、パケットごとに課金されるネットワークのコストを削減するのにも役立ちます…
はい、脆弱性は非常に古く、ネットワークが「パケット単位で課金されていた」時代にまで遡ります。
機能自体の詳細が私たちにとってそれほど重要ではありません(私たちの優先事項は単に「すべてをハックする」ことです)。しかし、脆弱なコードに到達するには、それを有効にする方法を知る必要があります。つまり、Telnetが接続パラメータをどのようにネゴシエートするかを少し学ぶ必要があるということです。
緊迫した交渉
相互運用性のために、Telnetクライアントとサーバーはデフォルトでこれらの高度なオプションを有効にしません。接続が最初に確立されると、IAC、つまり「Interpret As Command」バイト(16進数で0xFF)を介して、インバンドシグナリングが行われます(ほほほ、それがうまくいったのはいつでしたか?)。
ローカルエコーやテレタイプライターの速度(覚えていますか?私たちは覚えていません)など、交渉できることはたくさんあります。しかし、前述したように、私たちが関心のある機能は「LINEMODE」オプションです。
この機能によって定義されているSLC(または「Set Linemode Characters」)というものは、特に興味深いです。これにより、サーバーはクライアントと通信し、「バックスペース」のような新技術の特定の特殊文字が特定の制御コードで表されるべきであることをクライアントに通知できます。
少し焦点を絞るために、仮説的なネゴシエーションを見てみましょう。まず、TCP経由でTelnetサーバーに接続します。サーバーはすぐに次のデータを送信します。
IAC DO LINEMODE(または16進数で0xFF 0xFD 0x22)
ここで、「DO」はサーバーが機能性を要求していることを示しています。それを有効にするために、クライアントは「WILL」で応答します。
IAC WILL LINEMODE(0xFF 0xFB 0x22)
それが完了すると、サーバーは3バイトのトリプレットのリストを送信します。各トリプレットは、置換される特殊文字、サポートレベル、および実際の文字値を示します。クライアントはそれを見て、いずれかを変更したいかどうかを決定し、新しい値を含む応答を送信できます。これも3バイトのトリプレットのリストです。
IAC SB LINEMODE LM_SLC <トリプレット> IAC SE(0xFF 0xFA 0x03 <トリプレット> 0xFF 0xF0)
サーバーは、これらのすべての値を固定サイズのグローバル配列に格納します。境界チェックは行われません。待て、何だって?
はい、それが脆弱性です。1994年から検出されていません。パッチは情報セキュリティが到達できる限り現代アートに近いものです。
しかし待ってください!さらに「面白い」ことがあります!
何がもっと面白いのか、あなたは尋ねるかもしれません。
もし、まったく同じ脆弱性が、サーバーではなく、2005年のTelnetクライアントに存在したらどうなるでしょうか?
本当です、皆さん。CVE-2005-0469はこの脆弱性のドッペルゲンガーです。本質的に同じですが、クライアント側で、slc_add_replyという関数に境界チェックが欠けていました。修正は、今日の脆弱性に対する境界チェックパッチと同一です。
幸いなことに、20年後、誰かが同じ脆弱性をサーバー側でチェックすることを考えました。
歴史は繰り返さないと言う人もいますが、確かに韻を踏んでいます。
エクスプロイトへ
もちろん、多くの読者が知っているように、これは物語の終わりではありません。