---
title: "Analyse de malware — Triage rapide"
domain: security
subdomain: soc
phase: 03-response
type: snippet
tags: [soc, malware, analysis, sandbox, IOC, static, dynamic, reverse]
difficulty: advanced
status: stable
updated: "2025-05-13"
---
## Workflow d'analyse — Vue d'ensemble

```
Fichier suspect reçu
       │
       ▼
[1. Hashing + VirusTotal lookup]
       │ Malveillant confirmé? ──Oui──► Passer à IOC extraction
       │ Non/Inconnu
       ▼
[2. Analyse statique]
  - Strings, PE headers, imports
       │
       ▼
[3. Sandbox dynamique]
  - Comportement réseau, FS, registry
       │
       ▼
[4. IOC extraction + partage TIP]
       │
       ▼
[5. YARA rule creation]
```

---

## Analyse statique

### Identification du fichier

```bash
# Type de fichier réel (ignorer l'extension)
file suspicious.exe
file suspicious.pdf

# Entropie — haute entropie = packed/chiffré
python3 -c "
import sys, math
data = open('suspicious.exe', 'rb').read()
freq = {}
for b in data:
    freq[b] = freq.get(b, 0) + 1
entropy = -sum((c/len(data)) * math.log2(c/len(data)) for c in freq.values())
print(f'Entropy: {entropy:.2f} bits/byte (> 7.0 = likely packed)')
"

# Hashes — collecte complète
md5sum suspicious.exe
sha256sum suspicious.exe
sha1sum suspicious.exe
# Ou PowerShell
Get-FileHash suspicious.exe -Algorithm MD5, SHA1, SHA256 | Format-List
```

### VirusTotal & MalwareBazaar

```bash
# VirusTotal via API
VT_API="{{VT_API_KEY}}"
SHA256=$(sha256sum suspicious.exe | cut -d' ' -f1)

curl -s "https://www.virustotal.com/api/v3/files/$SHA256" \
  -H "x-apikey: $VT_API" | jq '{
    name: .data.attributes.meaningful_name,
    malicious: .data.attributes.last_analysis_stats.malicious,
    undetected: .data.attributes.last_analysis_stats.undetected,
    first_seen: .data.attributes.first_submission_date,
    family: .data.attributes.popular_threat_classification.suggested_threat_label
  }'

# MalwareBazaar lookup (pas de clé requise pour query)
curl -s -X POST "https://mb-api.abuse.ch/api/v1/" \
  -d "query=get_info&hash=$SHA256" | jq '.data[0] | {
    file_name, file_type, signature, tags, reporter
  }'
```

### Strings — Extraction et analyse

```bash
# Strings basiques
strings suspicious.exe | grep -iE "(http|ftp|\\\\|cmd|power|shell|download|upload)"

# Strings Unicode
strings -el suspicious.exe | head -100

# Strings avec offset (pour corrélation avec dissassembly)
strings -t x suspicious.exe | grep -iE "(CreateRemoteThread|VirtualAlloc|WriteProcessMemory)"

# Strings suspects — fonctions d'injection mémoire
SUSPECT_FUNCS=(
  "VirtualAlloc" "VirtualAllocEx" "WriteProcessMemory"
  "CreateRemoteThread" "NtCreateThreadEx" "RtlCreateUserThread"
  "ShellExecute" "WinExec" "CreateProcess"
  "RegSetValue" "RegCreateKey"
  "InternetOpen" "InternetConnect" "HttpSendRequest"
  "WSAStartup" "connect" "send" "recv"
)
for func in "${SUSPECT_FUNCS[@]}"; do
  count=$(strings suspicious.exe | grep -c "$func" 2>/dev/null)
  [ "$count" -gt 0 ] && echo "FOUND [$count]: $func"
done
```

### PE Headers — pestudio / pefile

```python
# Python — analyse PE avec pefile
import pefile
import sys

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

print("=== PE INFO ===")
print(f"Machine: {hex(pe.FILE_HEADER.Machine)}")
print(f"Timestamp: {pe.FILE_HEADER.dump_dict()['TimeDateStamp']['Value']}")
print(f"Subsystem: {pe.OPTIONAL_HEADER.Subsystem}")
print(f"Entry Point: {hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint)}")

print("\n=== SECTIONS ===")
for s in pe.sections:
    entropy = s.get_entropy()
    print(f"  {s.Name.decode().strip()} | VSize={s.Misc_VirtualSize} | Entropy={entropy:.2f}")
    if entropy > 7.0:
        print(f"    ^^^ HIGH ENTROPY — possible packed/encrypted section")

print("\n=== IMPORTS ===")
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
    for lib in pe.DIRECTORY_ENTRY_IMPORT:
        print(f"  {lib.dll.decode()}")
        for imp in lib.imports:
            if imp.name:
                func = imp.name.decode()
                if any(s in func for s in ["VirtualAlloc", "CreateRemoteThread", "WriteProcess",
                                           "LoadLibrary", "GetProcAddress", "ShellExec"]):
                    print(f"    *** SUSPICIOUS: {func}")

print("\n=== EXPORTS ===")
if hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'):
    for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
        if exp.name:
            print(f"  {exp.name.decode()}")
```

---

## Analyse dynamique — Sandbox

### Plateformes recommandées

| Plateforme | URL | Avantages |
|---|---|---|
| **ANY.RUN** | app.any.run | Interactif, temps réel, MITRE mapping |
| **Hybrid Analysis** | hybrid-analysis.com | Gratuit, rapport détaillé |
| **Joe Sandbox** | joesandbox.com | Deep analysis, déobfuscation |
| **Triage (Hatching)** | tria.ge | API-first, rapide |
| **Cuckoo** | Auto-hébergé | Privé, personnalisable |

### Cuckoo — Analyse locale

```bash
# Soumettre un fichier à Cuckoo
cuckoo submit --timeout 120 suspicious.exe

# Soumettre une URL
cuckoo submit --url "http://{{MALICIOUS_URL}}"

# Vérifier le résultat
cuckoo api  # Port 8090 par défaut
curl http://localhost:8090/tasks/report/{{TASK_ID}}/json | jq '.signatures[].name'

# Extraire les IOCs du rapport
curl http://localhost:8090/tasks/report/{{TASK_ID}}/json | jq '{
  domains: .network.domains[].domain,
  ips: .network.hosts[],
  mutexes: .behavior.summary.mutexes[],
  files: .behavior.summary.files[],
  registry: .behavior.summary.keys[]
}'
```

---

## Checklist IOC Extraction

<Checklist items={[
  "Hash MD5 / SHA1 / SHA256 du fichier",
  "IPs contactées (C2, download, exfil)",
  "Domaines résolus (C2, DGA patterns)",
  "URLs complètes (download, beacon, exfil path)",
  "Clés de registre créées/modifiées",
  "Fichiers créés/modifiés/supprimés",
  "Noms de mutexes créés",
  "Chemins de fichiers persistance",
  "Noms de services ou tâches planifiées créés",
  "User-Agent HTTP utilisé",
  "Certificats TLS (Subject, Issuer, fingerprint)",
  "JA3/JA3S fingerprint réseau",
  "Règle YARA créée et testée"
]} storageKey="soc-ioc-extraction" />

---

## YARA — Bases et exemple

### Structure d'une règle YARA

```yara
rule Malware_FamilyName_Variant {
    meta:
        author      = "{{ANALYST_NAME}}"
        date        = "2025-05-13"
        description = "Détecte {{MALWARE_FAMILY}} variant X"
        hash        = "{{SHA256_HASH}}"
        reference   = "https://{{REPORT_URL}}"
        mitre       = "T1059.001, T1071.001"

    strings:
        // Strings ASCII/Wide
        $s1 = "CreateRemoteThread" ascii
        $s2 = "VirtualAlloc" ascii
        $s3 = "{{C2_DOMAIN}}" wide ascii nocase

        // Pattern hexadécimal (shellcode signature)
        $hex1 = { 60 89 E5 31 D2 64 8B 52 30 }

        // Regex
        $re1 = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ // GUID mutex

    condition:
        uint16(0) == 0x5A4D          // MZ header (PE file)
        and filesize < 5MB
        and (
            (2 of ($s*)) or
            $hex1 or
            ($re1 and 1 of ($s*))
        )
}
```

### Tests YARA

```bash
# Tester sur un fichier
yara rule.yar suspicious.exe -s

# Tester sur un répertoire
yara -r rule.yar /malware_samples/

# Tester depuis un dossier de règles (SigmaHQ style)
yara rules/ target_file.exe --no-warnings

# Vérifier les faux positifs sur binaires légitimes
yara rule.yar /Windows/System32/ 2>/dev/null | head -20
```

---

## IOCs réseau — Analyse PCAP

```bash
# Wireshark / tshark — filtres pour trafic malware

# Connexions HTTP suspectes
tshark -r capture.pcap -Y "http.request" \
  -T fields -e ip.src -e ip.dst -e http.host -e http.request.uri -e http.user_agent

# DNS — domaines résolus
tshark -r capture.pcap -Y "dns.flags.response == 0" \
  -T fields -e ip.src -e dns.qry.name -e dns.qry.type

# Certificats TLS — extraction CN et SANs
tshark -r capture.pcap -Y "ssl.handshake.type == 11" \
  -T fields -e x509sat.uTF8String -e ip.dst

# Extraction automatique de fichiers HTTP (payloads)
tshark -r capture.pcap --export-objects http,/tmp/http_objects/

# Suricata sur PCAP existant
suricata -r capture.pcap -l /tmp/suricata_output/ -c /etc/suricata/suricata.yaml
jq '.alert.signature' /tmp/suricata_output/eve.json | sort | uniq -c | sort -rn
```

---

## Techniques d'évasion — VM detection

```bash
# Avant de détonner en sandbox : rechercher des marqueurs d'évasion dans les strings
strings suspicious.exe | grep -iE "(vmware|virtualbox|sandbox|wine|cuckoo|vbox|qemu)"
strings suspicious.exe | grep -iE "(SbieDll|sbiedrvr|snxhk|avghookx)"

# Marqueurs courants de VM detection
# - CPUID checks (hypervisor bit)
# - Registry keys : HKLM\SOFTWARE\VMware Inc.
# - Fichiers : C:\windows\system32\drivers\vmmouse.sys
# - Process : vmtoolsd.exe, vboxservice.exe
# - MAC prefix : 00:0C:29 (VMware), 08:00:27 (VirtualBox)
# - Timing attacks : RDTSC delta anormal
```

<Tip>Toujours détonner dans un réseau isolé (VLAN dédié, pas de routage vers Internet sauf proxy contrôlé) et vérifier les techniques de VM detection AVANT l'exécution — un malware qui détecte un sandbox peut adopter un comportement bénin. Utiliser des profils de sandbox qui imitent de vrais hôtes (nom réaliste, user actif, documents Office présents) pour contourner les évasions basiques.</Tip>
