Cifrado en Ensamblador: XOR, RC4, AES y Deteccion
Como identificar y analizar algoritmos de cifrado en ensamblador durante el analisis de malware. Patrones de XOR loops, implementacion de RC4, deteccion de AES por S-box, uso de FindCrypt y tecnicas para extraer claves.
Cifrado en malware: de lo trivial a lo robusto
Practicamente todo el malware moderno usa algun tipo de cifrado. Desde un simple XOR de un byte para ocultar strings hasta AES-256-CBC para cifrar la comunicacion con el C2. Como analista, identificar el algoritmo y extraer la clave es frecuentemente el paso que desbloquea todo el analisis.
Este articulo recorre los algoritmos mas comunes en malware, como se ven en ensamblador, y las tecnicas para identificarlos y romperlos.
XOR: el cifrado ubicuo del malware
XOR de clave fija (un byte)
El caso mas simple. El malware XOR cada byte del texto cifrado con un valor constante.
En ensamblador x86:
; XOR loop tipico: descifrar buffer en memoria
lea esi, [encrypted_data] ; puntero al buffer cifrado
mov ecx, 0x100 ; tamano: 256 bytes
mov al, 0x5A ; clave XOR: 0x5A
.loop:
xor byte [esi], al ; descifrar byte actual
inc esi ; avanzar al siguiente byte
dec ecx ; decrementar contador
jnz .loop ; repetir si no es cero
Caracteristicas identificables en el desensamblador:
- Un registro cargado con un valor constante (la clave)
- Un XOR dentro de un loop que usa ese registro
- El XOR opera sobre memoria indexada, no sobre si mismo (XOR EAX, EAX es zero-out, no cifrado)
XOR multi-byte
Clave de varios bytes. El malware indexa la clave ciclicamente:
; XOR con clave de 4 bytes "ABCD" (0x41424344)
lea esi, [encrypted_data]
lea edi, [xor_key] ; "ABCD"
mov ecx, buffer_size
xor ebx, ebx ; indice en la clave = 0
.loop:
mov al, [edi + ebx] ; byte de la clave
xor [esi], al ; descifrar
inc esi
inc ebx
cmp ebx, 4 ; longitud de la clave
jb .no_reset
xor ebx, ebx ; reset indice a 0
.no_reset:
dec ecx
jnz .loop
La diferencia visible: hay un segundo puntero que se resetea ciclicamente. El CMP con un valor pequeno (4, 8, 16, 32) sugiere la longitud de la clave.
XOR rolling
Cada byte descifrado se usa como clave para el siguiente:
; XOR rolling: cada byte depende del anterior
lea esi, [encrypted_data]
mov ecx, buffer_size
mov al, 0x5A ; semilla inicial
.loop:
xor [esi], al ; descifrar byte actual
mov al, [esi] ; el byte descifrado es la nueva clave
inc esi
dec ecx
jnz .loop
Este patron es mas resistente a analisis estadistico que XOR fijo, pero sigue siendo fragil. Si conoces un byte del plaintext (como un null terminator al final de un string), puedes derivar la clave de vuelta.
Deteccion de XOR: tecnicas practicas
Buscar instrucciones XOR en un loop: en Ghidra o IDA, busca instrucciones XOR que no sean XOR reg, reg (zero-out). Filtra por XOR que operen sobre memoria.
Entropy analysis: los datos cifrados con XOR tienen entropia alta. Herramientas como binwalk o DIE (Detect It Easy) muestran la entropia por secciones. Una seccion .data con entropia mayor a 7.0 (en escala de 0-8) probablemente contiene datos cifrados.
Known plaintext: si sospechas que el texto descifrado contiene "http://" o "MZ" (cabecera PE), XOR esos bytes con los datos cifrados. Si obtienes un patron repetitivo, has encontrado la clave.
# Python: encontrar clave XOR con known plaintext
encrypted = bytes.fromhex("1a0b1c06")
known = b"http"
key = bytes(e ^ k for e, k in zip(encrypted, known))
print(f"Clave: {key.hex()}") # Si se repite, es la clave
RC4: el favorito del malware
Por que RC4
RC4 es el algoritmo de cifrado de flujo mas usado en malware por varias razones:
- Implementacion muy simple (unas 20 lineas de C)
- No tiene constantes detectables (a diferencia de AES)
- La clave puede ser de cualquier longitud
- Es rapido incluso en ensamblador manual
Familias que usan RC4: TrickBot, Emotet (variantes), Gootloader, AsyncRAT, AgentTesla, y muchas mas.
RC4 en ensamblador: KSA (Key Scheduling Algorithm)
La primera fase de RC4 inicializa la S-box (array de 256 bytes) usando la clave:
; KSA: inicializar S-box con la clave
; S[0..255] = 0..255 inicialmente
lea edi, [s_box]
xor ecx, ecx
.init_loop:
mov [edi + ecx], cl ; S[i] = i
inc ecx
cmp ecx, 256
jb .init_loop
; Permutacion con la clave
xor ecx, ecx ; i = 0
xor edx, edx ; j = 0
.ksa_loop:
movzx eax, byte [edi + ecx] ; S[i]
add dl, al ; j = j + S[i]
movzx ebx, byte [key + ecx % key_len]
add dl, bl ; j = j + key[i % key_len]
; Swap S[i] y S[j]
movzx ebx, byte [edi + edx] ; temp = S[j]
mov [edi + edx], al ; S[j] = S[i]
mov [edi + ecx], bl ; S[i] = temp
inc ecx
cmp ecx, 256
jb .ksa_loop
RC4 en ensamblador: PRGA (Pseudo-Random Generation Algorithm)
La segunda fase genera el keystream y lo XOR con los datos:
; PRGA: generar keystream y descifrar
xor ecx, ecx ; i = 0
xor edx, edx ; j = 0
lea esi, [ciphertext]
mov ebp, data_length
.prga_loop:
inc cl ; i = (i + 1) mod 256
movzx eax, byte [edi + ecx] ; S[i]
add dl, al ; j = (j + S[i]) mod 256
; Swap S[i] y S[j]
movzx ebx, byte [edi + edx]
mov [edi + edx], al
mov [edi + ecx], bl
; Generar byte de keystream
add al, bl ; S[i] + S[j]
movzx eax, byte [edi + eax] ; K = S[(S[i] + S[j]) mod 256]
xor [esi], al ; descifrar: plaintext = ciphertext XOR K
inc esi
dec ebp
jnz .prga_loop
Como reconocer RC4 en desensamblado
Patrones clave que delatan RC4:
-
Inicializacion de array de 256 bytes con valores secuenciales (0x00 a 0xFF). Un loop que llena 256 posiciones con su propio indice.
-
Dos loops consecutivos sobre 256 iteraciones: primero el init, luego el KSA.
-
Swaps frecuentes: muchos MOV para intercambiar bytes usando un temporal.
-
Modulo 256 implicito: operaciones con registros de 8 bits (AL, CL, DL) que naturalmente hacen modulo 256 por overflow.
-
Sin constantes detectables: a diferencia de AES o MD5, RC4 no tiene tablas ni constantes fijas. FindCrypt no lo detecta.
Extraer la clave RC4
Si identificas la funcion KSA, la clave suele estar en el primer argumento o en la ubicacion que se carga justo antes de la llamada:
; Llamada tipica a funcion RC4
push 16 ; longitud de la clave
push offset rc4_key ; puntero a la clave
push data_size ; tamano de los datos
push offset ciphertext ; datos cifrados
call rc4_decrypt
Extrae los bytes en la direccion de rc4_key con la longitud indicada. Esa es tu clave.
AES: cifrado de grado militar en malware
Por que AES en malware
AES aparece en malware que necesita cifrado robusto:
- Ransomware: cifra archivos de la victima (LockBit, BlackCat, REvil)
- C2 cifrado: comunicacion con el servidor de comando (Cobalt Strike)
- Configuracion protegida: el payload cifra su configuracion embebida
Detectar AES: la S-box
AES tiene una S-box (Substitution Box) de 256 bytes que es una constante conocida. Los primeros bytes son:
63 7C 77 7B F2 6B 6F C5 30 01 67 2B FE D7 AB 76
CA 82 C9 7D FA 59 47 F0 AD D4 A2 AF 9C A4 72 C0
FindCrypt busca esta secuencia exacta en el binario. Si la encuentra, confirma la presencia de AES.
Tambien busca las constantes Rcon (Round Constants):
01 02 04 08 10 20 40 80 1B 36
Y la tabla de multiplicacion por 2 en GF(2^8) usada en MixColumns.
AES en ensamblador: patrones
Las implementaciones de AES en ensamblador varian mucho. Tres categorias principales:
AES con instrucciones nativas (AES-NI): procesadores Intel/AMD modernos tienen instrucciones hardware para AES:
; AES-NI: cifrado ultra-rapido
aesenc xmm1, xmm2 ; una ronda de cifrado AES
aesenclast xmm1, xmm2 ; ultima ronda de cifrado
aesdec xmm1, xmm2 ; una ronda de descifrado
aeskeygenassist xmm1, xmm2, imm8 ; generacion de claves de ronda
Si ves estas instrucciones, es AES sin duda. El malware que las usa es sofisticado y busca rendimiento.
AES con tablas T: implementacion comun en software. Usa cuatro tablas T de 1024 bytes cada una (Te0, Te1, Te2, Te3) que combinan SubBytes, ShiftRows y MixColumns. Busca cuatro arrays de 256 DWORDs consecutivos.
AES con S-box directa: implementacion basica que aplica la S-box explicitamente, luego ShiftRows, luego MixColumns. Mas lenta pero mas facil de reconocer.
Extraer la clave AES
La clave AES puede estar:
- Hardcodeada en el binario (busca 16, 24 o 32 bytes cerca de la S-box o de las llamadas a funciones de cifrado)
- Derivada de un password con PBKDF2 o similar
- Recibida del C2 durante la comunicacion inicial
- Calculada a partir de propiedades del sistema (hostname, MAC address)
Para ransomware, frecuentemente hay una clave simetrica por archivo, cifrada con RSA. La clave privada RSA esta en el servidor del atacante.
Otros algoritmos frecuentes
Base64 (codificacion, no cifrado)
No es cifrado, pero aparece constantemente. Patron en ensamblador:
; Tabla Base64 como string
db "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
; Loop de codificacion: toma 3 bytes, produce 4 caracteres
; Operaciones con SHR (shift right) y AND para extraer grupos de 6 bits
shr eax, 2 ; primeros 6 bits
and eax, 0x3F ; mascara 6 bits
Busca el string completo de la tabla Base64 o variantes (Base64url usa - y _ en lugar de + y /).
XOR + Base64 (combo clasico)
Patron extremadamente comun: el malware cifra con XOR y luego codifica en Base64 (o viceversa). Si descifras Base64 y obtienes datos que parecen aleatorios, aplica XOR con claves comunes.
Chacha20
Creciendo en popularidad en ransomware moderno (reemplazo de RC4 para velocidad). Tiene constantes detectables:
"expand 32-byte k" ; constante en la inicializacion del estado
Si encuentras este string, es Chacha20.
Herramientas de deteccion
FindCrypt (IDA Pro)
Instalacion: copiar findcrypt-yara a la carpeta de plugins de IDA. Ejecutar desde Edit, Plugins, FindCrypt.
Detecta: AES, DES, 3DES, Blowfish, RC2, MD5, SHA-1, SHA-256, SHA-512, CRC32, TEA/XTEA, Serpent, Twofish, Camellia.
No detecta: RC4 (sin constantes), XOR (trivial), algoritmos custom.
Ghidra FindCrypt equivalente
Para Ghidra, el script FindCrypt-Ghidra (disponible en GitHub) ofrece funcionalidad similar:
# Ejecutar desde Script Manager de Ghidra
# FindCrypt.py busca constantes criptograficas conocidas
KANAL (PEiD plugin) y Detect It Easy
Herramientas standalone que escanean el binario buscando constantes criptograficas sin necesidad de desensamblador completo.
Entropy analysis con binwalk
binwalk -E malware.exe
# Muestra grafico de entropia por offset
# Picos de entropia alta = datos cifrados o comprimidos
Flujo de trabajo para analisis de cifrado en malware
Paso 1: detectar presencia de cifrado
- Ejecutar FindCrypt o equivalente
- Revisar entropia por secciones
- Buscar strings sospechosamente ausentes (pocos strings = cifrado)
Paso 2: identificar el algoritmo
- FindCrypt dice AES: buscar S-box, AES-NI instructions, key schedule
- FindCrypt no detecta nada: buscar loops con XOR (probable RC4 o XOR custom)
- Constantes "expand 32-byte k": Chacha20
- Tabla Base64 presente: probablemente codificacion (no cifrado)
Paso 3: localizar la clave
- Trazar xrefs hasta la funcion de cifrado/descifrado
- Los parametros antes del CALL contienen: puntero a datos, tamano, puntero a clave, longitud de clave
- En el decompilador, la firma de la funcion revela los parametros
Paso 4: descifrar
- Extraer clave y datos cifrados del binario
- Aplicar el algoritmo identificado
- Verificar que el resultado tiene sentido (strings legibles, cabecera PE valida, JSON)
# Python: descifrar RC4 extraido de un sample
from Crypto.Cipher import ARC4
key = bytes.fromhex("5a3b4c2d1e0f")
ciphertext = open("encrypted_config.bin", "rb").read()
cipher = ARC4.new(key)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)
Paso 5: documentar IOCs
Los datos descifrados contienen los IOCs que buscas: URLs de C2, dominios de backup, mutex names, claves de registro de persistencia. Documenta todo con su contexto criptografico (algoritmo, clave, offset en el binario).
Conclusiones
El cifrado en malware sigue un patron predecible: la mayoria usa XOR o RC4 para strings y configuracion, y AES para payload y comunicaciones. Saber reconocer estos patrones en ensamblador te permite desbloquear el analisis en minutos.
La clave (literalmente) esta en encontrar la clave. Una vez identificado el algoritmo y extraida la clave, el descifrado es mecanico. Las herramientas como FindCrypt aceleran la deteccion de algoritmos con constantes conocidas, pero RC4 y XOR requieren reconocimiento manual de patrones.
En el articulo final de la serie, ponemos todo en practica con ejercicios de crackmes y muestras reales para consolidar lo aprendido.
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.