Communitygithub.com

Análisis de malware empaquetado con desempaquetador UPX

Identifica y desempaqueta muestras de malware empaquetadas con UPX, incluyendo binarios con bytes mágicos o cabeceras modificados que bloquean la descompresión automatizada, para recuperar el ejecutable original para análisis estático. Úsalo cuando una muestra muestre alta entropía, importaciones mínimas, o solo LoadLibrary/GetProcAddress en su tabla de importaciones, o al preparar un binario empaquetado para desensamblarlo en Ghidra o IDA.

¿Qué es Análisis de malware empaquetado con desempaquetador UPX?

Esta habilidad automatiza el proceso de desempaquetado de malware empaquetado con UPX, un empaquetador de ejecutables de código abierto comúnmente utilizado por los autores de malware para comprimir y ofuscar su código, dificultando el análisis estático. El flujo de trabajo comienza identificando la presencia de UPX u otros empaquetadores conocidos mediante herramientas como Detect It Easy (DIE), PEStudio o análisis de entropía de secciones. Luego, intenta la descompresión estándar con upx -d; si falla debido a cabeceras modificadas, utiliza un script en Python para reparar los bytes mágicos de UPX ("UPX!") y los nombres de sección. Si la reparación automatizada no es suficiente, proporciona pasos detallados para el desempaquetado manual con depuradores como x64dbg, incluyendo el uso de puntos de interrupción por hardware en ESP para localizar el Punto de Entrada Original (OEP) y la reconstrucción de la tabla de importaciones con Scylla. Finalmente, valida el binario desempaquetado verificando la integridad del PE, las importaciones resueltas y la entropía de las secciones, todo ello dentro de una máquina virtual aislada sin conectividad de red. Es compatible con plataformas Windows y Linux y está diseñado para analistas de malware que utilizan Ghidra, IDA Pro o depuradores dinámicos.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/analyzing-packed-malware-with-upx-unpacker

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace Análisis de malware empaquetado con desempaquetador UPX?

Cuándo usarlo

  • El análisis estático revela secciones de alta entropía e importaciones mínimas, indicando que el binario está empaquetado.
  • PEiD, Detect It Easy o PEStudio identifican UPX u otro empaquetador conocido.
  • La tabla de importaciones contiene solo LoadLibrary y GetProcAddress (resolución de importaciones en tiempo de ejecución, típica de binarios empaquetados).
  • Necesitas recuperar el binario original para un desensamblado y descompilación adecuados en Ghidra o IDA.
  • La descompresión automatizada de UPX falla porque el autor del malware modificó los bytes mágicos o las cabeceras de UPX.

No lo uses cuando trabajes con empaquetadores personalizados, protectores basados en VM (Themida, VMProtect), o muestras donde el desempaquetado dinámico mediante depuración sea más apropiado.

Prerrequisitos

  • UPX (Ultimate Packer for eXecutables) instalado (apt install upx-ucl o descargar de https://upx.github.io/)
  • Detect It Easy (DIE) para identificación de empaquetadores
  • Python 3.8+ con la librería pefile para reparación manual de cabeceras
  • x64dbg o x32dbg para desempaquetado manual cuando fallen las herramientas automatizadas
  • PE-bear o CFF Explorer para inspección y reparación de cabeceras PE
  • Máquina virtual de análisis aislada sin conectividad de red

Flujo de trabajo

Paso 1: Identificar el empaquetador

Determina si la muestra está empaquetada e identifica el empaquetador:

# Verificar con Detect It Easy
diec suspect.exe

# Verificar con UPX (prueba sin desempaquetar)
upx -t suspect.exe

# Detección de entropía y empaquetador basada en Python
python3 << 'PYEOF'
import pefile
import math

pe = pefile.PE("suspect.exe")

print("Análisis de secciones:")
for section in pe.sections:
    name = section.Name.decode().rstrip('\x00')
    entropy = section.get_entropy()
    raw = section.SizeOfRawData
    virtual = section.Misc_VirtualSize
    print(f"  {name:8s} Entropía: {entropy:.2f}  Raw: {raw:>8}  Virtual: {virtual:>8}")

# Verificar nombres de secciones UPX
section_names = [s.Name.decode().rstrip('\x00') for s in pe.sections]
if 'UPX0' in section_names or 'UPX1' in section_names:
    print("\n[!] Nombres de secciones UPX detectados")
elif '.upx' in [s.lower() for s in section_names]:
    print("\n[!] Nombres de secciones variantes de UPX detectados")

# Verificar cantidad de importaciones (los binarios empaquetados tienen muy pocas)
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
    total_imports = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
    print(f"\nTotal de importaciones: {total_imports}")
    if total_imports < 10:
        print("[!] Muy pocas importaciones - probablemente empaquetado")
else:
    print("\n[!] Sin directorio de importaciones - fuertemente empaquetado")
PYEOF

Paso 2: Intentar descompresión estándar de UPX

Prueba la descompresión integrada de UPX:

# Descompresión estándar de UPX
upx -d suspect.exe -o unpacked.exe

# Si UPX falla con el error "not packed by UPX", las cabeceras pueden estar modificadas
# Salida detallada para depuración
upx -d suspect.exe -o unpacked.exe -v 2>&1

# Verificar el archivo desempaquetado
file unpacked.exe
diec unpacked.exe

Paso 3: Reparar cabeceras UPX modificadas

Si la descompresión estándar falla, repara los bytes mágicos alterados:

# Reparar cabeceras UPX modificadas
import struct

with open("suspect.exe", "rb") as f:
    data = bytearray(f.read())

# Bytes mágicos de UPX: "UPX!" (0x55505821)
# Los autores de malware suelen modificarlos para evitar el desempaquetado automático

# Buscar firmas UPX modificadas
upx_magic = b"UPX!"
modified_patterns = [b"UPX0", b"UPX\x00", b"\x00PX!", b"UPx!"]

# Encontrar y restaurar nombres de secciones
pe_offset = struct.unpack_from("<I", data, 0x3C)[0]
num_sections = struct.unpack_from("<H", data, pe_offset + 6)[0]
section_table_offset = pe_offset + 0x18 + struct.unpack_from("<H", data, pe_offset + 0x14)[0]

print(f"Desplazamiento PE: 0x{pe_offset:X}")
print(f"Número de secciones: {num_sections}")
print(f"Desplazamiento de tabla de secciones: 0x{section_table_offset:X}")

for i in range(num_sections):
    offset = section_table_offset + (i * 40)
    name = data[offset:offset+8]
    print(f"Sección {i}: {name}")

# Restaurar bytes mágicos UPX en el binario
# Buscar la ubicación de la firma de cabecera UPX (típicamente cerca del final de los datos empaquetados)
for i in range(len(data) - 4):
    if data[i:i+3] == b"UPX" and data[i+3] != ord("!"):
        print(f"Bytes mágicos UPX modificados encontrados en desplazamiento 0x{i:X}: {data[i:i+4]}")
        data[i:i+4] = b"UPX!"
        print(f"Restaurado a: UPX!")

# También restaurar nombres de secciones si están modificados
for i in range(num_sections):
    offset = section_table_offset + (i * 40)
    name = data[offset:offset+8].rstrip(b'\x00')
    if name in [b"UPX0", b"UPX1", b"UPX2"]:
        continue  # Ya están correctos
    # Verificar modificaciones comunes
    if name.startswith(b"UP") or name.startswith(b"ux"):
        original = f"UPX{i}".encode().ljust(8, b'\x00')
        data[offset:offset+8] = original
        print(f"Nombre de sección restaurado en 0x{offset:X} a {original}")

with open("suspect_fixed.exe", "wb") as f:
    f.write(data)

print("\nArchivo corregido escrito. Reintentar: upx -d suspect_fixed.exe -o unpacked.exe")

Paso 4: Desempaquetado manual con depurador

Cuando el desempaquetado automatizado falla por completo, utiliza el desempaquetado dinámico:

Desempaquetado manual UPX con x64dbg:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Cargar la muestra empaquetada en x64dbg
2. Ejecutar hasta el punto de entrada (punto de interrupción del sistema, luego F9)
3. Patrón del stub de desempaquetado UPX:
   a. PUSHAD (guarda todos los registros)
   b. Bucle de descompresión (procesa las secciones empaquetadas)
   c. Resuelve importaciones (llamadas a LoadLibrary/GetProcAddress)
   d. POPAD (restaura los registros)
   e. JMP al OEP (punto de entrada original)
4. Establecer punto de interrupción por hardware en ESP después de PUSHAD:
   - Después de PUSHAD, haz clic derecho en ESP en registros -> Seguir en volcado
   - Establecer punto de interrupción por hardware en acceso a la dirección [ESP]
   - Ejecutar (F9) - se detiene en POPAD antes de JMP al OEP
5. Avanzar (F7/F8) hasta llegar al JMP al OEP
6. En OEP: Usar el plugin Scylla para volcar y corregir importaciones:
   - Plugins -> Scylla -> OEP = EIP actual
   - Clic en "IAT Autosearch" -> "Get Imports"
   - Clic en "Dump" para guardar el binario desempaquetado
   - Clic en "Fix Dump" para reparar la tabla de importaciones

Paso 5: Validar el binario desempaquetado

Verifica que la muestra desempaquetada sea válida y completa:

# Verificar que el PE desempaquetado sea válido
python3 << 'PYEOF'
import pefile

pe = pefile.PE("unpacked.exe")

# Verificar que las secciones sean normales
print("Análisis de secciones desempaquetadas:")
for section in pe.sections:
    name = section.Name.decode().rstrip('\x00')
    entropy = section.get_entropy()
    print(f"  {name:8s} Entropía: {entropy:.2f}")

# Verificar que las importaciones estén resueltas
print(f"\nCantidad de importaciones:")
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
    for entry in pe.DIRECTORY_ENTRY_IMPORT:
        dll = entry.dll.decode()
        count = len(entry.imports)
        print(f"  {dll}: {count} funciones")
    total = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
    print(f"  Total: {total} importaciones")

# Comparar tamaños de archivo
import os
packed_size = os.path.getsize("suspect.exe")
unpacked_size = os.path.getsize("unpacked.exe")
print(f"\nEmpaquetado: {packed_size:>10} bytes")
print(f"Desempaquetado: {unpacked_size:>10} bytes")
print(f"Proporción: {unpacked_size/packed_size:.1f}x")
PYEOF

Conceptos clave

TérminoDefinición
EmpaquetadoCompresión o cifrado de código ejecutable para reducir el tamaño del archivo y dificultar el análisis estático; el binario contiene un stub de desempaquetado que restaura el código en tiempo de ejecución
UPXUltimate Packer for eXecutables; empaquetador de ejecutables de código abierto comúnmente abusado por autores de malware porque es gratuito y efectivo
Punto de entrada original (OEP)Dirección real de inicio del código malicioso antes del empaquetado; el stub de desempaquetado descomprime el código y luego salta al OEP
Reconstrucción de importacionesProceso de reconstruir la tabla de direcciones de importación después de volcar un proceso desempaquetado de la memoria usando herramientas como Scylla o ImpRec
PUSHAD/POPADInstrucciones x86 que guardan/restauran todos los registros de propósito general; UPX usa este patrón para preservar el estado de los registros durante el desempaquetado
Entropía de secciónMedida de aleatoriedad de los datos de una sección PE; las secciones empaquetadas muestran entropía > 7.0 mientras que las secciones de código normales promedian 5.0-6.5
Bytes mágicosBytes de firma dentro de un archivo que identifican su formato; UPX usa "UPX!" que los autores de malware modifican para evitar la descompresión automatizada

Herramientas y sistemas

  • UPX: Empaquetador de ejecutables de código abierto con capacidad de descompresión integrada para archivos correctamente empaquetados
  • Detect It Easy (DIE): Herramienta de detección de empaquetadores, compiladores y enlazadores que identifica protección en archivos PE, ELF y Mach-O
  • x64dbg/x32dbg: Depurador de Windows de código abierto utilizado para desempaquetado manual mediante ejecución dinámica y búsqueda del OEP basada en puntos de interrupción
  • Scylla: Herramienta de reconstrucción de importaciones integrada con x64dbg para reconstruir la IAT después del volcado de memoria
  • PE-bear: Visor y editor de archivos PE para inspeccionar y reparar cabeceras PE después del desempaquetado

Escenarios comunes

Escenario: Desempaquetado de malware con cabeceras UPX modificadas

Contexto: Una muestra de malware es identificada como empaquetada con UPX por los nombres de sección (UPX0, UPX1) pero upx -d falla con "CantUnpackException: header corrupted". El autor del malware modificó los bytes mágicos de UPX para evitar la descompresión automatizada.

Enfoque:

  1. Abre el binario en un editor hexadecimal y busca el área de la cabecera UPX (típicamente al final de los datos empaquetados)
  2. Identifica los bytes mágicos modificados (por ejemplo, "UPX!" cambiado a "UPX\x00" o completamente puesto a cero)
  3. Usa el script de reparación en Python para restaurar la magia "UPX!" y corregir los nombres de sección
  4. Reintenta upx -d en el binario reparado
  5. Si la reparación falla, recurre al desempaquetado manual con x64dbg (PUSHAD -> BP por hardware en ESP -> POPAD -> JMP OEP)
  6. Valida que el binario desempaquetado tenga importaciones adecuadas y valores de entropía razonables
  7. Importa en Ghidra o IDA para un análisis estático completo

Errores comunes:

  • Asumir que UPX es el único empaquetador; el binario puede estar doblemente empaquetado (UPX + capa personalizada)
  • Modificar la muestra empaquetada original en lugar de trabajar sobre una copia
  • No reconstruir las importaciones después del volcado de memoria manual (el binario volcado fallará sin la corrección de la IAT)
  • Olvidar verificar la presencia de datos superpuestos añadidos después de las secciones PE empaquetadas con UPX

Formato de salida

INFORME DE ANÁLISIS DE DESEMPAQUETADO
=======================================
Muestra:          suspect.exe
SHA-256:          e3b0c44298fc1c149afbf4c8996fb924...
Empaquetador:     UPX 3.96 (cabeceras modificadas)

BINARIO EMPAQUETADO
Secciones:        UPX0 (entropía: 0.00) UPX1 (entropía: 7.89) .rsrc (entropía: 3.45)
Importaciones:    2 (kernel32.dll: LoadLibraryA, GetProcAddress)
Tamaño archivo:   98,304 bytes

MÉTODO DE DESEMPAQUETADO
Método:           Reparación de cabecera + UPX -d
Corrección cab.:  Bytes mágicos UPX! restaurados en desplazamiento 0x1F000
Comando:          upx -d suspect_fixed.exe -o unpacked.exe
Resultado:        ÉXITO

BINARIO DESEMPAQUETADO
Secciones:        .text (entropía: 6.21) .rdata (entropía: 4.56) .data (entropía: 3.12) .rsrc (entropía: 3.45)
Importaciones:    147 (kernel32, user32, advapi32, wininet, ws2_32)
Tamaño archivo:   245,760 bytes (expansión 2.5x)
OEP:              0x00401000

VALIDACIÓN
PE Válido:        Sí
Importaciones resueltas: Sí (147 funciones en 8 DLL)
Ejecutable:       Sí (se ejecuta sin fallo en sandbox)

PRÓXIMOS PASOS
- Importar unpacked.exe en Ghidra para desensamblado completo
- Ejecutar reglas YARA contra el binario desempaquetado
- Enviar binario desempaquetado a VirusTotal para una detección mejorada

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

abusing-dpapi-for-credential-access

Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket

abusing-shadow-credentials-for-privesc

Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target

achieving-cmmc-level-2-compliance

>-

acquiring-disk-image-with-dd-and-dcfldd

Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.

analyzing-active-directory-acl-abuse

Detect dangerous ACL misconfigurations in Active Directory using ldap3

analyzing-android-malware-with-apktool

Perform static analysis of Android APK malware using apktool for resource decompilation, jadx for Java source recovery, and androguard for manifest inspection, dangerous permission-combination detection, and identification of obfuscated code, dynamic code loading, and reflection-based API calls. Use to statically triage a suspicious APK without executing it or to build mobile malware detection rules.

analyzing-api-gateway-access-logs

Parses API Gateway access logs (AWS API Gateway, Kong, Nginx) to detect

analyzing-apt-group-with-mitre-navigator

Query ATT&CK data with attackcti, mitreattack-python, and stix2, then build MITRE ATT&CK Navigator layers and multi-layer heatmap overlays mapping one or more APT groups

analyzing-azure-activity-logs-for-threats

Queries Azure Monitor activity logs and sign-in logs via azure-monitor-query

analyzing-bootkit-and-rootkit-samples

Analyzes bootkit and advanced rootkit malware infecting the Master

analyzing-browser-forensics-with-hindsight

Parse Chromium-based browser databases with Hindsight to extract and correlate browsing history, downloads, cookies, cached content, autofill data, saved passwords, and extensions from Chrome, Edge, Brave, Opera, and Vivaldi into a unified timeline (XLSX, JSON, or SQLite output). Use during incident response, insider-threat investigations, or criminal cases when you need to reconstruct a user

analyzing-campaign-attribution-evidence

Systematically evaluate cyber-campaign evidence to attribute an operation to a threat actor, using the Diamond Model and Analysis of Competing Hypotheses (ACH) to weigh infrastructure overlaps, TTP consistency, malware code similarity, and timing/language artifacts into confidence-weighted attribution assessments. Use when an incident investigation needs a defensible attribution confidence level.

analyzing-certificate-transparency-for-phishing

Monitor Certificate Transparency logs using crt.sh and Certstream to

analyzing-cloud-storage-access-patterns

Detect abnormal access in AWS S3, GCS, and Azure Blob Storage by analyzing CloudTrail Data Events, GCS audit logs, and Azure Storage Analytics for after-hours bulk downloads, new-IP access, and API-call spikes (e.g. GetObject) via statistical baselines and time-series anomaly detection. Use when investigating suspected cloud data exfiltration or building related detection rules.

analyzing-cobalt-strike-beacon-configuration

Extract and analyze Cobalt Strike beacon configuration from PE files

analyzing-cobaltstrike-malleable-c2-profiles

Parse and analyze Cobalt Strike Malleable C2 profiles with dissect.cobaltstrike (profiles and beacon-payload configs) and pyMalleableC2 (AST parsing) to extract HTTP/DNS transforms, URIs, headers, sleep/jitter, and injection behavior, then generate network detection signatures. Use when reverse-engineering a captured malleable profile or building detections against Cobalt Strike Beacon traffic.

analyzing-command-and-control-communication

Analyzes malware C2 communication over HTTP, HTTPS, DNS, and custom

analyzing-cyber-kill-chain

Analyzes intrusion activity against the Lockheed Martin Cyber Kill Chain

analyzing-disk-image-with-autopsy

Perform comprehensive forensic analysis of raw (dd), E01, or AFF disk images with Autopsy and The Sleuth Kit, recovering deleted files, examining metadata and embedded artifacts, keyword searching, and building investigation timelines with visual reports. Use for structured analysis of a forensic disk image or when stakeholders need visual reports from evidence.

analyzing-dns-logs-for-exfiltration

Analyzes DNS query logs to detect data exfiltration via DNS tunneling,

Skills relacionados