06 - Kubernetes e Containers
video: https://youtu.be/... no frontmatter da nota.Kubernetes e Containers
Nota 06 do capítulo 26 (CTI e Threat Hunting em Ambientes Modernos), cobrindo a superfície de ataque de containers e Kubernetes e as TTPs específicas desse ecossistema.
A nota mapeia API server, kubelet, registry e service accounts, relaciona cada técnica de ataque à sua telemetria e entrega uma caça prática de exec não autorizado em pod.
Dialoga com a nota 16 do capítulo 08 (Hunting em Containers e Kubernetes), com o controle PRT.4 do capítulo 15 e com a nota 05 deste capítulo em telemetria de cloud.
1. Contexto e Posicionamento na Biblioteca
Containers e Kubernetes mudaram a geografia da intrusão dentro do datacenter: o sistema operacional do host passou a ser compartilhado por dezenas de cargas efêmeras, o controle de acesso virou RBAC de API e o alvo mais valioso não é uma máquina, mas o plano de controle que descreve todos os objetos do cluster. O adversário que alcança um pod com token de service account valioso ou que consegue criar um pod privilegiado está a poucos comandos do host e, a partir do host, de todo o ambiente. Esta nota organiza esse cenário em superfície de ataque, TTPs, telemetria e caça prática, com foco no que o hunter precisa coletar antes de precisar dele.
O posicionamento na biblioteca é de aprofundamento: a nota 16 do capítulo 08 apresentou as técnicas ATT&CK da matriz de containers, e aqui o trabalho desce ao nível operacional, com audit policy, regras Falco, eBPF runtime e a cadeia de verificação de hipótese. A nota 05 deste capítulo fornece o contexto de cloud que circunda o cluster, e a nota 07 cobre a esteira de CI-CD que fabrica e entrega as imagens, fechando o ciclo da aplicação cloud-native.
2. Superfície de Ataque em Containers e Kubernetes
A superfície de um cluster é formada por componentes com perfis de risco distintos, e o primeiro trabalho do hunter é saber exatamente quais deles estão expostos e logados. A lista abaixo descreve cada peça e o que ela significa em termos de telemetria e de alvo.
- API server (porta 6443): é o cérebro do cluster e a fonte de telemetria mais rica, pois toda ação de criação, modificação ou leitura de objeto passa por ele e pode ser registrada no audit log. Um atacante com credencial válida aqui dispensa exploit, porque kubectl é a ferramenta de administração e também a de ataque.
- Kubelet (porta 10250): o agente em cada nó aceita comandos de execução e de leitura de logs, e versões ou configurações com anonymous-auth habilitado transformam qualquer acesso de rede em execução remota no nó. O log do kubelet registra as chamadas de exec que nunca passaram pelo API server.
- Registry de imagens: o repositório que entrega imagens é um ponto de envenenamento, porque substituir uma tag ou publicar camada maliciosa distribui o compromisso a todo deployment que puxar a imagem. A telemetria do registry e o hash da imagem nos manifests são o par que valida integridade.
- Service accounts: cada pod nasce com um token montado em /var/run/secrets quando o automount está ativo, e esse token é credencial de API usável de dentro do container. Tokens de namespaces sensíveis, como kube-system, valem um pivô direto para o plano de controle.
- Componentes auxiliares: dashboard exposto, etcd acessível, ingress com vulnerabilidades conhecidas e admission webhooks sem autenticação mútua completam a lista de portas laterais que aparecem em avaliações reais de clusters.
A leitura operacional dessa superfície é que a maior parte das intrusões conhecidas em Kubernetes não explora bug, e sim configuração: RBAC permissivo, anonymous auth ligado, hostPath liberado e pods privilegiados por conveniência. Isso significa que a telemetria de auditoria, mesmo básica, é suficiente para detectar a cadeia inteira, desde que esteja ligada antes do incidente.
3. TTPs em Ambientes Containerizados
As técnicas da matriz ATT&CK para containers formam uma cadeia reconhecível que começa no acesso a API e termina no host. A tabela abaixo resume as cinco famílias dominantes, o equivalente ATT&CK e a assinatura que cada uma deixa na telemetria.
| TTP | ATT&CK | Assinatura na telemetria |
|---|---|---|
| Exec em pod | T1609 | verb create em pods/exec, com sourceIP e user fora do baseline |
| Pod privilegiado | T1610 | pods create com privileged true, hostPath ou hostNetwork |
| Abuso de token de service account | T1552.007, T1528 | leitura de /var/run/secrets, chamadas de API com token de pod |
| Escape para o host | T1611 | capabilities incomuns, nsenter, acesso a cgroup e release_agent |
| Persistência em CronJob | T1053.007 | cronjobs create fora da esteira de deploy |
| Descoberta no cluster | T1613 | rajada de list em pods, secrets e namespaces por identidade |
A sequência operacional típica vista em incidentes públicos combina essas peças: acesso inicial por token vazado em repositório ou imagem comprometida, descoberta com list em massa, criação de pod privilegiado montando o filesystem do host, exec para fixar persistência e uso do token de kube-system para escalar no plano de controle. Nenhuma etapa exige zero-day, e a cadeia inteira deixa rastro no audit log, o que torna o audit policy o controle de maior retorno por esforço investido no cluster.
O perfil do adversário nesse ecossistema também é distinto do mundo tradicional: clusters expostos à internet são varridos continuamente por campanhas de criptomineração em massa, com atores como o Kinsing e as operações de estilo TeamTNT explorando dashboards abertos e kubelets sem autenticação para plantar mineradores em minutos. Grupos de espionagem e de extorsão aparecem em estágio posterior, quando o cluster carrega segredos de aplicação ou credenciais de cloud, e é por isso que a cadeia de token abuse que termina em setIamPolicy na nota 05 deste capítulo é o desfecho mais perigoso dessas intrusões. Para o hunter, a implicação prática é que o volume de ruído de mineração é alto e o baseline de execução em pod precisa separar esse tráfego barulhento do comportamento cirúrgico de um intruso selecionado.
4. Telemetria Disponível
A telemetria de containers se divide em três planos que se complementam: auditoria do plano de controle, comportamento de runtime e integridade de imagem. Sem o primeiro, não se sabe quem chamou a API; sem o segundo, não se vê o que o processo fez dentro do container; sem o terceiro, não se distingue imagem aprovada de imagem plantada.
| Fonte | Cobertura | Ponto crítico |
|---|---|---|
| Audit log do API server | quem fez o quê em qualquer objeto do cluster | exige AuditPolicy configurada por nível (None, Metadata, RequestResponse) |
| Logs do kubelet e do CRI | exec e attach que chegam ao nó | precisam de coletor dedicado por nó |
| Falco e eBPF (Tetragon, Cilium, Sysdig) | syscalls, exec, montagens e rede do container | kernel com BTF e carga de regras versionada |
| Logs do registry e admission webhooks | push de imagem e resultado de política | valida hash e proveniência do artefato |
| Métricas do plano de controle | anomalias de volume de chamadas | complementa, mas não substitui o audit log |
| Syslog do nó host | atividade que escapou do container | requer coletor no host e separação por namespace de origem |
O ponto de partida concreto da coleta é um arquivo de policy que seleciona o que vale payload e o que vale apenas metadado, como no exemplo abaixo. Ele registra com payload completo os subrecursos que concentram as TTPs da seção 3, mantém metadado para mudanças em geral e silencia o ruído estrutural do plano de sistema.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["pods/exec", "pods/attach", "secrets"]
- level: Metadata
verbs: ["create", "update", "patch", "delete"]
- level: Metadata
users: ["system:kube-proxy", "system:serviceaccount:kube-system:metrics-server"]
- level: None
verbs: ["get", "list", "watch"]
resources:
- group: ""
resources: ["events", "pods/status"]
O nível de audit policy é a decisão que mais afeta o custo e a qualidade da caça: Metadata para tudo é o mínimo viável, RequestResponse em subrecursos críticos como pods/exec, secrets e token requests entrega o payload sem o custo integral, e None para leituras em massa de health check evita inundação. A regra prática do capítulo 15 (DAT.5) se aplica aqui integralmente: retenção centralizada em SIEM, porque o audit log local do API server rotaciona em horas sob carga. A coleta do plano de runtime e do kubelet costuma sair melhor com um DaemonSet de agentes por nó, que uniformiza a entrega de Falco, eBPF e syslog do host no mesmo pipeline, evitando o cenário comum de telemetria espalhada em volumes locais que morrem com o nó.
5. Hunting Específico: TTP, Telemetria e Hipótese
Cada TTP da seção 3 vira uma caça formulável, e a disciplina do capítulo 07 pede que a hipótese seja escrita antes da consulta. A tabela abaixo conecta as três colunas do raciocínio, no formato usado nos rituais de caça da biblioteca.
| TTP | Telemetria primária | Hipótese de caça |
|---|---|---|
| Exec em pod (T1609) | audit log pods/exec + Falco | Identidade fora da lista de SRE executou comando em pod de produção na última semana |
| Pod privilegiado (T1610) | audit log pods create + admission | Pod com privileged ou hostPath foi criado fora da esteira de CI-CD |
| Abuso de token (T1552.007) | Falco (leitura de secrets) + audit de API | Pod de aplicação acessou secret de namespace de outra aplicação |
| Escape (T1611) | eBPF runtime + eventos de capability | Processo dentro de container acessou caminhos do host ou alterou capabilities |
| CronJob (T1053.007) | audit log cronjobs | CronJob criado manualmente executa imagem não catalogada |
| Descoberta (T1613) | audit log list em massa | Identidade listou secrets em múltiplos namespaces em rajada curta |
| Imagem maliciosa (T1195.002) | logs de registry + admission | Tag de imagem foi sobrescrita por push fora da esteira de release |
A verificação dessas hipóteses segue o padrão das notas do capítulo 09: o resultado positivo vira alerta priorizado, o resultado com explicação administrativa vira baseline documentado, e o silêncio total vira evidência de lacuna de telemetria a reportar ao DAT.1. Nenhum resultado deve terminar sem uma das três saídas, porque caça sem destino documentado não acumula maturidade.
6. Exemplo de Caça: Exec Não Autorizado em Pod
A caça de exec não autorizado começa no audit log do API server, filtrando o subrecurso pods/exec e agrupando por identidade e origem. O comando abaixo, com jq sobre o arquivo de audit, produz a tabela inicial de candidatas, ordenada por volume, e já separa os usuários humanos das contas de serviço.
# Tabela inicial de execs por identidade e origem
jq -r 'select(.verb == "create" and .objectRef.resource == "pods/exec")
| [.stageTimestamp, .user.username, .sourceIPs[0],
.objectRef.namespace, .objectRef.name]
| @tsv' kube-apiserver-audit.log \
| sort | uniq -c | sort -rn | head -30
A segunda etapa cruza o resultado com a lista de operadores autorizados e com o range de rede dos bastions, e qualquer exec vindo de IP de workload ou de conta de serviço de aplicação é candidato forte. O passo final é a correlação temporal: exec seguido de leitura de secrets no mesmo namespace, dentro de dez minutos, caracteriza a cadeia de abuso de credencial da seção 5, e nessa altura o caso sai de hunting e entra em resposta a incidente pelo playbook de IR.3 do capítulo 15.
A mesma caça em runtime fica contínua com Falco, que vale como detecção permanente enquanto o audit log responde à pergunta investigativa. A regra abaixo combina syscall com metadados de Kubernetes e usa uma lista de operadores conhecidos para reduzir ruído.
- list: operadores_conhecidos
items: [sre-plantao, ci-deployer, kube-admin]
- rule: Exec nao autorizado em pod de producao
desc: exec dentro de pod de producao por identidade fora da lista de operadores
condition: >
evt.type = execve and evt.dir = < and container and
k8s.ns.name startswith prod and
proc.name in (bash, sh, nc, kubectl) and
not ka.user.name in (operadores_conhecidos)
output: "Exec suspeito (ns=%k8s.ns.name pod=%k8s.pod.name user=%ka.user.name cmd=%proc.cmdline)"
priority: WARNING
tags: [container, k8s, hunting]
A dupla camada tem uma divisão clara de trabalho: o Falco dispara no momento do evento e alimenta o SIEM como detecção, enquanto a consulta de audit log responde à pergunta histórica de quem executou o quê, com payload completo. Em times maduros, a regra nasce como caça manual, ganha baseline em duas ou três iterações e é promovida a detecção permanente, seguindo a ponte hunting-para-deteção do capítulo 18.
A família de caças de pod privilegiado segue o mesmo desenho, trocando o subrecurso pods/exec pelo recurso pods com inspeção do spec. A consulta abaixo recupera os pods criados com securityContext privilegiado ou com volume hostPath, que são as duas formas mais comuns de preparar um escape para o host.
# Pods privilegiados ou com hostPath criados no cluster
jq -r 'select(.verb == "create" and .objectRef.resource == "pods")
| .responseObject as $pod
| select(
($pod.spec.containers[]?.securityContext.privileged == true)
or ($pod.spec.volumes[]?.hostPath != null))
| [.stageTimestamp, .user.username,
.objectRef.namespace, .objectRef.name]
| @tsv' kube-apiserver-audit.log \
| sort | uniq -c | sort -rn | head -20
A leitura do resultado compara cada linha com a lista de identidades de deploy e com os charts que legitimamente montam paths do host, como agentes de log e drivers de storage. O que sobrar dessa interseção é candidato direto: pod privilegiado fora da esteira é a técnica T1610 em preparação, e a prioridade de resposta sobe quando a mesma identidade registrou exec em pod na mesma janela, unindo as duas caças em uma única narrativa investigativa.
7. Erros Comuns e Pontos de Atenção
- Rodar sem audit policy: o audit log desligado é o estado padrão de muitos clusters autogerenciados, e sem ele a caça de T1609, T1610 e T1613 simplesmente não existe; a policy é mudança de configuração com aprovação, mas de risco baixo e retorno altíssimo.
- Logar RequestResponse em tudo: o nível máximo em todos os recursos inunda o SIEM com payloads de list e watch, e o custo faz o time desligar a auditoria inteira depois de um mês; a seleção por subrecurso crítico é o caminho sustentável.
- Ignorar o token montado no pod: caçar credencial roubada só no endpoint esquece que o token da service account é credencial nativa dentro de cada container, e o automount desnecessário é uma credencial distribuída sem dono.
- Confundir baseline do cluster com baseline do namespace: automação legítima em um namespace pode ser anomalia grave em outro, e o agregado global esconde exatamente a diferença que caracteriza o abuso; o baseline precisa ser por namespace e por conta de serviço.
- Esquecer o registro e o supply: caçar apenas execução ignora que a porta de entrada frequente é a imagem, e a telemetria de push do registry precisa entrar no mesmo SIEM que recebe o audit log.
- Tratar imagem como confiável por padrão: hunting de runtime sem verificação de proveniência de imagem deixa passar o cenário de registry comprometido, que entrega payload já dentro do cluster.
- Analisar o container como caixa preta: ferramentas de eBPF e Falco entregam o processo dentro do namespace, e rejeitar essa telemetria porque o container é efêmero é abrir mão do único plano que registra o que o adversário executou de fato.
O ponto de atenção final é a efemeridade como inimiga da evidência: pod morto desaparece, e sem audit log centralizado e runtime persistido em SIEM a investigação reconstitui a intrusão apenas por inferência. A retenção de telemetria de cluster é, portanto, decisão de forense antecipada, e não de custo de storage.
8. Integração com o Restante da Biblioteca
Esta nota é a contraparte de infraestrutura da nota 16 do capítulo 08: lá estão as técnicas e o ATT&CK da matriz de containers, aqui está o terreno de execução com policy, regras e consultas. O controle PRT.4 do capítulo 15 recebe daqui o material de monitoramento cloud-native, e o TH.1 usa a tabela da seção 4 como inventário mínimo de dados para caça em cluster.
No bloco do capítulo 26, a nota 05 fornece a telemetria de cloud que circunda o cluster, a nota 07 cobre a esteira que fabrica as imagens e os manifests, e a nota 08 completa o quadro com o SaaS consumido pelo time de engenharia. A ponte com o capítulo 19 (emulação em Kubernetes) fecha o ciclo purple team: as hipóteses da seção 5 devem ser validadas com emulação controlada antes de virarem detecção permanente, e o resultado da validação alimenta o heatmap de cobertura do capítulo 15 (MAP.5).