Command Injection in Kubernetes Log Query Injeção de comandos na consulta de registro do Kubernetes
Comentários editoriais e adicionais por Tricia Howard
Resumo executivo
O pesquisador de segurança da Akamai, Tomer Peled, descobriu recentemente uma vulnerabilidade no Kubernetes que recebeu a atribuiçãoCVE-2024-9042.
A vulnerabilidade permite a execução remota de código (RCE) com privilégios de SYSTEM em todos os pontos de extremidade Windows dentro de um cluster Kubernetes. Para explorar essa vulnerabilidade, o cluster deve estar configurado para executar o novo mecanismo de logging “Consulta de Registro.”
A vulnerabilidade pode ser acionada com uma simples solicitação GET para o nó remoto.
A exploração bem-sucedida dessa vulnerabilidade pode levar à tomada completa de controle sobre todos os nós Windows em um cluster.
Essa vulnerabilidade pode ser explorada em instalações padrão do Kubernetes que optaram por usar recursos beta (anterior a versão 1.32.1), e foi testada tanto em implantações locais quanto no Azure Kubernetes Service.
Neste post de blog, fornecemos um comando curl de prova de conceito e discutimos possíveis mitigadores.
Introdução
O Kubernetes e os contêineres, de maneira geral, se tornaram uma força predominante no mundo da segurança — e, como tal, têm sido um ponto de interesse para pesquisadores de todo o mundo (inclusive nós). Nossa jornada de pesquisa inicialmente nos levou ao CVE-2023-3676: uma vulnerabilidade de injeção de comando que poderia ser explorada aplicando um arquivo YAML malicioso ao cluster. Essa pesquisa levou à descoberta devários outros problemas no código-fonte do Kubernetes que também permitem a tomada completa do cluster.
Essas vulnerabilidades não foram tudo o que encontramos — também houve uma descoberta significativa no projeto sidecar git-sync. Apresentamos essas descobertas no Red Team Village do DEF CON 32, e, em preparação para a palestra, nos deparamos com o tema deste post de blog: Outra oportunidade para injeção de comando — o recurso beta do Kubernetes para seuframework de logging maior, a consulta de registro..
O que é a consulta de registro?
A consulta de registro permite que os usuários consultem máquinas remotas para obter o status do sistema usando a CLI ou curl. Por exemplo, um usuário pode digitar o seguinte comando para consultar o status do serviço kubelet em um nó remoto:
kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet"
Quando vimos o exemplo de comando acima, nossa pesquisa anterior veio à mente: A consulta enviada para a máquina remota seria validada?
A Figura 1 é um exemplo do código-fonte da Consulta de Registro, onde encontramos vários comandos PowerShell sendo construídos.
Esses comandos são usados para recuperar logs de um determinado nó com base em diferentes parâmetros, como nomes de serviços do Windows, padrões de uso do tempo e mais.
Com a experiência anterior (CVE-2023-3676), , sabemos que o Kubernetes nem sempre valida a entrada do usuário antes de inseri-la como um parâmetro ao construir um comando PowerShell. Queríamos ver se isso também acontecia com a consulta de registro e descobrimos que os nomes dos serviços são, na verdade, validados usando uma regex pré-definida (Figura 2).
O nome reServiceNameUnsafeCharacters sugere que essa verificação é apenas para serviços. Essa hipótese é reforçada pelo fato de que não há outra regex presente no processo de análise.
Após examinar outros parâmetros, ficou claro que, de fato, o único parâmetro validado é o nome do serviço. Isso significa que podemos olhar para outros parâmetros na esperança de realizar uma injeção de comando. Na consulta de registro, existem vários parâmetros opcionais que os usuários podem fornecer, mas o único que é uma string é o parâmetro Pattern (Figura 3). Como mencionamos anteriormente, não há validação sobre esse parâmetro (além de seu comprimento).
Vale notar que explorar essa vulnerabilidade não foi trivial. Tentamos disparar os comandos na máquina remota utilizando várias permutações diferentes para o payload do PowerShell, como adicionar colchetes, usar separadores e assim por diante, mas nada parecia funcionar — também não houve erros, o que tornou ainda mais difícil descobrir a causa.
O problema não é o payload
Depois de tentar muitos métodos diferentes de injeção de comando, descobrimos que o problema não estava no payload em si. Para explorar essa vulnerabilidade, precisávamos especificar um serviço que estivesse registrando seu status nativamente para o event tracing for Windows (ETW) e não para o framework klog regular, já que a verificação vulnerável só existe quando o registro é feito para o ETW.
Um ambiente Kubernetes usando Calico (uma interface de rede popular e de código aberto para Kubernetes) fornece uma maneira confiável de explorar essa vulnerabilidade através do Non-Sucking Service Manager (NSSM).
Em uma configuração Calico, o NSSM geralmente está presente para controlar o estado dos serviços Kubernetes. Em outros ambientes/configurações, utilizam-se diferentes maneiras de gerenciar os estados dos serviços.
- O Kubernetes não gerencia a saída de logs do NSSM, garantindo que os logs sejam gravados diretamente no ETW e não através do klog.
Mostrando uma consulta de exploit
Uma consulta de exploit seria assim:
curl "<Kubernetes API Proxy server IP>/api/v1/nodes/<NODE name>/proxy/logs/?query=nssm&pattern=’\$(Start-process cmd)’"
*O token de autenticação necessário para falar com o servidor da API foi omitido
Leitores atentos podem ter notado os apóstrofos usados para escapar nosso comando malicioso. Precisamos deles porque o Kubernetes insere nossa entrada utilizando o seguinte comando:
…Where-Object -Property Message -Match '%s'...
Semelhante aos ataques clássicos de injeção de SQL, precisamos adicionar apóstrofos para escapar seu padrão, fazendo com que nossa entrada seja analisada como um comando separado (Figura 4).
Patch prioritário
Para ser afetado por essa vulnerabilidade, é necessário utilizar uma versão do Kubernetes anterior à 1.32.1. Se você ainda não corrigiu essa vulnerabilidade, é uma boa ideia priorizá-la. Isso é especialmente importante para organizações com nós Windows dentro de um cluster, pois é nesse ponto que reside a vulnerabilidade.
Felizmente, não parece ser o padrão do setor. Um administrador pode testar facilmente se o cluster de sua organização contém nós Windows executando o seguinte comando no controlador do cluster (Figura 5).
Será que estou vulnerável?
É fácil determinar se você está vulnerável. Note a parte "os=windows". Se não houver nós do Windows, o comando não teria nenhuma saída, o que significa que você não está vulnerável.
Como se trata de uma funcionalidade beta, o cluster também precisa estar configurado para utilizar o framework.
Para verificar se a funcionalidade está habilitada, os administradores podem consultar o parâmetro de inicialização “feature-gate” para o “kubelet.” Você pode obter mais informações no site do Kubernetes.
Análise de patches
Para corrigir essa vulnerabilidade, o Kubernetes decidiu usar uma variável de ambiente chamada “kubelet_pattern”, antes de passar o valor para o comando PowerShell.
Assim, a entrada do usuário será considerada como uma string literal, em vez de uma subexpressão que precisa ser avaliada.
Mitigação
Para ajudar a reduzir essa vulnerabilidade, os administradores podem usar o módulo de controle de acesso baseado em função (RBAC) para controlar quem tem acesso a consulta de registro e até mesmo desabilitar o acesso completamente. O RBAC é um método que segmenta as operações do usuário de acordo com a identidade do usuário. Por exemplo, cada usuário só pode criar pods em seu próprio namespace ou pode exibir apenas informações para namespaces permitidos. Isso reduziria o risco de execução remota de código (RCE) não apenas na execução, mas também na detecção — comportamentos anômalos de usuários são frequentemente um sinal claro de atividades indevidas.
Lembre-se de que essa vulnerabilidade afeta apenas os nós do Windows. Se o seu cluster Kubernetes não tiver nenhum nó Windows, você está protegido quanto a essa vulnerabilidade. No entanto, ainda é recomendável manter seus patches sempre atualizados para evitar outras vulnerabilidades desconhecidas.
Como o problema está no código-fonte, essa ameaça permanecerá ativa, e a exploração dela provavelmente aumentará. É por isso que recomendamos a aplicação de patches em seu cluster, mesmo que ele não tenha nós do Windows.
Conclusão
Neste post do blog, mostramos como um atacante com privilégios de consulta pode executar comandos em qualquer nó Windows dentro do cluster. Essa vulnerabilidade pode ser explorada por meio de um simples comando curl, ao invés de precisar enviar um arquivo YAML. Esse fato representa um grande risco, pois sua exploração é mais difícil de reduzir e detectar. Problemas de sanitização no Kubernetes não são exclusivos da consulta de registro, comodiscutimos anteriormente.
Membros da equipe de segurança azul devem estar atentos a comportamentos incomuns em suas organizações. Esse vetor de ataque pode levar à tomada completa do cluster; portanto, é importante aumentar a conscientização e ajudar os administradores de segurança a conhecerem o perigo potencial.
O Akamai Security Intelligence Group continuará a pesquisar e reportar ameaças como essas aos nossos clientes e à comunidade de segurança em geral. Para atualizações em tempo real sobre o que estamos trabalhando, siga-nos no X (antigo Twitter.)
Queremos agradecer à equipe do Kubernetes pela resposta e pela conversa.
Linha do tempo
28/06/2024 – Vulnerabilidade divulgada à equipe do Kubernetes
18/07/2024 — Equipe do Kubernetes começou a trabalhar na correção do problema
30/07/2024 – CVEs atribuídos pela equipe do Kubernetes
16/01/2025 — Kubernetes lançou as correções para os CVEs
24/01/2025 — Post do blog publicado