
ScareCrow - Framework de création de payloads conçu autour du contournement d'EDR.
Pour consulter la dernière version de ScareCrow ou soumettre un problème, référez-vous à https://github.com/Tylous/ScareCrow.
Si vous souhaitez en savoir plus sur les techniques utilisées dans ce framework, veuillez consulter Partie 1 et Partie 2
ScareCrow est un framework de création de payloads pour le chargement latéral (pas d'injection) dans un processus Windows légitime (contournant les contrôles de liste blanche d'applications). Une fois le chargeur DLL chargé en mémoire, il utilise une technique pour éliminer le hook d'un EDR des DLL système s'exécutant dans la mémoire du processus. Cela fonctionne car nous savons que les hooks des EDR sont placés lorsqu'un processus est créé.
ScareCrow peut cibler ces DLL et les manipuler en mémoire en utilisant la fonction API VirtualProtect, qui modifie les permissions d'une section de la mémoire d'un processus vers une valeur différente, notamment de Exécuter-Lire à Lire-Écrire-Exécuter.
ScareCrow utilise l'une des 2 méthodes pour retirer les hooks
Lorsqu'il est exécuté, ScareCrow copie les octets des DLL système stockées sur le disque dans C:\Windows\System32\. Ces DLL sont stockées sur le disque « propres », sans hooks des EDR, car elles sont utilisées par le système pour charger une copie non altérée dans un nouveau processus lorsqu'il est créé. Comme les EDR ne hookent ces processus qu'en mémoire, elles restent inchangées. ScareCrow ne copie pas l'intégralité du fichier DLL, mais se concentre uniquement sur la section .text des DLL. Cette section d'une DLL contient l'assembly exécutable, et ce faisant, ScareCrow réduit la probabilité de détection, car la relecture de fichiers entiers peut amener un EDR à détecter une modification d'une ressource système. Les données sont ensuite copiées dans la bonne région mémoire en utilisant le décalage (offset) de chaque fonction. Chaque fonction possède un décalage qui indique le nombre exact d'octets à partir de l'adresse de base où elle réside, fournissant ainsi l'emplacement de la fonction sur la pile.
Pour ce faire, ScareCrow modifie les permissions de la région mémoire .text à l'aide de VirtualProtect. Même s'il s'agit d'une DLL système, comme elle a été chargée dans notre processus (que nous contrôlons), nous pouvons modifier les permissions mémoire sans nécessiter de privilèges élevés.
ScareCrow charge le shellcode en mémoire en déchiffrant d'abord le shellcode, qui est chiffré par l'une des trois méthodes de chiffrement (décrites ci-dessous). Une fois déchiffré et chargé, le shellcode est ensuite exécuté. Selon les options du chargeur spécifiées, ScareCrow mettra en place différentes fonctions d'export pour la DLL. La DLL chargée ne contient pas non plus la fonction DLLMain standard que toutes les DLL doivent normalement posséder pour fonctionner. La DLL s'exécutera néanmoins sans problème car le processus dans lequel nous chargeons recherchera ces fonctions d'export et ne se souciera pas de la présence de DLLMain.
Après
KnownDLLs est une liste de DLL chargées par Windows lors du démarrage du système. Comme ces DLL sont considérées comme essentielles au fonctionnement du système d'exploitation, elles sont mises en cache pour réduire les temps de chargement et améliorer les performances au démarrage des applications. KnownDLLs inclut des DLL telles que kernel32.dll, kernelbase.dll et ntdll.dll.
En utilisant ces KnownDLLs, ScareCrow mappe une copie de la DLL depuis \KnownDlls\<nomdll> en utilisant une combinaison de NtOpenSection et NtMapViewOfSection pour la charger dans la mémoire du processus. ScareCrow ne charge pas l'intégralité de la DLL, mais seulement la section .text de celle-ci (car elle contient tous les appels système). Ensuite, ScareCrow utilise des appels système indirects pour appeler NtProtectVirtualMemory et modifier les permissions de la section mémoire .text de la DLL, permettant ainsi à ScareCrow d'écraser les hooks de l'EDR avant de restaurer les permissions.
Pour plus d'informations, vous pouvez lire l'article détaillé de modexp ici
Une fois ces hooks supprimés, ScareCrow utilise alors des appels système personnalisés pour charger et exécuter le shellcode en mémoire. ScareCrow fait cela même après la suppression des hooks de l'EDR pour éviter la détection par des outils de collecte de télémétrie non basés sur l'espace utilisateur, tels que le suivi d'événements pour Windows (ETW) ou d'autres mécanismes de journalisation d'événements. Ces appels système personnalisés sont également utilisés pour effectuer l'appel VirtualProtect afin de supprimer les hooks placés par les EDR, comme décrit ci-dessus, et ainsi éviter la détection par les contrôles anti-altération des EDR. Cela se fait en appelant une version personnalisée de l'appel système VirtualProtect, NtProtectVirtualMemory. ScareCrow utilise Golang pour générer ces chargeurs, puis l'assembleur pour ces fonctions d'appel système personnalisées.
Lors du processus de création du chargeur, ScareCrow utilise une bibliothèque pour se fondre dans l'arrière-plan après qu'un beacon ait contacté le serveur. Cette bibliothèque fait deux choses :
Les fichiers signés avec des certificats de signature de code sont souvent moins scrutés, ce qui facilite leur exécution sans être contestés, car les fichiers signés par un nom de confiance sont généralement moins suspects que d'autres. La plupart des produits antimalware n'ont pas le temps de valider et vérifier ces certificats (certains le font maintenant, mais généralement les noms de fournisseurs courants sont inclus dans une liste blanche). ScareCrow crée ces certificats en utilisant une version en package Go de l'outil limelighter pour créer un fichier pfx12. Ce package prend un nom de domaine saisi par l'utilisateur pour créer un certificat de signature de code pour ce domaine. Si nécessaire, vous pouvez également utiliser votre propre certificat de signature de code si vous en possédez un, en utilisant l'option de ligne de commande valid.
clone, ainsi que le chemin vers le fichier dont vous souhaitez copier le certificat. Lors de la signature du chargeur avec microsoft.com, leur utilisation contre les produits WINDOWS DEFENDER ATP peut ne pas être aussi efficace, car ils peuvent valider le certificat comme leur appartenant. Si vous utilisez un chargeur contre un produit Windows, utilisez éventuellement un domaine différent.
Avec ces fichiers et le code Go, ScareCrow les compile de manière croisée en DLL en utilisant l'option de bibliothèque partagée c-shared. Une fois la DLL compilée, elle est obscurcie en une chaîne base64 fragmentée qui sera intégrée dans un fichier. Cela permet au fichier d'être récupéré à distance, accédé et exécuté par programmation.
Bien que ScareCrow dispose d'une liste étendue d'attributs de fichiers, certaines circonstances peuvent nécessiter un ensemble d'attributs personnalisé (peut-être spécifique à l'environnement). Pour répondre à cela, ScareCrow permet la saisie d'un fichier JSON contenant des attributs. En utilisant l'option de ligne de commande -configfile, ScareCrow utilisera ces attributs et ce nom de fichier au lieu de ceux préexistants dans ScareCrow. Le fichier main.json contient un modèle d'exemple de la structure JSON nécessaire pour fonctionner correctement. Notez que ce que vous utilisez comme "InternalName" sera le nom du fichier.
ScareCrow nécessite désormais golang 1.19.1 ou une version ultérieure pour compiler les chargeurs. Si vous utilisez une version plus ancienne, veuillez utiliser la version 1.19.1 ou ultérieure.
Voir les nouvelles versions : https://golang.org/dl/.
La première étape, comme toujours, est de cloner le dépôt. Avant de compiler ScareCrow, vous devrez installer les dépendances.
Pour les installer, exécutez les commandes suivantes :``` go get github.com/fatih/color go get github.com/yeka/zip go get github.com/josephspurrier/goversioninfo go get github.com/Binject/debug/pe go get github.com/awgh/rawreader
Assurez-vous que les éléments suivants sont installés sur votre système d'exploitation :```
openssl
osslsigncode
mingw-w64
Ensuite, construisez-le``` go build ScareCrow.go
De plus, ScareCrow utilise [Garble](https://github.com/burrowers/garble) pour obscurcir tous les chargeurs.
Note : Plusieurs dépendances ne fonctionnent pas bien sur Windows lors de la compilation, c'est pourquoi il est recommandé de compiler vos chargeurs sur OSX ou Linux.
## Aide```
./ScareCrow -h
_________ _________
/ _____/ ____ _____ _______ ____ \_ ___ \_______ ______ _ __
\_____ \_/ ___\\__ \\_ __ \_/ __ \/ \ \/\_ __ \/ _ \ \/ \/ /
/ \ \___ / __ \| | \/\ ___/\ \____| | \( <_> ) /
/_______ /\___ >____ /__| \___ >\______ /|__| \____/ \/\_/
\/ \/ \/ \/ \/
(@Tyl0us)
“Fear, you must understand is more than a mere obstacle.
Fear is a TEACHER. the first one you ever had.”
Usage of ./ScareCrow:
-Evasion string
Sets the type of EDR unhooking technique:
[*] Disk - Retrives a clean version of the DLLs ".text" field from files stored on disk.
[*] KnownDLL - Retrives a clean version of the DLLs ".text" field from the KnownDLLs directory in the object namespace.
[*] None - The Loader that WILL NOT removing the EDR hooks in system DLLs and only use custom syscalls. (default "Disk")
-Exec string
Set the template to execute the shellcode:
[*] RtlCopy - Using RtlCopy to move the shellcode into the allocated address in the current running process by making a Syscall.
[*] ProcessInjection - Process Injection Mode.
[*] NtQueueApcThreadEx - Executes the shellcode by creating an asynchronous procedure call (APC) to a target thread.
[*] VirtualAlloc - Allocates shellcode into the process using custom syscalls in the current running process (default "RtlCopy")
-I string
Path to the raw 64-bit shellcode.
-Loader string
Sets the type of process that will sideload the malicious payload:
[*] binary - Generates a binary based payload. (This type does not benefit from any sideloading)
[*] control - Loads a hidden control applet - the process name would be rundll32 if -O is specified a JScript loader will be generated.
[*] dll - Generates just a DLL file. Can be executed with commands such as rundll32 or regsvr32 with DllRegisterServer, DllGetClassObject as export functions.
[*] excel - Loads into a hidden Excel process using a JScript loader.
[*] msiexec - Loads into MSIexec process using a JScript loader.
[*] wscript - Loads into WScript process using a JScript loader. (default "binary")
-O string
Name of output file (e.g. loader.js or loader.hta). If Loader is set to dll or binary this option is not required.
-clone string
Path to the file containing the certificate you want to clone
-configfile string
The path to a json based configuration file to generate custom file attributes. This will not use the default ones.
-console
Only for Binary Payloads - Generates verbose console information when the payload is executed. This will disable the hidden window feature.
-delivery string
Generates a one-liner command to download and execute the payload remotely:
[*] bits - Generates a Bitsadmin one liner command to download, execute and remove the loader (Compatible with Binary, Control, Excel, and Wscript Loaders).
[*] hta - Generates a blank hta file containing the loader along with an MSHTA command to execute the loader remotely in the background (Compatible with Control and Excel Loaders).
[*] macro - Generates an office macro that will download and execute the loader remotely (Compatible with Control, Excel, and Wscript Loaders).
-domain string
The domain name to use for creating a fake code signing cert. (e.g. www.acme.com)
-encryptionmode string
Sets the type of encryption to encrypt the shellcode:
[*] AES - Enables AES 256 encryption.
[*] ELZMA - Enables ELZMA encryption.
[*] RC4 - Enables RC4 encryption. (default "ELZMA")
-export string
For DLL Loaders Only - Specify an Export function for a loader to have.
-injection string
Enables Process Injection Mode and specify the path to the process to create/inject into (use \ for the path).
-noamsi
Disables the AMSI patching that prevents AMSI BufferScanner.
-noetw
Disables the ETW patching that prevents ETW events from being generated.
-nosign
Disables file signing, making -domain/-valid/-password parameters not required.
-nosleep
Disables the sleep delay before the loader unhooks and executes the shellcode.
-obfu
Enables Garbles Literal flag replaces golang libray strings with more complex variants, resolving to the same value at run-time. This creates a larger loader and times longer to compile
-outpath string
The path to put the final Payload/Loader once it's compiled.
-password string
The password for code signing cert. Required when -valid is used.
-sandbox
Enables sandbox evasion using IsDomainJoined calls.
-url string
URL associated with the Delivery option to retrieve the payload. (e.g. https://acme.com/)
-valid string
The path to a valid code signing cert. Used instead -domain if a valid code signing cert is desired.
Le Loader détermine le type de technique utilisé pour charger le shellcode dans le système cible. Si aucune option de Loader n'est choisie, ScareCrow compilera simplement un fichier DLL standard, qui peut être utilisé par rundll32, regsvr32, ou d'autres techniques qui utilisent une DLL. ScareCrow utilise trois types de chargeurs différents pour charger le shellcode en mémoire :
ScareCrow peut également générer des charges utiles binaires si nécessaire en utilisant l'option de ligne de commande -Loader. Ces binaires ne bénéficient d'aucune technique de chargement côte à côte mais servent de technique supplémentaire pour exécuter le shellcode selon la situation.
ScareCrow utilise une technique pour d'abord créer le processus puis le déplacer en arrière-plan. Cela fait deux choses : premièrement, cela aide à garder le processus caché et deuxièmement, évite d'être détecté par tout produit EDR. Lancer un processus immédiatement en arrière-plan peut être très suspect et est un indicateur de malveillance. ScareCrow le fait en appelant les fonctions Windows 'GetConsoleWindow' et 'ShowWindow' après la création du processus et le chargement des hooks EDR, puis modifie les attributs de la fenêtre en cachée. ScareCrow utilise ces API plutôt que la traditionnelle -ldflags -H=windowsgui car celle-ci est fortement signée et classée comme indicateur de compromission dans la plupart des produits de sécurité.
Si l'option de ligne de commande -console est sélectionnée, ScareCrow ne cachera pas le processus en arrière-plan. Au lieu de cela, ScareCrow ajoutera plusieurs messages de débogage indiquant ce que fait le chargeur.
ScareCrow utilise différents modèles pour exécuter le shellcode. Pour choisir le modèle, utilisez l'option de ligne de commande -Exec. Ces modèles incluent :
ScareCrow contient la capacité de réaliser des attaques par injection de processus. Pour éviter tout hook ou détection dans le processus du chargeur ou le processus injecté lui-même, ScareCrow désactive d'abord les hooks du processus du chargeur comme il le fait normalement, afin de garantir l'absence de hooks dans le processus. Une fois cela fait, le chargeur lance le processus spécifié dans la commande de création. Une fois lancé, le chargeur crée alors un handle vers le processus pour récupérer une liste des DLL chargées. Une fois les DLL trouvées, il énumère l'adresse de base de chaque DLL dans le processus distant. En utilisant la fonction WriteProcessMemory, le chargeur écrit ensuite les octets des DLL système stockées sur le disque (car elles sont « propres » des hooks EDR) sans avoir besoin de modifier d'abord les permissions mémoire. ScareCrow utilise WriteProcessMemory car cette fonction possède une fonctionnalité principalement utilisée dans le débogage où, même si une section de mémoire est en lecture seule, si tout est correct dans l'appel à WriteProcessMemory, elle changera temporairement la permission en lecture-écriture, mettra à jour la section mémoire puis restaurera les permissions d'origine. Une fois cela fait, le chargeur peut injecter le shellcode dans le processus lancé sans problème, car il n'y a pas de hooks EDR dans aucun des deux processus.
Cette option peut être utilisée avec n'importe laquelle des options de chargeur. Pour activer l'injection de processus, utilisez l'option de ligne de commande -injection avec le chemin complet du processus que vous souhaitez utiliser pour l'injection. Lorsque vous saisissez le chemin comme argument, il est important de l'entourer de "" ou d'utiliser des doubles \\ pour chaque répertoire du chemin.
ScareCrow contient la capacité de patcher les fonctions AMSI (Antimalware Scan Interface) et ETW, empêchant tout événement d'être généré par le processus.
AMSI est une API native de Windows qui permet à Windows Defender (ou d'autres produits antimalware) de s'interfacer profondément dans le système d'exploitation Windows et d'offrir une protection renforcée, en particulier contre les attaques basées en mémoire. AMSI permet aux produits de sécurité de mieux détecter les indicateurs malveillants et d'aider à stopper les menaces. Comme AMSI est natif de Windows, les produits n'ont pas besoin de « hooker » AMSI, ils chargent plutôt la DLL nécessaire pour obtenir une meilleure visibilité du processus. Pour cette raison, ScareCrow charge la DLL AMSI.dll puis la patche, afin de garantir que tous les résultats de l'interface de balayage reviennent propres. Patching AMSI est par défaut dans tous les chargeurs ; si vous ne souhaitez pas patcher AMSI, utilisez l'option de ligne de commande -noamsi pour le désactiver dans votre chargeur.
ETW utilise des appels système intégrés pour générer cette télémétrie. Comme ETW est également une fonctionnalité native de Windows, les produits de sécurité n'ont pas besoin de « hooker » les appels système ETW pour obtenir les informations. Par conséquent, pour empêcher ETW, ScareCrow patche de nombreux appels système ETW, flushant les registres et redirigeant le flux d'exécution vers l'instruction suivante. Patching ETW est maintenant par défaut dans tous les chargeurs ; si vous ne souhaitez pas patcher ETW, utilisez l'option de ligne de commande -noetw pour le désactiver dans votre chargeur.
Actuellement, ces options ne fonctionnent que pour le processus parent ; si l'option de ligne de commande -injection est utilisée, le processus principal patchera AMSI et ETW mais le processus injecté
Chiffrer le shellcode est une technique importante pour le protéger de la détection et de l'analyse par les EDR et autres produits de sécurité. ScareCrow propose plusieurs méthodes pour chiffrer le shellcode, notamment AES, ELZMA et RC4.
AES (Advanced Encryption Standard) est un algorithme de chiffrement symétrique largement utilisé pour chiffrer les données. ScareCrow utilise une taille de clé AES 256 bits pour chiffrer le shellcode. L'avantage d'utiliser AES pour chiffrer le shellcode est qu'il offre un chiffrement fort et est largement supporté par les bibliothèques cryptographiques. Cependant, l'utilisation d'une taille de bloc fixe peut le rendre vulnérable à certaines attaques, comme l'attaque par oracle de padding.
ELZMA est un algorithme de compression et de chiffrement souvent utilisé dans les malwares pour obscurcir le code. Pour chiffrer le shellcode avec ELZMA, le shellcode est d'abord compressé avec l'algorithme ELZMA. Les données compressées sont ensuite chiffrées avec une clé aléatoire. Les données chiffrées et la clé sont ensuite intégrées dans le code de l'exploit. L'avantage d'utiliser ELZMA pour chiffrer le shellcode est qu'il offre à la fois compression et chiffrement en un seul algorithme. Cela peut aider à réduire la taille du code de l'exploit et le rendre plus difficile à détecter.
RC4 est un algorithme de chiffrement symétrique souvent utilisé dans les malwares pour chiffrer le shellcode. C'est un chiffrement par flux qui peut utiliser des clés de longueur variable et est connu pour sa simplicité et sa rapidité.
L'utilisation de l'option de ligne de commande -obfu active l'indicateur Garbles Literal pendant le processus de compilation. Cela remplace toutes les références et chaînes de caractères des bibliothèques Go par une version plus complexe qui résout la même valeur lors de l'exécution. Ce processus prend plus de temps à terminer, ce qui donne un fichier GO plus volumineux. Une fois le fichier compilé, ScareCrow analyse le fichier nouvellement créé, en supprimant tout indicateur de compromission (IOC) basé sur des chaînes Go.
L'argument de ligne de commande de livraison vous permet de générer une commande ou une chaîne de code (dans le cas de macros) pour récupérer le fichier à distance depuis une source distante vers l'hôte de la victime. Ces méthodes de livraison incluent :