jueves, 28 de agosto de 2014

Ingeniería inversa de un parche de Microsoft Windows

A estas alturas ya hemos asumido que la seguridad total en Internet es, cuanto menos, un mito. Ningún software está libre de vulnerabilidades, y por mucha auditoría, test de intrusión o pruebas de fuzzing que nos empeñemos en hacer, ninguna metodología puede demostrar sin lugar a dudas que un software es 100% seguro. Ante este panorama, hay dos tendencias mayoritarias a la hora de hacer públicas las vulnerabilidades.
Por un lado, están los que piensan que cuando se descubre un fallo ha de hacerse público de forma inmediata. En este escenario, la publicación de una vulnerabilidad es el pistoletazo de salida para una carrera entre el desarrollador para sacar el parche y los "malos" para lograr explotarla. Esta política es conocida como full disclosure.
Por otro lado, tenemos a los siguen una política responsible disclosure, que abogan por mantener la vulnerabilidad en secreto hasta la salida del parche por parte del desarrollador. Sin entrar en cuestiones filosóficas que no vienen al caso sobre qué política es más adecuada, la segunda, seguida por empresas como Microsoft, han dado lugar a una práctica muy habitual últimamente. Cuando Microsoft publica un parche para un software, inmediatamente hay un montón de analistas que se dedican a hacer ingeniería inversa del parche, ya sea por pura curiosidad o para explotar la vulnerabilidad en aquellos equipos que aún no se hayan actualizado. En cualquier caso, puede ser muy ilustrativo ver cómo es el proceso de reversing de un parche de Windows, así que veamos un ejemplo sencillo.


Como ejemplo vamos a tomar una vulnerabilidad más o menos reciente. La KB2864063. Incluida en la actualización MS13-071 y también conocida como CVE-2013-0810. La vulnerabilidad que corrige esta actualización es la siguiente:


Microsoft Windows XP SP2 and SP3, Windows Server 2003 SP2, Windows Vista SP2, and Windows Server 2008 SP2 allow remote attackers to execute arbitrary code via a crafted screensaver in a theme file, aka "Windows Theme File Remote Code Execution Vulnerability."

Básicamente, se trata de una vulnerabilidad que permite la ejecución de código remoto a partir de un fichero de salvapantallas de un tema para Windows modificado de forma malintencionada. Más concretamente, es posible indicar una ruta cualquiera, incluyendo una ruta SMB para el archivo de salvapantallas, por lo que podría especificarse uno remoto.
Visto esto, vamos al grano y descarguemos la actualización desde la página oficial: http://www.microsoft.com/en-us/download/details.aspx?id=40062
En este caso descargamos la versión para Windows XP SP3, con la que vamos a hacer la demo dentro de una máquina virtual, pero el proceso es similar en cualquier versión de Windows, salvo algún detalle que comentaré sobre la marcha.

El archivo que hemos descargado es WindowsXP-KB2864063-x86-ESN.exe, que es un archivo comprimido ejecutable. Para extraer los archivos lo ejecutamos con la opción -x, y se expandirán los siguientes ficheros y directorios.


Dentro de la carpeta SP3QFE encontraremos un archivo llamado themeui.dll, que es precisamente el archivo DLL que va a reemplazar al que hay con el mismo nombre en la carpeta system32 de Windows.

Para versiones de Windows superiores a XP, los archivos de actualización tienen la extensión .msu y se extraen de forma diferente:

expand -F:* .msu C:\MSUFolder

Ya estamos listos para comenzar, y lo primero que tenemos que hacer es comparar el nuevo archivo themeui.dll con el anterior. Para ello nos valdremos de un plugin para IDA Pro llamado TurboDiff, que podemos descargar de http://corelabs.coresecurity.com/index.php?module=Wiki&action=view&type=tool&name=turbodiff. Sólo tenemos que descomprimir el plugin en el directorio ..\IDA\plugins de IDA Pro.
Por supuesto necesitamos IDA Pro. Podemos descargar una versión freeware desde https://www.hex-rays.com/products/ida/support/download_freeware.shtml.

Para no confundirnos con los ficheros, renombraremos el fichero themeui.dll antigua como themeuiOLD.dll
Los pasos para hacer la comparación son los siguientes.

- Cargamos el fichero themeuiOLD.dll antiguo en IDA Pro.
- Iniciamos TurboDiff desde File > plugins > turbodiff.
- Seleccionamos take info from this idb.

Repetimos los tres pasos con el nuevo themeui.dll.
Finalmente, volvemos a lanzar TurboDiff desde File > plugins > turbodiff pero en esta ocasión seleccionamos compare with....

Se abrirá una ventana en la que veremos qué funciones son iguales y cuales han cambiado, indicándonos las diferencias. Desgraciadamente, vamos encontrar muchos falsos positivos, ya que de una compilación a otra puede aplicarse optimizaciones de código diferentes o cambios en algunas direcciones de memoria, sin embargo, revisando bien las diferencias vemos que el método CThemePage::_OnLoadThemeValues ha cambiado bastante, así que lo seleccionamos y pulsamos OK, lo que abrirá dos ventanas en las que se muestran las diferencias de los dos archivos dentro del código.


TurboDiff usa un código de colores para indicar qué diferencias hay entre ambos códigos:
Blanco - No hay cambios. Son idénticos.
Verde - Tienen el mismo número de instrucciones, aunque no son iguales.
Amarillo - Tienen diferente número de instrucciones.
Rojo - El bloque de código no tiene correspondencia entre ambos ficheros.

En nuestro caso vemos que ha habido los siguientes cambios.


La ventana de la izquierda (con cuadros rojos) pertenece al fichero themeuiOLD.dll (el antiguo) y la de la derecha al nuevo.
No vamos a entrar en detalles sobre los cambios del código ya que no es la misión de este artículo que se acabaría extendiendo demasiado. Simplemente comentaremos muy por encima las modificaciones que se aprecian en la imagen.
El código en rojo es código que se ha eliminado de la DLL original. Este código utiliza un PropertyBag para almacenar directamente y tal como llega la información de la ruta del salvapantallas. Recordemos que era ahí precisamente donde estaba el problema, así que el desarrollador ha optado por eliminar este código y realizar las comprobaciones en una función llamada EnsureInboxScreenSaver.


Si escarbamos un poco más vemos que esta función se apoya en otra llamada IsInboxScreenSaver.


Si seguimos indagando podremos ver que lo que se pretende es que no sea posible usar una ruta remota para cargar el screensaver, así que ya tenemos una pista de por donde podemos explotar esta vulnerabilidad.
En definitiva, analizando la actualización, y sin tener conocimiento previo de la vulnerabilidad que soluciona (aunque en este caso teníamos cierta información) es posible averiguar dónde está el problema y crear un exploit a partir del parche, que sería peligroso para aquellos equipos que aún no estén actualizados. Por desgracia, ésta es una práctica extendida que pone de relieve la necesidad de mantener los equipos lo más actualizados posible.



No hay comentarios:

Publicar un comentario en la entrada