Avanzadopolimorfismometamorfismoevasióntécnicasmotoresdetección

Polimorfismo y Metamorfismo: La Evolución de los Motores de Mutación del Malware

Análisis técnico profundo de la evolución del polimorfismo y metamorfismo en el malware. Desde los primeros cifradores simples hasta los motores metamórficos completos como Simile y Zmist. Cómo estas técnicas, documentadas en ezines VX, transformaron la detección de malware para siempre.

MalwareIntel Research··11 min lectura
Serie: Ezines y Cultura VX — Parte 9

La carrera armamentista más larga de la informática

Si existe una constante en la historia de la seguridad informática, es la carrera armamentista entre los creadores de malware y los desarrolladores de herramientas de detección. Y el campo de batalla más significativo de esa carrera ha sido la evolución de las técnicas de mutación del código: desde los primeros cifradores simples de los años 80 hasta los motores metamórficos completos que transforman cada byte del virus en cada generación.

Esta evolución, documentada con extraordinario detalle técnico en las ezines VX (especialmente 29A Magazine, 40Hex y las publicaciones de Dark Avenger), no fue solo un fenómeno underground. Cada nueva técnica de mutación forzó a la industria antivirus a desarrollar nuevas técnicas de detección, que a su vez motivaron nuevas técnicas de evasión. Este ciclo de innovación ha moldeado la tecnología de seguridad que utilizamos hoy.

Generación 0: el cifrado simple

Los orígenes

Los primeros virus para PC (1986-1989) no utilizaban ninguna técnica de ocultación. Su código era visible como texto plano en los archivos infectados, lo que hacía que la detección fuera trivial: bastaba con buscar una secuencia de bytes característica (la "firma" del virus) en los archivos.

La primera respuesta de los virus writers fue el cifrado simple. Un virus cifrado tiene dos componentes:

El descifrador. Un bloque corto de código sin cifrar que, al ejecutarse, descifra el cuerpo del virus en memoria.

El cuerpo cifrado. El código real del virus, cifrado con una clave que cambia en cada infección. Al cambiar la clave, el cuerpo cifrado tiene un aspecto diferente en cada copia.

El primer virus que utilizó cifrado fue Cascade (1988). Cascade cifraba su cuerpo con una operación XOR byte a byte, usando una clave que cambiaba en cada infección. El resultado era que el cuerpo del virus parecía diferente en cada archivo infectado.

La debilidad

El problema del cifrado simple era que el descifrador permanecía constante. Aunque el cuerpo cifrado cambiaba con cada nueva clave, el código del descifrador era siempre el mismo. Los antivirus simplemente buscaban la firma del descifrador en lugar de la firma del cuerpo del virus. El cifrado simple proporcionaba protección contra inspección visual casual, pero no contra la detección automatizada.

Generación 1: polimorfismo oligomórfico

El siguiente paso

La respuesta al problema del descifrador constante fue el polimorfismo oligomórfico: un virus que tenía un conjunto limitado de descifradores diferentes y seleccionaba uno al azar en cada infección. El virus Whale (1990) utilizaba esta técnica, con varias docenas de descifradores predefinidos.

El polimorfismo oligomórfico complicaba la detección porque los antivirus necesitaban una firma para cada variante del descifrador. Pero el número de variantes era finito y manejable: un analista podía extraer firmas para todas las variantes en un tiempo razonable.

Generación 2: polimorfismo completo

El salto cualitativo

El polimorfismo completo, inaugurado efectivamente por el MtE (Mutation Engine) de Dark Avenger en 1991, representó un salto cualitativo. En lugar de seleccionar entre un conjunto finito de descifradores, un motor polimórfico completo genera un descifrador nuevo y único en cada infección.

Las técnicas utilizadas por los motores polimórficos incluyen:

Sustitución de registros. El descifrador utiliza registros diferentes en cada generación. Una instrucción que usa EAX en una copia puede usar EBX, ECX o EDX en otra, sin cambiar la funcionalidad.

Reordenación de instrucciones. Instrucciones independientes entre sí pueden ejecutarse en cualquier orden. Un motor polimórfico identifica las dependencias entre instrucciones y permuta las que son independientes.

Instrucciones basura (junk code). El motor inserta instrucciones que no afectan al resultado: NOPs (no-operation), operaciones que se anulan entre sí (ADD seguido de SUB), asignaciones a registros que no se usan después.

Equivalencia de instrucciones. Una misma operación puede expresarse de múltiples formas en x86. Incrementar un registro puede hacerse con INC, con ADD 1, con SUB -1, con LEA o con XOR seguido de ajustes. El motor polimórfico selecciona aleatoriamente entre equivalentes funcionales.

Variación del flujo de control. El descifrador puede implementarse como un bucle, como código desenrollado (cada iteración explícita), o como una combinación de ambos.

Los motores polimórficos notables

MtE (Dark Avenger, 1991). El primero distribuido como biblioteca independiente. Ver artículo dedicado sobre Dark Avenger.

TPE (Trident Polymorphic Engine, Masud Khafir, 1992). Un motor polimórfico que generaba descifradores extremadamente variables, utilizando técnicas de sustitución de registros y reordenación de instrucciones más agresivas que el MtE.

DAME (Dark Angel's Multiple Encryptor). Motor distribuido con la ezine 40Hex de Phalcon/Skism. Generaba descifradores con múltiples capas de cifrado.

SMEG (Simulated Metamorphic Encryption Generator, Black Baron, 1994). Un motor polimórfico británico que generaba descifradores de complejidad variable, desde simples hasta extremadamente ofuscados.

La respuesta de la industria: emulación

La respuesta principal de la industria antivirus al polimorfismo completo fue la emulación de código. Un emulador ejecuta el virus en un entorno virtual (sandbox a nivel de CPU) y espera a que el descifrador termine su trabajo. Una vez que el cuerpo del virus está descifrado en la memoria virtual, el emulador lo extrae y lo compara contra firmas conocidas.

Este enfoque fue efectivo pero planteaba sus propios desafíos:

Rendimiento. Emular cada archivo ejecutable del sistema era computacionalmente costoso. Los antivirus debían decidir cuánto tiempo emular antes de declarar que un archivo era seguro.

Evasión del emulador. Los virus writers respondieron con técnicas anti-emulación: instrucciones no documentadas que los emuladores no implementaban, llamadas a APIs del sistema operativo que los emuladores no simulaban, y "bombas de tiempo" que retrasaban la descifración para agotar el tiempo de emulación.

Generación 3: metamorfismo

La diferencia fundamental

Si el polimorfismo cambia la apariencia del descifrador pero mantiene el cuerpo del virus constante (una vez descifrado), el metamorfismo cambia el propio cuerpo del virus. Un virus metamórfico no tiene una parte constante: todo el código se transforma en cada generación.

La diferencia técnica es profunda. Un virus polimórfico necesita un motor de cifrado/descifrado. Un virus metamórfico necesita un motor de transformación de código que entienda la semántica de las instrucciones. Debe ser capaz de:

  1. Desensamblar su propio código para obtener una representación interna.
  2. Analizar las dependencias entre instrucciones.
  3. Transformar las instrucciones sustituyendo por equivalentes.
  4. Reordenar bloques de código independientes.
  5. Generar basura (código muerto) indistinguible del código real.
  6. Reensamblar el resultado en código ejecutable.

Un virus metamórfico es, en esencia, un compilador/optimizador que se aplica a sí mismo.

Virus metamórficos notables

Win32.Regswap (1998). Uno de los primeros virus metamórficos, que realizaba sustitución de registros en todo su código. Técnicamente simple pero conceptualmente importante: demostró que la transformación del cuerpo del virus era factible.

Win32.Zperm (2000). Un virus metamórfico que implementaba permutación de bloques de código. El virus dividía su código en bloques independientes y los reorganizaba aleatoriamente, insertando instrucciones de salto para mantener el flujo de ejecución correcto.

Win32.Simile / Metaphor (Mental Driller, 29A, 2002). El virus metamórfico más sofisticado jamás creado. Simile implementaba un pipeline de transformación completo:

  • Un desensamblador que convertía su propio código máquina en una representación intermedia.
  • Un analizador de dependencias que identificaba qué instrucciones podían reordenarse.
  • Un motor de sustitución de instrucciones con un repertorio extenso de equivalencias.
  • Un generador de código basura de alta calidad (indistinguible del código real para un analista humano).
  • Un reensamblador que producía el nuevo binario.

Con más de 14.000 líneas de ensamblador, Simile era un tour de force de ingeniería. Peter Szor y Peter Ferrie de Symantec publicaron un análisis detallado que se convirtió en referencia académica sobre metamorfismo.

Win32.Zmist / Mistfall (Zombie, 29A, 2001). Zmist implementaba una técnica llamada "code integration": en lugar de adjuntarse al programa infectado, Zmist desensamblaba el programa objetivo, mezclaba su propio código con el del programa original a nivel de instrucciones, y reensamblaba el resultado. El virus y el programa huésped se fusionaban en un todo indistinguible.

Esta técnica era devastadora para la detección porque no existía un "cuerpo del virus" separable: el código malicioso estaba entrelazado con el código legítimo. Detectar Zmist requería analizar la funcionalidad del programa completo, no buscar un patrón.

La respuesta defensiva al metamorfismo

Emulación avanzada

La emulación, que fue la respuesta al polimorfismo, era menos efectiva contra el metamorfismo porque no había un cuerpo cifrado que "descifrar". El virus metamórfico se ejecutaba directamente, sin fase de descifrado. Los emuladores necesitaban ejecutar el virus completo y analizar su comportamiento, no esperar a que se descifrase.

Análisis de flujo de control

Los investigadores de antivirus desarrollaron técnicas de análisis de flujo de control para detectar virus metamórficos. En lugar de buscar secuencias de bytes (firmas), analizaban la estructura lógica del código: los patrones de saltos, bucles, llamadas a funciones y acceso a datos.

La idea era que aunque las instrucciones individuales cambiaran, la estructura lógica del virus se mantendría. Un virus que infecta archivos siempre necesita abrir archivos, buscar ejecutables, leer y escribir datos. Estos patrones de comportamiento son más difíciles de ocultar que las instrucciones individuales.

Detección por grafo

Una evolución del análisis de flujo de control fue la detección por grafo: representar el programa como un grafo dirigido donde los nodos son bloques básicos de código y las aristas son saltos. Dos programas con la misma funcionalidad producen grafos similares, incluso si las instrucciones individuales son completamente diferentes.

Esta técnica fue efectiva contra muchos virus metamórficos, pero computacionalmente costosa y susceptible a evasión mediante la transformación del grafo (inserción de nodos falsos, partición de nodos existentes, fusión de bloques).

Machine learning

La última generación de técnicas de detección aplica machine learning a la clasificación de malware. En lugar de definir manualmente las características que distinguen el malware del software legítimo, un modelo entrenado con millones de muestras aprende a identificar patrones que los humanos no pueden especificar explícitamente.

El machine learning es conceptualmente la respuesta definitiva al metamorfismo: un modelo suficientemente potente debería poder detectar malware independientemente de las transformaciones aplicadas a su código. En la práctica, los modelos actuales son efectivos pero no infalibles, y la carrera armamentista continúa con técnicas adversariales diseñadas para engañar a los clasificadores de ML.

La herencia en el malware moderno

Packers y crypters

Los packers y crypters modernos son descendientes directos de los motores polimórficos de los 90. Un packer comprime y cifra un ejecutable, generando un stub de descompresión/descifrado que varía en cada uso. Los crypters comerciales y underground utilizan técnicas que son evoluciones refinadas de las documentadas en 29A Magazine y 40Hex.

Code virtualization

La virtualización de código es una evolución del metamorfismo. En lugar de transformar instrucciones x86 en otras instrucciones x86 equivalentes, la virtualización convierte el código en bytecode para una máquina virtual privada. Cada instancia del protector genera una máquina virtual con un conjunto de instrucciones diferente, lo que hace que el análisis requiera primero la ingeniería inversa de la VM.

Productos comerciales de protección de software como VMProtect y Themida utilizan esta técnica. El malware también la adopta: los troyanos bancarios y el ransomware frecuentemente utilizan capas de virtualización de código para dificultar el análisis.

Ofuscación en scripts

Las técnicas de polimorfismo y metamorfismo se han trasladado también a los lenguajes de scripting. El malware basado en PowerShell, JavaScript y VBScript utiliza técnicas de ofuscación que son adaptaciones de los principios polimórficos: codificación variable, sustitución de funciones por equivalentes, inserción de código muerto y transformación del flujo de control.

Estas técnicas son conceptualmente idénticas a las que los virus writers documentaron en ensamblador x86, adaptadas a un entorno de ejecución diferente.

La perspectiva del analista de malware

Para un analista de malware moderno, entender la evolución del polimorfismo y el metamorfismo no es un ejercicio histórico: es una necesidad práctica. Las técnicas de evasión que el malware actual utiliza tienen raíces directas en las investigaciones publicadas en las ezines VX. Un analista que entienda los principios del polimorfismo clásico puede reconocer sus variantes modernas más rápidamente.

Las herramientas de análisis modernas (IDA Pro, Ghidra, Binary Ninja, x64dbg) implementan funcionalidades que fueron desarrolladas específicamente para lidiar con virus polimórficos y metamórficos: deofuscadores, emuladores integrados, analizadores de flujo de control y visualizadores de grafos.

El conocimiento documentado en las ezines VX es, paradójicamente, más útil para los defensores que para los atacantes. Los atacantes modernos (grupos de APT, operadores de ransomware) utilizan herramientas automatizadas que implementan evasión sin requerir comprensión profunda de los principios. Pero los defensores necesitan entender esos principios para desarrollar detecciones efectivas y para analizar muestras que las herramientas automatizadas no detectan.

Fuentes y lecturas recomendadas

  • Szor, Peter. "The Art of Computer Virus Research and Defense". Addison-Wesley, 2005. Capítulos 8-11 sobre polimorfismo y metamorfismo.
  • Szor, Peter y Ferrie, Peter. "Hunting for Metamorphic". Virus Bulletin Conference, 2001.
  • 29A Magazine: artículos sobre motores polimórficos y metamórficos (números 4-8).
  • Filiol, Eric. "Computer Viruses: from Theory to Applications". Springer, 2005.
  • Borello, Jean-Marie y Me, Ludovic. "Code Obfuscation Techniques for Metamorphic Viruses". Journal in Computer Virology, 2008.

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.