Una vulnerabilidad en el Kernel permite escalar privilegios mediante la manipulación de directorios
Hace poco investigadores de seguridad de Qualys (una empresa de seguridad en la nube, cumplimiento y servicios relacionados) dieron a conocer los detalles de una vulnerabilidad que detectaron y que afectan al kernel de Linux.
CVE-2021-33909 afecta al kernel y permite que un usuario local logre la ejecución de código y escalar privilegios mediante la manipulación de directorios muy anidados.
La vulnerabilidad se debe a la falta de validación del resultado de convertir size_t al tipo int antes de realizar operaciones en el código seq_file, que crea archivos a partir de una secuencia de registros. La falta de validación puede resultar en escrituras en un área fuera de los límites del búfer al crear, montar y eliminar una estructura de directorio con un nivel muy alto de anidamiento (tamaño de ruta de más de 1 GB).
Cualquier usuario sin privilegios puede obtener privilegios de root en un host vulnerable aprovechando esta vulnerabilidad en una configuración predeterminada.
Como resultado, un atacante puede obtener una cadena de 10 bytes «//deleted» con un desplazamiento de «- 2 GB – 10 bytes», que apunta al área inmediatamente anterior al búfer asignado.
La amenaza de la vulnerabilidad se ve agravada por el hecho de que los investigadores pudieron preparar exploits funcionales en Ubuntu 20.04, Debian 11 y Fedora 34 en la configuración predeterminada. Se observa que no se han probado otras distribuciones, pero teóricamente también son susceptibles al problema y pueden ser atacadas.
La explotación exitosa de esta vulnerabilidad permite que cualquier usuario sin privilegios obtenga privilegios de root en el host vulnerable. Los investigadores de seguridad de Qualys han podido verificar de forma independiente la vulnerabilidad, desarrollar un exploit y obtener privilegios de root completos en instalaciones predeterminadas de Ubuntu 20.04, Ubuntu 20.10, Ubuntu 21.04, Debian 11 y Fedora 34 Workstation. Es probable que otras distribuciones de Linux sean vulnerables y probablemente explotables.
El trabajo del exploit se reduce a crear una jerarquía de aproximadamente un millón de directorios anidados a través de la llamada mkdir() para lograr un tamaño de ruta de archivo superior a 1 GB.
Este directorio se monta mediante bind-mount en un espacio de nombres de usuario separado, después de lo cual se ejecuta la función rmdir() para eliminarlo. Paralelamente, se crea un hilo que carga un pequeño programa eBPF, que se bloquea en la etapa después de verificar el pseudocódigo eBPF, pero antes de su compilación JIT.
En el espacio de nombres de ID de usuario sin privilegios, el archivo /proc/self/mountinfo se abre y lee la ruta de directorio larga montada con bind-mount, lo que da como resultado que la línea «//deleted» se escriba en la región antes del inicio del búfer. La posición para escribir la línea se elige de tal manera que sobrescriba la instrucción en el programa eBPF ya probado pero aún no compilado.
Además, en el nivel del programa eBPF, la escritura incontrolada fuera del búfer se transforma en una capacidad de lectura/escritura controlada en otras estructuras del núcleo mediante la manipulación de las estructuras btf y map_push_elem.
El exploit luego ubica el búfer modprobe_path[] en la memoria del kernel y sobrescribe la ruta «/sbin/modprobe» en él, lo que permite que cualquier archivo ejecutable sea lanzado como root si se realiza una llamada request_module (), que se ejecuta, por ejemplo, al crear un socket netlink …
Los investigadores han proporcionado varias soluciones que son efectivas solo para un exploit específico, pero no solucionan el problema en sí.
Como tal lo que se recomienda es establecer el parámetro «/proc/sys/kernel/unprivileged_userns_clone» en 0 para deshabilitar el montaje de directorios en un espacio de nombres de ID de usuario separado y «/proc sys/kernel/unprivileged_bpf_disabled» en 1 para deshabilitar la carga de programas eBPF en el núcleo.
Además de que tambien se recomienda a todos los usuarios de una distribución de Linux, realizar la actualización de su sistema para tener el parche correspondiente. El problema ha sido evidente desde julio de 2014 y afecta a las versiones del kernel desde 3.16. El parche de vulnerabilidad se coordinó con la comunidad y se aceptó en el kernel el 19 de julio.
Finalmente, si estás interesado en conocer más al respecto, puedes consultar los detalles en el siguiente enlace.