
Um script para verificar se um ambiente de contêiner está vulnerável a escapes de contêiner via CVE-2022-0492
Um script para verificar se um ambiente de contêiner é vulnerável a fugas de contêiner via CVE-2022-0492
Em 4 de fevereiro, o Linux anunciou CVE-2022-0492, uma nova vulnerabilidade de escalonamento de privilégios no kernel.
CVE-2022-0492 marca um bug lógico em grupos de controle (cgroups), um recurso do Linux que é um bloco fundamental de contêineres. O problema se destaca como um dos escalonamentos de privilégio mais simples descobertos recentemente: O kernel do Linux expôs erroneamente uma operação privilegiada para usuários não privilegiados.
Felizmente, os endurecimentos de segurança padrão na maioria dos ambientes de contêineres são suficientes para evitar a fuga de contêineres. Contêineres executando com AppArmor ou SELinux estão protegidos. Dito isso, se você executar contêineres sem as práticas recomendadas de endurecimento, ou com privilégios adicionais, pode estar em risco. A seção "Estou Afetado?" lista configurações vulneráveis de contêineres e fornece instruções sobre como testar se um ambiente de contêiner é vulnerável.
Além dos contêineres, a vulnerabilidade também pode permitir que processos root do host sem capacidades, ou processos não root do host com a capacidade CAP_DAC_OVERRIDE, escalonem privilégios e atinjam todas as capacidades. Isso pode permitir que atacantes contornem uma medida de endurecimento usada por certos serviços, que removem capacidades na tentativa de limitar o impacto se ocorrer uma violação.
CVE-2022-0492 é agora a terceira vulnerabilidade do kernel nos últimos meses que permite que contêineres maliciosos escapem. Em todas as três vulnerabilidades, proteger contêineres com Seccomp e AppArmor ou SELinux foi suficiente para evitar a fuga de contêineres.
Montar um cgroupfs requer a capacidade CAP_SYS_ADMIN no namespace de usuário que hospeda o namespace de cgroup atual. Por padrão, os contêineres são executados sem CAP_SYS_ADMIM e, portanto, não podem montar cgroupfs no namespace de usuário inicial. Mas através da chamada de sistema unshare(), os contêineres podem criar novos namespaces de usuário e de cgroup onde possuem a capacidade CAP_SYS_ADMIN e podem montar um cgroupfs.

Fig. 1 - Um contêiner criando um novo namespace de usuário onde terá a capacidade CAP_SYS_ADMIN.
Nem todo contêiner pode criar um novo namespace de usuário – o host subjacente deve ter namespaces de usuário não privilegiados habilitados. Esse é o padrão em versões recentes do Ubuntu, por exemplo. Como o Seccomp bloqueia a chamada de sistema unshare(), apenas contêineres executando sem Seccomp podem criar um novo namespace de usuário. O contêiner mostrado na captura de tela anexada é executado sem Seccomp, AppArmor ou SELinux.

Fig. 2 - O contêiner monta o cgroup de memória nos novos namespaces de usuário e de cgroup.
Na captura de tela acima, o contêiner montou com sucesso um cgroup de memória, mas você pode notar que o arquivo release_agent não está incluído no diretório montado!
Como mencionado anteriormente, o arquivo release_agent só é visível no cgroup raiz. Uma ressalva de montar um cgroupfs em um namespace de cgroup é que você monta o cgroup ao qual pertence, não o cgroup raiz.

Fig. 3 - O contêiner montando o cgroup RDMA raiz nos novos namespaces de usuário e de cgroup.
Para explorar o problema, precisamos escrever um agente de liberação malicioso no arquivo release_agent. Como visto na Fig. 3 acima, esse arquivo pertence ao root, então apenas processos root do contêiner podem definir o agente de liberação. A Fig. 4 mostra o contêiner definindo o agente de liberação, enquanto a Fig. 5 mostra um contêiner não root falhando ao fazer isso.

Fig. 4 - Um contêiner root definindo o agente de liberação.

Fig. 5 - Contêiner não root não pode definir o agente de liberação.
A etapa final da fuga é invocar o release_agent configurado, o que não requer privilégios. Como esta etapa é sempre realizável, não tem implicações sobre se um ambiente é vulnerável ao CVE-2022-0492, e então decidimos omiti-la. Você ainda pode ver como uma exploração completa se parece na captura de tela abaixo.

Fig. 6 - Explorando CVE-2022-0492 para fuga de contêiner, via namespaces de usuário..
Em vez de criar novos namespaces de usuário e de cgroup, uma exploração mais simples é possível se o contêiner receber a capacidade CAP_SYS_ADMIN. Um contêiner executando com a capacidade CAP_SYS_ADMIN tem permissão para montar cgroupfs, sem questionamentos. Como bônus, a maioria dos contêineres hoje é executada sem namespaces de cgroup, o que significa que o cgroup montado seria o cgroup raiz hospedando o arquivo release_agent.

Fig. 7 - No namespace de cgroup inicial, montar cgroupfs sempre montará o cgroup raiz, independentemente do cgroup do contêiner.
Mesmo com a capacidade CAP_SYS_ADMIN, AppArmor e SELinux ainda impedem a montagem, então contêineres executando com um deles não podem explorar CVE-2022-0492. A Fig. 8 mostra um contêiner executando sem AppArmor e SELinux, e com a capacidade CAP_SYS_ADMIN, explorando CVE-2022-0492 para escapar.

Fig. 8 - Explorando CVE-2022-0492 para fuga de contêiner via a capacidade CAP_SYS_ADMIN.
CVE-2022-0492 marca outra vulnerabilidade do Linux que pode ser explorada para fuga de contêiner. Felizmente, ambientes que seguem as melhores práticas estão protegidos contra esta vulnerabilidade. Ambientes com controles de segurança frouxos hospedando contêineres não confiáveis ou expostos publicamente estão, como esperado, em alto risco. Como sempre, é melhor atualizar seus hosts para uma versão corrigida do kernel.
Recomendamos fortemente executar contêineres com Seccomp e AppArmor ou SELinux habilitados, para se proteger contra esta vulnerabilidade e contra futuras vulnerabilidades de dia zero do Linux. Muitas vulnerabilidades de escalonamento de privilégios no kernel do Linux só podem ser exploradas para fuga de contêiner quando o contêiner tem permissão para criar um novo namespace de usuário, ou em outras palavras, quando o contêiner é executado sem Seccomp.
© 2022 - Not Sofiane Hamlaooui - Fazendo do mundo um lugar melhor 🌎