
CVE-2025-31133 PoC
This document explains the functionality of the provided Proof-of-Concept (PoC) script for the runc vulnerability CVE-2025-31133.
runc's maskedPaths handling.maskedPaths, allowing it to write to sensitive files on the host system. This constitutes a container escape./proc/sys/kernel/core_pattern file from within a container."pwned" to the target file and does not execute arbitrary code on the host. It also provides instructions to restore the original value.The maskedPaths feature in a container's OCI specification (config.json) is a security mechanism designed to prevent containers from accessing sensitive system files. It works by bind-mounting /dev/null (an empty device file) over these sensitive paths inside the container, effectively making them unreadable and unwritable.
The vulnerability (CVE-2025-31133) is a Time-of-Check to Time-of-Use (TOCTOU) race condition. The exploit works as follows:
runc sets up the container, it prepares to use the dev/null file from the container's rootfs as the source for the bind mount that will mask the sensitive path (e.g., /proc/sys/kernel/core_pattern).runc resolves the path to rootfs/dev/null and when it actually performs the mount operation.rootfs/dev/null file between a legitimate device node and a symbolic link pointing to the target file on the host (/proc/sys/kernel/core_pattern).runc will perform its mount operation at the exact moment when rootfs/dev/null is a symlink. This causes the kernel to follow the symlink, and the intended masking operation fails for /proc/sys/kernel/core_pattern.This PoC uses this technique to write to /proc/sys/kernel/core_pattern, a common target for such exploits because modifying it can lead to arbitrary code execution on the host when a process crashes. However, this PoC only writes a harmless string to prove the write primitive exists.
The poc.sh script automates the entire process described above.
Setup & Cleanup:
runc binary, container name, and rootfs path.cleanup function that ensures any previously created containers or files from the script are removed. This function is automatically called on exit, interruption, or termination.Preparation:
/proc/sys/kernel/core_pattern to a temporary file. This is used later to verify if the exploit succeeded and to help the user restore the system../rootfs) and a config.json file.config.json explicitly lists /proc/sys/kernel/core_pattern under maskedPaths—the very feature the exploit aims to bypass.The Race Function (symlink_race)
rootfs/dev/null.Prerequisites:
runc.busybox-static installed (for the container's shell).sudo) to run runc and modify /proc.Steps:
poc.sh.chmod +x poc.sh.sudo ./poc.sh.[+] EXPLOIT SUCCEEDED! message, it means the race condition was won. The host's /proc/sys/kernel/core_pattern was successfully modified from within the container, confirming the vulnerability.[-] Exploit did not succeed., the race was not won on this attempt. Race conditions are probabilistic and depend heavily on system timing and load. Try running the script a few more times.The PoC will modify a system file. To restore it to its original state, run the command suggested by the script:
# The 'ORIGINAL_PATTERN' will be the actual value from your system
echo 'original_core_pattern_value' | sudo tee /proc/sys/kernel/core_pattern
/proc/sys/kernel/core_patternrootfs/dev/null to the target host file (/proc/sys/kernel/core_pattern).rootfs/dev/null as a proper character device (mknod).Execution:
symlink_race function is started as a background process.runc run ... to create and start the container. This is when runc will attempt to apply the maskedPaths.runc exec to execute a command inside the container: echo 'pwned' > /proc/sys/kernel/core_pattern.Verification:
/proc/sys/kernel/core_pattern."pwned" string and the original value.[+] EXPLOIT SUCCEEDED! or [-] Exploit did not succeed. message.