7年来のOpenBSD脆弱性、PAP認証の完全バイパスを可能に

OpenBSDの同期PPPサブシステムに1999年から潜伏し続けていた重大な認証バイパス脆弱性が、問題のあるコードがソースツリーに取り込まれてから27年を経て、ついにパッチが適用されました。

このバグはsppp_pap_input()で発見されたもので、攻撃者がゼロ長の認証情報フィールドを送信するだけでPAP(Password Authentication Protocol)認証を完全にバイパスし、有効な認証情報を一切知らずにネットワークへの完全アクセスを獲得できるというものです。

この脆弱性はsys/net/if_spppsubr.cに存在しており、OpenBSDのsppp(4)サブシステムがPPPoEリンク確立時にPAP認証情報を検証する処理に問題がありました。

欠陥のあるロジックでは、bcmp()呼び出しにおける比較サイズとして、攻撃者が制御できる長さフィールドを直接使用していました。

致命的な欠陥は次の点にあります。bcmp(buf, ref, 0)はバッファの内容にかかわらず、無条件に0を返します。上限チェックは255を超える値を拒否する一方で、ゼロはチェックなしで通過してしまっていました。

name_len=0およびpasswd_len=0を指定したPAP Auth-Requestを送信すると、両方のbcmp呼び出しが成功を返し、失敗分岐が一度もトリガーされません。その結果、OpenBSDは認証情報が皆無の状態で認証を完全に許可するPAP_ACKを発行していました。

同じ根本原因を持つ二次的なヒープ過剰読み取り脆弱性も存在します。sp->hisauth.nameに割り当てられたサイズより大きなname_lenを指定すると、bcmpがヒープオブジェクトの境界を超えて読み取り、隣接するカーネルメモリが漏洩する可能性がありました。

この問題は、2009年2月のコミットで認証フィールドが固定サイズの構造体配列から動的割り当てバッファへと変更されたことで悪用可能となり、割り当てサイズと比較境界が切り離される形になりました。

脆弱性のあるコードは、1999年7月1日のコミットでFreeBSDからlmcドライバコードを取り込んだことにさかのぼります。そのFreeBSDのコードは、Cronyx EngineeringのSerge Vakulenko氏が1994年〜1996年にかけて作成した実装から派生したものです。

Argusによると、このゼロ長バイパスは最初の取り込み以降、OpenBSDの全リリースを通じて存在し続けていたとのことです。

皮肉なことに、同じファイル内のCHAPハンドラーはすでに正しいパターンを採用しており、bcmpを呼び出す前に厳密な長さの事前チェックを実施していました。PAPハンドラーには同様の処理が施されていませんでした。

両脆弱性はPPPoEデータパス経由でアクセス可能です:pppoe_data_input → pppoeintr → sppp_input → sppp_pap_input

同一ブロードキャストドメイン内で不正なPPPoEサーバーを運用する攻撃者は、ハンドシェイクの探索、LCPネゴシエーション、PAPバイパス、IPCPネゴシエーションの全過程を完了し、被害者のIPトラフィックを透過的に傍受・改ざんすることで、事実上の中間者攻撃を実行できます。

研究者らは、空のPAPフィールドによる完全なリンク確立を行い、不正トンネル経由でICMP echo replyの受信を確認するプルーフオブコンセプトスクリプト(poc-001-pap-bypass.py)を使用して、QEMU/KVM上のOpenBSD 7.6(amd64)に対してこの攻撃を検証しました。

このパッチは、CHAPハンドラーにすでに実装されている厳密な長さチェックと同じパターンを踏襲し、bcmpの比較前に長さの等値チェックを追加するものです。

これにより、ゼロ長バイパスとヒープ過剰読み取りの両方が一つの修正で解消されます。修正は2026年6月12日の責任ある脆弱性開示から2日後、2026年6月14日にmvsによってコミットされました。

CISOおよびセキュリティリーダーの皆様へ:次の侵害には”顔”がないかもしれません。ISC2のライブウェビナー 「Ghost in the Machine」にぜひご参加ください。

翻訳元: https://cyberpress.org/7-year-old-openbsd-flaw/

ソース: cyberpress.org