Aleatorización de la estructura KUSER_SHARED_DATA en Windows – Centro de respuestas de seguridad de Microsoft

Home windows 10 realizó muchas mejoras en la aleatorización del diseño del espacio de direcciones del kernel (KASLR) que aumenta el costo de explotación, en specific para las vulnerabilidades de ejecución remota de código. Muchas ubicaciones del espacio de direcciones virtuales (VAS) del núcleo, incluidas las pilas del núcleo, los grupos, los PTE del sistema, etc., son aleatorios. Una excepción bien conocida a esto es la estructura KUSER_SHARED_Details, que es una página de memoria que tradicionalmente siempre se ha asignado a una dirección digital fija en el kernel. Esta publicación destaca el trabajo que hemos realizado para fortalecer KASLR en Home windows mitigando la última estructura de destino de escritura ciega restante, que sepamos, en el núcleo que pueden utilizar las vulnerabilidades de ejecución remota de código.

Nada de este trabajo habría sido posible sin la estrecha colaboración entre los equipos de toda la organización de Windows y MSRC.

Antecedentes

La estructura KUSER_SHARED_Facts es una sola página (4096 bytes) en la memoria que se asigna a una dirección fija codificada tanto en el kernel como en el lado del usuario de VAS. KUSER_SHARED_Facts se asigna a cada proceso y proporciona un mecanismo rápido para obtener datos globales que se necesitan con frecuencia (tiempo de interrupción, versión, estado del depurador, extensiones del procesador, etc.) del núcleo sin involucrar el cambio de modo de usuario-núcleo mediante llamadas al sistema o interrupciones. En Windows de 64 bits, la dirección virtual de modo kernel de la página es 0xFFFFF78000000000 y está asignada con permisos de lectura y escritura. La asignación de modo de usuario está en la dirección 0x7FFE0000 y los permisos de página son de solo lectura. El kernel de NT y los controladores asociados escriben dinámicamente en los diversos campos de la estructura KUSER_SHARED_Details mediante la asignación de modo de kernel durante y después del arranque, y el código de modo de usuario puede leer estos valores mediante la asignación de modo de usuario.

Aunque la estructura KUSER_SHARED_Info no contiene ningún puntero (gracias al trabajo anterior sobre esto), el hecho de que esté asignada a una dirección digital codificada ha sido útil para la explotación remota en modo kernel. Cuando un atacante remoto obtiene una primitiva de ‘escritura’ al activar una vulnerabilidad en el kernel, KASLR es una barrera y debe averiguar dónde escribir exactamente. Una primitiva de escritura ciega como esta generalmente obliga a los atacantes a explotar una vulnerabilidad adicional que puede filtrar información para revelar la dirección de memoria de una estructura en modo kernel, preferiblemente cuyo contenido puede ser controlado por el atacante de forma remota. Pero como una forma de evitar tener que usar otro mistake en una cadena de explotación, los atacantes pueden usar la misma primitiva de escritura ciega y escribir algunas estructuras de datos especialmente diseñadas dentro de KUSER_SHARED_Details. Con esto, pueden usar la dirección de estos datos (fijada en los reinicios) como un puntero a otra ruta de código en el kernel. Esto puede, en ciertas situaciones, permitir a los atacantes extender la primitiva de escritura oculta inicial que obtuvieron (al activar la vulnerabilidad) para leer también regiones arbitrarias del kernel VAS, lo que resulta en un compromiso de KASLR. Un artículo de Ricerca Security detalla tal técnica escribiendo una carga útil (falsificada MDL estructuras) dentro de KUSER_SHARED_Facts y proporcionando la dirección de esta carga útil a una ruta de código específica que, esperando punteros de estructura MDL legítimos, lee de la memoria arbitraria como se describe en la carga útil. Esto permite extender la primitiva de escritura ciega a una primitiva de lectura de memoria arbitraria y se usó en el proceso de un exploit de prueba de concepto para la vulnerabilidad de ejecución remota de código que se parchó como CVE-2020-07096

Diseño de Mitigación

KUSER_SHARED_Information es una estructura suitable con versiones anteriores que existe desde las primeras versiones de Windows. Los campos dentro de la página se han mantenido en compensaciones fijas y se han agregado un par de campos adicionales a lo largo de los años. Como tal, una gran cantidad de código de modo kernel de terceros que se ejecuta en Windows depende de la lectura desde la dirección fija de esta página. ¿Cómo aleatorizamos esto sin romper esta suposición de la naturaleza estática de la página compartida?

Para garantizar la compatibilidad, decidimos mantener la página en la dirección digital codificada true (0xFFFFF78000000000), cambiar las protecciones de página para esta asignación a SÓLO LECTURA y crear un nuevo mapeo digital de la misma página física subyacente en una dirección aleatoria. Este nuevo mapeo aleatorio está mapeado con Browse y Escribe protecciones. Esencialmente, cualquier escritura en la página serious tendría que pasar por esta nueva dirección virtual aleatoria y la antigua dirección fija solo se puede leer pero no escribir.

Este diseño garantiza que no rompamos el uso existente de la dirección, pero mitiga la técnica mencionada anteriormente donde las vulnerabilidades remotas en modo kernel pueden utilizar la naturaleza escribible de la dirección digital fija para eludir KASLR.

Las siguientes figuras ilustran el cambio:

Figura 1: Antes de la Mitigación

Figura 2: Después de la Mitigación

Echemos un breve vistazo a cómo se implementa esta aleatorización y protección de página en Windows.

Como se ve en la Figura 2 anterior, el diseño requiere modificar todo el código existente en Windows que se basa en el diseño anterior para que sea compatible. Esto implicó cambiar todas las ubicaciones actuales en el código de modo kernel de Windows que escriben en la estructura KUSER_SHARED_Knowledge para usar la nueva dirección digital aleatoria.

Hay una nueva variable global. MmWriteableSharedUserData que almacena la dirección aleatoria de la nueva asignación. Esto no se exporta y solo es obvious para el código dentro del kernel de NT. La ubicación de esta variable world wide es aleatoria debido a que se encuentra dentro del núcleo NT, que a su vez es aleatorio..

Al principio, durante el arranque antes de la inicialización de la «Fase «, esta nueva variable worldwide contiene la dirección de la estructura fija (antigua) KUSER_SHARED_Information. Una vez que el sistema operativo está en la fase de inicialización (iniciando la paginación de administración de memoria, las entradas de la tabla de páginas del sistema, and so on.), la función que maneja la protección de la asignación KUSER_SHARED_Facts es MiProtectSharedUserPage. Anteriormente, esta función solo modificaba los permisos de la página KUSER_SHARED_Facts existente para que no fuera ejecutable. MiProtectSharedUserPage ahora realiza las siguientes acciones (no en el mismo orden en que se enumeran, el flujo se ha cambiado para mayor claridad):

  • Modifique los permisos de página del mapeo estático existente de la página KUSER_SHARED_Facts para que sea de solo lectura (sin permisos de escritura o ejecución). Cuando la página se mapea por primera vez al principio del arranque, tiene permisos RWX.
  • Cree una nueva asignación aleatoria de la página física KUSER_SHARED_Details subyacente. Establezca los permisos de esta asignación en READWRITE
  • La dirección digital de la nueva asignación aleatoria se escribe dentro de la variable world exclusiva de NTOS MmWriteableSharedUserData

Esta mitigación interrumpe la capacidad de los atacantes remotos de usar la estructura KUSER_SHARED_Facts para explotar las primitivas de escritura ciega, ya que la dirección de escritura ahora es aleatoria y la dirección estática es de solo lectura.

Compatibilidad de aplicaciones

La estructura KUSER_SHARED_Knowledge está destinada a ser actualizada solo por el sistema operativo central y los controladores internos. Los controladores externos de terceros deben no confiar en escribir o actualizar esta estructura. Hemos estado trabajando con proveedores externos y desarrolladores de controladores que están probando su código en compilaciones de Home windows Insiders para garantizar que sus productos sigan siendo compatibles. Un controlador de terceros incompatible que se basa en escribir en la dirección estática precise de KUSER_SHARED_Information provocará un bloqueo del sistema. Si desarrolla controladores para Windows, asegúrese de probarlos con las compilaciones actuales de Home windows Insider Preview y actualice cualquier código heredado para que siga siendo compatible con el sistema operativo más reciente.

Liberar

Esta función está habilitada solo en Home windows de 64 bits (AMD64 y ARM64) y puede probarla actualmente con un Programa Home windows Insider establish (felicitaciones a los investigadores de seguridad externos que ya han comenzado notando ¡estos cambios!). Tenemos la intención de incluir esta mitigación en una versión futura de Home windows.

Rohit madre, Centro de respuestas de seguridad de Microsoft (MSRC)

Agradecimientos especiales a joe bialek y el gobernador Maharaj




Fuente del articulo