Communitygithub.com

analyse-malware-paquee-avec-upx-unpacker

Identifie et désempaquette des échantillons de malwares compressés avec UPX, y compris les binaires dont les octets magiques ou en-têtes UPX ont été modifiés pour bloquer la décompression automatique, afin de récupérer l'exécutable original pour une analyse statique. À utiliser lorsqu'un échantillon présente une entropie élevée, des importations minimales ou seulement LoadLibrary/GetProcAddress dans sa table d'importation, ou lors de la préparation d'un binaire compressé pour le désassemblage dans Ghidra ou IDA.

Qu'est-ce que analyse-malware-paquee-avec-upx-unpacker ?

Ce skill spécialisé dans l'analyse de malwares permet de détecter les binaires compressés avec UPX (Ultimate Packer for eXecutables) et de les désempaqueter, même lorsque les en-têtes ont été volontairement modifiés par les auteurs de malware pour contourner les outils automatisés. Il guide l'utilisateur à travers un flux de travail complet : identification du packer via l'entropie des sections et les signatures, tentative de décompression standard avec UPX, réparation des en-têtes modifiés à l'aide de scripts Python, et désempaquetage manuel avec un débogueur (x64dbg) lorsque les méthodes automatisées échouent. Le skill valide ensuite le binaire désempaqueté en vérifiant la signature PE, le nombre d'importations et l'entropie des sections, et fournit un rapport structuré. Il prend en charge les plateformes Windows et Linux et s'intègre avec Ghidra, IDA, PE-bear, Detect It Easy et Scylla pour une analyse complète post-désempaquetage. Ce skill est essentiel pour les analystes en sécurité devant analyser des malwares compressés dont les mécanismes de protection ont été intentionnellement renforcés.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Analyse de Malwares Paquetés avec UPX Unpacker

Quand l'utiliser

  • L'analyse statique révèle des sections à haute entropie et des importations minimales, indiquant que le binaire est compressé
  • PEiD, Detect It Easy ou PEStudio identifient UPX ou un autre packer connu
  • La table d'importation ne contient que LoadLibrary et GetProcAddress (résolution d'importation dynamique typique des binaires compressés)
  • Vous devez récupérer le binaire original pour un désassemblage et une décompilation corrects dans Ghidra ou IDA
  • La décompression automatique UPX échoue car l'auteur du malware a modifié les octets magiques ou les en-têtes UPX

Ne pas utiliser avec des packers personnalisés, des protecteurs basés sur des machines virtuelles (Themida, VMProtect), ou des échantillons où le désempaquetage dynamique via débogage est plus approprié.

Prérequis

  • UPX (Ultimate Packer for eXecutables) installé (apt install upx-ucl ou téléchargement depuis https://upx.github.io/)
  • Detect It Easy (DIE) pour l'identification du packer
  • Python 3.8+ avec la bibliothèque pefile pour la réparation manuelle des en-têtes
  • x64dbg ou x32dbg pour le désempaquetage manuel lorsque les outils automatisés échouent
  • PE-bear ou CFF Explorer pour l'inspection et la réparation des en-têtes PE
  • Machine virtuelle d'analyse isolée sans connectivité réseau

Flux de travail

Étape 1 : Identifier le packer

Déterminez si l'échantillon est compressé et identifiez le packer :

# Vérification avec Detect It Easy
diec suspect.exe

# Vérification avec UPX (test sans désempaquetage)
upx -t suspect.exe

# Analyse d'entropie et détection de packer en Python
python3 << 'PYEOF'
import pefile
import math

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

print("Analyse des sections :")
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} Entropie : {entropy:.2f}  Brut : {raw:>8}  Virtuel : {virtual:>8}")

# Recherche des noms de sections 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[!] Noms de sections UPX détectés")
elif '.upx' in [s.lower() for s in section_names]:
    print("\n[!] Noms de sections variantes UPX détectés")

# Vérification du nombre d'importations (les binaires compressés en ont très peu)
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
    total_imports = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
    print(f"\nNombre total d'importations : {total_imports}")
    if total_imports < 10:
        print("[!] Très peu d'importations - probablement compressé")
else:
    print("\n[!] Aucune table d'importation - fortement compressé")
PYEOF

Étape 2 : Tenter la décompression UPX standard

Essayez la décompression UPX intégrée :

# Décompression UPX standard
upx -d suspect.exe -o unpacked.exe

# Si UPX échoue avec l'erreur "not packed by UPX", les en-têtes peuvent avoir été modifiés
# Sortie verbeuse pour le débogage
upx -d suspect.exe -o unpacked.exe -v 2>&1

# Vérification du fichier désempaqueté
file unpacked.exe
diec unpacked.exe

Étape 3 : Réparer les en-têtes UPX modifiés

Si la décompression standard échoue, réparez les octets magiques falsifiés :

# Réparation des en-têtes UPX modifiés
import struct

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

# Octets magiques UPX : "UPX!" (0x55505821)
# Les auteurs de malware modifient souvent ces octets pour empêcher le désempaquetage automatique

# Recherche des signatures UPX modifiées
upx_magic = b"UPX!"
modified_patterns = [b"UPX0", b"UPX\x00", b"\x00PX!", b"UPx!"]

# Recherche et restauration des noms de sections
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"Offset PE : 0x{pe_offset:X}")
print(f"Nombre de sections : {num_sections}")
print(f"Offset de la table des sections : 0x{section_table_offset:X}")

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

# Restauration des octets magiques UPX dans le binaire
# Recherche de l'emplacement de la signature d'en-tête UPX (généralement près de la fin des données compressées)
for i in range(len(data) - 4):
    if data[i:i+3] == b"UPX" and data[i+3] != ord("!"):
        print(f"Octets magiques UPX modifiés trouvés à l'offset 0x{i:X} : {data[i:i+4]}")
        data[i:i+4] = b"UPX!"
        print(f"Restauration en : UPX!")

# Restauration également des noms de sections si modifiés
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  # Déjà correct
    # Vérification des modifications courantes
    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"Nom de section restauré à 0x{offset:X} en {original}")

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

print("\nFichier réparé écrit. Réessayez : upx -d suspect_fixed.exe -o unpacked.exe")

Étape 4 : Désempaquetage manuel avec un débogueur

Lorsque le désempaquetage automatisé échoue complètement, utilisez le désempaquetage dynamique :

Désempaquetage manuel UPX avec x64dbg :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Charger l'échantillon compressé dans x64dbg
2. Exécuter jusqu'au point d'entrée (breakpoint système puis F9)
3. Modèle de la routine de désempaquetage UPX :
   a. PUSHAD (sauvegarde tous les registres)
   b. Boucle de décompression (traite les sections compressées)
   c. Résout les importations (appels LoadLibrary/GetProcAddress)
   d. POPAD (restaure les registres)
   e. JMP vers OEP (point d'entrée original)
4. Placer un breakpoint matériel sur ESP après PUSHAD :
   - Après PUSHAD, clic droit sur ESP dans les registres -> Suivre dans le dump
   - Placer un breakpoint matériel sur l'accès à l'adresse [ESP]
   - Exécuter (F9) - s'arrête à POPAD avant le JMP vers OEP
5. Avancer pas à pas (F7/F8) jusqu'à atteindre le JMP vers OEP
6. À l'OEP : Utiliser le plugin Scylla pour dumper et corriger les importations :
   - Plugins -> Scylla -> OEP = EIP actuel
   - Cliquer sur "IAT Autosearch" -> "Get Imports"
   - Cliquer sur "Dump" pour sauvegarder le binaire désempaqueté
   - Cliquer sur "Fix Dump" pour réparer la table d'importation

Étape 5 : Valider le binaire désempaqueté

Vérifiez que l'échantillon désempaqueté est valide et complet :

# Vérification que le PE désempaqueté est valide
python3 << 'PYEOF'
import pefile

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

# Vérification des sections normales
print("Analyse des sections désempaquetées :")
for section in pe.sections:
    name = section.Name.decode().rstrip('\x00')
    entropy = section.get_entropy()
    print(f"  {name:8s} Entropie : {entropy:.2f}")

# Vérification que les importations sont résolues
print(f"\nNombre d'importations :")
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} fonctions")
    total = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
    print(f"  Total : {total} importations")

# Comparaison des tailles de fichiers
import os
packed_size = os.path.getsize("suspect.exe")
unpacked_size = os.path.getsize("unpacked.exe")
print(f"\nCompressé :     {packed_size:>10} octets")
print(f"Désempaqueté : {unpacked_size:>10} octets")
print(f"Rapport :      {unpacked_size/packed_size:.1f}x")
PYEOF

Concepts clés

TermeDéfinition
Compression (packing)Compression ou chiffrement du code exécutable pour réduire la taille du fichier et entraver l'analyse statique ; le binaire contient une routine de désempaquetage qui restaure le code à l'exécution
UPXUltimate Packer for eXecutables ; compresseur d'exécutables open-source couramment utilisé par les auteurs de malwares car il est gratuit et efficace
Point d'Entrée Original (OEP)La véritable adresse de début du code malveillant avant compression ; la routine de désempaquetage décompresse le code puis saute vers l'OEP
Reconstruction des ImportationsProcessus de reconstruction de la table d'adresses d'importation après avoir dumpé un processus désempaqueté de la mémoire à l'aide d'outils comme Scylla ou ImpRec
PUSHAD/POPADInstructions x86 qui sauvegardent/restaurent tous les registres généraux ; UPX utilise ce motif pour préserver l'état des registres pendant le désempaquetage
Entropie de SectionMesure de l'aléatoire des données d'une section PE ; les sections compressées présentent une entropie > 7.0 tandis que les sections de code normales se situent en moyenne entre 5.0 et 6.5
Octets MagiquesOctets de signature dans un fichier identifiant son format ; UPX utilise "UPX!" que les auteurs de malwares modifient pour empêcher la décompression automatisée

Outils et systèmes

  • UPX : Compresseur d'exécutables open-source avec capacité de décompression intégrée pour les fichiers correctement compressés
  • Detect It Easy (DIE) : Outil de détection de packers, compilateurs et éditeurs de liens qui identifie les protections sur les fichiers PE, ELF et Mach-O
  • x64dbg/x32dbg : Débogueur Windows open-source utilisé pour le désempaquetage manuel via l'exécution dynamique et la recherche d'OEP par points d'arrêt
  • Scylla : Outil de reconstruction d'importations intégré à x64dbg pour reconstruire l'IAT après le dump mémoire
  • PE-bear : Visualiseur et éditeur de fichiers PE pour inspecter et réparer les en-têtes PE après désempaquetage

Scénarios courants

Scénario : Désempaquetage d'un malware avec en-têtes UPX modifiés

Contexte : Un échantillon de malware est identifié comme compressé UPX par les noms de sections (UPX0, UPX1) mais upx -d échoue avec l'erreur "CantUnpackException: header corrupted". L'auteur du malware a modifié les octets magiques UPX pour empêcher la décompression automatisée.

Approche :

  1. Ouvrir le binaire dans un éditeur hexadécimal et rechercher la zone d'en-tête UPX (généralement à la fin des données compressées)
  2. Identifier les octets magiques modifiés (par exemple, "UPX!" changé en "UPX\x00" ou complètement mis à zéro)
  3. Utiliser le script de réparation Python pour restaurer "UPX!" et corriger les noms de sections
  4. Réessayer upx -d sur le binaire réparé
  5. Si la réparation échoue, passer au désempaquetage manuel avec x64dbg (PUSHAD -> BP matériel sur ESP -> POPAD -> JMP OEP)
  6. Valider que le binaire désempaqueté a des importations correctes et des valeurs d'entropie raisonnables
  7. Importer dans Ghidra ou IDA pour une analyse statique complète

Pièges :

  • Supposer qu'UPX est le seul packer ; le binaire peut être doublement compressé (UPX + couche personnalisée)
  • Modifier l'échantillon compressé original au lieu de travailler sur une copie
  • Ne pas reconstruire les importations après un dump mémoire manuel (le binaire dumpé plantera sans correction de l'IAT)
  • Oublier de vérifier les données de superposition ajoutées après les sections PE compressées par UPX

Format de sortie

RAPPORT D'ANALYSE DE DÉSEMPAQUETAGE
======================================
Échantillon :       suspect.exe
SHA-256 :          e3b0c44298fc1c149afbf4c8996fb924...
Packer :           UPX 3.96 (en-têtes modifiés)

BINAIRE COMPRESSÉ
Sections :         UPX0 (entropie : 0.00) UPX1 (entropie : 7.89) .rsrc (entropie : 3.45)
Importations :     2 (kernel32.dll: LoadLibraryA, GetProcAddress)
Taille fichier :   98 304 octets

MÉTHODE DE DÉSEMPAQUETAGE
Méthode :          Réparation d'en-tête + UPX -d
Correction :       Octets magiques UPX! restaurés à l'offset 0x1F000
Commande :         upx -d suspect_fixed.exe -o unpacked.exe
Résultat :         SUCCÈS

BINAIRE DÉSEMPAQUETÉ
Sections :         .text (entropie : 6.21) .rdata (entropie : 4.56) .data (entropie : 3.12) .rsrc (entropie : 3.45)
Importations :     147 (kernel32, user32, advapi32, wininet, ws2_32)
Taille fichier :   245 760 octets (expansion 2.5x)
OEP :              0x00401000

VALIDATION
PE valide :        Oui
Importations résolues : Oui (147 fonctions sur 8 DLL)
Exécutable :       Oui (s'exécute sans plantage dans le bac à sable)

PROCHAINES ÉTAPES
- Importer unpacked.exe dans Ghidra pour un désassemblage complet
- Exécuter des règles YARA contre le binaire désempaqueté
- Soumettre le binaire désempaqueté à VirusTotal pour une détection améliorée

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 associés