
PoC: escape de contêiner totalmente não privilegiado para execução de código no nível do nó no Kubernetes via CVE-2026-31431 corrupção de cache de página + camadas de imagem compartilhadas. Validado no Alibaba Cloud ACK, Amazon EKS e Google GKE.
Uma prova de conceito demonstrando como um contêiner totalmente não privilegiado pode alcançar execução de código no nível do nó no Kubernetes explorando o bug de corrupção do cache de páginas do kernel Linux CVE-2026-31431 através de camadas de imagem de contêiner compartilhadas.
A primitiva de ataque central é: qualquer DaemonSet privilegiado que compartilhe camadas de imagem com um contêiner controlado pelo atacante pode ser transformado em arma para escape de contêiner. Esta PoC usa kube-proxy como um exemplo concreto, mas a técnica se generaliza para qualquer carga de trabalho privilegiada no cluster.
Validado em Alibaba Cloud ACK, Amazon EKS e Google GKE — um pod não privilegiado escreve [*] success no sistema de arquivos do host através do DaemonSet privilegiado kube-proxy:
| Alibaba Cloud ACK (kernel 6.6.88) | Amazon EKS (kernel 6.12.79) | Google GKE (kernel 6.12.68) |
|---|---|---|
![]() | ![]() | ![]() |
Aviso: Este repositório é publicado apenas para fins educacionais e de defesa. Use-o exclusivamente em sistemas que você possui ou possui autorização explícita para testar.
CVE-2026-31431 ("Copy Fail") é uma vulnerabilidade do kernel Linux no caminho de Copy-on-Write (CoW) do cache de páginas. Uma condição de corrida com AF_ALG splice permite que um processo não privilegiado corrompa as páginas do cache de páginas de um arquivo somente leitura. A corrupção persiste no cache de páginas do kernel e é visível para todos os processos que posteriormente leem ou executam o arquivo — incluindo processos em outros contêineres ou no host.
Para detalhes completos sobre a vulnerabilidade original, veja copy.fail.
O ataque explora três propriedades que comumente coexistem em clusters Kubernetes:
privileged: true, hostNetwork: true, capacidades amplas, etc.) que executam periodicamente binários de sua imagem.Quando essas condições se alinham, um pod não privilegiado pode corromper um binário em uma camada de imagem compartilhada, e um DaemonSets privilegiado no mesmo nó executará inconscientemente o binário corrompido com seus privilégios elevados — alcançando execução de código no nível do nó.
O alvo da vulnerabilidade NÃO se limita ao kube-proxy. Qualquer DaemonSets privilegiado (agentes de monitoramento, plugins CNI, coletores de log, agentes de segurança, etc.) cuja imagem de contêiner compartilhe camadas com uma imagem controlada pelo atacante é um alvo viável.
A cadeia de ataque tem três estágios: corrupção do cache de páginas, propagação entre contêineres e execução privilegiada.
O subsistema AF_ALG (criptografia) do kernel expõe uma interface baseada em socket para operações criptográficas do espaço do usuário. O exploit abusa de uma condição de corrida em como o kernel lida com splice() de um arquivo em um socket AF_ALG:
authencesn(hmac(sha256),cbc(aes)).MSG_MORE, informando ao kernel que mais dados virão.splice() para transferir o conteúdo do arquivo alvo de um fd → pipe → socket AF_ALG.O exploit repete isso para cada janela de 4 bytes até que todas as páginas em cache do binário alvo sejam sobrescritas com uma carga útil personalizada.
Nenhuma permissão de escrita no arquivo é necessária. O arquivo no disco não é alterado — apenas o cache de páginas na memória é corrompido.
Os runtimes de contêiner usam sistemas de arquivos overlay. Quando dois contêineres compartilham a mesma camada de imagem, o kernel serve as leituras de arquivos a partir das mesmas páginas do cache de páginas.
O atacante constrói sua imagem PoC FROM a mesma imagem base do DaemonSets privilegiado alvo. Como ambos os contêineres compartilham o mesmo diretório inferior overlay, binários na camada compartilhada mapeiam para páginas do cache de páginas idênticas.
Quando o contêiner PoC não privilegiado corrompe o cache de páginas de um binário, a corrupção é imediatamente visível para o contêiner privilegiado no mesmo nó — com zero comunicação entre contêineres.
Quando o DaemonSets privilegiado executa qualquer binário corrompido (através do seu ciclo normal de operação), o kernel carrega as páginas corrompidas do cache de páginas. A carga útil do atacante é executada com todos os privilégios do DaemonSets — potencialmente incluindo:
A carga útil nesta PoC (payload/payload.c) simplesmente monta o sistema de arquivos raiz do host e escreve um arquivo marcador em /root/res como prova de execução de código no nível do nó.
┌──────────────────────────┐ ┌──────────────────────────┐
│ Contêiner PoC │ │ DaemonSets Privilegiado│
│ (não privilegiado) │ │ (ex.: kube-proxy, │
│ │ │ agente de monitora.) │
│ 1. Abre binário alvo │ │ │
│ (somente leitura) │ │ │
│ │ │ │
│ 2. Corrida splice AF_ALG│ │ │
│ corrompe cache de │ │ │
│ páginas │ │ │
│ │ │ │ │
└──────────┼───────────────┘ └──────────────────────────┘
│ │
▼ │
┌─────────────────────┐ │
│ Cache de Páginas │ │
│ do Kernel │ │
│ │◄────────────────────┘
│ Binário da camada │ 3. DaemonSets executa o
│ compartilhada │ binário corrompido
│ (CORROMPIDO) │ → carrega páginas
│ contém bytes da │ corrompidas
│ carga útil do │ → carga útil executa com
│ atacante │ privilégios do DaemonSets
└─────────────────────┘
A PoC foi validada com sucesso nas seguintes plataformas Kubernetes gerenciadas: