
CVE-2024-21626(runcコンテナエスケープの脆弱性)の概念実証。検証スクリプト、2つの悪用手法(cronリバースシェルとコマンド置換)、および根本原因とパッチの分析を含みます。
| 脆弱性名 | docker runcエスケープ脆弱性 |
|---|---|
| 脆弱性番号 | CVE-2024-21626 |
| 公開日 | 2024-01-31 |
| 特徴 | / |
| 影響バージョン | runc @ [v1.0.0-rc93,1.1.11] |
悪用条件はやや厳しく、被害者の操作が必要であり、個人的にはあまり実用的ではないと考えます:
脆弱性の存在確認とファイル記述子の取得:
git clone https://github.com/V0WKeep3r/CVE-2024-21626-runcPOC.git
cd CVE-2024-21626-runcPOC
bash verify.sh
下図のように、脆弱性が存在し、ファイル記述子は/proc/self/fd8です。
verify.shは現在のマシン環境におけるfdの具体的な値を特定します。fdが8でない場合は、DockerfileのWORKDIRを対応する値に変更するか、docker runで-wオプションを指定してください。
エスケープ/権限昇格の検証: ここではより実戦に近い形で、poc.shはcronジョブを使用してリバースシェルを取得します。 poc2.shはコマンド置き換え方式を使用します(注意:この方式を使用するには事前にファイルのバックアップが必要です。復元が困難になるため)。
# cronジョブファイルが存在することを確認する必要があります。存在しない場合は作成して書き込むこともできますが、その場合はcronジョブがトリガーされません。
# crontab -eで作成された、crontabグループ内のファイルのみが定期的に実行されます。
docker build . -t poc1
docker run -it --rm poc1 bash /poc.sh

POC2:
docker build . -t poc2
docker run -it --rm poc2 bash /poc.sh
# 別のターミナルを開く
/bin/bash.copy

完全には理解できていませんが、パッチと合わせて大まかな理解は得られます。
docker execやdocker runのプロセスでは、runcのexecve関数が呼び出されます。しかし、runcのexec中にfdファイル記述子が閉じられていないため、ホストのファイル記述子がコンテナ環境にも漏洩します。ユーザーはこのファイル記述子を介してホストのファイルを読み書きでき、コンテナエスケープが可能になります。
修正方法 runcを1.12以上にアップグレードしてください。runc公式リンク:https://github.com/opencontainers/runc/releases
パッチ分析
diffコミット:https://github.com/opencontainers/runc/commit/2a4ed3e75b9e80d93d1836a9c4c1ebfa2b78870e
execveの前に内部fdsを適切に閉じる
init_linux.goでは、chdir後にcwd(カレントワーキングディレクトリ)がコンテナ内にあることを検証する
