AvanzadoWindowsEDRevasiónhookssyscallskernel callbacks

EDR Internals: Cómo Funcionan y Cómo se Evaden

Análisis técnico de la arquitectura interna de los EDR modernos. User-mode hooks, kernel callbacks, ETW consumers, minifilters, y las técnicas de evasión que usa el malware: unhooking, direct syscalls, BYOVD, callback removal. Perspectiva ofensiva y defensiva.

MalwareIntel Research··9 min lectura
Serie: Malware en Windows — Parte 19

Cómo ve un EDR lo que ocurre en tu sistema

Un EDR (Endpoint Detection and Response) no es un antivirus con otro nombre. Es un sistema de monitorización y respuesta que opera en múltiples capas del sistema operativo simultáneamente. Entender su arquitectura interna es necesario tanto para los defensores (para saber qué cobertura tienen realmente) como para entender por qué ciertas técnicas de malware son efectivas.

Arquitectura de un EDR moderno

Las capas de monitorización

User Mode (Ring 3)
├── [Capa 1] Hooks en ntdll.dll
│   └── Interceptan: NtAllocateVirtualMemory, NtWriteVirtualMemory,
│       NtCreateThreadEx, NtMapViewOfSection, etc.
│
├── [Capa 2] ETW Consumers (user-mode)
│   └── Consumen: PowerShell, .NET, AMSI, DNS, WMI events
│
└── [Capa 3] AMSI Provider
    └── Escanea: scripts PowerShell, VBScript, .NET assemblies

Kernel Mode (Ring 0)
├── [Capa 4] Kernel Callbacks
│   ├── PsSetCreateProcessNotifyRoutine (procesos)
│   ├── PsSetCreateThreadNotifyRoutine (threads)
│   ├── PsSetLoadImageNotifyRoutine (DLLs/images)
│   ├── ObRegisterCallbacks (handles/objects)
│   └── CmRegisterCallback (registro)
│
├── [Capa 5] ETW Consumers (kernel)
│   └── Microsoft-Windows-Threat-Intelligence (ETW-TI, PPL required)
│
├── [Capa 6] Minifilter Driver
│   └── Intercepta I/O de archivos (crear, escribir, eliminar)
│
└── [Capa 7] Network Filter
    └── WFP (Windows Filtering Platform) para monitorizar red

Cloud
├── [Capa 8] Telemetría enviada al cloud
│   └── Análisis con ML, correlación entre endpoints, threat intel
│
└── [Capa 9] Respuesta remota
    └── Aislar endpoint, matar proceso, rollback

User-mode hooks: la capa más visible y más atacada

Cuando un EDR se instala, modifica funciones clave de ntdll.dll en cada proceso. El mecanismo es un inline hook:

ntdll!NtAllocateVirtualMemory (ORIGINAL):
  4C 8B D1          mov r10, rcx
  B8 18 00 00 00    mov eax, 0x18    ; syscall number
  0F 05             syscall
  C3                ret

ntdll!NtAllocateVirtualMemory (HOOKEADA por EDR):
  E9 XX XX XX XX    jmp EDR_Hook_NtAllocVM   ; salta al codigo del EDR
  B8 18 00 00 00    mov eax, 0x18
  0F 05             syscall
  C3                ret

Los primeros bytes se reemplazan con un jmp al código del EDR. El EDR analiza los parámetros, decide si la llamada es legítima, y si lo es, ejecuta las instrucciones originales seguidas del syscall.

Funciones comúnmente hookeadas

Función (ntdll)Por qué la hookea el EDR
NtAllocateVirtualMemoryDetectar asignación de memoria RWX (code injection)
NtWriteVirtualMemoryDetectar escritura en memoria de otro proceso
NtCreateThreadExDetectar creación de threads remotos
NtProtectVirtualMemoryDetectar cambio de permisos (RW→RWX)
NtMapViewOfSectionDetectar section mapping (PE loading)
NtQueueApcThreadDetectar APC injection
NtCreateFileMonitorizar acceso a archivos sensibles
NtOpenProcessDetectar acceso cross-process
NtDuplicateObjectDetectar duplicación de handles
NtSetContextThreadDetectar modificación de contexto (hollowing)

Kernel callbacks: la capa difícil de evadir

Los kernel callbacks se registran en el kernel del sistema operativo y notifican al EDR de eventos a nivel de sistema:

CallbackRegistrado conEventos
Process creationPsSetCreateProcessNotifyRoutineExTodo nuevo proceso
Thread creationPsSetCreateThreadNotifyRoutineTodo nuevo thread
Image loadPsSetLoadImageNotifyRoutineToda DLL/EXE cargada
Handle operationsObRegisterCallbacksApertura/duplicación de handles a procesos/threads
RegistryCmRegisterCallbackExOperaciones en el registro

Estos callbacks se ejecutan en kernel mode. No se pueden bypassear con técnicas de user-mode (unhooking, syscalls directas). Solo se pueden evadir con acceso al kernel (BYOVD, kernel exploit).

Técnicas de evasión de EDR

Técnica 1: Unhooking de ntdll

Restaurar las funciones originales de ntdll.dll eliminando los hooks del EDR:

Método A: Leer ntdll.dll desde disco

// 1. Abrir ntdll.dll desde disco (copia limpia, sin hooks)
HANDLE hFile = CreateFile("C:\\Windows\\System32\\ntdll.dll", GENERIC_READ, ...);

// 2. Mapear en memoria
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
LPVOID cleanNtdll = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

// 3. Encontrar la seccion .text de la copia limpia
// 4. Copiar .text limpio sobre .text hookeado del ntdll cargado
LPVOID hookedNtdll = GetModuleHandle("ntdll.dll");
// ... copiar seccion .text de cleanNtdll a hookedNtdll

Método B: Leer desde KnownDlls

// KnownDlls es un directorio de objetos del kernel con copias limpias de DLLs del sistema
HANDLE hSection;
UNICODE_STRING name;
RtlInitUnicodeString(&name, L"\\KnownDlls\\ntdll.dll");
OBJECT_ATTRIBUTES objAttr;
InitializeObjectAttributes(&objAttr, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);
NtOpenSection(&hSection, SECTION_MAP_READ, &objAttr);
// Mapear y copiar .text

Método C: Suspender threads del EDR y unhook

Suspender los threads del EDR temporalmente para que no detecte el unhooking:

// 1. Enumerar threads del proceso del EDR
// 2. SuspendThread() en cada uno
// 3. Unhook ntdll
// 4. Ejecutar payload
// 5. Re-hook ntdll (opcional)
// 6. ResumeThread() en cada uno

Técnica 2: Direct Syscalls

Eludir ntdll completamente ejecutando syscalls directamente:

; En vez de llamar a NtAllocateVirtualMemory en ntdll (hookeado):
; Ejecutar la syscall directamente

mov r10, rcx
mov eax, 0x18        ; Syscall number de NtAllocateVirtualMemory
syscall              ; Ir directamente al kernel
ret

Problema: los syscall numbers cambian entre versiones de Windows. Herramientas que lo resuelven:

HerramientaMétodo
SysWhispers3Genera stubs con syscall numbers hardcodeados por versión
HellsGateLee los syscall numbers dinámicamente de ntdll en runtime
Halo's GateComo HellsGate pero funciona incluso si ntdll está hookeada (lee de funciones vecinas)
TartarusGateCombinación de técnicas para máxima compatibilidad
RecycledGateReutiliza stubs de syscall de funciones no hookeadas

Técnica 3: Indirect Syscalls

Variante de direct syscalls que es más difícil de detectar:

En vez de ejecutar 'syscall' en el codigo del malware (detectable por EDR como
codigo fuera de ntdll ejecutando syscall), el malware salta a la instruccion
'syscall' DENTRO de ntdll, pero DESPUES del hook.

Hook del EDR:     jmp EDR_Hook    ← saltar esto
Instrucciones:    mov eax, 0x18
                  syscall          ← saltar directamente aqui
                  ret

El EDR ve una syscall ejecutándose desde dentro de ntdll (normal), pero sin pasar por su hook (bypassed).

Técnica 4: BYOVD para eliminar kernel callbacks

Cubierto en detalle en el artículo de BYOVD. Desde kernel mode, el atacante puede desregistrar los callbacks del EDR, cegándolo a nivel de kernel.

Técnica 5: ETW patching

Patchear EtwEventWrite en ntdll para que no genere eventos ETW. Cubre solo eventos user-mode; los kernel-mode requieren kernel access.

Técnica 6: Thread stack spoofing

Modificar el call stack de un thread para que parezca legítimo durante la inspección del EDR:

Call stack real:                Call stack spoofed:
malware.exe → inject_code      svchost.exe → normal_function
                                (ocultar la llamada maliciosa)

Comparativa: qué evasión bypasea qué capa

Técnica de evasiónUser hooksKernel callbacksETW userETW kernelMinifilter
Unhooking ntdllNoNoNoNo
Direct syscallsNoSí (parcial)NoNo
Indirect syscallsNoNoNoNo
ETW patchingNoNoNoNo
BYOVDSí (si kernel)
Thread stack spoofParcialNoNoNoNo

Conclusión: solo BYOVD (acceso al kernel) puede evadir todas las capas. Las técnicas de user-mode solo afectan hooks en ntdll y ETW user-mode. Un EDR con buena cobertura de kernel callbacks y ETW-TI sigue detectando actividad incluso si los hooks de user-mode son bypasseados.

Estado del arte en la defensa de EDR

Protección de hooks

Los EDR modernos implementan protección contra unhooking:

  • Monitorizar VirtualProtect en ntdll: si alguien cambia los permisos de memory de ntdll, alertar
  • Verificar periódicamente la integridad de hooks: comparar hooks actuales con estado esperado
  • Hooks en kernel además de user-mode: incluso si el user-mode hook se elimina, el kernel callback sigue activo

Detección de syscalls directas

  • Call stack analysis: verificar que las syscalls provienen de ntdll, no de código desconocido
  • ETW-TI: eventos del kernel que se generan independientemente de hooks
  • Kernel callbacks: siempre se invocan, independientemente de cómo se hizo la syscall

Protección PPL

Los EDR registran su proceso como PPL (Protected Process Light):

  • No puede ser terminado por otros procesos (incluso admin)
  • No puede ser inyectado
  • Solo puede ser atacado desde kernel mode (BYOVD)

HVCI como última línea

Con HVCI activo, incluso los ataques BYOVD son limitados:

  • El hypervisor valida la integridad del código del kernel
  • Drivers vulnerables en la blocklist no pueden cargarse
  • Modificaciones al código del kernel son detectadas

Para el defensor: verificar la cobertura de tu EDR

Preguntas que debes hacer a tu vendor de EDR

  1. ¿Usan hooks en user-mode, kernel callbacks, o ambos?
  2. ¿Consumen ETW-TI (requiere PPL)?
  3. ¿Detectan unhooking de ntdll?
  4. ¿Detectan direct/indirect syscalls (call stack validation)?
  5. ¿Protegen contra BYOVD (driver blocklist integrada)?
  6. ¿Su proceso corre como PPL?
  7. ¿Es compatible con HVCI?

Testing con herramientas abiertas

HerramientaQué testea
Atomic Red TeamTécnicas ATT&CK genéricas
ScareCrowEvasión de EDR con payloads de Cobalt Strike
SharpBlockTestea bypass de ETW y AMSI
InlineWhispersDirect syscalls para testing
NimBlackoutBYOVD testing (terminar procesos PPL)

Mapeo MITRE ATT&CK

TécnicaIDContexto EDR
Impair Defenses: Disable or Modify ToolsT1562.001Desactivar EDR (BYOVD, unhook)
Process InjectionT1055Evasión de hooks via injection techniques
Exploitation for Privilege EscalationT1068BYOVD para kernel access
Indicator RemovalT1070Eliminar evidencia post-evasión
Execution GuardrailsT1480Malware que solo ejecuta si puede evadir EDR

Fuentes y referencias

  • Russinovich, M. et al. "Windows Internals Part 1." Microsoft Press, 2017.
  • Yosifovich, P. "Windows Kernel Programming." 2023.
  • Outflank. "Direct Syscalls vs Indirect Syscalls." 2022.
  • MDSec. "Bypassing User-Mode Hooks and Direct Invocation of System Calls." 2020.
  • Elastic Security Labs. "EDR Architecture and Evasion." 2023.
  • jthuraisamy. "SysWhispers3." https://github.com/jthuraisamy/SysWhispers
  • am0nsec & smelly_vx. "HellsGate." 2020.
  • CrowdStrike. "EDR Evasion Techniques in Modern Attacks." 2024.
  • MITRE ATT&CK. "Impair Defenses (T1562)." https://attack.mitre.org/techniques/T1562/
  • Red Canary. "EDR Evasion in 2024." Red Canary, 2024.

Preguntas frecuentes

Artículos relacionados

Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.