AvanzadoransomwarecriptografíaAESRSAChaCha20cifrado híbrido

Técnicas de Cifrado en Ransomware: AES, RSA, ChaCha20 y Cifrado Híbrido

Análisis técnico profundo de los algoritmos criptográficos que usan los ransomware modernos. AES-256, RSA-2048, ChaCha20-Poly1305, Curve25519, cifrado híbrido, cifrado parcial y los errores criptográficos que han permitido descifrar familias como Hive y Akira.

MalwareIntel Research··16 min lectura
Serie: Ransomware — Parte 4

Por qué la criptografía importa para los defensores

Cuando un equipo de respuesta a incidentes llega a una red cifrada por ransomware, la primera pregunta es: ¿se pueden recuperar los archivos sin pagar? La respuesta depende enteramente de la implementación criptográfica del ransomware. Un error en la generación de claves, un IV reutilizado o un PRNG predecible pueden ser la diferencia entre una recuperación completa y una pérdida total.

Este artículo analiza los algoritmos y patrones criptográficos que usan las familias de ransomware modernas. No es un curso de criptografía: asume conocimiento básico de cifrado simétrico y asimétrico. El objetivo es que un analista pueda identificar qué algoritmos usa una muestra, evaluar si la implementación tiene debilidades y saber dónde buscar artefactos criptográficos durante un análisis forense.

Cifrado simétrico: AES-256

Fundamentos

AES (Advanced Encryption Standard) es el algoritmo simétrico más usado en ransomware. Opera sobre bloques de 128 bits con claves de 128, 192 o 256 bits. La variante de 256 bits es la estándar en ransomware por razones de marketing tanto como de seguridad: "cifrado militar de 256 bits" suena más intimidante en una nota de rescate.

Modos de operación en ransomware

El modo de operación determina cómo AES procesa múltiples bloques. Cada modo tiene implicaciones de seguridad y rendimiento:

ModoDescripciónFamilias que lo usanDebilidades conocidas
CBC (Cipher Block Chaining)Cada bloque se XORea con el bloque cifrado anteriorREvil, Maze, GandCrabRequiere padding, vulnerable a padding oracle si hay retroalimentación
CTR (Counter)Convierte AES en cifrado de stream usando un contadorLockBit 2.0, RyukReutilización de nonce = catastrófico (keystream reutilizado)
GCM (Galois/Counter Mode)CTR + autenticación integrada (AEAD)Hive (parcial)Misma vulnerabilidad de nonce que CTR, más overhead
ECB (Electronic Codebook)Cada bloque se cifra independientementeRansomware amateurPatrones del plaintext visibles en el ciphertext. Inseguro

ECB es un indicador de ransomware de baja calidad. Cifrar una imagen BMP en modo ECB deja visible la silueta de la imagen original porque bloques idénticos de plaintext producen bloques idénticos de ciphertext. Ninguna familia seria lo usa.

CBC es el modo más común en familias legacy. Requiere un IV (Initialization Vector) único por archivo. Si el IV se reutiliza o es predecible, puede facilitar el análisis.

CTR es preferido por familias modernas porque permite cifrado en paralelo (cada bloque se puede cifrar independientemente con su valor de contador) y no requiere padding. Pero la reutilización de nonce es fatal: si dos archivos se cifran con el mismo nonce y la misma clave, el XOR de los dos ciphertexts revela el XOR de los dos plaintexts, lo que frecuentemente permite recuperar ambos.

Pseudocódigo: cifrado AES-CTR en ransomware

# Rutina de cifrado simplificada (NO código real de malware)
def encrypt_file_aes_ctr(filepath, aes_key, nonce):
    """
    Cifra un archivo con AES-256-CTR.
    aes_key: 32 bytes (256 bits) generados con CSPRNG
    nonce: 16 bytes unicos por archivo
    """
    plaintext = read_file(filepath)
    cipher = AES_CTR(key=aes_key, nonce=nonce)
    ciphertext = cipher.encrypt(plaintext)
    
    # Escribir: nonce + ciphertext cifrado
    write_file(filepath + ".encrypted", nonce + ciphertext)
    
    # Cifrar la clave AES con la clave publica RSA del atacante
    encrypted_key = rsa_encrypt(aes_key, attacker_public_key)
    
    # Almacenar la clave cifrada (en el archivo o en fichero separado)
    append_to_file(filepath + ".encrypted", encrypted_key)
    
    # Borrar el archivo original
    secure_delete(filepath)

ChaCha20-Poly1305: la alternativa moderna

Por qué ChaCha20 gana terreno

ChaCha20 es un cifrado de stream diseñado por Daniel J. Bernstein como alternativa a AES. Su adopción en ransomware ha crecido significativamente desde 2020 por varias razones:

Rendimiento en software puro: en CPUs sin instrucciones AES-NI (hardware de aceleración AES), ChaCha20 es 2-3 veces más rápido que AES. Esto importa en servidores antiguos, máquinas virtuales donde AES-NI no siempre está expuesto, y dispositivos ARM (NAS, IoT).

Simplicidad de implementación: ChaCha20 usa operaciones simples (sumas de 32 bits, XOR, rotaciones) que son difíciles de implementar incorrectamente. AES-CBC requiere gestionar padding, IVs, y es vulnerable a timing attacks si se implementa con tablas de lookup en software.

AEAD integrado: ChaCha20-Poly1305 combina cifrado y autenticación en un solo paso, eliminando la necesidad de gestionar un MAC separado.

Familias que usan ChaCha20

FamiliaVarianteNotas
ContiChaCha20 (32 threads)Adopción por rendimiento en despliegue masivo
BabukChaCha20 + ECDH (Curve25519)Cross-platform: Windows, Linux, ESXi
Royal/BlackSuitChaCha20 parcialCifrado intermitente con ChaCha20
HiveChaCha20 + RSA-2048Error en generación de keystream que permitió descifrado
RansomExxChaCha20 + RSA-4096Variante Linux

Parámetros de ChaCha20

ChaCha20 opera con:

  • Clave: 256 bits (32 bytes)
  • Nonce: 96 bits (12 bytes) en la variante estándar, 192 bits (24 bytes) en XChaCha20
  • Counter: 32 bits, permite cifrar hasta 256 GB con un solo par clave/nonce

La reutilización de nonce en ChaCha20 tiene las mismas consecuencias catastróficas que en AES-CTR: el keystream se repite y el XOR de los ciphertexts expone relaciones entre los plaintexts.

Cifrado asimétrico: RSA y curvas elípticas

RSA en ransomware

RSA se usa exclusivamente para cifrar las claves simétricas (AES o ChaCha20), nunca para cifrar archivos directamente (demasiado lento). Las variantes más comunes:

  • RSA-2048: 2048 bits de módulo. Considerado seguro con tecnología actual. Factorizar RSA-2048 requeriría recursos computacionales que no existen
  • RSA-4096: 4096 bits. Overkill para la mayoría de escenarios, pero usado por familias que quieren proyectar sofisticación (REvil, RansomExx)

Flujo de claves RSA en ransomware

El esquema típico usa dos niveles de claves RSA:

Nivel 1: Master Key (del operador)
  RSA key pair generado offline por el operador
  Clave publica embebida en el builder
  Clave privada almacenada de forma segura por el operador

Nivel 2: Session Key (por victima)
  RSA key pair generado en la maquina de la victima
  Clave publica de sesion se usa para cifrar las claves AES por archivo
  Clave privada de sesion se cifra con la Master Public Key
  Solo el operador puede descifrar la clave privada de sesion

Resultado:
  Archivo cifrado con AES key unica
  AES key cifrada con Session Public Key
  Session Private Key cifrada con Master Public Key
  Solo el Master Private Key del operador puede desbloquear toda la cadena

Este esquema de dos niveles permite que el builder genere payloads sin contener la clave privada maestra. Incluso si un investigador extrae todas las claves del payload, solo obtiene la clave pública maestra.

Curve25519 / X25519: la alternativa moderna

Familias recientes (Babuk, Conti v3, algunas variantes de BlackCat) usan criptografía de curva elíptica en vez de RSA:

  • Curve25519: curva elíptica de Montgomery, 128 bits de seguridad
  • X25519: protocolo de intercambio de claves Diffie-Hellman sobre Curve25519
  • Ed25519: esquema de firma digital sobre la misma curva

Ventajas sobre RSA:

  • Claves mucho más pequeñas (32 bytes vs 256-512 bytes)
  • Operaciones más rápidas
  • Más difícil de implementar incorrectamente (la curva fue diseñada para resistir errores de implementación)
  • Daniel J. Bernstein diseñó tanto ChaCha20 como Curve25519, lo que hace que la combinación sea natural

El flujo completo: cifrado híbrido paso a paso

Pseudocódigo del flujo completo de un ransomware que usa ChaCha20 + X25519:

# FASE 1: Inicializacion (al ejecutarse en la maquina victima)
def initialize():
    # Clave publica del operador (embebida en el binario)
    operator_pubkey = HARDCODED_X25519_PUBLIC_KEY
    
    # Generar par de claves de sesion para esta victima
    session_privkey = x25519_generate_private_key()
    session_pubkey = x25519_derive_public_key(session_privkey)
    
    # Derivar shared secret con la clave del operador
    shared_secret = x25519_key_exchange(session_privkey, operator_pubkey)
    
    # La session_privkey se cifra con el shared_secret y se guarda
    # Solo el operador puede recalcular el shared_secret usando
    # su clave privada + session_pubkey de la victima
    
    return session_pubkey, shared_secret

# FASE 2: Cifrado de archivos
def encrypt_file(filepath, shared_secret, session_pubkey):
    # Generar clave y nonce unicos para este archivo
    file_key = csprng(32)      # 256 bits
    file_nonce = csprng(12)    # 96 bits
    
    plaintext = read_file(filepath)
    
    # Cifrar con ChaCha20-Poly1305
    ciphertext, tag = chacha20_poly1305_encrypt(
        key=file_key,
        nonce=file_nonce,
        plaintext=plaintext
    )
    
    # Cifrar la file_key con el shared_secret (AES-256-GCM o similar)
    encrypted_file_key = aes_gcm_encrypt(
        key=shared_secret[:32],
        plaintext=file_key
    )
    
    # Escribir archivo cifrado
    # Formato: [session_pubkey | nonce | encrypted_file_key | tag | ciphertext]
    write_encrypted_file(filepath, session_pubkey, file_nonce, 
                         encrypted_file_key, tag, ciphertext)
    
    # Limpiar claves de memoria
    secure_zero(file_key)
    secure_zero(plaintext)

# FASE 3: Descifrado (por el operador tras el pago)
def decrypt_file(filepath, operator_privkey):
    # Leer componentes del archivo cifrado
    session_pubkey, nonce, encrypted_file_key, tag, ciphertext = \
        parse_encrypted_file(filepath)
    
    # Recalcular shared_secret
    shared_secret = x25519_key_exchange(operator_privkey, session_pubkey)
    
    # Descifrar la file_key
    file_key = aes_gcm_decrypt(
        key=shared_secret[:32],
        ciphertext=encrypted_file_key
    )
    
    # Descifrar el archivo
    plaintext = chacha20_poly1305_decrypt(
        key=file_key, nonce=nonce,
        ciphertext=ciphertext, tag=tag
    )
    
    write_file(filepath, plaintext)

Cifrado intermitente: velocidad sobre completitud

El problema del rendimiento

En una red empresarial con decenas de terabytes de datos, cifrar cada byte de cada archivo puede tardar horas. Los defensores tienen tiempo para detectar la actividad anómala de I/O, aislar sistemas y contener el ataque.

El cifrado intermitente resuelve este problema cifrando solo una fracción del archivo. Un archivo de 10 GB cifrado al 4% tarda segundos en vez de minutos, pero el archivo queda igualmente inutilizable.

Estrategias de cifrado parcial

EstrategiaImplementaciónVentajasDesventajas
Primeros N bytesCifrar los primeros 4 KB, 64 KB o 1 MBSimple, destruye headers de formatoDatos recuperables en la porción no cifrada
Bloques alternosCifrar bloque de 1 MB, saltar 1 MB, repetirDistribución uniforme del dañoPatrón predecible, facilita análisis
Porcentaje adaptativoArchivos pequeños (menos de 5 MB) completos, grandes al 4-10%Balance rendimiento/dañoLógica más compleja
Cabeza + colaCifrar primeros y últimos N bytesDestruye headers y footersDatos intermedios intactos
StripesBandas de N KB cifradas con gaps de M KBConfigurable en el builderPatrón regular detectable

Implicaciones forenses del cifrado parcial

El cifrado parcial tiene consecuencias importantes para la recuperación:

  1. Headers de archivo: si solo se cifran los primeros bytes, herramientas de carving pueden identificar el tipo de archivo por la extensión y intentar reparar headers
  2. Bases de datos: las bases de datos SQL parcialmente cifradas pueden tener registros completos recuperables en las secciones no cifradas
  3. Máquinas virtuales: archivos VMDK parcialmente cifrados pueden montarse con herramientas especializadas que reconstruyen la tabla de asignación
  4. Imágenes y vídeos: los datos de píxeles/frames en la porción no cifrada son recuperables, aunque sin headers válidos requieren reconstrucción manual

File targeting: qué se cifra y qué no

Extensiones objetivo típicas

Las familias de ransomware mantienen listas de extensiones a cifrar. Una lista representativa:

Documentos:    .doc .docx .xls .xlsx .ppt .pptx .pdf .odt .ods .odp
Bases de datos: .sql .sqlite .mdb .accdb .dbf .mdf .ldf .ndf
Código fuente:  .py .java .cs .cpp .h .js .ts .php .rb .go .rs
Imágenes:       .jpg .jpeg .png .gif .bmp .svg .psd .ai .raw .tiff
Audio/Video:    .mp3 .mp4 .avi .mkv .mov .wav .flac
Comprimidos:    .zip .rar .7z .tar .gz .bz2
Virtualizacion: .vmx .vmdk .vhd .vhdx .qcow2
Backup:         .bak .bkf .vbk .vrb .vib
Crypto:         .wallet .key .pem .pfx
Email:          .pst .ost .eml .msg
CAD:            .dwg .dxf .step .stl

Exclusiones (para que el sistema siga operativo)

Directorios excluidos:
  C:\Windows\
  C:\Program Files\
  C:\Program Files (x86)\
  C:\ProgramData\Microsoft\
  %AppData%\Microsoft\
  $Recycle.Bin\
  System Volume Information\
  Boot\
  
Extensiones excluidas:
  .exe .dll .sys .msi .drv .com .ocx
  .lnk .url .ini .inf .bat .cmd
  .lock (propia extension del ransomware, evitar doble cifrado)

Archivos excluidos:
  ntldr, bootmgr, ntdetect.com
  desktop.ini, thumbs.db, iconcache.db
  La propia nota de rescate

La exclusión de .exe y .dll es deliberada: si el ransomware cifra los ejecutables del sistema, Windows deja de funcionar. La víctima no puede leer la nota de rescate, no puede abrir un navegador para acceder al portal de pago y no puede pagar. El atacante pierde dinero.

Key management: gestión de claves

Claves por archivo vs claves por sesión

EstrategiaDescripciónSeguridadRendimiento
Clave por archivoCada archivo tiene su propia clave AES/ChaCha20Máxima: comprometer una clave solo afecta a un archivoMás lento: más operaciones de generación de claves y cifrado asimétrico
Clave por sesiónUna sola clave para todos los archivos de la máquinaMenor: si se extrae la clave de memoria, todos los archivos se descifranMás rápido: una sola operación asimétrica
Clave por directorioUna clave por cada directorioCompromiso intermedioIntermedio

Las familias profesionales (LockBit, BlackCat, Conti) usan clave por archivo o por bloque de archivos. Las familias amateur a veces usan una sola clave por sesión, lo que las hace vulnerables a extracción de claves de memoria si se actúa rápido.

Limpieza de claves en memoria

Un error crítico es no limpiar las claves de la memoria después de usarlas. Si el ransomware mantiene las claves AES en memoria y un analista puede hacer un dump de memoria (volatility, procdump) antes de que el proceso termine, las claves se pueden recuperar.

Buenas prácticas que implementan las familias sofisticadas:

  • SecureZeroMemory() en Windows para limpiar buffers de claves
  • Cifrar las claves en memoria con una master key derivada de la clave de sesión
  • Terminar el proceso tras completar el cifrado (no dejar residuos)
  • Evitar paginación de memoria con VirtualLock() para que las claves no se escriban al pagefile

Errores criptográficos que permitieron descifrado

La tabla más valiosa de este artículo para un equipo de respuesta a incidentes:

FamiliaError criptográficoConsecuenciaDecryptor disponible
HiveKeystream de ChaCha20 generado con bug: se podía predecir la clave maestra a partir de claves parcialesFBI infiltró la red 7 meses, distribuyó 1.300+ clavesSí (KISA, Bitdefender)
GandCrab (v1-v5.0.3)Debilidad en generación de claves RSA permitió derivar la clave privadaBitdefender publicó decryptor gratuitoSí (NoMoreRansom)
Akira (versiones tempranas)Uso de std::random_device con seed predecible basado en timestampInvestigadores podían reproducir las claves si conocían el timestamp de cifradoSí (Avast)
MazeIV constante para AES-CBC en algunas versionesFacilitó análisis y descifrado parcialSí (tras disolución del grupo)
Babuk (ESXi)Implementación incorrecta de ECDH permitía derivar shared secretDecryptor publicado por AvastSí (Avast)
BlackBasta (nov-dic 2023)Bug en cifrado de archivos entre 5000 bytes y 1 GB: uso XChaCha20 con keystream predecible por flaw en counterSRLabs publicó "Black Basta Buster"Sí (SRLabs, parcheado por el grupo en enero 2024)
Conti (tras leaks)Código fuente filtrado permitió análisis completo; no un bug per se, pero facilitó decryptorsMúltiples decryptors basados en análisis del códigoParcial (depende de la versión)
WannaCryClaves RSA privadas persistían en memoria (no se limpiaban) porque el proceso no terminabaHerramienta Wannakey extraía primos RSA de memoria antes de reinicioSí (en ciertas condiciones, solo XP/7)
Petya (original, no NotPetya)Cifrado Salsa20 del MBR con debilidad en expansión de claveClave de descifrado calculable con algoritmo genético

Cómo encuentran los investigadores estos errores

Los investigadores de seguridad analizan las implementaciones criptográficas de ransomware buscando estos patrones:

Análisis de IVs/nonces: verificar que cada archivo tiene un IV/nonce único. Si múltiples archivos comparten el mismo valor, el cifrado de stream (CTR, ChaCha20) es vulnerable.

Predicción de PRNG: si las claves se generan con un PRNG no criptográfico (rand(), srand(time(NULL))), conocer el timestamp aproximado de infección permite probar un espacio de claves reducido.

Memory forensics: analizar dumps de memoria buscando claves AES/RSA que no fueron limpiadas. Volatility puede buscar patrones de bloques AES expandidos (key schedule) o estructuras RSA (BIGNUM).

Análisis de entropía: comparar la entropía del archivo cifrado con la del original. Cifrado parcial deja secciones con entropía baja (datos originales) alternadas con secciones de entropía alta (datos cifrados).

Reverse engineering del binario: desensamblar el ransomware para identificar las APIs criptográficas usadas, los parámetros, y posibles errores de lógica. Herramientas como IDA Pro, Ghidra y CAPA automatizan parte de este análisis.

Mapeo MITRE ATT&CK

TécnicaIDDescripción en contexto ransomware
Data Encrypted for ImpactT1486La técnica principal: cifrado de archivos para extorsión
Inhibit System RecoveryT1490Eliminación de shadow copies y deshabilitación de recovery
Disk WipeT1561Algunos ransomware destruyen en vez de cifrar (wipers disfrazados)
Data DestructionT1485Destrucción selectiva de backups

Recursos para análisis de criptografía en ransomware

Para analistas que necesiten evaluar la implementación criptográfica de una muestra:

HerramientaUso
CAPA (Mandiant)Detección automática de capacidades de malware, incluidas APIs criptográficas
FindCrypt (IDA plugin)Identifica constantes criptográficas en binarios (S-boxes AES, constantes de ChaCha20)
Crypto Identifier (Ghidra)Equivalente a FindCrypt para Ghidra
Volatility 3Extracción de claves criptográficas de memory dumps
CyberChefPruebas rápidas de descifrado con diferentes algoritmos y parámetros
NoMoreRansomRepositorio de decryptors gratuitos para familias con errores conocidos

Lo que viene después

Este artículo ha cubierto la teoría y la práctica del cifrado en ransomware. El siguiente artículo de la serie analiza el otro pilar de presión del ransomware moderno: la doble extorsión. Cómo los grupos exfiltran datos antes de cifrar, cómo operan los leak sites en Tor, y qué impacto legal y reputacional tiene para las víctimas la publicación de sus datos.


Fuentes y referencias

  • Aumasson, J.P. "Serious Cryptography: A Practical Introduction to Modern Encryption." No Starch Press, 2017.
  • Bernstein, D.J. "ChaCha, a variant of Salsa20." SASC 2008.
  • Bernstein, D.J. "Curve25519: New Diffie-Hellman Speed Records." PKC 2006.
  • KISA (Korea Internet & Security Agency). "Hive Ransomware Decryption: Recovering Files Using a Master Key." 2022.
  • SRLabs. "Black Basta Buster: Recovering files encrypted by Black Basta ransomware." 2024.
  • Avast Threat Intelligence. "Babuk Ransomware Decryptor." 2021.
  • Avast Threat Intelligence. "Akira Ransomware Decryptor." 2023.
  • No More Ransom Project. https://www.nomoreransom.org/
  • Mandiant. "CAPA: The FLARE Team's Open-Source Tool to Identify Capabilities in Executable Files." 2020.
  • Suiche, M. "WannaCry Ransomware: Analysis of Encryption Routine." 2017.
  • MITRE ATT&CK. "Data Encrypted for Impact (T1486)." https://attack.mitre.org/techniques/T1486/
  • NIST. "Recommendation for Block Cipher Modes of Operation." SP 800-38A.
  • The DFIR Report. Multiple ransomware analysis reports. https://thedfirreport.com/

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.