DLL Hijacking

Recientemente estoy realizando unos cursos de Pentester Academy muy interesantes. Gracias a ellos estoy aprendiendo bastante, dado que tratan temas muy particulares con ejemplos claros.  Hoy voy a mostrarte lo que he aprendido sobre DLL Hijacking.

Un DLL es una biblioteca de vínculos dinámicos. Existen dos tipos de DLL: los DLL del sistema, que proporciona propiamente Windows, y los DLL de las aplicaciones, en las que el desarrollador de la aplicación divide su funcionalidad en distintos DLLs.

Los ejecutables utilizan estos DLLs porque supone un diseño modular del código y permite la reutilización del mismo. Al hacerlo se crean dependencias, y según la importancia del DLL, si esas dependencias fallan al no encontrar el DLL, el programa puede seguir ejecutándose si se trata de un DLL que implementa una funcionalidad secundaria, o parar su ejecución si es un DLL imprescindible.

¿Cómo encuentra una aplicación el DLL adecuado? Mediante un orden de búsqueda determinado:

  1. Búsqueda en el directorio en el que se ha cargado la aplicación.
  2. Búsqueda en el directorio actual.
  3. Búsqueda en el directorio del sistema usando la función GetSystemDirectory.
  4. Búsqueda en el directorio de sistema de 16 bits.
  5. Búsqueda en el directorio de Windows usando la función GetWindowsDirectory.
  6. Búsqueda en todos los directorios listados en la variable de entorno PATH.

Si el modo SafeDllSearchMode está activo, la opción 2 pasa a ser la penúltima.

Esta disposición permite realizar algunos ataques de DLL Hijacking, en los que creas un DLL malicioso y lo haces pasar por uno que una aplicación necesite. A continuación vamos a ver una prueba de concepto de este tipo de ataque.

 

The Basics

En primer lugar necesitas descargar la herramienta Sysinternals Suite.  Dentro de todas las herramientas que nos ofrece este paquete, ejecutaremos Procmon.exe.

Como programa de pruebas utilizaremos 7-zip.exe. Al abrir Procmon, nos aparecerán todos los procesos que están corriendo ahora mismo en el sistema. En primer lugar debemos añadir un filtro para que solo nos muestre los procesos de 7-zip, mediante la pestaña de Filter:

Añadiremos otros dos filtros más: uno para indicar que la ruta contiene el texto “dll” (de esa forma se nos mostrarán solo los dll) y otro en el que el campo Result contenga “NAME NOT FOUND”, lo que indicará que no ha podido encontrar ese dll. Finalmente, este es el resultado:

Para encontrar un candidato idóneo que suplantar, buscaremos uno cuya operación sea “CreateFile”, que tenga disposición “Open” y que no haya encontrado el DLL. “Bcrypt.dll” nos valdrá:

A continuación vamos a crear un DLL que haga alguna función básica, para hacer una primera prueba de concepto, y después lo pondremos en la ruta donde está el exe, con ese nombre. Este es el código que tendría un DLL básico que muestra un mensaje al ejecutarse, está hecho en C:

Nos aprovechamos del DllMain para ejecutar lo que queramos. Para compilarlo, lo hacemos mediante el siguiente comando:

                        i686-w64-mingw32-gcc maliciousdll.c -o maliciousdll.dll -shared

Por último, lo colocamos en la misma carpeta en la que está el ejecutable de 7-zip, y lo renombramos a “Bcrypt.dll”. Y al abrirlo…

¡Estupendo! Dependiendo del dll escogido, la aplicación puede continuar ejecutándose o no. En principio, deberíamos poder colocar una reverse shell en lugar de un mensaje… Intentémoslo.

Reverse Shell con DLL Hijacking

Para conseguir el payload de la shell, he utilizado msfvenom. Con -p indico el tipo de shell, una reverse shell tcp de windows, con lhost indico la ip de la máquina atacante, con lport el puerto donde voy a estar a la escucha, con -a que la arquitectura es x86, con -platform que es para windows, y por último con -f indico que quiero el payload en hexadecimal:

Tras obtener el payload de la reverse shell de windows en hexadecimal, vamos a crear un nuevo script en c llamando de nuevo a la función DllMain:

Guardamos este archivo y lo compilamos como un dll mediante el comando i686-w64-mingw32-gcc maliciousdll2.c -o maliciousdll2.dll -shared

Ahora repetimos la operación anterior: ponemos la dll en el mismo sitio donde esté el ejecutable, y lo renombramos como uno de los dlls que utiliza el programa y no encuentra. Por ejemplo, esta vez podemos renombrarlo como PROPSYS.dll. En nuestra máquina atacante nos ponemos a la escucha con nc -lvnp 1234. Y al ejecutarlo…

Sin embargo, una gran cantidad de antivirus detecta esta shell como un virus. En concreto, 12 de los 50 antivirus más famosos lo detectan. Actualmente me encuentro investigando la forma de evadir los antivirus. Cuando lo consiga publicaré un nuevo post de una versión más avanzada de esta técnica con antivirus evasion.

Lethani.

 

Deja una respuesta