1. Introduction : pourquoi le reverse engineering est incontournable
Le reverse engineering (RE) constitue une discipline fondamentale de la cybersecurite offensive et defensive. Loin de se limiter a une activite marginale reservee a quelques chercheurs, il represente aujourd'hui une competence strategique pour toute equipe de securite qui souhaite comprendre en profondeur les menaces auxquelles elle fait face. Que ce soit pour analyser un malware decouvert lors d'un incident, identifier des vulnerabilites dans un logiciel proprietaire, resoudre des challenges CTF ou mener des investigations forensiques, la capacite a desassembler et decomposer un binaire est devenue indispensable.
L'analyse de malware, en particulier, repose massivement sur les techniques de reverse engineering. Lorsqu'un analyste du SOC detecte un comportement suspect, ou qu'une equipe DFIR (Digital Forensics and Incident Response) recupere un echantillon malveillant, c'est le reverse engineer qui va decomposer le binaire pour en extraire les indicateurs de compromission (IOC), comprendre les mecanismes de persistance, identifier les serveurs de commande et controle (C2), et evaluer l'etendue de la compromission. Sans cette analyse approfondie, la reponse a incident reste superficielle et incomplete.
Dans le domaine de la recherche de vulnerabilites (vulnerability research), le RE permet d'auditer des logiciels pour lesquels le code source n'est pas disponible. Les chercheurs en securite utilisent le desassemblage et la decompilation pour identifier des failles de type buffer overflow, use-after-free, integer overflow ou logic bugs dans des logiciels commerciaux, des firmwares embarques ou des drivers noyau. Cette discipline alimente directement les programmes de bug bounty et les publications de CVE qui permettent de securiser l'ecosysteme numerique.
En matiere de CTF (Capture The Flag), les challenges de reverse engineering sont parmi les plus formateurs. Ils obligent les participants a maitriser les architectures processeur, les formats executables, les conventions d'appel et les techniques d'obfuscation. Cette experience pratique se transfere directement aux contextes professionnels d'analyse de menaces reelles.
Cadre legal en France
En France, le reverse engineering est encadre par le Code de la propriete intellectuelle. L'article L122-6-1 autorise explicitement la decompilation d'un logiciel lorsqu'elle est necessaire pour obtenir les informations indispensables a l'interoperabilite avec d'autres logiciels. Par ailleurs, la recherche en securite beneficie d'un cadre plus favorable depuis la loi pour une Republique numerique de 2016, qui protege les lanceurs d'alerte en matiere de securite informatique (article L2321-4 du Code de la defense). L'ANSSI (Agence Nationale de la Securite des Systemes d'Information) encourage la divulgation responsable des vulnerabilites et offre un canal de signalement dedie.
Il est neanmoins essentiel de distinguer clairement les contextes legitimes (analyse de malware sur des echantillons obtenus dans le cadre d'un incident, recherche de vulnerabilites avec autorisation, education et CTF) des usages illicites (contournement de protections DRM sans base legale, utilisation a des fins de piratage). Toute activite de reverse engineering doit s'inscrire dans un cadre legal et ethique clair, avec une documentation rigoureuse des autorisations obtenues et des methodes employees.
Avertissement legal
Les techniques presentees dans cet article sont destinees exclusivement a des fins educatives, de recherche en securite et de reponse a incident. L'analyse de malware doit toujours etre realisee dans un environnement isole et securise. Assurez-vous de disposer des autorisations necessaires avant toute activite de reverse engineering sur des logiciels tiers.
2. Fondamentaux du reverse engineering
Architecture x86/x64 : les bases indispensables
Pour pratiquer le reverse engineering, une comprehension solide de l'architecture x86/x64 est prerequise. Le processeur x86 (32 bits) utilise huit registres generaux : EAX (accumulateur, valeurs de retour), EBX (base), ECX (compteur de boucles), EDX (donnees, extension de EAX pour les multiplications), ESI et EDI (source et destination pour les operations sur les chaines), EBP (base pointer, pointe vers la base du stack frame courant) et ESP (stack pointer, pointe vers le sommet de la pile). En x64, ces registres sont etendus a 64 bits (RAX, RBX, etc.) et huit registres supplementaires (R8 a R15) sont ajoutes.
Le registre EIP/RIP (Instruction Pointer) contient l'adresse de la prochaine instruction a executer. Le registre EFLAGS/RFLAGS stocke les drapeaux d'etat (Zero Flag, Carry Flag, Sign Flag, Overflow Flag) qui determinent le comportement des instructions de saut conditionnel. Comprendre ces drapeaux est essentiel pour suivre le flux de controle d'un programme desassemble.
La pile (stack) est une structure LIFO (Last In, First Out) utilisee pour stocker les variables locales, les parametres de fonctions et les adresses de retour. En convention d'appel cdecl (32 bits), les arguments sont empiles de droite a gauche et l'appelant nettoie la pile. En convention stdcall (API Windows 32 bits), c'est l'appele qui nettoie la pile. En x64 (Microsoft), les quatre premiers arguments entiers sont passes dans les registres RCX, RDX, R8, R9, et les suivants sur la pile. En System V AMD64 (Linux), les six premiers arguments utilisent RDI, RSI, RDX, RCX, R8, R9.
Formats executables : PE, ELF et Mach-O
Les trois formats executables majeurs sont le PE (Portable Executable) sous Windows, ELF (Executable and Linkable Format) sous Linux et Mach-O sous macOS. Chacun possede une structure propre, mais tous partagent des concepts communs : un en-tete decrivant le fichier, des sections contenant le code et les donnees, et des tables d'importation/exportation.
Le format PE Windows commence par un en-tete DOS (signature MZ), suivi du PE Header contenant la signature PE, le COFF Header (architecture, nombre de sections, timestamp), et l'Optional Header (point d'entree/AddressOfEntryPoint, ImageBase, taille des sections, Data Directories). Les Data Directories contiennent les references vers la table d'importation (IAT - Import Address Table), la table d'exportation (EAT), les ressources, les relocations et les informations de debug.
Sections principales d'un executable
| Section | Contenu | Permissions typiques |
|---|---|---|
.text | Code executable (instructions machine) | Read + Execute |
.data | Variables globales initialisees | Read + Write |
.rdata / .rodata | Donnees en lecture seule (constantes, strings) | Read |
.bss | Variables globales non initialisees | Read + Write |
.rsrc | Ressources (icones, dialogues, manifeste) | Read |
.reloc | Table de relocation (ASLR) | Read |
.idata | Table d'importation (IAT) | Read + Write |
.edata | Table d'exportation (EAT) | Read |
L'Import Address Table (IAT) est particulierement importante en analyse de malware : elle liste les fonctions importees depuis les DLL systeme (kernel32.dll, ntdll.dll, ws2_32.dll, etc.). L'analyse de l'IAT revele immediatement les capacites d'un binaire : des imports de CreateRemoteThread, VirtualAllocEx et WriteProcessMemory suggerent une injection de processus, tandis que InternetOpenA, HttpSendRequest indiquent des communications reseau.
Le format ELF Linux suit une structure similaire avec un ELF Header, des Program Headers (segments pour le chargement en memoire) et des Section Headers. Les sections .plt (Procedure Linkage Table) et .got (Global Offset Table) jouent un role equivalent a l'IAT pour la resolution dynamique des symboles. Le format Mach-O d'Apple utilise des load commands pour decrire la structure du binaire, avec des segments (similaires aux sections PE/ELF) et des tables de symboles pour les imports/exports.
Compilation et linking : du source au binaire
Le processus de compilation transforme le code source en binaire executable en quatre etapes principales : le preprocessing (expansion des macros, inclusion des headers), la compilation proprement dite (transformation en code assembleur), l'assemblage (conversion en code machine, creation de fichiers objets .o/.obj) et le linking (resolution des symboles, fusion des fichiers objets, creation de l'executable final). Comprendre ce processus aide le reverse engineer a identifier les patterns generes par les differents compilateurs (MSVC, GCC, Clang) et a reconnaitre les optimisations appliquees.
Le linking peut etre statique (les bibliotheques sont integrees directement dans l'executable, ce qui produit des binaires plus volumineux mais autonomes) ou dynamique (les bibliotheques sont chargees a l'execution via des DLL/SO). Le linking dynamique est plus courant et facilite l'analyse car les fonctions importees sont visibles dans l'IAT. Le linking statique, en revanche, complique l'analyse car les fonctions de la bibliotheque standard sont incorporees directement dans le code et doivent etre identifiees par signature (FLIRT signatures dans IDA Pro).
3. Analyse statique : dissequer sans executer
Triage initial : les premieres minutes comptent
Avant de plonger dans le desassemblage, un triage rapide permet de categoriser l'echantillon et d'orienter l'analyse. Cette phase initiale, qui ne devrait pas prendre plus de 10 a 15 minutes, fournit des informations cruciales pour la suite de l'investigation.
La premiere etape consiste a identifier le type de fichier avec la commande file sous Linux ou l'outil Detect It Easy (DIE) qui remplace avantageusement le classique PEiD. DIE identifie le compilateur utilise, detecte les packers connus (UPX, Themida, VMProtect, ASPack), determine l'architecture cible et repere les protections eventuelles. Un binaire packe presente generalement une entropie elevee (proche de 8 pour les sections compressees), peu de strings lisibles et une IAT minimale.
# Triage rapide sous Linux
file suspicious.exe
# PE32 executable (GUI) Intel 80386, for MS Windows
strings -n 8 suspicious.exe | head -50
# Extraction des chaines ASCII (minimum 8 caracteres)
strings -el suspicious.exe | head -50
# Extraction des chaines Unicode (wide strings)
sha256sum suspicious.exe
# Hash pour recherche sur VirusTotal / MalwareBazaar
python3 -c "import pefile; pe=pefile.PE('suspicious.exe'); print(pe.dump_info())"
# Analyse detaillee du PE header avec pefile
L'outil FLOSS (FLARE Obfuscated String Solver) de Mandiant va au-dela de la simple extraction de strings : il detecte et decode automatiquement les chaines obfusquees par XOR, stack strings, et autres techniques de chiffrement simples. C'est un outil indispensable pour le triage car les malwares modernes chiffrent systematiquement leurs chaines de caracteres pour echapper a la detection statique.
# FLOSS - extraction avancee de strings
floss suspicious.exe --no-static-strings
# Affiche uniquement les strings decodees/deobfusquees
# Soumission a VirusTotal via API
vt scan file suspicious.exe
# Calcul de l'entropie par section
python3 -c "
import pefile, math
pe = pefile.PE('suspicious.exe')
for section in pe.sections:
data = section.get_data()
entropy = 0
for x in range(256):
p = data.count(bytes([x])) / len(data)
if p > 0:
entropy -= p * math.log2(p)
print(f'{section.Name.decode().strip(chr(0)):10s} Entropy: {entropy:.2f} Size: {section.SizeOfRawData}')
"
Desassemblage avec Ghidra
Ghidra, developpe par la NSA et publie en open source en 2019, est devenu l'outil de reference pour l'analyse statique gratuite. Il supporte un nombre impressionnant d'architectures (x86, x64, ARM, MIPS, PowerPC, SPARC, etc.) et offre un decompilateur integre qui produit du pseudo-code C remarquablement lisible. Son installation est simple : il suffit de Java (JDK 17+) et de telecharger l'archive depuis le site officiel de la NSA.
Pour commencer l'analyse d'un binaire dans Ghidra, creez un nouveau projet, importez le fichier (Ghidra detecte automatiquement le format et l'architecture), puis lancez l'auto-analyse en acceptant les options par defaut. L'auto-analyse effectue la detection des fonctions, la propagation des types, la resolution des references croisees (xrefs) et la reconnaissance des signatures de bibliotheques. Ce processus prend de quelques secondes a plusieurs minutes selon la taille du binaire.
La navigation dans Ghidra s'organise autour de plusieurs vues complementaires : le Listing (desassemblage lineaire), le Decompiler (pseudo-code C), le Function Graph (representation visuelle du control flow), le Symbol Tree (arborescence des fonctions, imports, exports) et le Data Type Manager (gestion des structures et types). La vue decompilee est particulierement utile car elle transforme le code assembleur en un pseudo-code C comprehensible, meme pour les analystes qui ne maitrisent pas parfaitement l'assembleur.
# Script Ghidra (Python/Jython) pour lister les appels a des API suspectes
# A placer dans le Script Manager de Ghidra
from ghidra.program.model.symbol import SymbolType
suspicious_apis = [
"VirtualAlloc", "VirtualAllocEx", "VirtualProtect",
"CreateRemoteThread", "WriteProcessMemory", "NtWriteVirtualMemory",
"CreateProcess", "ShellExecute", "WinExec",
"InternetOpen", "HttpSendRequest", "URLDownloadToFile",
"CryptEncrypt", "CryptDecrypt", "BCryptEncrypt",
"RegSetValue", "RegCreateKey",
"IsDebuggerPresent", "CheckRemoteDebuggerPresent"
]
symbol_table = currentProgram.getSymbolTable()
for symbol in symbol_table.getAllSymbols(True):
if symbol.getSymbolType() == SymbolType.FUNCTION:
for api in suspicious_apis:
if api.lower() in symbol.getName().lower():
refs = getReferencesTo(symbol.getAddress())
print(f"[!] {symbol.getName()} referenced from {len(list(refs))} locations")
for ref in getReferencesTo(symbol.getAddress()):
func = getFunctionContaining(ref.getFromAddress())
if func:
print(f" Called from: {func.getName()} @ {ref.getFromAddress()}")
IDA Pro et IDA Free
IDA Pro reste l'outil commercial de reference en reverse engineering, utilise par la majorite des equipes professionnelles de threat intelligence et de malware analysis. Sa force reside dans la qualite de sa detection de fonctions, son systeme de FLIRT signatures (Fast Library Identification and Recognition Technology) qui identifie automatiquement les fonctions de bibliotheques standard, et son decompilateur Hex-Rays qui produit un pseudo-code C de haute qualite.
La version gratuite IDA Free supporte les binaires x86 et x64 avec un decompilateur cloud. Les fonctionnalites cles d'IDA incluent la vue graphe (affichage du control flow sous forme de graphe avec les blocs basiques), les cross-references (xrefs) qui permettent de tracer tous les appels et references a une fonction ou une donnee, le type system riche pour appliquer des structures C/C++ aux donnees, et le support des plugins IDAPython pour automatiser l'analyse.
Radare2/Cutter et Binary Ninja
Radare2 est un framework d'analyse binaire open source en ligne de commande, extremement puissant mais avec une courbe d'apprentissage abrupte. Son interface graphique Cutter rend l'outil plus accessible tout en conservant la puissance du moteur radare2. Radare2 excelle dans l'analyse scriptee et l'automatisation grace a son API r2pipe accessible depuis Python, JavaScript et d'autres langages.
Binary Ninja se positionne comme un intermediaire entre Ghidra (gratuit) et IDA Pro (cher), avec une licence personnelle abordable. Son point fort est sa IL (Intermediate Language) a plusieurs niveaux : Low Level IL, Medium Level IL et High Level IL, qui permettent d'analyser le code a differents niveaux d'abstraction. Son API Python est particulierement bien concue pour l'automatisation et le developpement de plugins.
Identification de patterns dans le code decompile
L'analyse du code decompile necessite la reconnaissance de patterns recurrents. Les boucles de dechiffrement XOR apparaissent frequemment dans les malwares : une boucle itere sur un buffer et applique un XOR avec une cle fixe ou rotative. Les resolutions dynamiques d'API (GetProcAddress + LoadLibrary) indiquent que le malware charge ses fonctions a l'execution pour echapper a l'analyse de l'IAT. Les appels systeme directs (syscall/int 0x2e) sans passer par ntdll.dll suggerent des techniques d'evasion EDR avancees, comme detaillees dans notre article sur l'evasion EDR/XDR.
Un pattern frequemment observe est la resolution de fonctions par hash : plutot que de stocker les noms de fonctions en clair, le malware calcule un hash (CRC32, DJB2, ou un hash custom) du nom de chaque fonction exportee par une DLL et compare avec des valeurs pre-calculees. Cette technique, popularisee par les shellcodes et utilisee par de nombreux loaders, necessite de reconnaitre le pattern de hashing pour identifier les API appelees.
4. Analyse dynamique : observer le malware en action
Environnement sandbox : isoler pour mieux observer
L'analyse dynamique consiste a executer le malware dans un environnement controle pour observer son comportement reel. Cette approche complement l'analyse statique en revelant les actions effectivement executees : fichiers crees/modifies, cles de registre ajoutees, connexions reseau etablies, processus lances, etc. L'environnement d'analyse doit etre rigoureusement isole pour empecher toute propagation.
FlareVM est la distribution de reference pour l'analyse de malware Windows. Basee sur une VM Windows, elle pre-installe plus de 140 outils d'analyse : x64dbg, Ghidra, Process Monitor, Wireshark, FLOSS, PE-bear, CFF Explorer, API Monitor, etc. L'installation s'effectue via un script PowerShell qui configure automatiquement l'environnement. REMnux est l'equivalent pour Linux : cette distribution basee sur Ubuntu regroupe les outils d'analyse de malware, de reverse engineering et de forensic network (FakeNet-NG, INetSim, Volatility, YARA, etc.).
La configuration reseau est critique : utilisez un reseau Host-Only ou Internal Network dans votre hyperviseur pour isoler completement la VM du reseau reel. La machine REMnux est configuree comme passerelle et serveur DNS pour la VM FlareVM, interceptant ainsi tout le trafic genere par le malware. INetSim ou FakeNet-NG simulent les services Internet (HTTP, HTTPS, DNS, SMTP, FTP) pour que le malware puisse "dialoguer" avec ses serveurs C2 sans jamais atteindre Internet. Cette approche permet de capturer les communications C2, les telechargements de payloads supplementaires et les exfiltrations de donnees.
Debugging avec x64dbg
x64dbg est le debugger open source de reference pour Windows. Il supporte le debugging 32 bits (x32dbg) et 64 bits (x64dbg) avec une interface intuitive et de nombreux plugins. Les fonctionnalites essentielles incluent les breakpoints materiels et logiciels, le step-into/step-over/step-out, l'inspection de la memoire, les breakpoints conditionnels et le scripting.
Pour analyser un malware avec x64dbg, commencez par charger l'executable et placer un breakpoint sur l'entry point. Identifiez les appels a VirtualAlloc ou VirtualProtect qui indiquent souvent une decompression ou un dechiffrement de code en memoire. Utilisez les breakpoints conditionnels pour arreter l'execution uniquement quand un registre contient une valeur specifique (par exemple, quand EAX contient l'adresse d'un buffer dechiffre). Le plugin ScyllaHide masque la presence du debugger pour contourner les techniques anti-debug basiques.
// Script x64dbg - Tracer les appels VirtualAlloc
// Placer un BP conditionnel sur VirtualAlloc
bp VirtualAlloc
SetBreakpointCommand VirtualAlloc, "log 'VirtualAlloc({arg.get(0)}, size={arg.get(1)}, type={arg.get(2)}, protect={arg.get(3)})'; run"
// Breakpoint hardware en ecriture sur une adresse memoire
bphws 0x00401000, "w", 4
// Logger les appels CreateFile
bp CreateFileA
SetBreakpointCommand CreateFileA, "log 'CreateFileA: {s:arg.get(0)}'; run"
// Dumper une region memoire
savedata "C:\\dump\\payload.bin", 0x10000, 0x5000
WinDbg pour l'analyse kernel
WinDbg (Windows Debugger) est indispensable pour le debugging kernel-mode, necessaire pour analyser les rootkits et les drivers malveillants. Configure en mode kernel debugging via une connexion serie virtuelle, COM pipe ou reseau entre deux VMs, WinDbg permet d'inspecter les structures du noyau Windows (EPROCESS, ETHREAD, DRIVER_OBJECT), de tracer les appels systeme et de detecter les hooks SSDT/IDT. Pour une analyse approfondie des techniques d'exploitation kernel, consultez notre article sur l'exploitation kernel Windows.
Monitoring API et comportemental
API Monitor intercepte et enregistre tous les appels API Windows effectues par un processus. Il permet de filtrer par categorie (fichiers, registre, reseau, processus, threads) et de visualiser les parametres et valeurs de retour de chaque appel. Process Monitor (ProcMon) de Sysinternals capture les operations sur le systeme de fichiers, le registre et les processus en temps reel. Process Hacker offre une vue detaillee des processus en cours, de leurs threads, handles, connexions reseau et modules charges.
Pour la capture reseau, Wireshark enregistre tout le trafic genere par le malware. FakeNet-NG de Mandiant va plus loin en interceptant et en simulant les reponses des serveurs distants, ce qui permet au malware de poursuivre son execution meme sans connexion Internet. Il supporte les protocoles HTTP, HTTPS, DNS, TCP et UDP generiques.
Analyse automatisee en sandbox
Les sandbox automatisees executent les echantillons et produisent des rapports detailles. ANY.RUN offre une analyse interactive en temps reel dans un navigateur, avec la possibilite d'interagir avec le malware (cliquer sur des boutons, fermer des boites de dialogue). Joe Sandbox genere des rapports extremement detailles incluant le graphe de comportement, les IOC, les regles YARA matchees et la classification MITRE ATT&CK. CAPE (Malware Configuration And Payload Extraction), basee sur Cuckoo Sandbox, excelle dans l'extraction automatique de configurations de malware et de payloads dechiffres. Ces plateformes sont particulierement utiles pour le triage a grande echelle lorsque le volume d'echantillons depasse la capacite d'analyse manuelle.
5. Techniques anti-analyse : l'arsenal defensif des malwares
Les malwares sophistiques deploient un arsenal de techniques destinees a ralentir, perturber ou empecher l'analyse par les chercheurs en securite. Comprendre ces techniques est indispensable pour les contourner efficacement. Ces mecanismes sont egalement utilises par les frameworks C2 modernes decrits dans notre article sur les frameworks C2 Mythic, Havoc et Sliver.
Packing et protection
Le packing est la technique anti-analyse la plus repandue. Un packer compresse et/ou chiffre le code original du malware, qui n'est restaure en memoire qu'a l'execution. UPX (Ultimate Packer for Executables) est le packer le plus basique et le plus facile a decompresser (une simple commande upx -d suffit). Les packers commerciaux comme Themida, VMProtect et Obsidium sont beaucoup plus complexes : ils utilisent de la virtualisation de code (transformation du code en bytecode pour une VM interne), de l'anti-tampering, et des techniques anti-debug sophistiquees.
Les indicateurs d'un binaire packe incluent : une entropie elevee (superieure a 7.0 pour les sections principales), tres peu de strings lisibles, une IAT minimale (souvent uniquement LoadLibrary et GetProcAddress), des noms de sections inhabituels (UPX0, UPX1, .vmp0, .themida), et un ecart important entre la taille virtuelle et la taille brute des sections (la section de code a une taille brute proche de zero car le code sera decompresse en memoire).
Anti-debugging
Les techniques anti-debug detectent la presence d'un debugger et modifient le comportement du malware en consequence (arret, execution d'un code leurre, auto-destruction). Les methodes les plus courantes :
| Technique | Mecanisme | Contournement |
|---|---|---|
IsDebuggerPresent | Verifie le flag BeingDebugged dans le PEB | Patcher le PEB ou hooker l'API |
NtQueryInformationProcess | ProcessDebugPort / ProcessDebugObjectHandle | ScyllaHide / hook ntdll |
| Timing checks | RDTSC, QueryPerformanceCounter, GetTickCount | Patcher les appels ou emuler les valeurs |
| TLS Callbacks | Code execute avant l'entry point via TLS Directory | Mettre un BP sur le TLS callback |
| INT 2D / INT 3 | Exceptions gerees differemment sous debugger | Configurer le handler d'exception |
| NtSetInformationThread | ThreadHideFromDebugger cache le thread | Hook ou patch NtSetInformationThread |
| Parent process check | Verifie si le parent est explorer.exe | Spoofer le PPID |
| Hardware breakpoint detection | Verifie les Debug Registers (DR0-DR7) | Utiliser des BP logiciels |
Anti-VM et anti-sandbox
Les malwares detectent les environnements virtualises pour eviter l'analyse en sandbox. Les techniques de detection de VM incluent :
- Instruction CPUID : l'hypervisor bit (bit 31 de ECX pour CPUID leaf 1) indique la presence d'un hyperviseur. Le vendor string (CPUID leaf 0x40000000) revele le type : "VMwareVMware", "Microsoft Hv", "KVMKVMKVM".
- Verification du registre : cles HKLM\SOFTWARE\VMware, HKLM\SYSTEM\CurrentControlSet\Services\VBoxGuest.
- Adresse MAC : les 3 premiers octets identifient le fabricant (00:0C:29 = VMware, 08:00:27 = VirtualBox, 00:15:5D = Hyper-V).
- WMI queries : Win32_ComputerSystem.Model contient "VirtualBox" ou "VMware".
- Fichiers et processus : presence de vmtoolsd.exe, VBoxService.exe, fichiers vmware*.sys.
- Resolution d'ecran / nombre de CPU / taille RAM : les sandbox ont souvent une configuration minimale (1 CPU, 2 Go RAM, 1024x768).
Les techniques anti-sandbox specifiques ciblent l'environnement d'analyse automatisee : verification de l'interaction utilisateur (mouvements de souris, frappes clavier), delais d'execution (sleep de plusieurs minutes pour depasser le timeout de la sandbox), verification du nombre de fichiers recents, du nombre de programmes installes ou de l'historique du navigateur (une machine d'analyse fraichement installee sera suspectee). Certains malwares verifient meme la presence d'un nom d'utilisateur ou d'un hostname typique des sandbox (malware, sandbox, analysis, test).
Obfuscation de code
L'obfuscation rend le code difficile a comprendre sans empecher son execution. Le control flow flattening transforme la structure conditionnelle naturelle du code en un switch/case geant dans une boucle, eliminant la hierarchie logique visible dans le graphe de controle. Les opaque predicates sont des conditions qui semblent complexes mais dont le resultat est toujours le meme (toujours vrai ou toujours faux), ajoutant de faux chemins d'execution. Le chiffrement de strings remplace chaque chaine en clair par un appel a une fonction de dechiffrement, rendant l'analyse des strings completement inefficace. Les techniques de Living-off-the-Land combinent souvent ces obfuscations avec l'utilisation d'outils systeme legitimes.
6. Unpacking et desobfuscation : retrouver le code original
Unpacking manuel : la technique de reference
L'unpacking manuel consiste a trouver le Original Entry Point (OEP), c'est-a-dire le point ou le code original est completement decompresse en memoire et pret a s'executer. La methode classique procede en plusieurs etapes : identifier le moment ou le packer a termine son travail, dumper la memoire du processus, puis reconstruire la table d'importation (IAT).
Pour trouver l'OEP, plusieurs approches existent. La methode du breakpoint hardware sur ESP (ou "ESP trick") exploite le fait que la plupart des packers sauvegardent les registres au debut (PUSHAD) et les restaurent avant de sauter a l'OEP (POPAD). Placez un breakpoint hardware en acces sur l'adresse pointee par ESP juste apres le PUSHAD : le debugger s'arretera au moment du POPAD, et l'instruction suivante sera generalement un JMP vers l'OEP.
Une alternative consiste a placer un breakpoint hardware sur VirtualAlloc et a observer les allocations memoire successives. Quand le packer alloue une grande region memoire avec les permissions PAGE_EXECUTE_READWRITE, c'est generalement pour y decompresser le code original. Apres le retour de VirtualAlloc, vous pouvez placer un breakpoint en execution au debut de cette region pour detecter quand le code decompresse commence a s'executer.
Une fois l'OEP atteint, utilisez le plugin Scylla integre a x64dbg pour dumper le processus et reconstruire l'IAT. Scylla analyse la memoire du processus, identifie les imports resolus, et reconstruit une table d'importation valide dans le PE dumpe. L'outil pe-sieve de hasherezade peut egalement detecter et extraire automatiquement les modules depackes en memoire.
Desobfuscation de strings et emulation
La desobfuscation des chaines de caracteres est souvent la premiere etape apres l'unpacking. Quand le malware utilise un chiffrement XOR simple ou une fonction de dechiffrement custom, un script Python suffit pour decoder toutes les strings :
# Desobfuscation XOR avec cle rotative
def xor_decrypt(data, key):
return bytes([b ^ key[i % len(key)] for i, b in enumerate(data)])
# Exemple : dechiffrer un buffer avec une cle de 4 octets
encrypted = bytes.fromhex("4a1b3c2d5e6f7081...")
key = bytes.fromhex("deadbeef")
print(xor_decrypt(encrypted, key))
# Script Ghidra pour trouver et decoder les appels de dechiffrement
# Identifier le pattern : push encrypted_addr; push key; call decrypt_func
from ghidra.program.util import DefinedDataIterator
for ref in getReferencesTo(toAddr(0x00401230)): # adresse de decrypt_func
caller = ref.getFromAddress()
# Extraire les parametres pushes avant l'appel
# ... logique d'extraction des arguments
Pour les cas plus complexes, l'emulation permet d'executer selectivement des parties du code sans lancer le malware complet. Unicorn Engine est un framework d'emulation CPU leger qui supporte x86, ARM, MIPS et d'autres architectures. Qiling va plus loin en emulant non seulement le CPU mais aussi le systeme d'exploitation (appels systeme, structures du noyau, gestion des fichiers), permettant d'executer des fonctions individuelles du malware dans un environnement completement controle. Ces outils sont particulierement utiles pour dechiffrer des configurations, des URLs de C2 ou des payloads secondaires sans risque d'infection.
# Emulation avec Unicorn pour decoder des strings
from unicorn import *
from unicorn.x86_const import *
# Initialiser l'emulateur x86 32 bits
mu = Uc(UC_ARCH_X86, UC_MODE_32)
# Mapper la memoire et charger le code du malware
mu.mem_map(0x400000, 0x10000) # section .text
mu.mem_map(0x410000, 0x10000) # section .data
# Charger les sections depuis le PE
with open("malware.exe", "rb") as f:
code = f.read()
mu.mem_write(0x400000, code[0x400:0x10400]) # .text
mu.mem_write(0x410000, code[0x10400:0x20400]) # .data
# Configurer les registres (stack)
mu.mem_map(0x7F0000, 0x10000) # stack
mu.reg_write(UC_X86_REG_ESP, 0x7FFFF0)
mu.reg_write(UC_X86_REG_EBP, 0x7FFFF0)
# Emuler la fonction de dechiffrement (adresse 0x401230)
mu.emu_start(0x401230, 0x4012FF) # start, end
# Lire le resultat dechiffre
result = mu.mem_read(0x410100, 256)
print(bytes(result).split(b'\x00')[0].decode())
Les malwares utilisant des techniques de persistance UEFI ou firmware, comme decrits dans notre article sur les UEFI bootkits, necessitent souvent des techniques d'unpacking et d'emulation specifiques pour analyser les implants boot-level.
7. Ecriture de regles YARA : transformer l'analyse en detection
YARA est le standard de facto pour l'ecriture de regles de detection de malware basees sur des patterns. Developpe par Victor Alvarez chez VirusTotal, YARA permet de definir des regles combinant des chaines de caracteres (ASCII, hexadecimaux, expressions regulieres) et des conditions logiques pour identifier des families de malware, des packers ou des techniques specifiques.
Syntaxe YARA : les fondamentaux
Une regle YARA se compose de trois parties : les meta (metadonnees descriptives), les strings (patterns a rechercher) et la condition (logique de detection). Les strings peuvent etre des chaines de texte ("MZ"), des patterns hexadecimaux ({ 4D 5A 90 00 }) avec des wildcards (?? pour un octet quelconque) et des sauts ([4-8]), ou des expressions regulieres (/https?:\/\/[a-z0-9]+\./).
rule APT_Loader_Generic_2026 {
meta:
author = "Ayi NEDJIMI"
date = "2026-02-15"
description = "Detecte un loader generique avec resolution dynamique d'API"
tlp = "WHITE"
mitre_attack = "T1055 - Process Injection"
strings:
// Resolution dynamique d'API par hash
$api_hash_loop = {
8B ?? ?? // mov reg, [reg+offset] - parcours EAT
33 ?? // xor reg, reg
[2-6] // instructions variables
C1 ?? 0D // ror/rol reg, 0x0D - rotation ROR13
03 ?? // add reg, reg
[0-4]
3B ?? ?? ?? ?? ?? // cmp reg, hash_value
}
// Chaines suspectes (chiffrees ou en clair)
$s1 = "VirtualAlloc" ascii wide
$s2 = "NtWriteVirtualMemory" ascii
$s3 = "RtlMoveMemory" ascii
// Patterns d'injection de processus
$inject1 = { FF 15 ?? ?? ?? ?? [0-8] 50 [0-4] FF 15 } // call [IAT]; push; call [IAT]
// User-Agent typique de C2
$ua = "Mozilla/5.0" ascii
$c2_pattern = /https?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d{2,5})?\/[a-z]{3,8}/
condition:
uint16(0) == 0x5A4D and // PE file
filesize < 500KB and // Taille raisonnable pour un loader
$api_hash_loop and // Resolution par hash
(2 of ($s*)) and // Au moins 2 strings suspectes
(#inject1 > 1 or $c2_pattern) // Injection ou pattern C2
}
rule Packed_High_Entropy {
meta:
description = "Detecte les executables avec une entropie suspecte"
condition:
uint16(0) == 0x5A4D and
math.entropy(0, filesize) > 7.0 and
pe.number_of_sections < 5 and
pe.imports("kernel32.dll", "LoadLibraryA") and
pe.imports("kernel32.dll", "GetProcAddress") and
pe.number_of_imports < 10
}
Modules YARA et signatures robustes
YARA dispose de modules specialises qui enrichissent les capacites de detection. Le module PE permet d'inspecter les en-tetes PE (nombre de sections, imports, exports, timestamps, ressources), le module math calcule l'entropie et d'autres metriques statistiques, le module hash verifie les empreintes de sections specifiques. Pour ecrire des signatures robustes qui resistent aux variations mineures du malware, privilegiez les patterns hexadecimaux avec wildcards plutot que les strings en clair, combinez plusieurs indicateurs dans la condition, et testez vos regles contre un corpus de fichiers legitimes pour minimiser les faux positifs.
Integration dans le pipeline de detection
Les regles YARA s'integrent dans de multiples outils et pipelines : YARA + ClamAV pour le scan en temps reel des serveurs de fichiers et des passerelles email, YARA + SIEM (Splunk, Elastic) pour la detection sur les endpoints via les agents EDR, YARA + MISP pour le partage de signatures au sein de la communaute threat intelligence. L'outil yarGen genere automatiquement des regles YARA a partir d'echantillons de malware en identifiant les strings uniques par rapport a un corpus de binaires legitimes (Goodware String Database).
# Utilisation de yarGen pour generation automatique
python yarGen.py -m /path/to/malware/samples/ \
--goodware_strings /path/to/goodware_strings.db \
-o output_rules.yar \
--excludegood
# Scan avec YARA
yara -r -s rules/apt_loaders.yar /path/to/suspicious/files/
# -r : recursif, -s : afficher les strings matchees
# Integration Python
import yara
rules = yara.compile(filepath='rules/malware_detection.yar')
matches = rules.match('/path/to/sample.exe')
for match in matches:
print(f"Rule: {match.rule}, Tags: {match.tags}")
for string in match.strings:
print(f" Offset: {string[0]}, ID: {string[1]}, Data: {string[2]}")
8. Methodologie complete d'analyse de malware
Une analyse de malware professionnelle suit une methodologie structuree en six etapes. Cette approche systematique garantit la completude de l'analyse et facilite la production de rapports exploitables par les equipes SOC, DFIR et threat intelligence. Les techniques de post-exploitation identifiees lors de l'analyse permettent de mieux comprendre les objectifs de l'attaquant.
Etape 1 : Triage (15 minutes)
Le triage initial determine la nature de l'echantillon et oriente la strategie d'analyse. Calculez les hash (MD5, SHA256, SHA1, SSDeep/TLSH pour la similarite fuzzy), soumettez a VirusTotal et MalwareBazaar, identifiez le type de fichier et le packer eventuel avec DIE, extrayez les strings avec FLOSS, et calculez l'entropie par section. A l'issue du triage, vous devriez savoir si le binaire est packe, quelle architecture il cible, s'il est deja connu des antivirus, et quelles sont ses capacites probables.
Etape 2 : Analyse statique (2-4 heures)
Chargez le binaire (depacke si necessaire) dans Ghidra ou IDA. Commencez par l'entry point, identifiez la fonction main/WinMain, puis explorez les fonctions appelees. Concentrez-vous sur les imports suspects (API reseau, cryptographie, manipulation de processus, registre), les strings dechiffrees, et les structures de donnees (configurations C2, cles de chiffrement). Documentez les fonctions principales en les renommant et en ajoutant des commentaires.
Etape 3 : Analyse dynamique (2-4 heures)
Executez l'echantillon dans la sandbox isolee avec monitoring complet. Capturez les operations fichier/registre avec ProcMon, le trafic reseau avec Wireshark/FakeNet-NG, et les appels API avec API Monitor. Utilisez x64dbg pour valider les hypotheses de l'analyse statique, tracer les flux de dechiffrement et extraire les payloads en memoire. Prenez un snapshot avant l'execution et revenez-y apres chaque session.
Etapes 4-6 : Analyse approfondie, extraction d'IOC et reporting
L'analyse approfondie se concentre sur les mecanismes specifiques du malware : protocole de communication C2 (decodage du protocole, extraction des commandes supportees), algorithme de chiffrement utilise (identification de constantes cryptographiques comme les S-boxes AES ou les constantes RC4), extraction de la configuration (adresses C2, cles de chiffrement, identifiants de campagne). L'extraction d'IOC compile tous les indicateurs techniques exploitables pour la detection : hash des fichiers (PE, DLL, scripts), adresses IP et domaines des serveurs C2, noms de mutex, cles de registre modifiees, noms de fichiers crees, user-agents HTTP, JA3/JA3S fingerprints. Le rapport final structure ces informations pour les differentes audiences (management, SOC, DFIR) et est exporte au format STIX pour partage via MISP ou d'autres plateformes de threat intelligence.
Bonnes pratiques de documentation
Documentez chaque etape de votre analyse : screenshots des vues Ghidra/IDA, captures ProcMon filtrees, extraits de PCAP annotes, scripts de desobfuscation utilises. Cette documentation sera essentielle pour le rapport final, pour la reproductibilite de l'analyse, et pour la formation des analystes juniors. Utilisez un template standardise et alimentez systematiquement votre base de connaissances interne avec les TTPs (Tactics, Techniques and Procedures) observes.
9. Conclusion
Le reverse engineering et l'analyse de malware constituent des competences fondamentales dans l'arsenal de tout professionnel de la cybersecurite. Dans un paysage de menaces ou les attaquants deploient des malwares de plus en plus sophistiques, meles a des techniques d'evasion EDR avancees, de la communication C2 chiffree et des mecanismes de persistance firmware, la capacite a decomposer, comprendre et documenter ces menaces est devenue une necessite strategique.
L'ecosysteme d'outils n'a jamais ete aussi riche et accessible : Ghidra offre une plateforme d'analyse statique gratuite de qualite professionnelle, x64dbg fournit un debugger open source puissant, et les sandbox automatisees comme CAPE et ANY.RUN democratisent l'analyse comportementale. Combine avec la puissance des regles YARA pour la detection et le framework MITRE ATT&CK pour la classification, l'analyste de malware dispose aujourd'hui d'un arsenal complet pour affronter les menaces les plus complexes.
La cle du succes reside dans la methodologie : une approche structuree en six etapes (triage, analyse statique, analyse dynamique, analyse approfondie, extraction d'IOC, reporting) garantit la completude de l'analyse et la qualite des livrables. Le partage des resultats via les plateformes de threat intelligence (MISP, STIX/TAXII) amplifie l'impact de chaque analyse individuelle en beneficiant a l'ensemble de la communaute de defense.
Pour approfondir les sujets connexes, explorez nos articles sur l'evasion EDR/XDR, les frameworks C2 modernes, l'exploitation kernel Windows et les techniques de post-exploitation. La maitrise combinee de ces domaines forme la base d'une expertise complete en securite offensive et defensive.
Besoin d'une analyse de malware professionnelle ?
Notre equipe d'experts en reverse engineering et threat intelligence peut analyser vos echantillons suspects, extraire les IOC et vous fournir un rapport detaille avec recommandations de remediation.
Points cles a retenir
- Le triage initial (file, strings, FLOSS, entropie, VirusTotal) oriente l'ensemble de l'analyse en 15 minutes.
- Ghidra (gratuit) et IDA Pro (commercial) sont les piliers de l'analyse statique, avec leurs decompilateurs respectifs.
- L'analyse dynamique dans une sandbox isolee (FlareVM + REMnux) revele le comportement reel du malware.
- Les techniques anti-analyse (packing, anti-debug, anti-VM) se contournent avec methode et les bons outils.
- L'unpacking manuel (OEP finding + Scylla) et l'emulation (Unicorn/Qiling) permettent de retrouver le code original.
- Les regles YARA transforment l'analyse en detection operationnelle deployable dans le SIEM et l'EDR.
- La methodologie en 6 etapes garantit une analyse complete et un rapport exploitable.
- Le partage via MISP/STIX amplifie l'impact de chaque analyse.
References et ressources externes
- Ghidra - NSA Software Reverse Engineering — Plateforme d'analyse statique open source de reference
- x64dbg — Debugger open source pour Windows x86/x64
- YARA - Pattern matching tool — Standard de detection de malware par patterns
- MITRE ATT&CK Framework — Base de connaissances des tactiques et techniques adverses
- FlareVM - Mandiant — Distribution Windows pour l'analyse de malware
- REMnux — Distribution Linux pour la retro-ingenierie de malware
- MalwareBazaar - abuse.ch — Partage d'echantillons de malware
- MISP Project — Plateforme de partage d'indicateurs de menaces
