
CVE-2022-0847 (Dirty Pipe) utilizado para lograr escape de contenedor.
CVE-2022-0847 utilizado para lograr escape de contenedor (sobrescribir cualquier archivo de solo lectura en el host)
Diapositivas (en chino) disponibles aquí
利用CVE-2022-0847 (Dirty Pipe) 实现容器逃逸(效果为覆写宿主机上任意只读文件)
中文汇报PPT在这里
Si el kernel es vulnerable a CVE-2022-0847, un atacante puede sobrescribir archivos de solo lectura (¡No persistente! Visite https://dirtypipe.cm4all.com/ para más detalles). Sin embargo, el contenedor solo puede acceder a archivos dentro del contenedor. Afortunadamente, cuando se le otorga CAP_DAC_READ_SEARCH, ¡el atacante puede sobrescribir archivos en el host!
Como explica https://dirtypipe.cm4all.com/, para sobrescribir un archivo de solo lectura, debemos usar splice() para enviarlo a un pipe. Para usar splice(), primero debemos abrir el archivo objetivo con la bandera O_RDONLY para obtener un file descriptor.
Fue entonces cuando pensé en CAP_DAC_READ_SEARCH. Según el manual de Linux, cuando se le otorga CAP_DAC_READ_SEARCH, un atacante dentro del contenedor puede:
Con la capacidad CAP_DAC_READ_SEARCH, podemos explorar el sistema de archivos del host y usar open_by_handle_at(2) para abrir en modo solo lectura cualquier archivo del host desde el contenedor, obteniendo su file descriptor (Visite http://stealth.openwall.net/xSports/shocker.c para más detalles).
Ahora que tenemos el file descriptor del archivo objetivo en el host, ¡por supuesto podemos usar splice() para enviar el contenido del archivo objetivo al pipe y luego sobrescribirlo!
cp /etc/password . # back up /etc/password
gcc dp.c -o dp
docker run --rm -it -v $(pwd):/exp --cap-add=CAP_DAC_READ_SEARCH ubuntu
/exp/dp /etc/passwd 1 ootz: # overwrite /etc/password on host from offset 1
/etc/dp /etc/passwd # dump /etc/passwd on host
Primero, cree un archivo de solo lectura /home/vagrant/flag.txt como usuario root en el host, cuyo contenido es hello world:

Luego, inicie un contenedor con la capacidad CAP_DAC_READ_SEARCH, intente primero volcar /home/vagrant/flag.txt del host, obtenemos hello world:

Luego intente sobrescribir el archivo objetivo desde el offset 1 con el contenido abcdefghij:

Vuelva a volcar el archivo objetivo, ¡ahora el contenido es habcdefghij! Salga del contenedor y verifique /home/vagrant/flag.txt en el host, su contenido es habcdefghij.

¡Sí, acabamos de sobrescribir un archivo del host desde el contenedor!