Falha grave de segurança no runC pode permitir escalonamento de privilégios para root no Docker e no Kubernetes
13 de fevereiro de 2019
0 minutos de leituraUma falha de segurança descoberta por Adam Iwaniuk e Borys Popławski no software de código aberto runC foi divulgada em 11 de fevereiro de 2019 e descrita na CVE-2019-5736.
A vulnerabilidade afeta vários mecanismos de contêiner, como Docker e Kubernetes. Ela está em um componente essencial desses mecanismos e permite que contêineres escapem do ambiente isolado e acessem o servidor host em que são executados, podendo também acessar outros contêineres e obter privilégios de root no host.
Esse problema de segurança vem na sequência de uma vulnerabilidade crítica relatada em 3 de dezembro de 2018, que identificou um componente da API do Kubernetes vulnerável a ataques que permitem executar comandos arbitrários em contêineres em execução.
William Bowling compartilhou no Twitter um vídeo que mostra o ataque de prova de conceito em ação. O binário runC no servidor host é alterado de dentro de um contêiner em execução por uma versão com uma porta dos fundos:
Hoje, Iwaniuk e Popławski publicaram uma postagem no blog detalhando o ataque do runC e descrevendo a motivação da pesquisa que levou à descoberta da vulnerabilidade.
A vulnerabilidade
Como essa vulnerabilidade é possível? Christian Brauner escreveu sobre a importância de entender a semântica de contêineres privilegiados e não privilegiados:
O que realmente queremos dizer com um contêiner privilegiado é um contêiner em que a semântica do ID 0 é a mesma dentro e fora do contêiner, mantidas as demais condições. Digo “mantidas as demais condições” porque o uso de LSMs, seccomp ou qualquer outro mecanismo de segurança não altera o significado do ID 0 dentro e fora do contêiner. Por exemplo, uma fuga causada por um bug na implementação do runtime dará acesso root ao host.
Um contêiner não privilegiado é aquele em que a semântica do ID 0 dentro do contêiner é diferente da do ID 0 fora dele. Por exemplo, uma fuga causada por um bug na implementação do runtime não dará acesso root ao host por padrão. Isso só deveria ser possível se houver um bug na implementação de namespaces de usuário do kernel.
A gravidade alta dessa vulnerabilidade e seu alcance se devem ao fato de os contêineres Docker serem executados como contêineres privilegiados por padrão e também à forma como o binário de linha de comando runC é usado.
Comece a jogar Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo à gravação sob demanda do nosso workshop virtual introdutório.
Como explica Brauner, implementações de tecnologia de contêineres, como o Docker, executam o binário runC sempre que um comando de contêiner é solicitado; em seguida, o processo runC é encerrado. Por isso, um contêiner malicioso pode alterar o binário runC, e todos os comandos de contêiner subsequentes acabam executando o binário runC modificado.
Isso é bem diferente do funcionamento do LXC, em que um processo semelhante não é encerrado após executar comandos de contêiner:
LXC não pode ser atacado por meio de uma imagem maliciosa, pois o processo monitor (único para cada contêiner) nunca é encerrado durante o ciclo de vida do contêiner. Como o kernel não permite modificações em binários em execução, o invasor não consegue corrompê-lo. Quando o contêiner é desligado ou encerrado, a tarefa do invasor também é encerrada antes de causar qualquer dano. O monitor só é encerrado depois que o último processo em execução dentro do contêiner termina. Assim, se você executar contêineres OCI privilegiados usando nosso modelo OCI com LXC, estará protegido contra imagens maliciosas. Apenas o vetor de ataque por meio do binário de conexão continua aplicável.
Essa vulnerabilidade também reforça a importância do princípio de segurança do privilégio mínimo e das práticas recomendadas para evitar que o elo mais fraco abra caminho para escalonamentos e explorações mais graves.
Preocupações com segurança e divulgação responsável
O princípio fundamental da tecnologia de contêineres é o isolamento entre diferentes aplicativos e serviços. Por isso, quando esse isolamento falha, é natural que os sinais de alerta acendam.
Ataques à cadeia de suprimentos de software não são novidade no universo dos contêineres e também já ganharam destaque no caso de bibliotecas de aplicativos. Em um artigo publicado no Threatpost em 2018, uma pesquisa do Kromtech Security Center identificou que mais de 17 contêineres maliciosos estavam sendo usados ativamente em atividades ilegais de mineração de criptomoedas. As imagens maliciosas estavam hospedadas no Docker Hub, o registro público oficial de imagens Docker, e foram removidas posteriormente.
Em uma atualização sobre a vulnerabilidade do runC, Aleksa Sarai, mantenedor do runC e engenheiro de software sênior na SUSE Linux, informou ontem que outra tecnologia de contêineres Linux, chamada LXC, também é vulnerável à CVE mencionada, embora por um vetor de ataque diferente.
A atualização também mencionou que o código de exploração será divulgado publicamente em 18 de fevereiro para testar e verificar se a vulnerabilidade foi corrigida com sucesso, e recomendou que os usuários apliquem as correções de forma responsável.
Se você ainda não experimentou o Snyk, considere usar nossa CLI para executar testes localmente ou conectar seus repositórios de código-fonte para fazer varreduras e correções automatizadas. Se você já usa o Snyk, saiba que registramos essa vulnerabilidade no nosso banco de dados.
Ficamos felizes em saber que a Open Container Initiative (OCI) adicionou um arquivo SECURITY.md ao registro para oferecer aos pesquisadores diretrizes de divulgação responsável de problemas de segurança. Já havíamos recomendado isso, junto com outras diretrizes para o gerenciamento seguro de código-fonte, que você encontra em nossas práticas recomendadas de segurança do GitHub.
Principais conclusões
Evite executar imagens base de contêineres que não sejam confiáveis e verificadas.
Sempre aplique o princípio do privilégio mínimo e opte por executar contêineres não privilegiados.
Procure vulnerabilidades em bibliotecas de código aberto para identificar servidores sem correção que você possa ter e que ainda estejam vulneráveis a esta CVE.