La falla del motor de base de datos Jet puede conducir a la explotación: análisis de CVE-2018-8423


En septiembre de 2018, la Zero Day Initiative publicó un prueba de concepto para una vulnerabilidad en el motor de base de datos Jet de Microsoft. Microsoft lanzó un parche en octubre de 2018. Investigamos esta falla en ese momento para proteger a nuestros clientes. Pudimos encontrar algunos problemas con el parche e informarlo a Microsoft, lo que resultó en otra vulnerabilidad, CVE-2019-0576, que se corrigió el 8 de enero de 2018 (martes de parche de Microsoft enero de 2019).

La vulnerabilidad explota el motor de base de datos Microsoft Jet, un componente utilizado en muchas aplicaciones de Microsoft, incluido Access. La falla permite que un atacante ejecute código para escalar privilegios o descargar malware. No sabemos si la vulnerabilidad se utiliza en algún ataque; sin embargo, el código de prueba de concepto está ampliamente disponible.

Visión general

Para aprovechar esta vulnerabilidad, un atacante necesita usar técnicas de ingeniería social para convencer a una víctima de que abra un archivo JavaScript que utiliza un objeto de conexión ADODB para acceder a un archivo malicioso de la base de datos Jet. Una vez que se accede al archivo malicioso de la base de datos de Jet, llama a la función vulnerable en msrd3x40.dll que puede conducir a la explotación de esta vulnerabilidad.

Aunque la prueba de concepto disponible provoca un bloqueo en wscript.exe, cualquier aplicación que use esta DLL es susceptible al ataque.

El siguiente mensaje de error indica que la vulnerabilidad se activó correctamente:

El mensaje muestra que se produjo una infracción de acceso en la DLL vulnerable. Esta vulnerabilidad es un "Escritura fuera de límites", Que se puede activar a través de OLE DB, la API utilizada para acceder a datos en muchas aplicaciones de Microsoft. Este tipo de vulnerabilidad indica que los datos se pueden escribir fuera del búfer previsto, lo que resulta en un bloqueo. La causa del bloqueo es el archivo de base de datos Jet creado con fines malintencionados. El archivo explota un campo de índice en el formato de archivo de la base de datos Jet con un número inesperadamente grande, lo que resulta en una escritura fuera de los límites y, en última instancia, el bloqueo anterior.

El siguiente diagrama proporciona una vista de alto nivel de cómo funciona el exploit:

Explotar en acción

El código de prueba de concepto contiene un archivo JavaScript (poc.js), que llama a un segundo archivo (grupo1). Este es el archivo de base de datos Jet. Al ejecutar poc.js a través de wscript.exe, podemos activar el bloqueo.

Como vemos en la imagen anterior, podemos revisar la información de depuración para determinar que la función que falla es "msrd3x40! TblPage :: CreateIndexes". Además, podemos determinar que el programa está intentando escribir datos y falla. Específicamente, podemos ver que el programa está utilizando el registro "esi" para escribir en la ubicación (edx + ecx * 4 + 574h), pero esa ubicación no es accesible.

Necesitamos entender cómo se construye esta ubicación para proporcionar pistas sobre la causa raíz. La información de depuración muestra que el registro ecx contiene el valor 0x00002300. Edx es un puntero a la memoria que veremos nuevamente más tarde. Finalmente, se agregan junto con un desplazamiento de 574 bytes hexadecimales para hacer referencia a la ubicación de la memoria. A partir de esta información, podemos adivinar el tipo de datos que se almacenan allí. Parece ser una matriz en la que cada variable tiene 4 bytes de longitud y comienza en la ubicación edx + 574h. Mientras rastreamos el programa, determinamos que el valor 0x00002300 proviene del archivo de prueba de concepto group1.

Sabemos que el programa intenta escribir fuera de los límites y sabemos dónde ocurre el intento. Ahora necesitamos determinar por qué el programa intenta escribir en esa ubicación. Investigamos los datos proporcionados por el usuario de 0x00002300 para comprender su propósito. Para hacer esto debemos entender el archivo de base de datos Jet.

Analizando el archivo de base de datos Jet

Muchos investigadores han analizado ampliamente la estructura de archivos de la base de datos Jet. Algunos de los detalles del trabajo anterior se pueden encontrar en los siguientes enlaces:

Para resumir, un archivo de base de datos Jet está organizado como una colección de páginas, como se muestra en la siguiente imagen:

La página de encabezado contiene diversa información relacionada con el archivo:

Después del encabezado vienen 126 bytes, RC4 encriptados, con la clave específica 0x6b39dac7, que es la misma para cada archivo JetDB. Al comparar el valor clave con el archivo de prueba de concepto, podemos identificar que group1 es un archivo Jet Versión 3.

Un examen más detallado lleva a una sección de Páginas de definición de tabla, que describe varias estructuras de datos para una tabla. (Haga clic aquí para más detalles).

Los datos de definición de la tabla tienen varios campos, incluidos dos de nota: Recuento de índice y Recuento de índice real.

Podemos determinar el valor de estos en nuestro archivo de prueba de concepto. Cuando verificamos esto con el archivo group1, vemos lo siguiente:

Hay un total de dos índices en el Recuento de índices. Cuando analizamos ambos índices, vemos el valor familiar de 0x00002300:

Nuestro valor ofensivo 0x00230000 es el número de índice para index2 en la tabla. Este índice parece bastante grande y conduce al bloqueo. ¿Por qué bloquea el programa? Analizando más el archivo, encontramos los nombres de los dos índices:

Depuración

Con un depurador conectado, podemos ver que el primer programa llama a la función "operador msrd3x40 nuevo". Esto asigna memoria que almacena la dirección del puntero de memoria en eax:

Después de asignar la memoria, el programa crea el nuevo índice:

Este número de índice se usa más adelante en la ejecución. La función msrd3x40! Index :: Restore copia ese número de índice en la dirección de índice + 24h. Este proceso se repite en un bucle para todos los índices. Primero llama al operador "nuevo", que asigna la memoria. Luego crea un índice en esa dirección y mueve el número de índice a la dirección base del índice + 24h. Vemos este movimiento en el siguiente código, que muestra el valor del índice malicioso copiado en el índice recién creado:

Una vez que se ha movido con éxito, se llama a la función msrd3x40! NamedObject :: Rename y copia el valor del nombre del índice en la dirección del índice + 40h:

Si miramos el registro esi, vemos que apunta a la dirección del índice. El registro ecx tiene un valor de (esi + 24h), que es el número de índice:

Después de algunas instrucciones más, podemos observar las instrucciones originales de bloqueo. Edx apunta a la ubicación de la memoria. Ecx contiene un número muy grande del grupo de archivos1. El programa intenta acceder a la memoria en la ubicación (edx + ecx * 4 + 574h), lo que provocará una escritura fuera de los límites y el programa se bloquea:

¿Qué está pasando con los datos que el programa intenta escribir? Si miramos las instrucciones, vemos que el programa intenta escribir el valor de esi en (edx + ecx * 4 + 574). Si imprimimos esi o el valor anterior, vemos que contiene el nombre de índice ParentIdName, que vimos en group1:

Finalmente, el programa se bloquea al intentar procesar ParentIDName con un número de índice muy grande. La lógica:

  • Asigne la memoria y coloque el puntero al inicio de la ubicación de la memoria.
  • Desde el inicio de la ubicación de memoria + 574h, el programa guarda los punteros en los nombres de índice, cada uno de los cuales ocupa 4 bytes multiplicados por el número de índice mencionado en el archivo.

Si el número de índice es muy grande, como en este caso, y no se realiza ninguna validación, entonces el programa intentará escribir fuera de los límites y bloquearse.

Conclusión

Este es un error lógico y tales errores a veces son difíciles de atrapar. Muchos desarrolladores toman precauciones adicionales para evitar este tipo de errores en su código. Es aún más desafortunado cuando estos errores conducen a serios problemas de seguridad, como con CVE-2018-8423. Cuando se descubren y reparan estos problemas, recomendamos aplicar el parche del proveedor lo antes posible para reducir sus riesgos de seguridad.

Los parches de Microsoft se pueden descargar e instalar desde las siguientes ubicaciones para los CVE respectivos:

CVE-2018-8423

https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8423

CVE-2019-0576

https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0576

Detección de McAfee:

Los clientes de McAfee Network Security Platform están protegidos de esta vulnerabilidad mediante los identificadores de firma 0x45251700 – HTTP: Vulnerabilidad de ejecución remota de código del motor de base de datos Microsoft JET (CVE-2018-8423) y 0x4525890 – HTTP: Vulnerabilidad de ejecución remota de código del motor de base de datos Microsoft JET (CVE-2019- 0576).

McAfee AV detecta archivos maliciosos como BackDoor-DKI.dr .

McAfee HIPS, la función GBOP (Generic Buffer Overflow Protection) podría cubrir esto, dependiendo del proceso utilizado para explotar la vulnerabilidad.

Agradecemos a Steve Povolny, del equipo de Investigación Avanzada de Amenazas de McAfee, y a Bing Sun e Imran Ebrahim, del equipo Hybrid Gateway Security de McAfee, por su apoyo y orientación con este análisis.

Referencias





Enlace a la noticia original