Dirty Pipe: una vulnerabilidad que permite sobrescribir datos
Hace poco se dio a conocer la noticia de que fue identificada una vulnerabilidad en el kernel de Linux y la cual ya está catalogada bajo CVE-2022-0847 y a la cual han nombrado como «Dirty Pipe».
Esta vulnerabilidad bautizada como «Dirty Pipe»permite sobrescribir el contenido de la caché de la página para cualquier archivo, incluidos aquellos en modo de solo lectura, abiertos con el indicador O_RDONLY o ubicados en sistemas de archivos montados en modo de solo lectura.
En el aspecto práctico, la vulnerabilidad podría usarse para inyectar código en procesos arbitrarios o dañar datos en archivos abiertos. Por ejemplo, puede cambiar el contenido del archivo authorized_keys para el proceso sshd.
Sobre Dirty Pipe
Es similar a la vulnerabilidad crítica Dirty COW identificada en 2016 y se menciona que Dirty Pipe está al mismo nivel que Dirty COW en términos de peligro, pero que esta es mucho más fácil de operar.
Dirty Pipe se identificó durante el análisis de quejas sobre daños periódicos a archivos descargados a través de la red en un sistema que descarga archivos comprimidos de un servidor de registro (37 daños en 3 meses en un sistema cargado), que se prepararon utilizando la operación splice() y pipes sin nombre.
La vulnerabilidad se ha estado manifestando desde la version del kernel de Linux 5.8, lanzado en agosto de 2020.
Visto de otra manera podemos decir que está presente en Debian 11 pero no afecta el kernel base en Ubuntu 20.04 LTS, mientras que para los núcleos RHEL 8.x y openSUSE/SUSE 15 que se basan originalmente en ramas antiguas, pero es posible que el cambio que causa el problema se haya transferido a ellos (aún no hay datos exactos).
La vulnerabilidad se debe a la falta de inicialización del valor «buf->flags» en el código de las funciones copy_page_to_iter_pipe() y push_pipe(), a pesar de que la memoria no se borra cuando se asigna la estructura, y con ciertas manipulaciones con conductos sin nombre, «buf->flags» puede contener un valor de otra operación. Con esta característica, un usuario local sin privilegios puede lograr la apariencia del valor PIPE_BUF_FLAG_CAN_MERGE en la bandera, lo que le permite sobrescribir datos en la memoria caché de la página simplemente escribiendo nuevos datos en una tubería sin nombre especialmente preparada (pipe).
Para que un ataque pueda ser realizado, se necesita de un archivo de destino que debe ser legible y dado que los derechos de acceso no se verifican al escribir en una canalización, se puede realizar un reemplazo en el caché de la página, incluso para archivos ubicados en particiones de solo lectura (por ejemplo, para archivos c CD -ROM).
Con ello, después de reemplazar la información en el caché de la página, el proceso, al leer los datos del archivo, no recibirá los datos reales, sino los reemplazados.
Se menciona que la operación de Dirty Pipe se reduce a crear una tubería sin nombre y llenarla con datos arbitrarios para lograr la configuración de la bandera PIPE_BUF_FLAG_CAN_MERGE en todas las estructuras de anillo asociadas con ella.
A continuación, los datos se leen de la tubería, pero el indicador permanece establecido en todas las instancias de la estructura pipe_buffer en las estructuras de anillo pipe_inode_info. Luego, se realiza una llamada a splice() para leer los datos del archivo de destino en una tubería sin nombre, comenzando en el desplazamiento requerido. Al escribir datos en esta tubería sin nombre, el indicador PIPE_BUF_FLAG_CAN_MERGE sobrescribirá los datos en el caché de la página en lugar de crear una nueva instancia de la estructura pipe_buffer.
Finalmente si estás interesado en poder conocer más al respecto, puedes consultar los detalles en la nota original en el siguiente enlace.
Ademas, si estás interesado en poder seguir o conocer sobre la publicación de actualizaciones de paquetes en las principales distribuciones, puedes hacerlo desde estas páginas: Debian, SUSE, Ubuntu, RHEL, Fedora, Gentoo, Arch Linux.
Se menciona que la corrección de vulnerabilidad propuesta, esta disponible en las versiones del Kernel de Linux 5.16.11, 5.15.25 y 5.10.102 y la solución también está incluida en el kernel utilizado en la plataforma Android.