poortry
Threat Research

Poortry et Stonestop : amélioration d’un outil d’attaque (EDR Killer) qui affecte les ordinateurs Windows

Un EDR Killer que Sophos X-Ops traque depuis trois ans continue de perturber les entreprises ciblées par des gangs de ransomware.

En 2022 et 2023, Sophos X-Ops a publié une étude sur un ensemble d’outils permettant de saboter les fonctions des logiciels de protection endpoint, développés et utilisés en collaboration avec plusieurs gangs de ransomware majeurs. Mandiant avait précédemment nommé cet outil Poortry et son application de chargement Stonestop.

Les créateurs de l’outil Poortry ont réussi à faire signer des pilotes au niveau du noyau, spécialement conçus et personnalisés, via le processus de signature d’attestation de Microsoft. Après avoir publié nos recherches (et après le traitement par Microsoft de cette faille qui permettait à ces pilotes d’être signés), les créateurs de l’outil ne se sont pas arrêtés là. Ils ont continué à ajouter des fonctionnalités au pilote Poortry, dans une tentative continue d’échapper à la détection et de trouver de nouvelles façons de désactiver les logiciels EDR et de protection endpoint.

Pour expliquer les nouvelles fonctionnalités de Poortry, examinons comment les pilotes interagissent avec le système d’exploitation et comment les développeurs de cet EDR Killer ont fait évoluer leur outil au fil du temps.

Comment les pilotes Windows peuvent saboter la protection ?

La plupart des EDR Killers s’appuient sur un pilote de périphérique chargé dans le noyau du système d’exploitation, leur donnant ainsi accès à des fonctionnalité de bas niveau qui permettent de désactiver et bloquer différents types de logiciel de protection.

Sous Windows, qui prend en charge une multitude de périphériques et de composants connectés, les pilotes en mode noyau bénéficient d’une grande latitude pour ces types de fonction de bas niveau. Dans des circonstances normales, ces pilotes n’interagissent pas avec les logiciels ou le matériel d’autres entreprises ou fabricants, mais ce type de comportement n’est pas une obligation. Ainsi, si un pilote légitime signé ne valide pas correctement les processus interagissant avec lui, les EDR Killers peuvent exploiter certaines de ses fonctionnalités pour supprimer les mesures de protection.

Microsoft a développé plusieurs méthodes permettant à ses systèmes d’exploitation de contrôler si les pilotes sont chargés ou non, comme le mécanisme DSE (Driver Signature Enforcement) : les pilotes doivent être signés numériquement par un éditeur de logiciels auquel Microsoft fait confiance avant de pouvoir être chargés.

Les développeurs d’EDR Killers exploitent les lacunes de ce modèle de confiance : en effet, ils peuvent utiliser un pilote vulnérable à certains abus qui a déjà été publié par une société de logiciels légitime ; ils peuvent également signer leur propre pilote avec un certificat de signature de code légitime (et il existe de nombreuses façons d’obtenir des certificats volés ou divulgués).

En général, il existe trois façons, utilisées par les développeurs d’EDR Killers, pour exploiter de manière malveillante des signatures de code :

Abus de certificats divulgués

Voici la manière la plus simple de gérer ce problème : recherchez un certificat de signature de code divulgué, volé ou bien compromis auprès d’une entreprise légitime et utilisez-le pour signer votre pilote (ou pour tromper les RCA – Root Certificate Authorities – afin qu’elles vous délivrent un certificat).

Pour toutes les versions de Windows postérieures à Windows 10 version 1607, Microsoft a exigé que tous les développeurs tiers de pilotes en mode noyau soumettent leur pilote au portail des développeurs de Microsoft, pour qu’il soit soumis à une signature croisée de Microsoft. Cependant, les pilotes signés de manière croisée et non signés par Microsoft peuvent toujours être chargés s’ils remplissent l’une des conditions suivantes :

  • Le PC a été mis à niveau à partir d’une version antérieure de Windows vers Windows 10, version 1607.
  • Le démarrage sécurisé (Secure Boot) est désactivé dans le BIOS du système.
  • Le pilote a été signé avec un certificat d’entité finale (end-entity) émis avant le 29 juillet 2015 qui est lié à une autorité de certification (CA) à signature croisée et prise en charge.

Même si la mise à jour a réduit le danger que représentent des pilotes à signature croisée et signés par des certificats volés, la troisième point mentionné crée une faille qui permet aux attaquants d’utiliser la deuxième méthode.

Falsification de l’horodatage de la signature

Afin de maintenir la compatibilité avec les pilotes plus anciens, Windows charge les pilotes signés avec “un certificat d’entité finale émis avant le 29 juillet 2015 qui est lié à une autorité de certification à signature croisée et prise en charge”.

Lors de la signature d’un pilote de noyau, Microsoft fournit à l’éditeur du logiciel un outil nommé signtool.exe. En plus de signer le fichier fourni, signtool vérifie également que le certificat fourni soit toujours valide. Une façon de garantir cette validité est d’utiliser cette fonction.

Grâce à une série de hooks au niveau de ces appels API de bas niveau à l’intérieur du système d’exploitation, les attaquants peuvent modifier le processus de signature et contourner ces contrôles pour signer leur propre pilote de noyau. L’une des fonctions utilisées dans cette technique est GetLocalTime pour renvoyer un horodatage falsifié afin de passer avec succès les vérifications dans signtool.exe.

Contourner la signature d’attestation de Microsoft

La dernière méthode consiste à passer par le processus de signature d’attestation de Microsoft et à faire signer le pilote du noyau directement par ce dernier. C’est probablement la méthode la plus difficile à mettre en œuvre, mais elle fournit également une signature avec un certificat WHQL solide émis par Microsoft lui-même, d’une certaine manière le Saint Graal des signatures numériques.

Pour abuser de cette méthode, les attaquants ont besoin :

  • D’un certificat EV valide.
  • D’un accès au portail des développeurs Microsoft.

Si ces exigences sont remplies, ils peuvent préparer un fichier CAB, qui inclut le pilote lui-même, le signer avec le certificat EV et le soumettre au tableau de bord (dashboard).

poortry

Une fois soumis, le pilote subit plusieurs contrôles pour s’assurer qu’il n’est pas malveillant. Si le pilote réussit ces tests, il portera la signature “Microsoft Windows Hardware Compatibility Publisher“.

poortry

L’un des pilotes signés par WHQL lors des attaques de 2022-2023.

Poortry et Stonestop : une menace à prendre en compte depuis 2022

Poortry (parfois aussi appelé BurntCigar) est un pilote de noyau malveillant utilisé en conjonction avec un chargeur nommé Stonestop par Mandiant, qui a été le premier à signaler l’existence de l’outil. Le pilote contourne le mécanisme DSE (Driver Signature Enforcement) en utilisant l’une des trois techniques décrites ci-dessus. Les deux sont fortement obfusqués par des packers commerciaux ou open source, tels que VMProtect, Themida ou ASMGuard.

De fin 2022 à mi-2023, les variantes de Poortry portaient le certificat Microsoft WHQL. Cependant, grâce au travail conjoint de Sophos X-Ops et Microsoft, la plupart de ces échantillons d’attestation signés ont été retrouvés et Microsoft a désactivé les comptes qui ont été abusés pour signer ces pilotes.

Les créateurs de Poortry n’ont pas, pour autant, baissé les bras ; au lieu de cela, ils ont opté soit pour la falsification d’horodatage de signature, soit pour l’obtention d’un certificat valide ayant été divulgué.

Au cours de l’année passée, nous avons pu relier l’utilisation de Poortry à des attaques impliquant au moins cinq grandes familles de ransomware :

  • CUBA
  • BlackCat
  • Medusa
  • LockBit
  • RansomHub

Depuis 2023, nous avons observé que les acteurs malveillants utilisaient à plusieurs reprises Poortry lors d’attaques. Lors de nos précédentes recherches nous avons observé une caractéristique particulière : à savoir que les créateurs de Poortry changeaient fréquemment leur packer, créant ainsi un volume de variantes légèrement modifiées toujours basées sur celle d’origine. Au cours de nos recherches, nous avons trouvé plusieurs variantes différentes signées par WHQL, préparées avec différents packers commerciaux ou non.

Comme cette voie était sans issue pour eux, les créateurs de Poortry déploient désormais des pilotes signés par une grande variété de certificats non-Microsoft.

La figure ci-dessous illustre une chronologie des noms de signataire observés et utilisés par le pilote de charge virale de Poortry sur une période de 15 mois.

poortry

Il convient de mentionner que parfois, nos observations sont réalisées lors d’interventions IR (Incident Response) et, à d’autres moments, elles sont collectées sous forme de télémétrie. Une chose dont nous pouvons être sûrs est que le nombre total et la variété des certificats sont plus importants que ce que nos seules observations peuvent déterminer.

Certificats et jeu de la roulette

Sophos a observé, de temps à autre, un acteur malveillant déployer des variantes de Poortry sur différentes machines au sein d’un même parc lors d’une attaque. Ces variantes contiennent la même charge virale, mais signées avec un certificat différent de celui du pilote vu pour la première fois lors de l’attaque en question. En août 2023, lors d’une investigation Sophos X-Ops, nous avons découvert que les attaquants avaient obtenu un accès initial via un outil d’accès à distance nommé SplashTop. Dès que les attaquants ont été sur le réseau, ils ont déployé Poortry et Stonestop. Mais le nom du signataire, “bopsoft“, était déjà connu comme étant un certificat volé et a donc été bloqué à l’aide d’une règle comportementale.

Dans les 30 secondes qui ont suivi la dernière tentative utilisant le code signé “Bopsoft“, les attaquants ont chargé un autre pilote Poortry, celui-ci signé par “Evangel Technology (HK) Limited“. L’hôte a été rapidement isolé et l’attaque déjouée.

poortry

Passage d’un EDR Killer à un EDR Wiper

En juillet 2024, alors qu’il était impliqué dans un incident où des adversaires tentaient de déployer le ransomware RansomHub, Sophos CryptoGuard a déjoué la tentative de chiffrement des données alors que les analystes fermaient les points d’accès des attaquants. Une analyse post-incident a révélé que deux exécutables supplémentaires avaient été déposés sur plusieurs machines avant l’attaque finale du ransomware :

<d>\Users\<u>\desktop\c7iy3d.exe
<d>\Users\<u>\appdata\local\temp\usnnr.sys

Grâce à une combinaison d’analyses statiques et dynamiques, nous avons déterminé qu’il s’agissait des fichiers Poortry et Stonestop. Parmi les différences que nous avons observées entre la version précédente et cette version, Poortry pouvait désormais également supprimer complètement les composants EDR critiques, au lieu de simplement mettre fin à leurs processus.

Trend Micro a rapporté en 2023 que Poortry avait développé la capacité de supprimer des fichiers du disque, mais c’était la première fois que nous observions cette fonctionnalité utilisée dans une attaque.

Une observation plus approfondie des dernières variantes

L’exécutable Stonestop et le pilote Poortry utilisent tous deux massivement les packers et l’obfuscation. Ce chargeur/loader a été obfusqué par un packer à source fermée nommé ASMGuard, disponible sur Github.

poortry

Les propriétés du pilote PoorTry affichées dans CFF Explorer révèlent que le fichier a été créé en août 2024.

Le piloté est signé avec un certificat portant le nom du signataire “FEI XIAO“. Sophos X-Ops est convaincu que l’horodatage de la signature a été falsifié pour signer le pilote. Il tente notamment de se faire passer pour un pilote (idmtdi.sys) d’un logiciel disponible dans le commerce, Internet Download Manager de Tonec Inc., en utilisant les mêmes informations dans sa feuille de propriétés. Mais il ne s’agit pas du pilote de ce logiciel : les attaquants ont simplement cloné les informations à partir de celui-ci.

poortry

Feuille de propriétés du pilote PoorTry avec des dates de validité antérieures à sa création de plus d’une décennie.

Pour faciliter les explications, nous divisons le flux d’exécution en trois phases distinctes.

Phase d’initialisation

Dans les incidents que nous avons suivis, les acteurs malveillants déposent Poortry et Stonestop ensemble, dans le même répertoire. Lors de l’exécution, Stonestop vérifie le pilote correspondant dans le répertoire courant.

poortry

Message d’erreur affiché lorsque le chargeur/loader ne parvient pas à se connecter au pilote du noyau.

Le nom de fichier et le nom de périphérique du pilote sont tous deux hardcodés dans le chargeur. Au démarrage, le chargeur récupère le handle du pilote de noyau malveillant et lance un établissement de liaison (handshake) en envoyant une chaîne hardcodée au pilote via l’appel API DeviceIoControl.

Dans l’ensemble, la communication entre les composants s’effectue via l’API DeviceIoControl. Chaque fonctionnalité fournie par le composant en mode noyau est déclenchée via l’envoi d’un code IOCTL différent. Les variantes antérieures communiquaient via le handler IRP_MJ_DEVICE_CONTROL. La variante actuelle utilise désormais le handler IRP_MJ_MAXIMUM_FUNCTION pour recevoir les paquets de requête E/S.

Il convient de mentionner que les mappages du code IOCTL avec les diverses fonctionnalités ont changé depuis notre dernière analyse. À titre d’exemple, la commande permettant de tuer un processus spécifique par ID de processus a été déclenchée par l’envoi d’un paquet de requête E/S avec le code 0x222094. Le dernier échantillon mappe le code IOCTL 0x222144 avec la même fonctionnalité.

Depuis le rapport 2023 de Trend Micro, les développeurs de Poortry ont augmenté le nombre de codes IOCTL recevables de 10 à 22. Notre analyse de toutes les fonctionnalités disponibles est toujours en cours.

Comme les versions précédentes, un établissement de liaison (handshake) est initié en envoyant une chaîne hardcodée au pilote. Une fois la valeur du handshake acceptée, elle définit un indicateur (flag) dans le binaire qui active les fonctionnalités du pilote malveillant.

poortry

Valeur du handshake envoyée à Poortry

Phase d’altération

La deuxième phase est axée sur la désactivation des produits EDR via une série de techniques différentes, telles que la suppression ou la modification des routines de notification du noyau.

Les pilotes de sécurité utilisent plusieurs fonctionnalités différentes fournies par le système d’exploitation Windows pour enregistrer des rappels (callbacks) lorsque des événements spécifiques se produisent sur le système Windows. Un exemple serait la fonction PsSetCreateProcessNotifyRoutine, qui ajoute une routine de rappel (callback) fournie par le pilote lorsqu’un nouveau processus est créé.

L’élimination de ces routines de rappel est souvent une étape critique pour rendre les produits EDR inefficaces. En 2022, nous avons également écrit sur un cas similaire où le ransomware BlackByte a abusé d’un pilote vulnérable légitime pour supprimer les routines de notification critiques du noyau.

Dans la deuxième phase, nous avons observé qu’un total de sept codes IOCTL distincts étaient envoyés au composant en mode noyau. Seule la fonctionnalité mappée avec 0x222400 était exécutée. Les autres fonctionnalités ont été abandonnées prématurément en raison d’indicateurs (flags) spécifiques définis dans le binaire. Nous soupçonnons que les fonctionnalités non déclenchées sont soit expérimentales, soit déclenchées uniquement sur des types spécifiques de système, soit simplement désactivées.

Les codes IOCTL et leurs comportements mappés sont les suivants :

0x2220C0 (Désactivé)

Une fois ce code reçu, Poortry entre dans une routine d’initialisation supplémentaire, récupérant les adresses de diverses structures et fonctions critiques.

0x222100 (Désactivé)

Une fois ce code reçu, Poortry tente de désactiver ou d’activer les rappels du noyau via la modification de l’indicateur/flag PspNotifyEnableMask. Il s’agit d’une astuce couramment utilisée par les rootkits pour activer ou désactiver les rappels de routine du noyau, comme expliqué dans cet article.

0x222104 (Désactivé)

Une fois ce code reçu, Poortry modifie les rappels du noyau au niveau des types d’objet suivants :  PsProcess, PsThread et ExDesktopObj. Il s’agit de structures de données en mode noyau qui représentent des objets spécifiques dans le noyau Windows. Explicite en soi, le type d’objet PsProcess représente un objet de processus. Ces types d’objet contiennent également une variable pointant vers les rappels enregistrés pour l’objet correspondant.

Étant donné que cette fonctionnalité a été désactivée, nous ne savons pas comment les adversaires pourraient chercher à modifier ces listes de rappel. Un scénario possible pourrait être de les désactiver complètement en définissant les rappels au niveau d’une fonction personnalisée sans aucune fonctionnalité, en effectuant tout simplement un renvoi instantané.

poortry

Modification des listes de rappel du type d’objet

0x222108 (Désactivé)

Une fois ce code reçu, Poortry modifie la variable CmpCallbackCount pour activer ou désactiver les rappels du noyau du registre. La variable est utilisée pour compter le nombre de rappels enregistrés. Nous pensons que si cette valeur est mise à zéro, les rappels seront alors inefficaces.

0x22210C (Désactivé)

Une fois ce code reçu, Poortry tente de supprimer le pilote fltMgr.sys du périphérique \\FileSystem\\FastFat et \\FileSystem\\Ntfs à l’aide de la fonction DeviceIoDetachDevice. La fonction est généralement utilisée par les pilotes valides pour effectuer le nettoyage lors de l’arrêt. Cependant, les rootkits peuvent utiliser cette fonction pour empêcher les pilotes ciblés de recevoir d’autres requêtes E/S.

fltMgr.sys est le gestionnaire de filtre sous Windows. Ce pilote est utilisé pour étendre ou modifier les capacités des fonctionnalités existantes sur le système Windows. Le pilote est également souvent utilisé par les produits EDR.

Nous soupçonnons qu’en le détachant via l’utilisation de IoDetachDevice, les filtres installés sont rendus inefficaces sur le système ciblé.

0x2221C0 (Désactivé)

Une fois ce code reçu, Poortry entre dans des routines pour récupérer l’adresse des principaux handlers/gestionnaires de fonctions de ClassPnp.sys et ntfs.sys, tels que NtfsFsdClose ou NtfsFsdRead de ntfs.sys. Nous pensons donc que cette routine peut être utilisée comme routine d’initialisation supplémentaire pour récupérer les adresses de fonctions critiques utilisées par d’autres fonctionnalités.

0x222400 (activé)

Une fois ce code reçu, Poortry désactive les rappels du noyau installés via une série de techniques différentes. Le composant en mode utilisateur inclut le nom du pilote ciblé lorsque le paquet de requête E/S est envoyé.

poortry

Présentation des routines de correctif et de la vérification du handshake

Les rappels du noyau installés via PsSetLoadImageNotifyRoutine, PsSetCreateThreadNotifyRoutine et PsSetCreateProcessNotifyRoutine sont corrigés. Dans la phase prologue de la fonction de rappel, Poortry modifie la première instruction pour renvoyer instantanément zéro lors de la saisie.

poortry

Comparaison avant et après la correction de la phase prologue

Jusqu’à présent, nous avons identifié les techniques suivantes pour rendre les rappels du noyau et les pilotes de sécurité inefficaces :

  • Les structures internes utilisées par les fonctions correspondantes PsSetLoadImageNotifyRoutine, PsSetCreateThreadNotifyRoutine et PsSetCreateProcessNotifyRoutine sont itérées. Si le rappel appartient à un pilote de sécurité balisé (tagged), par conséquent, la fonction de rappel enregistrée se ferme immédiatement sans exécuter aucune des opérations prévues.
  • Le noyau Windows implémente des structures de données importantes telles que PsProcess, PsThread et ExDesktopObject qui représentent des éléments fondamentaux du système d’exploitation Windows. Ces structures contiennent une variable nommée CallbackList qui gère toutes les routines de rappel associées à l’objet spécifique. Poortry parcourt cette liste et si le rappel appartient à un pilote de sécurité balisé, par conséquent, la fonction de rappel enregistrée se ferme immédiatement sans exécuter aucune de opérations prévues.
  • Une liste liée interne utilisée par CmRegisterCallback et CmUnregisterCallback est itérée. Cette liste chaînée contient des points de fonction vers des rappels de registre et d’objet enregistrés. Si le rappel appartient à un pilote de sécurité balisé, le prologue de la fonction est corrigé.
  • Poortry utilise la fonction exportée FltEnumerateFilters de fltMgr.sys pour parcourir les filtres appliqués. Si le filtre appartient à un pilote de sécurité balisé, le prologue de la fonction est corrigé.
  • Bien que nous n’ayons pas pu déclencher directement la fonctionnalité, nous avons trouvé des preuves que Poortry pouvait abuser de la fonction IoDetachDevice pour détacher un objet de périphérique de la pile de périphériques d’un système. Contrairement à la fonctionnalité fournie par le code IOCTL 0x22210C, il est moins évasif et détache les appareils uniquement si le nom de l’appareil correspond au nom d’entrée envoyé via DeviceIoControl.

Phase de nettoyage

Après l’altération, l’EDR Killer vise à mettre fin aux processus liés à la sécurité et à rendre l’agent EDR inefficace en effaçant les fichiers critiques du disque.

Tout d’abord, le composant en mode utilisateur envoie plusieurs requêtes E/S avec le code IOCTL 0x222144 au composant en mode noyau, notamment l’ID de processus à tuer.

Le chargeur contient une liste de chemins hardcodés pointant vers l’emplacement où les produits EDR sont installés. Il parcourt tous les sous-dossiers et fichiers du dossier et supprime les fichiers critiques pour l’agent EDR, tels que les fichiers EXE ou les fichiers DLL en envoyant une requête IOCTL au pilote avec le code 0x222180. La demande envoyée inclut le chemin du fichier à supprimer.

Soulignons que le composant en mode utilisateur peut fonctionner selon deux modes :

  • Suppression de fichiers par type.
  • Suppression de fichiers par nom.

Nous soupçonnons que l’auteur ait ajouté ces modes de fonctionnement pour garantir la flexibilité lors du ciblage des différents objectifs. Nous pensons également que la liste des chemins hardcodés et pointant vers les dossiers d’installation des produits EDR change en fonction de la cible.

poortry

Mise en œuvre de la suppression de fichiers par type

En conclusion

Poortry et son chargeur associé Stonestop ont subi une sérieuse amélioration de leurs fonctionnalités au cours des 20 mois qui ont suivi la publication par Sophos et Microsoft d’un rapport conjoint sur l’abus du mécanisme de signature WHQL par cet EDR Killer. Ce qui était autrefois un outil relativement simple pour déconnecter les composants de protection endpoint “problématiques” est devenu, en soi, un couteau suisse avec des capacités malveillantes abusant d’une quantité pratiquement illimitée de certificats de signature de code volés ou utilisés de manière inappropriée afin de contourner les protections en matière de vérification de la signature du pilote.

Les développeurs de Poortry utilisent clairement la caractéristique différenciante de leur outil comme une capacité à faire bien plus que simplement déconnecter un EDR ou un pilote antialtération de protection endpoint. Poortry a évolué vers une sorte de rootkit qui dispose également de contrôles limités sur un certain nombre d’appels API différents utilisés pour contrôler les fonctionnalités de bas niveau du système d’exploitation. Il dispose désormais également de la capacité d’éliminer ses ennemis, à savoir les logiciels de sécurité, directement au niveau du disque afin de libérer la voie au déploiement d’un ransomware.

Sophos X-Ops a publié des indicateurs de compromission (IOC) sur notre GitHub.

Billet inspiré de Attack tool update impairs Windows computers, sur le Blog Sophos.