Esta entrada corresponde a la segunda y última parte del análisis que previamente habíamos comenzado. En la primera parte vimos como obtener la imagen TIFF (Tagged Image File Format) que dispara la vulnerabilidad, en este post analizaremos un poco el bug y veremos como se ejecuta el código remoto.

Para entender el post, serán necesarios diferentes conocimientos sobre exploit writing y arquitectura de computadoras.

Examinando la vulnerabilidad

El agujero de seguridad se encuentra en la siguiente zona:

Esta porción de código corresponde al módulo AcroForm.api de Adobe Reader. Aquí se esta copiando la cantidad de bytes definidos en el registro EDI a una variable local, esta variable reside en la pila del programa, al no haber ningún chequeo de tamaño tiene la posibilidad de escribir zonas contiguas de memoria en la pila del programa.

Esta es una técnica de explotación que tiene mas de 20 años de antigüedad, conocida mundialmente como buffer overflow. El valor de EDI  contiene el campo "Numero de valores" de las etiquetas de la imagen TIFF. Estas etiquetas tienen la siguiente estructura:

Tamaño Valor
2 bytes código identificador del tag
2 bytes Tipo de dato
4 bytes Numero de valores
4 bytes Desplazamiento hasta el dato

Veamos en el depurador para entender un poco más:

En primer lugar, se encuentra la etiqueta 0x150 correspondiente a DotRange marcado en amarillo, luego el numero de valores está marcado en verde y es el dato que manipula el registro EDI. Para ver esto, se modifica el valor y se verifica el registro EDI al momento de la llamada a memcpy vulnerable:

Al momento de empujar el argumento "n" de la llamada a memcpy, el registro tiene el doble del valor dispuesto en el campo "Numero de valores" de la etiqueta DotRange.

¿Que datos se copian a la pila del programa?

Si se presta atención a los datos de la estructura, más concretamente al campo offset resaltado con rosa, se puede observar el valor 0x2092. Este es el desplazamiento a los datos a partir del principio de la imagen:

Lo que se hizo anteriormente fue sumar la dirección de memoria del principio de la imagen con el valor de desplazamiento para obtener la ubicación en memoria de donde se usarán los datos a grabar. En la posición 0x354DFCA aparece lo siguiente:

La zona marcada corresponde a los gadgets ROP, esto dice tres cosas:

  • El dato realmente tendría que tener 8 bytes como mucho, ya que esa es la cantidad de memoria designada para el dato.
  • El software puede ser explotado aunque la protección DEP esté activada en Windows.
  • La primera dirección marcado en rojo, sobrescribe una dirección de retorno del programa haciendo que cambie el flujo de ejecución hacia una librería llamada BIB.

La elección de dicha DLL no es arbitraria, se usó la misma porque no tiene ASLR. Con eso garantizan que esas direcciones apunten a zonas de código especificas de la cual sacan provecho y logran hacer efectivo el exploit en distintos ámbitos.

Ya en esta parte, el atacante tiene completo control de lo que hará la maquina afectada, al ejecutarse el exploit se observa como solicita una zona de memoria con NtAllocateVirtualMemory:

Esta llamada la lanza con la API KiFastSystemCall, la misma se encarga de pasar de RING3 a RING0. Para analizar estas zonas se necesita un debugger de RING0, como por ejemplo WinDBG.

Luego copia diferentes bytes en las zona de memoria solicitada y le pasa la ejecución:

Esto es un egghunter, utilizado en exploit writing para localizar el código que se quiere ejecutar. Aparece una llamada a la interrupción 2e, encargada de pasar a RING0 y verificar la API NtAccessCheckAndAuditAlarm para chequear cuando se produce una excepción por leer memoria no válida:

Hasta ahora todo lo que se ejecutó fue para saltar las diferentes protecciones que tienen los sistemas Windows actuales, tales como DEP/ASLR y la imposibilidad de no predecir que zonas de memoria serán solicitadas por el programa. Luego del egghunter viene un puente de instrucciones NOP y posteriormente la shellcode:

Se podría observar perfectamente a partir del depurador para ver que es lo que ejecuta en realidad, pero en el Laboratorio de Análisis e Investigación de ESET Latinoamérica se ha creado una herramienta que una vez copiado el payload, lo ejecuta automáticamente y da información relevante. Estas son las llamadas más importantes que hace el payload:

Con esa llamada a la API, se descarga un ejecutable desde una URL con dominio .cc y  lo copia en los archivos temporales, luego procede a la ejecución del mismo con WinExec:

Al momento de realizar este análisis la URL estaba dada de baja, pero se presume que se trata de un cliente bot.

Conclusión

Hemos visto las diferentes etapas de un análisis de malware, y podemos llegar a la conclusión de que todo tiene su porqué en este mundo.

La primera etapa del FlateDecode era para poder insertar un archivo XML que será analizado para crear un formulario con el módulo AcroForm. Con esto ya se encuentra cargada la zona de memoria donde se encuentra la vulnerabilidad.

Luego, a través de la lectura de una imagen TIFF especialmente manipulada, se ejecutan diferentes códigos para saltar las barreras que tienen los actuales Windows contra este tipo de amenazas.

Para finalizar, debemos hacer especial hincapié en que es necesario tener el software actualizado, ya sea de nuestros navegadores, como también de los lectores PDF o cualquier software que corra en nuestra maquina. Con esto evitamos quedar expuestos ante una posible vulnerabilidad en el código del programa.

Javier Aguinaga
Malware Analyst