
このドキュメントでは、runc の脆弱性 CVE-2025-31133 に対する提供された Proof-of-Concept (PoC) スクリプトの機能について説明します。
runc の maskedPaths 処理におけるシンボリックリンクの競合状態。maskedPaths の保護をバイパスし、ホストシステム上の機密ファイルに書き込むことができます。これは コンテナエスケープ を構成します。/proc/sys/kernel/core_pattern ファイルを変更することで、脆弱性を安全に実証すること。"pwned" を書き込むだけで、ホスト上で任意のコードを実行しません。また、元の値を復元する手順も提供します。コンテナのOCI仕様 (config.json) における maskedPaths 機能は、コンテナが機密システムファイルにアクセスするのを防ぐセキュリティメカニズムです。この機能は、これらの機密パスに対して /dev/null (空のデバイスファイル) をバインドマウントすることで動作し、コンテナ内部からこれらのファイルを事実上読み取り不可かつ書き込み不可にします。
脆弱性 (CVE-2025-31133) は Time-of-Check to Time-of-Use (TOCTOU) 競合状態です。エクスプロイトは次のように動作します:
runc がコンテナをセットアップする際、機密パス (例: /proc/sys/kernel/core_pattern) をマスクするバインドマウントのソースとして、コンテナのrootfsにある dev/null ファイルを使用する準備をします。runc が rootfs/dev/null へのパスを解決してから実際にマウント操作を実行するまでの間に、わずかな時間の窓があります。rootfs/dev/null ファイルを正規のデバイスノードと、ホスト上のターゲットファイル (/proc/sys/kernel/core_pattern) を指すシンボリックリンクとの間で連続的かつ非常に高速に切り替えるスクリプトを作成できます。runc は rootfs/dev/null がシンボリックリンクである瞬間にマウント操作を実行します。これによりカーネルがシンボリックリンクをたどり、/proc/sys/kernel/core_pattern に対する意図されたマスク操作が失敗します。/proc/sys/kernel/core_pattern に書き込むことができ、これによりホストのファイルが直接変更され、コンテナエスケープが達成されます。このPoCはこの手法を使用して /proc/sys/kernel/core_pattern に書き込みます。これは、プロセスがクラッシュしたときにホスト上で任意のコード実行につながる可能性があるため、このようなエクスプロイトの一般的なターゲットです。ただし、このPoCは書き込みプリミティブが存在することを証明するために、無害な文字列のみを書き込みます。
poc.sh スクリプトは、上記のプロセス全体を自動化します。
セットアップとクリーンアップ:
runc バイナリ、コンテナ名、rootfsパスの変数を定義します。cleanup 関数を含みます。この関数は、終了時、中断時、または終了時に自動的に呼び出されます。準備:
/proc/sys/kernel/core_pattern の元の内容を一時ファイルに保存します。これは後でエクスプロイトが成功したかどうかを確認し、ユーザーがシステムを復元するのに役立ちます。./rootfs) と config.json ファイルを作成します。config.json は /proc/sys/kernel/core_pattern を maskedPaths の下に明示的にリストします。これはエクスプロイトがバイパスしようとするまさにその機能です。レース関数 (symlink_race)
rootfs/dev/null を削除します。rootfs/dev/null からターゲットホストファイル (/proc/sys/kernel/core_pattern) への シンボリックリンク を作成します。rootfs/dev/null を適切な キャラクタデバイス (mknod) として再作成します。実行:
symlink_race 関数がバックグラウンドプロセスとして開始されます。runc run ... を実行してコンテナを作成し起動します。これが runc が maskedPaths を適用しようとするタイミングです。runc exec を使用してコンテナ内部でコマンドを実行します: echo 'pwned' > /proc/sys/kernel/core_pattern。検証:
/proc/sys/kernel/core_pattern の現在の内容を読み取ります。"pwned" 文字列および元の値と比較します。[+] EXPLOIT SUCCEEDED! または [-] Exploit did not succeed. メッセージを表示します。前提条件:
runc。busybox-static がインストールされていること (コンテナのシェル用)。runc を実行し /proc を変更するための root 権限 (sudo)。手順:
poc.sh として保存します。chmod +x poc.sh。sudo ./poc.sh。[+] EXPLOIT SUCCEEDED! メッセージが表示された場合、競合状態に勝利したことを意味します。ホストの /proc/sys/kernel/core_pattern がコンテナ内部から正常に変更され、脆弱性が確認されました。[-] Exploit did not succeed. が表示された場合、この試行では競合に勝利できませんでした。競合状態は確率的であり、システムのタイミングと負荷に大きく依存します。スクリプトをさらに数回実行してみてください。PoCはシステムファイルを変更します。元の状態に復元するには、スクリプトが提案するコマンドを実行します:
# The 'ORIGINAL_PATTERN' will be the actual value from your system
echo 'original_core_pattern_value' | sudo tee /proc/sys/kernel/core_pattern