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:
- Obtener el handler del proceso a partir de su PID
- Comprobar si existe el DLL a inyectar y localizarlo
- Reservar espacio en la memoria de la aplicación para cargar el DLL
- Usar la función LoadLibraryA el DLL kernel32.dll para cargar el DLL en la memoria del proceso
- 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:
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