Seguridad

Las puertas del malware: técnicas modernas de evasión mediante syscalls directas

Los EDRs modernos colocan ganchos (hooks) sobre funciones sensibles de ntdll.dll, haciendo que cualquier intento de ejecutar NtWriteVirtualMemory, NtOpenProcess, o similares, sea interceptado y registrado. Para evadir esto, han surgido una serie de técnicas que explotan el mecanismo de syscalls directamente, evitando por completo la ejecución de funciones hookeadas. Estas técnicas, conocidas como «gates», permiten a un payload comunicarse con el kernel de Windows sin ser detectado. En este artículo se describen las más relevantes, ordenadas cronológicamente, con fragmentos de código y una tabla comparativa.

Hell’s Gate (2018)

Hell’s Gate fue una de las primeras técnicas en explotar directamente los stubs de ntdll.dll para extraer el syscall ID y emitir una syscall sin pasar por los hooks. Su popularidad se debe a su simplicidad: permite a un atacante escanear ntdll, identificar el syscall ID, y construir una instrucción syscall válida desde código propio. Es particularmente útil cuando el EDR no ha alterado el stub original.

DWORD GetSyscallId(const char* name) {
    BYTE* addr = (BYTE*)GetProcAddress(GetModuleHandleA("ntdll.dll"), name);
    if (addr[0] == 0x4C && addr[1] == 0x8B && addr[2] == 0xD1 && addr[3] == 0xB8)
        return *(DWORD*)(addr + 4); // syscall ID está justo después del mov eax
    return 0;
}

Ventajas: sencilla, evasiva, portable.

Desventajas: rota si el EDR modifica los stubs o syscall IDs.

Halo’s Gate (2020)

Halo’s Gate fue ideada como evolución de Hell’s Gate, reconociendo que muchos EDRs ya estaban alterando los stubs de syscall. En lugar de depender del stub exacto, busca en la memoria cercana otros stubs válidos que no hayan sido hookeados. A partir de estos, deduce el syscall ID necesario por offset. Esta técnica se vuelve extremadamente valiosa cuando los hooks de EDRs distorsionan el contenido de ntdll.dll.

DWORD FindNearbySyscallId(BYTE* target) {
    for (int i = -0x40; i <= 0x40; i++) {
        BYTE* addr = target + i;
        if (addr[0] == 0x4C && addr[3] == 0xB8 && addr[8] == 0x0F && addr[9] == 0x05)
            return *(DWORD*)(addr + 4) - i; // compensar el desplazamiento
    }
    return 0;
}

Ventajas: más robusta que Hell’s Gate, recupera el ID aunque esté oculto.

Desventajas: más compleja, aún depende de ntdll.

Heaven’s Gate (legacy, reaplicada)

Heaven’s Gate es una técnica que permite a un proceso de 32 bits en WoW64 ejecutar código de 64 bits saltando a segmentos de 64 bits con un far call. En evasión moderna se usa para invocar syscalls desde el modo WOW64, donde muchos EDRs no tienen visibilidad.

; Desde código 32-bit:
mov eax, selector64
push offset_64bit_code
retf ; salto far a 64 bits

Ventajas: oculta la syscall ejecutándola en un contexto inesperado.

Desventajas: requiere entorno WoW64, no funciona en procesos puramente x64.

Sith’s Gate (2022)

Sith’s Gate elimina completamente la dependencia de ntdll.dll. Usa syscall IDs que han sido previamente determinados (hardcoded) y construye directamente la instrucción syscall inline, sin utilizar ninguna API del sistema. Esta técnica es extremadamente útil para payloads inyectados o shellcode que no pueden resolver funciones dinámicamente.

mov r10, rcx
mov eax, 0x003A ; NtAllocateVirtualMemory en Win10 22H2 syscall ret

Ventajas: no depende de ninguna DLL ni export.

Desventajas: frágil ante cambios de syscall ID por versión de Windows.

Tartarus Gate (2022)

Tartarus Gate va un paso más allá: ejecuta la syscall desde un contexto completamente controlado y aislado, usualmente con NtContinue o RtlRestoreContext, que permite establecer manualmente el registro RIP, RSP, y simular una llamada legítima. Esto evade EDRs que rastrean call stacks, ya que el stub se ejecuta sin una traza de llamadas sospechosa.

// Se arma un CONTEXT con RIP = stub de syscall y RSP spoofeado
CONTEXT ctx = {0};
ctx.ContextFlags = CONTEXT_FULL;
ctx.Rip = (DWORD64)&SyscallStub;
ctx.Rsp = spoofed_stack_addr;
NtContinue(&ctx, FALSE);

Ventajas: evasión incluso contra análisis de flujo o ETW.

Desventajas: requiere spoofing de stack y ejecución indirecta, compleja.

Nyx (2023)

Nyx representa el máximo nivel de evasión: funciona desde shellcode puro, sin IAT ni imports, accediendo directamente al PEB o estructuras internas como la SSDT para extraer la syscall table y los IDs de funciones. Esta técnica permite ejecutar payloads reflectivos y fileless sin dejar rastro alguno en el espacio de usuario.

// Pseudocódigo: leer syscall ID desde estructura interna
DWORD id = ReadFromSSDT("NtOpenProcess");
__asm {
    mov r10, rcx
    mov eax, id
    syscall
}

Ventajas: evasión total, funciona sin ntdll ni IAT.

Desventajas: altamente dependiente de versión, muy frágil.

Tabla comparativa

Técnica   Evade Hooks    Usa ntdll   Requiere syscall ID   Spoofing Stack   Portabilidad 
 Hell’s Gate   Dinámico   Alta
 Halo’s Gate  Deducción por offset    Media
 Heaven’s Gate    No aplica   Baja
 Sith’s Gate  Hardcoded   Baja
 Tartarus Gate  Variable   Media
 Nyx  Dinámico interno   Muy baja

Conclusiones

Las técnicas «Gate» han evolucionado para adaptarse a un panorama de detección cada vez más agresivo. Desde el análisis de stubs (Hell's Gate) hasta la ejecución totalmente desvinculada de librerías (Nyx), todas apuntan al mismo objetivo: ejecutar syscalls sin ser interceptadas. La elección de técnica depende del entorno, el nivel de stealth requerido y la portabilidad deseada. En escenarios altamente vigilados, combinaciones como Sith + Tartarus o Tartarus + Nyx representan el estado del arte en evasión. Para el red teamer moderno, dominar estas puertas es fundamental para abrir paso hacia ejecuciones realmente invisibles.

Powered by WPeMatico

Gustavo Genez

Informático de corazón y apasionado por la tecnología. La misión de este blog es llegar a los usuarios y profesionales con información y trucos acerca de la Seguridad Informática.