
Combinaison BOF de KillDefender et Backstab
28/06/2022 : Microsoft a déployé un correctif qui empêche l'ouverture d'un handle vers le jeton de MsMpEng.exe, et par conséquent la partie KillDefender de cet outil ne fonctionne plus. Backstab devrait toujours fonctionner. Je ne suis pas sûr de l'ID du correctif, cela peut fonctionner sur des systèmes plus anciens non corrigés. Vérifié sur Win10 21H2 et Win11.
Il s'agit d'une implémentation combinée en Beacon Object File de Backstab de Yaxser et de KillDefender de pwn1sher pour une utilisation avec Cobalt Strike.

KDStab est un outil de post-exploitation pour vaincre Windows Defender (en théorie, il pourrait fonctionner pour d'autres solutions également mais cela n'a pas été testé) afin que d'autres outils post-exploitation puissent être utilisés avec moins de crainte de détection. Il utilise Backstab et KillDefender pour y parvenir, tous deux appelés lorsque nécessaire par la commande kdstab de Cobalt Strike.
KDStab a été testé avec succès sur Windows 10 x64, Windows 11 et Server 2019.
KDStab nécessite des privilèges Administrateur ou Système.
Fonctions principales :
Énumérer l'intégrité d'un processus
Dépouiller un processus de ses privilèges et définir son intégrité sur Non fiable
Tuer un processus protégé par PPL
Lister les handles d'un processus protégé par PPL
Fermer un handle spécifique d'un processus protégé par PPL
Vérifier le niveau d'intégrité d'un processus

Dépouiller un processus de ses privilèges et définir son jeton sur Non fiable

Résultat de la commande /STRIP

Tuer un processus protégé par PPL

Je suis tombé sur KillDefender de pwn1sher peu après sa sortie et j'ai trouvé cela génial ; en plus de rendre MsMpEng.exe (Defender) inutile, il laisse le processus en cours d'exécution, ce qui semble souhaitable d'un point de vue OPSEC (en plus du fait que le comportement par défaut du service WinDefend est de redémarrer MsMpEng.exe en cas d'échec - quelque chose qui sera utile plus tard).
Bien que aveugler Defender soit génial pour une mission, en tant que professionnels, nous sommes responsables de la restauration des actifs du client dans l'état dans lequel nous les avons trouvés ; de plus, nous ne voulons pas vraiment laisser leurs systèmes exposés à d'autres acteurs parce que nous avons Kill(ed)Defender.
Le problème est qu'il est difficile de "restaurer" MsMpEng.exe dans son état de fonctionnement. KillDefender fonctionne en dépouillant le processus cible de ses privilèges (SeDebugPrivilege, etc.) et en définissant l'intégrité de son jeton sur non fiable. On ne peut pas simplement "ré-élever" le jeton vers Système et restaurer les privilèges, le processus doit être tué et une nouvelle instance démarrée. Bien sûr, MsMpEng.exe est également un processus PsProtectedSignerAntimalware-Light, donc même en tant que Système, nous ne pouvons pas simplement terminer le processus. Frustrant, le groupe TrustedInstaller a été récemment retiré de MsMpEng.exe (vous pouvez trouver d'autres recherches à ce sujet), rendant inefficace cette technique pour vraiment tuer le processus MsMpEng.exe (ou le service WinDefend) qui existe depuis de nombreuses années. Dans ce cas, la seule option apparemment viable est de redémarrer la machine, ce qui pourrait causer des problèmes au client si nous parlons de serveurs et de contrôleurs de domaine.
Armé de ce problème, j'ai commencé à chercher et j'ai rapidement trouvé Backstab de Yaxser. Backstab est capable de tuer des processus protégés par PPL en utilisant le pilote de ProcExp ; il s'agit d'un pilote signé par Microsoft provenant de Sysinternals, ce qui joue en notre faveur. Backstab effectue certaines actions non sûres du point de vue OPSEC ; il dépose le pilote sur le disque et crée des clés de registre. Cependant, si Defender est déjà aveugle... :).
J'ai entrepris de porter ces deux outils au format BOF afin qu'ils puissent être utilisés via un Beacon Cobalt Strike sans avoir à les déposer sur le disque (le binaire original de Backstab a été bloqué au moment de l'exécution par Defender).
Je suis à la fois novice en C/C++ et en écriture de BOF, et j'ai beaucoup appris au cours du processus. Vous trouverez quelques incohérences dans le code (comme le fait que Backstab_bof est écrit et compilé sur Linux avec gcc et que KillDefender_bof est écrit et compilé dans Visual Studio) en raison de mon apprentissage pendant le processus de création, mais j'ai effectué pas mal de tests pour garantir la fonctionnalité et j'ai également intégré pas mal de garde-fous dans le script aggressor pour assurer une utilisation et une saisie correctes des BOF. J'espère que vous trouverez cet outil utile.
Quelques modifications notables ont été apportées au code source des outils et certains choix programmatiques ont été faits qui seront mentionnés ici :
Le pilote ProcExp n'est plus stocké/chargé en tant que ressource, il s'agit d'un tableau d'octets codé en dur dans backstab_src/resource.c
Plusieurs fuites de mémoire dans le code original de Backstab ont été trouvées et résolues
La POC de KillDefender échoue lorsque l'utilisateur n'est pas Système ; j'ai ajouté un extrait pour énumérer l'utilisateur en cours et obtenir les privilèges Système par l'impersonation du jeton de Winlogon si nécessaire.
KillDefender a été modifié pour permettre aux utilisateurs de spécifier quel processus cibler ; de plus, un mode "Check" a été ajouté pour énumérer le niveau d'intégrité d'un processus (ce qui peut confirmer qu'un processus a été correctement dépouillé de ses privilèges et de son intégrité).
Backstab utilise suffisamment d'API et d'appels C différents pour que Cobalt Strike ne puisse pas gérer la résolution de toutes les fonctions dynamiques - trustedsec à la rescousse ! J'ai implémenté leur résolution de fonctions dynamiques pour compléter celle de CS afin que toutes les API nécessaires puissent être appelées.
Le Backstab original comporte plusieurs instructions switch/case qui ont causé des problèmes lors du portage, elles ont donc été remplacées par des instructions if/else. De plus, pratiquement toutes les variables globales ont été éliminées pour des raisons similaires.
Je sais qu'il est étrange qu'un outil ait été écrit pour Visual Studio et l'autre pour GCC ; c'est une conséquence de mes difficultés à les porter avec succès et de nombreuses difficultés d'apprentissage en cours de route. Les futurs outils devraient bénéficier de nombreuses leçons que j'ai apprises ici.
KillDefender_bof et Backstab_bof existent tous deux en tant que dépôts autonomes. NOTEZ QUE LE CODE EST DIFFÉRENT ENTRE LES DÉPÔTS AUTONOMES ET CET OUTIL. Cela a été fait pour les rendre plus flexibles et capables de s'intégrer dans un seul package.
Je n'ai pas essayé de compiler l'un ou l'autre outil pour x86 ; si vous avez vraiment besoin d'une version pour cela, je vous laisse trouver comment faire.
Pour compiler le Backstab_bof en utilisant gcc :
x86_64-w64-mingw32-gcc -o backstab.x64.o -Os -c main.c -DBOF -D_UNICODE
Assurez-vous d'avoir mis à jour votre mingw vers la dernière version ! J'ai eu des problèmes car ma version avait des fichiers d'en-tête obsolètes, mais les fichiers d'en-tête de la dernière version sont corrects.
Pour compiler le KillDefender_bof en utilisant l'invite de commandes Native x64 :
cl.exe /c /GS- /TP killdefender_bof.cpp /FoKillDefender.x64.o
Yaxser et son outil Backstab : https://github.com/Yaxser/Backstab
pwn1sher et son outil KillDefender : https://github.com/pwn1sher/KillDefender
Trustedsec pour son dépôt CS-Situational-Awareness-BOF qui a été d'une grande aide pendant le processus de portage. J'ai utilisé des extraits de son code dans ce projet et je recommande vivement à toute personne qui se lance dans l'écriture de BOF de consulter ce dépôt : https://github.com/trustedsec/CS-Situational-Awareness-BOF