Condición de carrera en el recolector de basura del kernel de Linux que puede provocar una escalada de privilegios

Jann Horn del equipo de Google Project Zero, que una vez identificó las vulnerabilidades Spectre y Meltdown, publicó una técnica para explotar una vulnerabilidad (CVE-2021-4083) en el recolector de basura del kernel de Linux. La vulnerabilidad se debe a una condición de carrera al limpiar descriptores de archivos en sockets Unix y potencialmente permite que un usuario local sin privilegios ejecute su código a nivel del kernel.

El problema es interesante porque se estimó que la ventana de tiempo durante la cual ocurre la condición de carrera era demasiado pequeña para crear exploits reales, pero el autor del estudio demostró que incluso esas vulnerabilidades inicialmente escépticas pueden convertirse en una fuente de ataques reales si el creador del exploit ha las habilidades y el tiempo necesarios. Yann Horn mostró cómo, con la ayuda de manipulaciones de filigrana, se puede reducir la condición de carrera que se produce al llamar simultáneamente a las funciones close() y fget() a una vulnerabilidad de uso después de la liberación totalmente explotable y lograr acceso a datos ya liberados. estructura dentro del núcleo.

Se produce una condición de carrera durante el proceso de cerrar un descriptor de archivo mientras se llama a close() y fget() al mismo tiempo. La llamada a close() puede ocurrir antes de que se ejecute fget(), lo que confundirá al recolector de basura porque, según el refcount, la estructura del archivo no tendrá referencias externas, sino que permanecerá adjunta al descriptor del archivo, es decir. El recolector de basura pensará que tiene acceso exclusivo a la estructura, pero de hecho, durante un corto período de tiempo, la entrada restante en la tabla de descriptores de archivos seguirá apuntando a la estructura que se está liberando.

Para aumentar la probabilidad de entrar en una condición de carrera, se utilizaron varios trucos que permitieron aumentar la probabilidad de éxito de la explotación al 30% al introducir optimizaciones específicas del sistema. Por ejemplo, para aumentar el tiempo de acceso a una estructura con descriptores de archivos en varios cientos de nanosegundos, se eliminaron datos de la memoria caché del procesador saturando la memoria caché con actividad en otro núcleo de la CPU, lo que hizo posible recuperar la estructura de la memoria en lugar de desde el rápido caché de la CPU.

La segunda característica importante fue el uso de interrupciones generadas por un temporizador de hardware para aumentar el tiempo de condición de carrera. Se seleccionó el momento para que el controlador de interrupciones se activara cuando ocurriera una condición de carrera e interrumpiera la ejecución del código durante algún tiempo. Para retrasar aún más la recuperación del control, se generaron alrededor de 50 mil entradas en la cola de espera utilizando epoll, lo que requirió una búsqueda a través del controlador de interrupciones.

La técnica para explotar la vulnerabilidad se reveló después de un período de confidencialidad de 90 días. El problema aparece desde el kernel 2.6.32 y se solucionó a principios de diciembre. La solución se incluyó en el kernel 5.16 y también se transfirió a las ramas LTS del kernel y a los paquetes del kernel suministrados en las distribuciones. Cabe destacar que la vulnerabilidad se identificó durante el análisis de un problema similar CVE-2021-0920, que se manifiesta en el recolector de basura al procesar el indicador MSG_PEEK.

Fuente: opennet.ru

Añadir un comentario