
Exploit de prova de conceito para a vulnerabilidade de escape de contêiner runc CVE-2024-21626. Inclui script de verificação, escape via cron ou substituição de comando e análise de patch.
| Nome da Vulnerabilidade | Vazamento de Escape do docker runc |
|---|---|
| Número da Vulnerabilidade | CVE-2024-21626 |
| Data de Divulgação | 2024-01-31 |
| Característica | / |
| Versões Afetadas | runc @ [v1.0.0-rc93,1.1.11] |
As condições de exploração são um tanto rigorosas, exigindo interação da vítima. Pessoalmente, acho um tanto inútil:
Verificação da Existência da Vulnerabilidade e Obtenção do Descritor:
git clone https://github.com/V0WKeep3r/CVE-2024-21626-runcPOC.git
cd CVE-2024-21626-runcPOC
bash verify.sh
Conforme a imagem abaixo, a vulnerabilidade existe e o descritor de arquivo é /proc/self/fd8
O verify.sh pode encontrar o valor específico do fd correspondente no ambiente da máquina atual. Se o fd não for 8, é necessário modificar o WORKDIR no Dockerfile para o valor correspondente ou usar -w no docker run para especificá-lo.
Verificação de Escape/Elevação de Privilégios: Aqui estou mais próximo da prática real, o poc.sh usa uma tarefa agendada para obter um shell reverso. O poc2.sh usa um método de substituição de comando (observe que, ao usar este método, é necessário fazer backup dos arquivos com antecedência para evitar dificuldades na recuperação dos arquivos).
# 需要确认定时任务文件存在,不存在可以创建写,但是那样不能触发定时任务
# 只有crontab -e创建的,在crontab组的文件才会被定时执行。
docker build . -t poc1
docker run -it --rm poc1 bash /poc.sh

POC2:
docker build . -t poc2
docker run -it --rm poc2 bash /poc.sh
# 另起一个terminal
/bin/bash.copy

Não é uma compreensão completa, mas combinando com o patch dá para ter uma ideia geral.
Durante o processo de docker exec ou docker run, a função execve do runc é chamada, mas durante o exec do runc, os descritores de arquivo fd não são fechados, resultando no vazamento dos descritores de arquivo do host para o ambiente do contêiner. O usuário pode usar esses descritores de arquivo para ler e escrever arquivos do host, realizando assim o escape do contêiner.
Solução de Correção Atualizar o runc para a versão 1.12 ou superior. Link oficial do runc: https://github.com/opencontainers/runc/releases
Análise do Patch
diff commit: https://github.com/opencontainers/runc/commit/2a4ed3e75b9e80d93d1836a9c4c1ebfa2b78870e
Fechar os fds internos antes do execve
init_linux.go, verificar se o cwd (diretório de trabalho atual) está dentro do contêiner após o chdir
