
Evasión del análisis de comportamiento mediante la ejecución de código malicioso dentro de pilas de llamadas de Microsoft de confianza, biblioteca de hooking sin parches IAT/EAT.
LazyHook es un framework sigiloso de hooking de API que evita los sistemas de prevención de intrusiones de host (HIPS) mediante la suplantación de la pila de llamadas. Al aprovechar los puntos de interrupción de hardware a nivel de CPU y el manejo de excepciones vectorizadas, ejecuta código arbitrario como si se originara en módulos confiables firmados por Microsoft, engañando por completo a los motores de análisis de comportamiento que dependen de la inspección de la pila de llamadas y la verificación del origen del módulo.
Evita el análisis de comportamiento ejecutando código malicioso dentro de pilas de llamadas confiables de Microsoft
Utiliza puntos de interrupción de hardware + VEH para secuestrar funciones legítimas y suplantar orígenes de módulos
Los sistemas de prevención de intrusiones de host (HIPS) y los motores de análisis de comportamiento monitorean las aplicaciones mediante:
Sistemas como Kaspersky System Watcher, Windows Defender, Cylance y CrowdStrike emplean variaciones de estas técnicas.
Al secuestrar una función en un ensamblado firmado por Microsoft (ej., System.Windows.Forms.dll, user32.dll), podemos ejecutar lógica arbitraria dentro de una pila de llamadas que parece completamente legítima.
Nota: Es posible hacer un JmpHook, que enganchará MsgBox -> y justo después llamará a tu código personalizado. LazyHook no hace eso.
Por qué funciona esto:
El software de seguridad ve el segundo escenario y piensa: "¿MessageBoxA de user32.dll está llamando a las API de Windows? Eso es comportamiento normal."
┌─────────────────────────────────────────────────────────┐
│ 1. Llamada a la función objetivo │
│ ↓ │
│ 2. Se activa el registro de depuración de la CPU (DR0-DR3)│
│ ↓ │
│ 3. Se genera EXCEPTION_SINGLE_STEP │
│ ↓ │
│ 4. El manejador VEH intercepta la excepción │
│ ↓ │
│ 5. La ejecución se redirige a la función hook │
│ ↓ │
│ 6. CallOriginal() desactiva temporalmente el punto de interrupción│
│ ↓ │
│ 7. Se ejecuta la función original │
│ ↓ │
│ 8. Se reactiva el punto de interrupción │
└─────────────────────────────────────────────────────────┘
Intercepta funciones importadas localizando su dirección en la IAT y estableciendo un punto de interrupción de hardware. Esto engancha la importación específica en tu proceso.
HookIAT("user32.dll", "MessageBoxA", HookFunction, &OriginalFunction);
Engancha funciones exportadas globalmente desde una DLL resolviendo su dirección a través de la tabla de exportación. Esto afecta a todas las llamadas a esa exportación.
HookEAT("amsi.dll", "AmsiScanBuffer", HookFunction, &OriginalFunction);
La demostración incluida muestra tres escenarios prácticos:
Demuestra el hooking de IAT interceptando llamadas a MessageBoxA y modificando el mensaje mostrado:
int WINAPI HookMessageBoxA(HWND H, LPCSTR T, LPCSTR C, UINT U)
{
printf("[*] MessageBoxA hooked!\n");
return LazyHook::CallOriginal<int>(LazyHook::GetIatState(), H, "Hooked!", ">:)", U);
}
Muestra cómo monitorear operaciones de archivos registrando llamadas a CreateFileA:
HANDLE WINAPI HookCreateFileA(LPCSTR Filename, ...)
{
printf("[*] CreateFileA hooked: %s\n", Filename);
return LazyHook::CallOriginal<HANDLE>(...);
}
Demuestra el bypass del software de seguridad forzando a que todos los escaneos de AMSI devuelvan resultados limpios:
HRESULT WINAPI HookAmsiScanBuffer(...)
{
printf("[*] AmsiScanBuffer hooked! Bypassing...\n");
HRESULT OrgResult = LazyHook::CallOriginal<HRESULT>(...);
(*Result) = AMSI_RESULT_CLEAN; // Force clean regardless of content
return OrgResult;
}
La demostración prueba el bypass de AMSI escaneando "Invoke-Mimikatz" (una cadena maliciosa conocida) y muestra que se clasifica como limpio.
DR7 Layout (Simplified):
- Bits 0,2,4,6: Enable flags for DR0-DR3 (Local Enable)
- Bits 16-31: Breakpoint conditions (Execute, Write, IO, R/W)
El framework configura DR7 para:
El manejador VEH:
EXCEPTION_SINGLE_STEPEXCEPTION_CONTINUE_EXECUTION para reanudar en el hooktemplate<typename Ret, typename... Args>
Ret CallOriginal(VehHookState* State, Args... args)
{
RemoveHardwareBreakpoint(State->DrIndex); // Disable temporarily
Ret Result = ((FuncType)State->OriginalFunction)(args...);
SetHardwareBreakpoint(State->OriginalFunction, State->DrIndex); // Re-enable
return Result;
}
La demostración muestra el hooking de AmsiScanBuffer para forzar resultados de escaneo limpios:
HRESULT WINAPI HookAmsiScanBuffer(...)
{
HRESULT Result = LazyHook::CallOriginal<HRESULT>(...);
(*Result) = AMSI_RESULT_CLEAN; // Force clean result
return Result;
}
Esto demuestra cómo el comportamiento del software de seguridad puede modificarse en tiempo de ejecución interceptando llamadas críticas de API.
Engancha CreateFileA para registrar el acceso a archivos sin modificar el comportamiento de la aplicación:
HANDLE WINAPI HookCreateFileA(LPCSTR Filename, ...)
{
printf("File accessed: %s\n", Filename);
return LazyHook::CallOriginal<HANDLE>(...);
}
Este código demuestra técnicas avanzadas de evasión para:
⚠️ Advertencia: El uso no autorizado para eludir controles de seguridad, modificar el comportamiento del software o eludir protecciones puede violar las leyes de fraude informático (CFAA, GDPR, legislación equivalente). Este framework se proporciona solo para investigación de seguridad educativa y autorizada.
Comprender las técnicas ofensivas construye mejores defensas.