## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-R4MBB-CVE-2024-21626-POC
# CVE-2024-21626
Корневая причина & Proof Of Code
# Как использовать poc-autoplay?
root@kitploit:~
make install
make uninstall
# 1\. Корневая причина
* Уязвимость возникает из-за того, что в runc версии v1.1.11 и ниже при открытии каталога /sys/fs/cgroup хоста для настройки cgroup этот файловый дескриптор не закрывается в процессе инициализации контейнера.
1. На этапе runc init через /sys/fs/cgroup хоста получается /proc/{PID}/fd/7.
2. Не закрывая этот fd, выполняется fork/exec для PID 1 контейнера.
3. В spec runc или в опции runc exec —cwd рабочий каталог (cwd) задаётся как контролируемый атакующим путь, например, полученный выше /proc/self/fd/7/.
4. После chdir cwd процесса PID 1 оказывается за пределами rootfs контейнера.
5. Подтверждается, что процессы внутри контейнера получают доступ к файловой системе хоста и могут изменять её, что приводит к container escape.
root@kitploit:~
--- a/libcontainer/init_linux.go
+++ b/libcontainer/init_linux.go
@@ -7,6 +7,7 @@ import (
"net"
"os"
+ "path/filepath"
"runtime"
"runtime/debug"
"strconv"
@@ -268,6 +272,32 @@ func populateProcessEnvironment(env []string) error {
return nil
}
+// verifyCwd ensures that the current working directory is still inside
+// the container’s mount-namespace root. If getcwd(2) returns ENOENT,
// it indicates the cwd is outside the container.
// See CVE-2024-21626.
+func verifyCwd() error {
+ if wd, err := unix.Getwd(); errors.Is(err, unix.ENOENT) {
+ return errors.New("current working directory is outside of container mount namespace root -- possible container breakout detected")
+ } else if err != nil {
+ return fmt.Errorf("failed to verify if current working directory is safe: %w", err)
+ } else if !filepath.IsAbs(wd) {
+ // Sanity check: cwd should always be absolute
+ return fmt.Errorf("current working directory is not absolute -- possible container breakout detected: cwd is %q", wd)
+ }
+ return nil
+}
@@ -326,6 +353,10 @@ func finalizeNamespace(config *initConfig) error {
if err := system.ClearKeepCaps(); err != nil {
return fmt.Errorf("unable to clear keep caps: %w", err)
}
+ // After chdir to config.Cwd, ensure it’s still inside the container
+ if err := verifyCwd(); err != nil {
+ return err
+ }
return nil
}