
Freeze est une boîte à outils de payloads pour contourner les EDR en utilisant des processus suspendus, des appels système directs et des méthodes d'exécution alternatives.
Pour voir la dernière version de Freeze ou soumettre un problème, référez-vous à https://github.com/Tylous/Freeze.
Si vous souhaitez en savoir plus sur les techniques utilisées dans ce framework, veuillez consulter le SourceZero Blog
Freeze est un outil de création de charge utile (payload) utilisé pour contourner les contrôles de sécurité EDR afin d'exécuter du shellcode de manière furtive. Freeze utilise plusieurs techniques non seulement pour supprimer les hooks EDR en espace utilisateur, mais aussi pour exécuter le shellcode de manière à contourner d'autres contrôles de surveillance des terminaux.
Lorsqu'un processus est créé, Ntdll.dll est la première DLL chargée. Cela se produit avant que les DLL EDR ne soient chargées. Cela signifie qu'il y a un certain délai avant qu'un EDR puisse être chargé et commencer à hooker et modifier les assemblages des DLL système. En examinant les appels système Windows dans Ntdll.dll, on peut voir que rien n'est encore hooké. Si nous créons un processus en état suspendu (gelé dans le temps), nous pouvons voir qu'aucune autre DLL n'est chargée, à l'exception de Ntdll.dll. Vous pouvez également voir qu'aucune DLL EDR n'est chargée, ce qui signifie que les appels système situés dans Ntdll.dll ne sont pas modifiés.
Afin d'utiliser ce processus suspendu propre pour supprimer les hooks du chargeur Freeze, nous avons besoin d'un moyen de trouver et lire programmatiquement la mémoire du processus suspendu propre. C'est là que la randomisation de l'espace d'adressage (ASLR) entre en jeu. L'ASLR est un mécanisme de sécurité conçu pour prévenir les vulnérabilités basées sur la corruption de la mémoire de la pile. L'ASLR randomise l'espace d'adressage à l'intérieur d'un processus, afin de garantir que tous les objets mappés en mémoire, la pile, le tas et le programme exécutable lui-même, soient uniques. Maintenant, c'est là que cela devient intéressant car bien que l'ASLR fonctionne, il ne fonctionne pas pour le code indépendant de la position tel que les DLL. Ce qui se passe avec les DLL (en particulier les DLL système connues), c'est que l'espace d'adressage est randomisé une fois au démarrage. Cela signifie que nous n'avons pas besoin d'énumérer les informations d'un processus distant pour trouver l'adresse de base de sa ntdll.dll car elle est la même dans tous les processus, y compris celui que nous contrôlons. Puisque l'adresse de chaque DLL est la même par démarrage, nous pouvons récupérer ces informations depuis notre propre processus sans jamais avoir à énumérer le processus suspendu pour trouver l'adresse.
Avec ces informations, nous pouvons utiliser l'API ReadProcessMemory pour lire la mémoire d'un processus. Cet appel API est couramment associé à la lecture de LSASS dans le cadre d'attaques basées sur les identifiants ; cependant, en soi, il n'est pas intrinsèquement malveillant, surtout si nous lisons simplement une section arbitraire de la mémoire. La seule fois où ReadProcessMemory sera signalé comme suspect, c'est si vous lisez quelque chose que vous ne devriez pas (comme le contenu de LSASS). Les produits EDR ne devraient jamais signaler le fait que ReadProcessMemory a été appelé, car il existe des utilisations opérationnelles légitimes pour cette fonction et cela entraînerait de nombreux faux positifs.
Nous pouvons aller plus loin en ne lisant qu'une section de Ntdll.dll où tous les appels système sont stockés - sa section .text, plutôt que de lire la DLL entière.
En combinant ces éléments, nous pouvons obtenir programmatiquement une copie de la section .text de Ntdll.dll pour écraser notre section .text hookée existante avant d'exécuter le shellcode.
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 intégrée à Windows, les produits de sécurité n'ont pas besoin de "hooker" les appels système ETW pour accéder aux informations. Par conséquent, pour empêcher ETW, Freeze corrige de nombreux appels système ETW, vidant les registres et renvoyant le flux d'exécution à l'instruction suivante. La correction d'ETW est maintenant par défaut dans tous les chargeurs.
Étant donné que seule Ntdll.dll est restaurée, tous les appels ultérieurs pour exécuter le shellcode doivent résider dans Ntdll.dll. En utilisant Go (notez que vous pouvez le faire dans d'autres langages mais en Go, c'est assez facile à implémenter), nous pouvons définir et appeler les appels système NT nécessaires pour allouer, écrire et protéger le shellcode, en contournant efficacement les appels standard situés dans kernel32.dll et Kernelbase.dll, car ceux-ci peuvent encore être hookés.
Freeze a été développé en Golang.
Pour installer Freeze, exécutez les commandes suivantes, ou utilisez le binaire compilé :
go build Freeze.go
___________
\_ _____/______ ____ ____ ________ ____
| __) \_ __ \_/ __ \_/ __ \\___ // __ \
| \ | | \/\ ___/\ ___/ / /\ ___/
\___ / |__| \___ >\___ >_____ \\___ >
\/ \/ \/ \/ \/
(@Tyl0us)
Soon they will learn that revenge is a dish... best served COLD...
Utilisation de ./Freeze :
-I string
Chemin vers le shellcode 64 bits brut.
-O string
Nom du fichier de sortie (ex. loader.exe ou loader.dll). Selon l'extension de fichier définie, Freeze déterminera s'il crée une dll ou un exe.
-console
Uniquement pour les charges utiles binaires - Génère des informations console détaillées lors de l'exécution de la charge utile. Cela désactivera la fonction de fenêtre cachée.
-encrypt
Crypte le shellcode en utilisant le chiffrement AES 256
-export string
Pour les chargeurs DLL uniquement - Spécifie une fonction d'exportation spécifique pour un chargeur.
-process string
Le nom du processus à créer. Ce processus doit exister dans C:\Windows\System32\. Exemple 'notepad.exe' (par défaut "notepad.exe")
-sandbox
Active l'évasion de bac à sable en vérifiant :
Le point de terminaison est-il joint à un domaine ?
Le point de terminaison a-t-il plus de 2 CPU ?
Le point de terminaison a-t-il plus de 4 Go de RAM ?
-sha256
Fournit la valeur SHA256 des chargeurs (utile pour le suivi)
Freeze peut générer un fichier .exe ou .dll. Pour spécifier cela, assurez-vous que l'option de ligne de commande -O se termine par .exe pour les binaires ou .dll pour les dll. Aucun autre type de fichier n'est actuellement supporté. Dans le cas des fichiers DLL, Freeze peut également ajouter des fonctionnalités d'exportation supplémentaires. Pour ce faire, utilisez -export avec un nom de fonction d'exportation spécifique.
Freeze utilise une technique qui consiste 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, cela évite d'être détecté par un produit EDR. Créer un processus directement en arrière-plan peut être très suspect et un indicateur de malveillance. Freeze le fait en appelant les fonctions Windows 'GetConsoleWindow' et 'ShowWindow' après la création du processus et le chargement des hooks de l'EDR, puis en modifiant les attributs de la fenêtre pour la cacher. Freeze utilise ces API plutôt que d'utiliser les traditionnelles -ldflags -H=windowsgui, car cela est fortement signé et classifié comme indicateur de compromission dans la plupart des produits de sécurité.
Si l'option de ligne de commande -console est sélectionnée, Freeze ne cachera pas le processus en arrière-plan. Au lieu de cela, Freeze ajoutera plusieurs messages de débogage affichant ce que fait le chargeur.