martes, mayo 11, 2021

Cómo explotar una vulnerabilidad de DLL Hijacking en Slack para Windows

Hasta aquí hemos hablado sobre qué es una DLL y en qué consisten las técnicas de DLL Injection, y también de cómo detectar oportunidades para el DLL Hijacking usando Process Explorer, en el caso de nuestro ejemplo en Slack para Windows. Ahora nos toca continuar el trabajo donde lo dejamos e intentar explotar esta oportunidad de DLL Injection

Figura 1: Cómo explotar una vulnerabilidad de DLL Hijacking en Slack para Windows

Como hasta este momento no hemos analizado el binario, no sabemos cómo reaccionará el programa frente al ataque, por lo que la única manera de saber si alguna de esas DLL hace al programa realmente vulnerable al hijacking es mediante ensayo y error. Por norma general, para demostrar un DLL Hijacking de forma práctica se suele recurrir a un programa que simplemente cargue una DLL en tiempo de ejecución mediante la función LoadLibrary(). El ejemplo típico es el siguiente:

Figura 2: Código prototipo en la demostración de un ataque de DLL Hijacking

Hacer un DLL hijacking a este programa es trivial ya que basta con crear una DLL que contenga en su entry-point un payload que nos ayude a identificar que esta DLL maliciosa se carga. En el caso de la siguiente figura el payload es una caja de texto con un mensaje.

Figura 3: DLL maliciosa cuyo payload lanza una ventana con un texto cuando se ejecuta

En este caso, al utilizar la función LoadLibrary() sin especificar la ruta absoluta de la DLL se buscará primero en el directorio de la aplicación (donde se ha depositado la DLL maliciosa previamente) y cuando se cargue la DLL maliciosa se ejecutará el lanzando el mensaje que habíamos escrito:

Figura 4: Resultado de la ejecución del payload

El problema surge cuando queremos ejecutar este mismo ataque con programas reales, entonces observamos que este ejemplo no es muy representativo en la práctica real. Cuando se trata de programas complejos la mayoría de las DLL que identificaremos como vulnerables al hijacking se cargarán mediante vinculación implícita (a través del linker) y, además, tendremos que asegurarnos de que la ejecución del programa no se rompa cuando se cargue la DLL maliciosa en vez de la DLL legítima. 

Figura 5: Libro de Hacking Windows en 0xWord
de Valentín Martín, Carlos García y Pablo González

Esto significa que nuestra DLL maliciosa debe contener, de alguna manera, las funciones que el programa importaría de la DLL legítima. Para lograr esto vamos a recurrir a una técnica conocida como DLL Proxying.

Efectuando un DLL Proxying

Como no sería práctico copiar o replicar en nuestra DLL cada una de las funciones que exporta la DLL legítima a la que intentamos suplantar, vamos a aprovechar la capacidad que nos ofrece el compilador de C/C++ de Visual Studio de Microsoft para exportar funciones a través de una directiva de preprocesador

Figura 6: Sintaxis de la directiva que actúa como forwarder

La idea es que cuando se cargue la DLL maliciosa, además de ejecutarse el payload, le “diga” al loader que las funciones deben importarse desde la DLL legítima, haciendo que nuestra DLL actúe como un proxy de funciones. Las directivas export que hacen esto posible se conocen como forwarders y tienen la sintaxis que puedes ver en la Figura 6. En resumen, para hacer un DLL Proxying vamos a introducir dos DLL en el directorio de la aplicación:
  • La DLL maliciosa que actuará como proxy y que contiene el payload y los forwarders.
  • La DLL legítima que contiene las funciones que necesitan ser exportadas para que el programa se ejecute correctamente.
El proceso para crear una DLL Proxy es un poco tedioso. Tras identificar la DLL que queremos suplantar, necesitamos conocer las funciones que esta DLL exporta. Para hacer esto vamos a utilizar el programa DLL Export Viewer (dllexp). El uso de dllexp es muy sencillo: abrimos el programa y seleccionamos la ruta de la DLL que queremos inspeccionar (generalmente en C:\Windows\System32\) y una vez generada la lista de funciones la exportamos como reporte en HTML:

Figura 7: Uso de DLL Export Viewer

Ahora que tenemos la lista de funciones exportadas hay que crear una directiva que sirva como forwarder para cada una de las funciones. Para hacer esto hay varios scripts que automatizan la tarea de convertir el reporte HTML a las directivas #pragma que necesitamos copiar en el código de nuestra DLL. Yo he usado el script de itm4n (Apartado 3, el script está incrustado como texto plano). Tras copiar las directivas en la DLL maliciosa tendrá este aspecto:

Figura 8: Ejemplo de DLL con directivas que actúan como forwarders

Con esto ya tenemos lista la DLL que actuará como proxy. También necesitamos copiar la DLL legítima que se encuentra en C:\Windows\System32\. Ahora solo tenemos que renombrar la DLL maliciosa con el nombre de la DLL legítima y la DLL legítima según el nombre que hayamos puesto en la directiva pragma. Si usas el script de itm4n el nombre por defecto es el mismo nombre de la DLL añadiendo el sufijo “_orig”. 

Figura 9: PoC de DLL Hijacking en Slack para Windows

Una vez hecho este trabajo, basta con introducir ambas DLL en el directorio de la aplicación y comprobar que al ejecutar Slack se ejecuta también nuestro payload tal y como se puede ver en el vídeo de la PoC anterior.

No hay comentarios:

Publicar un comentario