Nota perev. : Esta nota foi escrita por um pesquisador de segurança de TI da Aqua Security, uma empresa DevSecOps. Ela é uma excelente ilustração das sutilezas na configuração do Kubernetes, que é importante sempre ter em mente ao servir clusters na produção. Claro, se você pensar sobre a segurança deles ...
O Kubernetes consiste em muitos componentes e, às vezes, combiná-los de uma certa maneira leva a resultados inesperados. Neste artigo, mostrarei como um pod iniciado com privilégios de root e um diretório
/var/log
montado de um nó pode
expandir o conteúdo de todo o sistema de arquivos host para um usuário com acesso aos seus logs. Também discutiremos soluções para esse problema.
Como o Kubernetes vê os logs
Você já se perguntou como o
kubectl logs <pod_name>
extrai os logs do pod? Quem é responsável pela coleta de logs dos contêineres? E como eles chegam ao seu computador?
O diagrama a seguir ilustra o processo:

O Kubelet cria uma estrutura dentro do diretório
/var/log
no host que representa os pods no host. Há um arquivo
0.log
(1) no diretório do nosso
0.log
, mas na verdade é um link simbólico para o log do contêiner localizado em
/var/lib/docker/containers
. Isso tudo é do ponto de vista do host.
O Kubelet abre o endpoint
/logs/
(2), que simplesmente trabalha com o servidor de arquivos HTTP no diretório (3), disponibilizando os logs para solicitações provenientes do servidor da API.
Agora imagine que implantamos o pod com o
hostPath
montado em
/var/log
. Esse pod terá acesso a todos os arquivos de log no host. Embora isso seja um problema em potencial, podemos dar o próximo passo lógico. E se substituirmos
0.log
por um link simbólico para ... digamos,
/etc/shadow
?
│ ├── var │ ├── logs │ │ ├── pods │ │ │ ├── default_mypod_e7869b14-abca-11e8-9888-42010a8e020e │ │ │ │ ├── mypod │ │ │ │ │ ├── 0.log -> /etc/shadow │ │ │ │ │ │
Agora, tentando fazer o download dos logs usando os logs do
kubectl logs
na máquina cliente, obtemos:
$ kubectl logs mypod failed to get parse function: unsupported log format: "root:*:18033:0:99999:7:::\n"
O Kubelet segue o link e lê o conteúdo do arquivo para o qual ele aponta (pode ser qualquer arquivo no nó).
Como o JSON era esperado, o kubectl travou após a primeira linha, no entanto, podemos ler facilmente as linhas específicas do arquivo
shadow
executando o comando com o
–-tail=-<line_number>
.
Isso é incrível. Como o kubelet segue o link simbólico, você pode usar seus privilégios de root para ler qualquer arquivo no nó, simplesmente criando um link simbólico dentro do pod.
Escape from the pod
Vamos ainda mais longe. Sabemos que, ao iniciar um pod no Kubernetes, o token ServiceAccount é instalado nele. Portanto, se a conta de serviço permitir acesso aos logs, podemos acessar diretamente os privilégios de kubelet e root no nó.
Eu escrevi uma prova de conceito (POC) demonstrando esse vetor de ataque:
- implantação de pod com ponto de montagem
/var/log
; - criando um link simbólico para o diretório raiz do host;
- lendo a chave privada ssh do usuário no host.
O
vídeo a seguir mostra dois comandos especiais executados dentro de um pod:
lsh == ls
(no sistema de arquivos host);cath == cat
(no sistema de arquivos host).
Nota perev. : Infelizmente, eles não corrigiram a inserção de conteúdo de asciinema no hub, embora já tenhamos abordado esse problema, portanto somos forçados a "incorporar" o vídeo com o link simples acima.Todos os arquivos envolvidos neste POC podem ser encontrados no
repositório GitHub correspondente . Há outro script POC que coleta automaticamente chaves privadas e tokens ServiceAccount do sistema de arquivos host.
Montar diretórios pode ser perigoso
Então, isso é uma vulnerabilidade ou apenas uma má prática?
A implantação de um pod com um
hostPath
em
/var/log
é rara (também existem outras maneiras de abusar da montagem de diretórios secretos do host no pod). Porém, mesmo que você soubesse que montar
/var/log
era uma prática duvidosa, provavelmente não esperava que isso lhe permitisse dominar o nó com tanta facilidade.
Antes da publicação, contatamos a equipe de segurança do Kubernetes para descobrir se eles consideram isso uma vulnerabilidade. Eles concluíram que isso era apenas uma conseqüência triste da montagem de um diretório de host privado com permissões de gravação: os riscos envolvidos estão bem
documentados . No entanto, essa vulnerabilidade é bastante fácil de explorar. No mundo, existem
muitos projetos que usam esse suporte. Se você estiver usando um desses projetos, lembre-se de que sua implantação estará vulnerável a esta maneira de seqüestrar o host.
Este método foi testado no Kubernetes 1.15 e 1.13, mas provavelmente afeta outras versões.
Eliminação
Essa "fuga" só é possível se o pod estiver sendo executado como root. Isso geralmente
deve ser evitado . O Aqua CSP permite que você defina uma política com um mínimo de esforços que impeça a execução de contêineres na raiz ou conceda permissões apenas a um grupo específico de imagens que realmente precisam de raiz.
Outra maneira é simplesmente não implantar pods com o
hostPath
com permissões de gravação em
/var/log
. Essa abordagem não é definida por padrão e não é uma prática comum; portanto, é necessário determiná-la conscientemente (no entanto, a possibilidade ainda permanece). Mas como verificar?
Adicionamos um novo script (hunter) ao
kube-hunter - nossa ferramenta leve de código aberto para testar o Kubernetes - que verifica o cluster em busca de pods com pontos de montagem tão perigosos.
( Nota : O Kube-hunter esteve presente em uma revisão recente dos utilitários de segurança do K8s, que publicamos em nosso blog.)Os usuários do Aqua podem se proteger desse risco usando a política de tempo de execução para impedir que determinados volumes sejam montados:
Nota perev. : Parte desse problema pode ser resolvida usando as políticas de segurança do pod , nomeadamente AllowedHostPaths
. No entanto, isso também não é proteção contra links simbólicos. Finalmente, como sugerem os comentários, podemos simplesmente limitar o lançamento como root, novamente guiado pelo PSP .Sumário
O Kubernetes é um sistema complexo com muitas sutilezas nas configurações de segurança, que nem sempre são óbvias para o usuário médio e até experiente. Neste artigo, mostrei como, sob certas circunstâncias, o registro inocente pode levar a uma possível vulnerabilidade. Na maioria dos casos, isso não é possível, mas o Kubernetes oferece aos usuários maior liberdade de ação que pode afetar a segurança. É importante ter isso em mente e implementar controles apropriados para evitar esses erros.
PS do tradutor
Leia também em nosso blog: