DLL Injection con BoomER - BoomerNiX

lunes, 9 de julio de 2018

DLL Injection con BoomER

En el post de hoy vengo a hablar de cómo realizar una inyección de DLL con BoomER. Cuento con la colaboración de Antonio Marcos Peña, mi compañero durante el desarrollo del trabajo fin de máster.

Durante el desarrollo de BoomER, nuestro tutor (Pablo González) nos propuso añadir una funcionalidad para realizar DLL hijacking, es decir, aprovechar las DLLs que las aplicaciones intentan cargar en su memoria, pero que no se encuentran en el sistema. Nosotros le dimos una vuelta a esta propuesta y al final implementamos un módulo que permitiese la carga de DLLs en una aplicación, aunque ésta no hiciese uso del DLL que se inyectase. Para este desarrollo nos apoyamos en la librería mayhem la cual podemos encontrar en GitHub y que facilita el trabajo con procesos de Windows, además de proporcionar ejemplos de su uso.

DLL Injection - Explicación a alto nivel

El funcionamiento del módulo es bastante simple, solo necesita dos parámetros de entrada, la ruta al DLL a inyectar y el proceso a donde lo vamos a inyectar. Los pasos que sigue el módulo para lograr inyectar una librería son los siguientes:

  1. Obtener el handler del proceso a partir de su PID
  2. Comprobar si existe el DLL a inyectar y localizarlo
  3. Reservar espacio en la memoria de la aplicación para cargar el DLL
  4. Usar la función LoadLibraryA el DLL kernel32.dll para cargar el DLL en la memoria del proceso
  5. Crear un hilo remoto que ejecute dicho DLL

A continuación, se muestra una captura con el funcionamiento del módulo en un equipo Windows 10 completamente actualizado sobre el proceso TuneUpUtilitiesAppx64.exe.


Y la evidencia de la inyección:


Nota: aclarar que la inyección de DLL solo la podremos hacer en procesos que corran con los mismos permisos que el usuario que lanza el DLL Inyection, es decir, que el objetivo de este módulo no es escalar privilegios ni nada parecido, sino hacer más difícil la detección de lo que ejecute el DLL. Además, no siempre podremos inyectar librerías en un proceso, hay un factor que nos limita y es la arquitectura de la aplicación, es decir, si es de 64 o 32 bits ya que no podremos inyectar librerías de 64 bits en un proceso de 32 por ejemplo.

DLL Injection - Scripts en Python

Una vez realizamos la funcionalidad del DLL Inyection y dado que el desarrollo se ha realizado usando Python, nos planteamos si sería posible dar la oportunidad a un pentester a desarrollar un pequeño script en Python y ejecutarlo en la máquina de forma que lo haga cargado en la memoria de un proceso, de forma que disminuyese la detección de éste. Tras analizarlo y estudiarlo, observamos que en caso de tener instalado Python, el lenguaje incorpora un DLL llamado python36.dll en caso de ser la versión 3.6.*, en cualquier el nombre se puede construir como la major y minor versión de Python.


Es por eso, que si usábamos lo que ya teníamos seríamos capaces de cargar este DLL en un proceso, lo único que nos faltaba era que pudiésemos ejecutar código Python desde el DLL.

A partir de la documentación oficial de Python observamos que el DLL proporcionaba una serie de funciones, de las cuales dos de ellas resolvían nuestra casuística. Estas funciones son Py_InitializeEx y PyRun_SimpleString. La primera función carga el intérprete de Python, lo cual nos permitirá posteriormente lanzar comandos en este lenguaje usando la segunda función, la cual solo nos permite ejecutar comandos en una línea.

En este caso el módulo es muy similar al anterior, es decir, inyecta un DLL en un proceso, sin embargo, va más allá y ejecuta código (Python) en la memoria del proceso. A diferencia del módulo de DLL Injection a este módulo no se le indica la ruta del DLL a inyectar ya que el nombre es conocido y se busca dinámicamente. En su lugar, se solicita o bien un script en Python escrito en una línea, o bien la ruta a un fichero que contenga el script.

En la siguiente captura se muestra a continuación se realiza un sencillo script que ejecutar la calculadora del sistema.



En la siguiente figura se muestra cómo el proceso carga el DLL de Python.


Y en la imagen que vemos abajo, se muestra cómo se ha ejecutado el código y se ejecuta la calculadora:


Por último, al igual que en apartado anterior, es necesario indicar dos aspectos, que son los siguientes: el requisito más obvio e importante es que es necesario que la máquina donde se realiza la inyección tenga instalado Python. El segundo aspecto es lo que se comentó anteriormente sobre la arquitectura de los procesos, si la versión de Python que tenemos instalada es de 64 bits, no podremos realizar la inyección del DLL de Python y por lo tanto no podremos ejecutar ningún script.

A continuación, se muestran un par de vídeos:






Hasta aquí llega el post de hoy, gracias por tu colaboración Antonio.

No hay comentarios:

Publicar un comentario