
BOF CobaltStrike pour générer des Beacons par détournement de répertoire d'application DLL.
DropSpawn est un BOF CobaltStrike utilisé pour générer des Beacons supplémentaires via une méthode relativement méconnue de détournement de DLL. Fonctionne en x86-x86, x64-x64 et x86-x64/vice versa. Utilisez-le comme alternative à l'injection de processus.
Les exécutables Windows suivent l'ordre de recherche des DLL lorsqu'ils tentent de charger des DLL dont les chemins absolus n'ont pas été spécifiés :

Le détournement de DLL nécessite généralement que soit :
A. Un utilisateur dispose de droits d'écriture dans un dossier avec une priorité d'ordre de recherche supérieure à celui où se trouve la vraie DLL
ou
B. Que la DLL en question n'existe nulle part sur le système, auquel cas elle peut être placée dans un dossier modifiable par l'utilisateur dans la variable %PATH% de l'utilisateur (comme %USERPROFILE%\appdata\local\microsoft\windowsapps).
Ces exigences excluent le détournement de DLL pour les exécutables résidant dans C:\Windows\System32 car presque toutes les DLL que ces exécutables chargent résident également dans System32. Copier un exécutable System32 vers un emplacement modifiable par l'utilisateur et l'exécuter là-bas est une option, mais n'est pas très sûr en termes d'OPSEC car les binaires System32 s'exécutant depuis des emplacements alternatifs sont faciles à identifier.
DropSpawn permet le détournement de DLL en utilisant des exécutables System32 (et d'autres trouvés dans des dossiers supplémentaires non modifiables par l'utilisateur) en usurpant le « Répertoire à partir duquel l'application est chargée » vers un répertoire spécifié arbitrairement par l'utilisateur.
La version publique de DropSpawn diffère légèrement de la version non publique. La version non publique utilise un générateur de charge utile propriétaire, rendant l'expérience beaucoup plus fluide pour l'opérateur. La version publique a été légèrement modifiée pour tenir compte du fait que les utilisateurs auront leurs propres moyens de générer des charges utiles compatibles avec le détournement de DLL. Un script Python3 ainsi que le code source d'une DLL de démonstration ont été inclus pour aider les utilisateurs à intégrer et à armer dropspawn.
Identifiez des exécutables cibles qui tentent de charger des DLL sans spécifier leur chemin absolu. Vous pouvez le faire en copiant l'exe dans un répertoire modifiable par l'utilisateur et en l'exécutant tout en le surveillant avec Procmon. Dans cet exemple, nous utiliserons WerFault.exe qui réside normalement dans C:\Windows\System32\WerFault.exe

Dans l'exemple ci-dessus, cryptsp.dll, wer.dll, dbghelp.dll et bcrypt.dll sont tous des candidats viables car leurs chemins absolus n'ont pas été spécifiés dans WerFault ; par conséquent, WerFault tentera de les charger d'abord depuis son répertoire d'application avant de recourir au reste de l'ordre de recherche des DLL. Notez que cela n'est généralement pas un problème car le répertoire d'application de WerFault EST System32.
Téléchargez l'une des DLL détournables depuis le système cible.
C'est nécessaire pour que nous puissions extraire ses exports et les inclure dans notre DLL de charge utile. Il est important de récupérer la DLL détournable depuis la même machine sur laquelle vous souhaitez utiliser DropSpawn, car les DLL changent entre les versions de Windows. De plus, si vous exécutez un beacon x86 et souhaitez générer un beacon x64 avec DropSpawn, assurez-vous de télécharger la version x64 de la vraie DLL en spécifiant 'C:\windows\sysnative...' au lieu de 'C:\windows\system32...'.
Exécutez generate_dll.py en passant la DLL téléchargée et l'architecture de charge utile souhaitée. Generate_dll.py est une version modifiée de ce script. Il analysera la DLL fournie, créera un fichier .def contenant les exports de la DLL, et appellera MingW pour compiler notre DLL de charge utile de démonstration. Lorsque le processus généré tente d'appeler une fonction réelle dans la DLL usurpée, notre DLL de charge utile redirigera l'appel vers la vraie DLL située dans System32 afin que le processus hôte ne plante pas.

Appelez dropspawn en utilisant la DLL de charge utile générée.
dropspawn <payload DLL> <x86|x64> <program to spawn> [writable target folder] [parent]
payload DLL - le chemin complet vers la DLL de charge utile générée.
architecture - l'architecture du processus que vous souhaitez générer
program to spawn - le nom/chemin du processus que vous souhaitez générer. Si ce processus se trouve dans System32 (ou syswow64), vous pouvez simplement spécifier le nom. Sinon, spécifiez le chemin complet. Vous pouvez également fournir des arguments en ligne de commande au processus. S'il y a des espaces dans le chemin/si vous utilisez des arguments, mettez le tout entre guillemets.
writable target folder - Optionnel. Si laissé vide, dropspawn essaiera d'utiliser le répertoire actuel du Beacon. Utilisez des guillemets s'il y a des espaces dans le chemin.
parent - Optionnel. Le nom du processus à utiliser pour l'usurpation de PPID avec le processus nouvellement généré. Si un processus est spécifié qui a plusieurs instances en cours d'exécution avec des niveaux de privilèges différents (ex. svchost.exe), dropspawn essaiera d'en identifier un qui peut être utilisé pour l'usurpation de PPID.
Exemple : dropspawn /root/gitlab/DropSpawn_BOF/dist/dbgcore.dll x64 "WerFault.exe -u -p 4352 -s 160" C:\users\user\appdata\local\temp explorer.exe
Cela déposera la DLL de charge utile 'dbgcore.dll' sur le disque à 'c:\users\user\appdata\local\temp\dbgcore.dll' et générera un processus WerFault.exe x64 avec les arguments de ligne de commande '-u -p 4352 -s 160' et explorer.exe comme processus parent.


Le nettoyage est facile. En incluant la fonction Self-Deletion dans la DLL de charge utile déposée sur le disque, elle sera supprimée dès que notre nouveau processus se génère et la charge. C'est un changeur de jeu, car typiquement la DLL serait verrouillée sur le disque tant que notre processus qui l'a chargée continue de s'exécuter. Si la technique d'auto-suppression échoue pour une raison quelconque (ou si le processus ne parvient pas à se générer), DropSpawn tentera de supprimer la DLL de charge utile du disque et informera l'utilisateur du résultat de l'opération dans tous les cas.
L'injection de processus suit généralement la chaîne ouvrir un processus distant -> allouer de la mémoire distante -> écrire de la mémoire distante -> exécuter de la mémoire distante, avec une option pour générer un nouveau processus au début au lieu d'en utiliser un existant. DropSpawn crée seulement un nouveau processus ; le processus nouvellement généré est responsable de l'allocation, de l'écriture et de l'exécution du shellcode, ce qui nous permet d'éviter beaucoup d'IOC typiquement associés à l'injection de processus distant.
Cette technique est bien sûr à la merci de la qualité de vos DLL de charge utile. Mais nous pouvons jeter un œil à ce que Windows voit (cette section suivante utilise la version privée de DropSpawn et génère des Beacons).
En ce qui concerne l'Observateur d'événements, tout semble normal :

Dans MDE, il y a très peu à voir.
Exécution de dropspawn :

Journaux MDE :
Avec usurpation de PPID :

Sans usurpation de PPID :

Dans les deux cas, nous voyons notre processus beacon original (également un werfault) déposer dbgcore.dll sur le disque, créer un nouveau processus WerFault.exe, le processus nouvellement généré charger dbgcore.dll, puis le renommer (supprimer). De manière critique, il n'y a pas d'examen supplémentaire de dbgcore.dll qui accompagne souvent les détournements de DLL parce que nous ne l'écrivons pas dans un emplacement souvent détourné, et WerFault.exe (ou tout autre processus que vous choisissez d'utiliser) n'est pas vraiment associé aux détournements de DLL comme le sont des choses comme WmiPrvSE.exe.
Fait intéressant, il est presque plus visible de faire cela avec l'usurpation de PPID que sans. Cela peut varier cependant en fonction du produit de sécurité.
Comme mentionné, il est essentiel que les utilisateurs téléchargent les vraies DLL depuis la machine cible sur laquelle ils prévoient d'utiliser DropSpawn. Utiliser une mauvaise version d'une DLL peut entraîner le plantage du processus généré s'il tente d'appeler une fonction qui n'existe pas.
DropSpawn peut être utilisé avec des exécutables en dehors de System32 ; soyez averti cependant que des problèmes peuvent survenir si le processus tente de charger des DLL supplémentaires depuis le véritable répertoire d'application du processus. Parce que nous avons usurpé le répertoire d'application ailleurs, si le vrai répertoire d'application n'est pas également accessible via l'ordre de recherche des DLL autrement, le processus plantera/ne démarrera pas car il ne peut pas localiser les DLL essentielles. Testez toujours les détournements potentiels sur des machines de développement avant de les utiliser en production !
Cette recherche a vu le jour lorsque j'explorais comment les processus assemblent leur ordre de recherche final des DLL (car il doit être déterminé à l'exécution en raison des exécutables résidant dans différents répertoires, le répertoire courant faisant partie du chemin de recherche, etc.). Mes recherches m'ont conduit à ce message de forum, qui a servi d'origine aux deux API critiques non documentées qui sont centrales à cette technique.
Ils sont déjà liés plus tôt, mais ce message concernant l'évitement du verrouillage du chargeur, ce script pour générer un fichier .def pour le proxy DLL, et cette recherche sur l'activation de l'auto-suppression des exécutables en cours d'exécution sont essentiels pour produire des charges utiles DLL efficaces et armées adaptées à DropSpawn.
Lorsque j'ai publié cette technique pour la première fois sur Twitter, plusieurs autres ont rejoint la conversation et produit des POC. SecurityAndStuff a produit celle-ci, tandis que Snovvcrash a la sienne ici