cks

3.13 “Hack” Secrets (RBAC escape)

Detalhamento de como um atacante (ou auditor) pode acessar Secrets sem permissão RBAC direta sobre o recurso Secret — técnicas comuns no exame CKS.

O que é

Mesmo que um usuário não tenha get secrets, ele pode obter dados de Secrets de outras formas: lendo de volumes montados em pods onde tem exec, lendo variáveis de ambiente em pods, ou usando o token da ServiceAccount de um pod para chamar a API. No exame isso aparece como “hack” ou “RBAC escape”: identificar onde os secrets estão expostos e acessá-los.

1. Secrets montados em volumes

Pods podem montar Secrets como arquivos. Quem tem exec no pod pode ler esses arquivos:

# Listar pods e ver onde secrets estão montados
kubectl -n <ns> get pod <pod> -o yaml | grep -i secret

# Ler do volume montado (path típico: /path/to/secret-volume/chave)
kubectl -n <ns> exec <pod> -- cat /path/to/secret-volume/password
# ou
kubectl -n <ns> exec <pod> -- cat /run/secrets/.../password

2. Secrets em variáveis de ambiente

Se o Secret foi injetado como env (envFrom ou valueFrom), os valores ficam em variáveis de ambiente:

kubectl -n <ns> exec <pod> -- env | grep PASS
# ou
kubectl -n <ns> exec <pod> -- printenv

3. ServiceAccount token (acesso à API)

Todo pod tem um token da ServiceAccount montado em:

/run/secrets/kubernetes.io/serviceaccount/token

Com esse token é possível chamar a API do Kubernetes (como aquela SA). Se a SA tiver permissão para listar/obter Secrets, um atacante com exec no pod pode fazer:

# Dentro do pod ou usando o token em base64
curl -k -H "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" \
  "https://kubernetes.default.svc/api/v1/namespaces/<ns>/secrets"

Para um secret específico:

curl -k -H "Authorization: Bearer $(token)" \
  "https://kubernetes.default.svc/api/v1/namespaces/<ns>/secrets/<secret-name>"

O corpo da resposta (JSON) terá .data.password (ou outro campo) em Base64. Decodificar:

echo <base64-value> | base64 -d

Mitigações (conceito para o exame)

Resumo para o exame