Hace poco se dio a conocer la noticia de que los investigadores del equipo de Google Project Zero han desarrollado un método para explotar vulnerabilidades en el kernel de Linux causadas por la desreferenciación del puntero NULL.
Hasta ahora, los problemas en el kernel relacionados con la desreferenciación de punteros NULL no han recibido la debida atención, ya que se consideraba poco realista convertir tales problemas en ataques que condujeran a la escalada de privilegios o la ejecución de código propio (prohibido mapear procesos sin privilegios en la región inferior del espacio de direcciones).
Como regla general, tales errores conducen a la generación de advertencias de oops por parte del núcleo, después de lo cual se completan las tareas problemáticas y se restaura el estado sin necesidad de detener el sistema.
El nuevo método de ataque se basa en el manejo de estados «oops», que pueden resultar en un aumento en el valor del contador de referencia (refcount), lo que a su vez puede provocar el desbordamiento del contador y liberar la memoria asociada con el refcount.
En este caso, la explotación se reduce a manipulaciones típicas de los ataques use-after-free (surge una situación en la que el recuento de referencias del objeto se vuelve cero, la memoria se libera, pero de hecho hay enlaces en funcionamiento que apuntan a la memoria liberada).
En la actualidad, cuando el kernel de Linux activa una anulación de referencia nula desde dentro de un contexto de proceso, genera un oops , que es distinto de un kernel panic. Se produce un pánico cuando el kernel determina que no hay una forma segura de continuar con la ejecución y que, por lo tanto, debe cesar toda ejecución . Sin embargo, el kernel no detiene toda la ejecución durante un oops; en su lugar, el kernel intenta recuperarse lo mejor que puede y continúa con la ejecución.
La desreferenciación de un puntero NULL se usa aquí como una forma de generar el estado «oops» de manera controlada. El problema es que se necesitan alrededor de 232 llamadas de estado «oops» para alcanzar un desbordamiento de refcount de 32 bits.
Desde un punto de vista práctico, se necesitan alrededor de 8 días de generación continua de estados «oops» para realizar un ataque utilizando el exploit propuesto. Si tiene éxito, el exploit le permite lograr la ejecución de su código a nivel de kernel.
La desreferencia del puntero NULL utilizada en el exploit se solucionó en octubre, pero dado que problemas similares no son infrecuentes y anteriormente se trataban como errores, no como vulnerabilidades, los desarrolladores agregarán protección general al kernel de Linux para evitar ataques que manipulan la generación de «oops».
En el caso de una tarea, eso implica descartar la pila del kernel existente e ir directamente a make_task_dead que llama a do_exit. El kernel también publicará en dmesg un registro de «bloqueo» y un seguimiento del kernel que muestra en qué estado se encontraba el kernel cuando ocurrió el error. Esta puede parecer una elección extraña cuando claramente se ha producido una corrupción de la memoria; sin embargo, la intención es permitir que los errores del kernel sean más fáciles de detectar y registrar bajo la filosofía de que un sistema en funcionamiento es mucho más fácil de depurar que uno inactivo.
En particular, el Kernel 6.2 incluye cambios para limitar el número máximo de «oops». Después de alcanzar el límite, que está establecido en 10 mil oops de forma predeterminada (si lo desea, puede cambiarlo mediante el parámetro oops_limit), el núcleo iniciará una transición al estado de «pánico», seguido de un reinicio, que no permitirá el número de iteraciones necesarias para restablecer refcount a cero.
También está previsto que la restricción se transfiera a las ramas del kernel lanzadas anteriormente, pero aún admitidas, así como a los paquetes del kernel de las distribuciones populares.
Finalmente si estás interesado en poder conocer más al respecto, puedes consultar los detalles en el siguiente enlace.