Infección sin escribir ni un solo byte: un solo puntero en memoria engañó a todo el sistema de seguridad

Infección sin escribir ni un solo byte: un solo puntero en memoria engañó a todo el sistema de seguridad

Los hackers ya no escriben código: simplemente señalan dónde ya está, y Windows hace el resto.

image

Nuevas investigaciones han demostrado formas de inyectar código malicioso en procesos de Windows sin recurrir a las etapas tradicionales de asignación y escritura de memoria, pilares sobre los que se basan casi todos los sistemas de detección de ataques. En los experimentos, los especialistas se centraron exclusivamente en la etapa de ejecución y demostraron que esta por sí sola puede bastar para lograr una inyección exitosa.

El esquema clásico de ataques con inyección de código en un proceso ajeno implica una secuencia de pasos: primero, el atacante asigna memoria en el proceso objetivo (por ejemplo, con VirtualAllocEx), luego escribe la carga útil (normalmente mediante WriteProcessMemory), y después la ejecuta, por ejemplo, con CreateRemoteThread o APC. Esta cadena —asignación, escritura, ejecución— es la que detectan y bloquean la mayoría de las soluciones EDR actuales. Sin embargo, el nuevo estudio demuestra que dicha cadena no es imprescindible.

Los investigadores partieron de la siguiente idea: ¿qué pasa si se eliminan tanto la asignación como la escritura de memoria? Es decir, si se emplean únicamente mecanismos de ejecución. Uno de los primeros métodos fue una variante "por puntero" de la inyección DLL. En ella, LoadLibraryA se llama con un puntero a una cadena ya existente en la memoria del proceso objetivo, como la cadena “0”, que siempre está presente en ntdll.dll. Luego, se introduce en el sistema de archivos un archivo llamado “0.dll”, y el sistema lo carga sin necesidad de escribir nada en la memoria del proceso. Este ataque pasó desapercibido para dos soluciones EDR líderes.

Otro enfoque consiste en usar CreateRemoteThread junto con SetThreadContext. Se crea un nuevo hilo en estado suspendido, y luego se configura manualmente su contexto, incluyendo los registros RCX, RDX, R8 y R9, en línea con la convención de llamadas de funciones en Windows x64. Esto permite invocar cualquier función de la API, como VirtualAlloc o RtlFillMemory, con los argumentos deseados. La escritura y ejecución ocurren desde dentro del proceso víctima, lo que impide que herramientas externas de monitoreo detecten comportamientos anómalos.

El tercer método utiliza NtCreateThread, una llamada al sistema poco documentada que permite pasar directamente al kernel una estructura CONTEXT con los registros y un puntero a la pila. A diferencia de CreateRemoteThread, donde el contexto se modifica a posteriori, aquí se define de antemano, lo que facilita el control sobre el hilo y reduce la visibilidad del ataque. En una de las variantes, el hilo se inicia con un gadget ROP que, mediante una cadena de instrucciones, llama primero a VirtualAlloc, luego a RtlFillMemory y finalmente ejecuta el shellcode.

La investigación también destacó una debilidad estructural en los sistemas de detección de ataques. Muchas soluciones EDR operan bajo la premisa de correlacionar dos o tres acciones sospechosas: asignación remota de memoria, modificación de esa memoria y ejecución de código. Si sólo se utilizan mecanismos de ejecución y todo ocurre localmente dentro del proceso objetivo, esta lógica se rompe. Especialmente difícil resulta rastrear la manipulación del contexto del hilo si no va acompañada de escritura directa o de llamadas a APIs populares.

También se observó que la creación de hilos entre procesos no es necesariamente un comportamiento sospechoso: lo hacen depuradores, herramientas de análisis de rendimiento, sistemas de compatibilidad, agentes de monitoreo e incluso componentes legítimos de Windows. Por eso, las señales generadas durante CreateRemoteThread suelen diluirse en el ruido de fondo.

Los investigadores implementaron las técnicas descritas. Lograron realizar inyecciones DLL o introducir shellcode sin operaciones de escritura, empleando diversos métodos de ejecución: desde el clásico CreateRemoteThread hasta NtQueueApcThreadEx2. También se contempló la manipulación del contexto utilizando gadgets ROP o técnicas en dos fases.

Los autores señalaron que, aunque enfrentaron limitaciones —como la dificultad de controlar la pila o el número restringido de argumentos—, todas ellas fueron superadas con éxito. Algunos métodos requieren encontrar gadgets ROP en la memoria, pero esto puede resolverse mediante análisis estático de archivos PE.

La conclusión clave fue que los mecanismos de defensa actuales dependen en exceso de un modelo de ataque basado en patrones, lo que les hace ignorar escenarios complejos donde el atacante logra que el propio proceso víctima ejecute las acciones deseadas. En este tipo de ataques, el control real cambia de manos, pero la telemetría no registra señales de intrusión evidentes. Esta asimetría es precisamente lo que hace que las técnicas de ejecución sin escritura sean tan peligrosas.

En resumen, EDR resuelve una ecuación de tres variables: quién asignó memoria, quién la modificó y quién ejecutó el código. Pero si el atacante conoce de antemano la respuesta —por ejemplo, que basta con invocar LoadLibraryA sobre una cadena ya existente—, puede anticiparse y mantenerse invisible.

Las huellas digitales son tu debilidad, y los hackers lo saben

¡Suscríbete y descubre cómo borrarlas!