
Концепт-эксплойт для CVE-2024-21626 — уязвимости выхода из контейнера в runc. Включает скрипты проверки, два метода эксплуатации (reverse shell через 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, необходимо изменить WORKDIR в Dockerfile на соответствующее значение или указать его с помощью -w в docker run.
Проверка побега/повышения привилегий:
Здесь я больше ориентируюсь на реальную практику: poc.sh использует запланированную задачу для обратного шелла. poc2.sh использует метод замены команд (обратите внимание, при использовании этого метода необходимо заранее сделать резервную копию файлов, чтобы избежать трудностей с восстановлением).
# 需要确认定时任务文件存在,不存在可以创建写,但是那样不能触发定时任务
# 只有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
# 另起一个terminal
/bin/bash.copy

Полного понимания нет, но в сочетании с патчем можно уловить суть.
В процессе docker exec или docker run вызывается функция execve из runc, но в процессе runc exec файловые дескрипторы не закрываются, что приводит к утечке файловых дескрипторов хоста в среду контейнера. Пользователь может использовать эти дескрипторы для чтения и записи файлов хоста, тем самым осуществляя побег из контейнера.
Способ исправления Обновите runc до версии 1.12 и выше. Официальная ссылка runc: https://github.com/opencontainers/runc/releases
Анализ патча diff commit: https://github.com/opencontainers/runc/commit/2a4ed3e75b9e80d93d1836a9c4c1ebfa2b78870e Закрытие внутренних файловых дескрипторов перед execve

init_linux.go, после chdir проверяется, находится ли cwd (текущий рабочий каталог) внутри контейнера
