Couper le son : enchaîner les vulnérabilités pour obtenir une RCE sur Outlook : partie 1
Synthèse
Le chercheur d'Akamai Ben Barnea a découvert deux vulnérabilités dans Microsoft Windows auxquelles ont été attribués les codes CVE-2023-35384 et CVE-2023-36710.
Un attaquant sur Internet peut enchaîner les vulnérabilités pour créer un exploit d'exécution de code à distance (RCE) complet et Zero Click contre les clients Outlook.
La première vulnérabilité réside dans l'analyse d'un chemin par la fonction MapUrlToZone . L'exploitation de cette vulnérabilité nécessite l'envoi d'un e-mail élaboré à un client Outlook, qui téléchargera à son tour un fichier son spécial à partir d'un serveur contrôlé par l'attaquant.
La seconde vulnérabilité réside dans le gestionnaire de compression audio (ACM). Cette vulnérabilité est exploitée lorsque le fichier audio téléchargé est lu automatiquement et peut conduire à l'exécution de code sur la machine victime. Cette vulnérabilité est décrite en détail dans la seconde partie de cet article de blog.
Ces vulnérabilités ont été révélées de manière responsable à Microsoft et corrigées à l'occasion du Patch Tuesday d'août 2023 et d'octobre 2023.
Les machines Windows sur lesquelles la mise à jour logicielle d'octobre 2023 est installée sont protégées contre ces vulnérabilités. En outre, les clients Outlook qui utilisent des serveurs Exchange corrigés avec la mise à jour logicielle de mars 2023 sont protégés contre la fonctionnalité exploitée.
Présentation
Parmi les vulnérabilités corrigées dans le cadre du Patch Tuesday de mars 2023 figurait une vulnérabilité critique dans Outlook, à laquelle a été attribué le code CVE-2023-23397, qui a été exploitée dans la nature par Forest Blizzard, que Microsoft a identifié comme un acteur malveillant parrainé par l'État russe. En décembre 2023, Microsoft et le Polish Cyber Command (DKWOC) ont publié une déclaration dans laquelle ils affirment avoir constaté de récentes tentatives d'exploitation de la vulnérabilité par le même acteur malveillant. Cette vulnérabilité permettait à un attaquant de forcer un client Outlook à se connecter au serveur de l'attaquant. Dans le cadre de cette connexion, le client envoie ses informations d'identification NTLM à l'attaquant, qui peut ensuite les déchiffrer hors ligne ou les utiliser dans le cadre d'une attaque par relais. Cette vulnérabilité peut être exploitée à distance via Internet sans aucune action de la part de l'utilisateur (attaque de type Zero Click).
Après la publication du correctif pour cette vulnérabilité, nous avons trouvé un contournement que nous avons décrit dans un précédent billet de blog,. Ce contournement a été corrigé dans le Patch Tuesday de mai 2023. Dans cette publication, nous avons recommandé à Microsoft de supprimer cette fonctionnalité exploitée, car elle introduit une surface d'attaque vaste et complexe. Puisque la fonctionnalité reste dans Outlook, nous avons décidé de l'étudier plus en détail.
Finalement, nous avons pu réaliser une chaîne de vulnérabilité RCE complète sur Outlook. Nous avons trouvé un autre contournement de la vulnérabilité originale d'Outlook. Celui-ci nous a permis une fois de plus de contraindre le client à se connecter à un serveur contrôlé par l'attaquant et à télécharger un fichier son malveillant. Ensuite, nous avons réussi à trouver une vulnérabilité dans la bibliothèque d'analyse multimédia de Windows qui est utilisée pour traiter et lire n'importe quel fichier audio en général et les sons de notification d'Outlook en particulier. Un attaquant enchaînant ces vulnérabilités peut réaliser une RCE Zero Click sur les clients Outlook vulnérables.
Cette série de billets de blog en deux parties présentera les recherches que nous avons menées pour trouver ces deux vulnérabilités. Cette première partie se concentre sur le contournement précédent et sur un nouveau contournement. Dans la seconde partienous décrirons la vulnérabilité d'analyse des médias que nous avons trouvée.
Vulnérabilité d'origine
La vulnérabilité Outlook corrigée en mars est déclenchée lorsqu'un attaquant envoie un e-mail contenant un rappel avec un son de notification personnalisé. Ce son personnalisé est spécifié par l'attaquant comme un chemin, à l'aide de la propriété MAPI PidLidReminderFileParameter. Un attaquant peut spécifier un chemin UNC qui pourrait amener le client à récupérer le fichier son à partir de n'importe quel serveur SMB. Dans le cadre de la connexion au serveur SMB distant, le hachage Net-NTLMv2 est envoyé dans un message de négociation (Figure 1).
Pour résoudre le problème, le code invoque la fonction MapUrlToZone pour classer le chemin comme intranet, local ou Internet. Si l'URL pointe vers une ressource sur Internet, le son de rappel par défaut est utilisé à la place du son personnalisé.
Trouver un contournement
Une fois les mesures d'atténuation mises en place, nous nous sommes demandé s'il était possible de les contourner.
Dans ce contexte, un contournement signifie un chemin qui passera le test de localité et sera utilisé par Outlook pour télécharger le fichier son à partir d'un emplacement distant. En d'autres termes, nous devons trouver un chemin que MapUrlToZone, considérerait comme non-Internet, mais que CreateFile traiterait comme un domaine Internet.
Pour trouver un tel contournement, nous avons dû comprendre parfaitement le fonctionnement interne des fonctions et les opérations effectuées dans le cadre de l'analyse du chemin.
Chemins et URL Windows
Il existe de nombreux types de chemins DOS dans Windows, et de nombreuses recherches ont été menées sur ces chemins et leur conversion en chemins NT. Nous ne couvrirons pas ici les différents types de chemins Windows ; l'article de James Forshaw sur son blog couvre ce sujet de manière exhaustive.
Revenons aux fonctions qui nous intéressent. CreateFile reçoit un chemin Windows ; MapUrlToZone, (comme indiqué par son nom) peut recevoir soit une URL, soit un chemin. Pour trouver un contournement, nous devons d'abord comprendre quels types de chemins sont pris en charge par chaque fonction (ou par les deux).
Remarque: CreateFile et MapUrlToZone, ne traitent pas eux-mêmes les chemins, mais utilisent d'autres fonctions WinAPI à cette fin. Par souci de brièveté, nous utiliserons CreateFile et MapUrlToZone, pour faire référence à leurs fonctions sous-jacentes d'analyse des chemins.
CreateFile |
MapUrlToZone, |
|
---|---|---|
RtlPathTypeUncAbsolute |
✔ |
✔ |
RtlPathTypeDriveAbsolute |
✔ |
✔ |
RtlPathTypeDriveRelative |
✔ |
✔ |
RtlPathTypeRooted |
✔ |
✘ |
RtlPathTypeRelative |
✔ |
✘ |
RtlPathTypeLocalDevice |
✔ |
✔ |
RtlPathTypeRootLocalDevice |
✔ |
✘ |
Schémas (file://, http://) |
✘ |
✔ |
Tableau 1 : Tableau comparatif des fonctionnalités de chemin de CreateFile et MapUrlToZone,
Comme le montre le tableau 1, seuls quatre types de chemins sont pris en charge par les deux fonctions : RtlPathTypeUncAbsolute, RtlPathTypeDriveAbsolute, RtlPathTypeDriveRelative et RtlPathTypeLocalDevice.
Première tentative
La première tentative de recherche d'un contournement a été effectuée avec un chemin UNC absolu (RtlPathTypeUncAbsolute). La figure 2 détaille la structure du chemin.
Comment Windows sait-il où commence le composant du chemin ? Le tableau 2 indique le code correspondant (RtlGetFullPathName_Ustr).
case RtlPathTypeUncAbsolute:
SeperatorsFound = 0;
for ( CurrentIndex = 2; CurrentIndex < InputPathLength; ++CurrentIndex )
{
CurrentChar = InputPathString->Buffer[CurrentIndex];
if ( CurrentChar == '\\' || CurrentChar == '/' )
{
SeperatorsFound++;
if ( SeperatorsFound == 2 )
break;
}
}
Tableau 2 : RtlGetFullPathName_Ustr Extrait de code qui gère le chemin UNC
Nous pouvons voir que le code ne tient pas compte du préfixe UNC absolu ("\\"), puis suppose que le composant du chemin commence un caractère après le deuxième séparateur de chemin ("\" ou "/").
Mais que se passe-t-il si nous fournissons un chemin tel que "\\\\localhost\..\Akamai.com\dir\file.txt" ?
Le chemin sera traité comme suit :
"\\\\" est interprété comme le préfixe UNC et le composant du chemin racine
Le composant de chemin est "localhost\..\Akamai.com\dir\file.txt"
Normalement, aucun nombre de ".." ne peut dépasser le chemin racine. Par exemple, "\Nlocalhost\Ndirectory\N..\Nfile.txt" donnera "\Nlocalhost\Ndirectory\Nfile.txt". Cependant, comme dans notre exemple le ".." ne fait pas partie du chemin racine, le chemin est converti en "\\\Akamai.com\dir\file.txt".
Cela signifie que nous avons trouvé un moyen d'altérer le chemin en en supprimant des parties.
C'est comme ça que CreateFile traite ce chemin. Comment MapUrlToZone, le traite-t-il (Tableau 3) ? Il supprime d'abord les barres obliques inverses supplémentaires et interprète donc le chemin d'une manière différente :
\\localhost est le nom du serveur
\..\ est ignoré (car nous ne pouvons pas aller au-delà du nom du serveur)
Akamai.com \dir\file.txt comprend le composant du chemin
Chemin d'entrée : \\\\localhost\..\akamai.com/fr\dir\file.txt |
|
---|---|
CreateFile |
MapUrlToZone, |
\\\Akamai.com\dir\file.txt |
\\localhost\Akamai.com\dir\file.txt |
Tableau 3 : Chemins d'entrée pour CreateFile et MapUrlToZone, et le résultat de leur analyse
MapUrlToZone, renvoie 0 (local) pour le chemin de sortie vu ci-dessus.
Bien qu'il semble que nous ayons trouvé une solution de contournement, le chemin ne peut malheureusement pas être utilisé pour déclencher une requête UNC. Remarquez la barre oblique supplémentaire au début du chemin traité par CreateFile – elle marque le nom du serveur comme étant vide. Lorsque le fournisseur multiple UNC (MUP) demande aux différents fournisseurs de réseau s'ils peuvent traiter ce nom de serveur (vide), ils renvoient tous false, aucune demande n'est donc faite.
Utiliser de manière abusive la différence entre la façon dont MapUrlToZone, et CreateFile gèrent ce chemin peut nécessiter une solution plus compliquée, par exemple, trouver un moyen d'omettre la barre oblique inverse supplémentaire, ou trouver une erreur d'analyse dans le code MUP. Il s'agit d'une suggestion pour de futures recherches.
Deuxième tentative : contournement nº 1 (CVE-2023-29324)
Comme jouer avec des chemins UNC absolus n'a pas vraiment fonctionné, nous avons continué avec le type de chemin suivant qui prend en charge UNC – RtlPathTypeLocalDevice. "\\.\UNC\Akamai.com\test.wav" est un exemple de chemin à un terminal local. Plus précisément, il pointe vers le nom du terminal UNC, qui sera redirigé vers le pilote MUP.
Comme nous l'avons dit précédemment, pour trouver un contournement, nous devons examiner les différentes opérations effectuées dans le cadre de l'analyse des chemins. Le tableau 4 montre cette différence.
CreateFile |
MapUrlToZone, |
---|---|
Si RtlPathTypeLocalDevice → avance de 4 caractères |
Si RtlPathTypeLocalDevice → avance de 4 caractères |
Ignorer les espaces de fin |
|
Convertir '/' en '\' |
|
Réduire la répétition '\' |
|
Supprimer les composants "." et ".." |
Supprimer les composants "." et ".." |
Tableau 4 : Différentes opérations effectuées dans le cadre de l'analyse des chemins
Nous pouvons voir que CreateFile effectue des opérations supplémentaires, telles que la conversion des barres obliques en barres obliques inverses et la réduction des barres obliques inverses répétées.
Jetons un coup d'œil à un chemin qui tire parti de l'une de ces différences (en utilisant un séparateur de chemin supplémentaire). Le tableau 5 montre les chemins résultants après que le code a ignoré le préfixe "UNC\".
Chemin d'entrée : \\.\UNC\\Akamai.com\test.wav |
|
---|---|
CreateFile |
MapUrlToZone, |
Akamai.com\test.wav |
\Akamai.com\test.wav |
Tableau 5 : Chemins après avoir ignoré le préfixe UNC/
Remarquez le chemin dans la colonne de droite. Un chemin qui commence par un séparateur de chemin suivi d'un caractère qui n'est pas un séparateur de chemin s'appelle un chemin enraciné. MapUrlToZone, utilise les fonctions IsRootedPath ou IsDrivePath pour déterminer si le composant du chemin racine est local. Dans notre cas, le chemin est enraciné et donc MapUrlToZone, renvoie local.
CreateFile n'a pas le séparateur de chemin supplémentaire après le préfixe UNC, il sait donc extraire le nom de domaine correctement et accède maintenant au serveur SMB d'Akamai.com pour récupérer le fichier test.wav. Nous avons trouvé un chemin que MapUrlToZone, considère local, mais que CreateFile ne considère pas comme local. Ce contournement a rendu possible l'exploitation de la vulnérabilité d'Outlook. CVE-2023-23397.
Pour atténuer ce problème, Microsoft a tenté de rendre les deux flux plus similaires ; les opérations de conversion des barres obliques en barres obliques inverses et de réduction des séparateurs de chemin répétés ont été ajoutées au flux d'analyse du chemin MapUrlToZone, .
Petite réflexion…
Dans la section précédente, nous avons noté que MapUrlToZone, vérifie si le composant du chemin qui suit "\\.\UNC\" est un lecteur ou un chemin racine. Nous ne pouvons pas faire de ce composant de chemin un chemin enraciné après la correction parce que les séparateurs de chemin répétés sont réduits. Cependant, nous pouvons toujours fournir un chemin de lecteur ; par exemple, "\\.\UNC\C:Akamai.com/test.wav".
Ce faisant, MapUrlToZone, renvoie 0. Malheureusement, aucun fournisseur de réseau n'est capable de gérer un chemin contenant deux points, et cette confusion n'est donc pas utile pour nous. Comme pour notre première tentative (ratée), trouver une confusion avec le code d'analyse MUP peut mener à une nouvelle vulnérabilité.
Troisième tentative : contournement n° 2 (CVE-2023-35384)
Après la correction, les opérations effectuées par les deux fonctions sont presque les mêmes (Tableau 6).
CreateFile |
MapUrlToZone, |
---|---|
Si RtlPathTypeLocalDevice → avance de 4 caractères |
Si RtlPathTypeLocalDevice → avance de 4 caractères |
Ignorer les espaces de fin |
|
Convertir '/' en '\' |
Convertir '/' en '\' |
Réduire la répétition '\' |
Réduire la répétition '\' |
Supprimer les composants "." et ".." |
Supprimer les composants "." et ".." |
Tableau 6 : Opérations effectuées par CreateFile et MapUrlToZone, suffixe
Cependant, si nous allons plus loin dans le détail, nous pouvons nous poser la question suivante : Comment chaque fonction décide-t-elle que le chemin est un chemin de terminal local ? Le tableau 7 présente des extraits de code de chaque fonction qui aident à déterminer le type de chemin.
CreateFile
if (IS_PATH_SEPARATOR(Path[0]) &&
IS_PATH_SEPARATOR(Path[1]) &&
(Path[2] == '.' || Path[2] == '?') &&
IS_PATH_SEPERATOR(Path[3])
return RtlPathTypeLocalDevice;
MapUrlToZone,
!strncmp(path, "\\.\", 4) || !strncmp(path, "\\?\", 4)
Tableau 7 : Extraits de code qui déterminent le type de chemin
Avec CreateFilele séparateur de chemin peut être une barre oblique ou une barre oblique inverse ; par exemple, "\\./" est considéré comme un chemin de terminal local. Avec MapUrlToZone,seuls les chemins exacts "\\.\" ou "\\?\" sont considérés comme des chemins de terminal locaux. Il s'agit d'une confusion de type de chemin : nous pouvons faire en sorte que CreateFile reconnaisse le composant "\\N./" comme un chemin de terminal local alors que MapUrlToZone, ne le fera pas. Cette confusion implique une gestion différente du chemin par les deux fonctions.
Dans cette optique, utilisons un chemin qui contient le composant à l'origine de la confusion : \\./UNC/Akamai.com/file.wav.
Lors de l'analyse de la prise de décision pour le type de chemin, il s'agit du flux MapUrlToZone, :
Le chemin est-il un lecteur local ou un chemin enraciné ? Non
IsLocalDeviceUNC ? Non
PathIsUNCW ? Oui
PathIsUNCW renvoie true, et donc la fonction le marque comme un chemin UNC absolu et avance deux caractères pour ignorer le préfixe UNC "\\". Les sorties de chaque fonction sont présentées dans le tableau 8.
Chemin d'entrée : \\./UNC/Akamai.com/file.wav |
|
---|---|
CreateFile |
MapUrlToZone, |
UNC\Akamai.com\file.wav |
./UNC/Akamai.com/file.wav |
Tableau 8 : Sorties de chemins pour les fonctions CreateFile et MapUrlToZone,
À ce stade, CreateFile conclut que son résultat est un chemin UNC et que Akamai.com est le nom d'hôte.
À l'inverse, MapUrlToZone, conclut les informations suivantes :
Modèle : file://
Host : . (point)
Chemin d'accès : /UNC/Akamai.com/file.wav
URI absolu : file://./UNC/Akamai.com/file.wav
Il s'avère que lorsque l'URI absolu commence par "file://./" (l'hôte étant "."), le code interprète le nom de fichier comme faisant partie de l'espace de noms des terminaux DOS (Figure 3). Ainsi, "file://./UNC/" fait référence à l'espace de noms UNC.
Pour clarifier, les deux fonctions considèrent notre chemin d'entrée comme un chemin UNC, mais d'un type différent : CreateFile le traite comme un chemin de terminal local Windows, tandis que MapUrlToZone, le voit comme une URL.
À ce stade, nous pouvons déclencher une confusion entre les deux fonctions. Malheureusement, si nous n'intervenons pas, MapUrlToZone, interprétera toujours Akamai.com comme nom d'hôte, et comme ce nom d'hôte est un domaine Internet, la fonction renverra 3, et il ne s'agit donc pas d'un contournement. Nous devons trouver un autre moyen de tirer parti du processus d'analyse.
Plus tard, MapUrlToZone, utilise une fonction interne nommée SetPath pour agir sur le composant du chemin (tableau 9).
CreateFile |
SetPath |
---|---|
Si RtlPathTypeLocalDevice → avance de 4 caractères |
|
Ignorer les espaces de fin |
|
Convertir '/' en '\' |
|
Réduire la répétition '\' |
|
Supprimer les composants "." et ".." |
Supprimer les composants "." et ".." |
Tableau 9 : Comparaison des opérations réalisées entre CreateFile et SetPath
Une fois de plus, nous pouvons tirer parti de la différence entre les opérations effectuées par les deux fonctions. Nous savons, grâce à notre précédente vulnérabilité, que l'ajout d'une barre oblique supplémentaire peut mener à un contournement, il est donc logique d'essayer de nouveau. CreateFile supprime simplement la barre oblique supplémentaire.
Avec MapUrlToZone, CreateUri renvoie l'URI absolu "file://./UNC//Akamai.com/file.wav". Cet URI est transmis à GetZoneFromUriInternal, ce qui conduit en interne à un autre appel CreateUri.
Et pourquoi est-ce un problème ? Puisque CreateUri a reçu une URL, il la convertit à nouveau en chemin Windows à l'aide de PathCreateFromUrlW. Le chemin Windows renvoyé est "\\.\UNC\\Akamai.com\test.wav". La version corrigée sait maintenant supprimer la barre oblique supplémentaire et comprend donc correctement que le nom d'hôte est Akamai.com.
Cela signifie que nous avons besoin d'une exploitation plus compliquée de la différence entre CreateFile et SetPath. Cette fois, nous allons exploiter deux différences :
CreateFile réduit les séparateurs de chemins répétés.
CreateFile supprime les composants "." et ".." après la réduction des séparateurs de chemins répétés.
Un chemin qui exploite les deux différences est \\./UNC/C://../Akamai.com/file.wav. Son traitement est détaillé dans le diagramme de la figure 4.
Figure 4 : Diagramme du chemin analysé par les deux fonctions
Nous savons déjà que le chemin final de CreateFileva être traité comme un chemin UNC. Quant à la sortie de SetPath, MapUrlToZone, va appeler GetZoneFromUriInternal avec l'URI absolu file://./UNC/C:/Akamai.com/file.wav. Cette fois PathCreateFromUrlW convertit cette URL en chemin Windows "\\.\UNC\C:\Akamai.com\file.wav". Il s'agit d'un chemin local, et donc MapUrlToZone, renvoie 0 (local). Nous avons encore une fois trouvé un contournement intéressant !
Pour résoudre le problème, le code invoque la fonction NormalizeDosDevicePrefix pour convertir les barres obliques en barres obliques inverses, évitant ainsi toute confusion dans la détection d'un chemin de terminal local.
Détection et prévention
Microsoft a publié des conseils complets sur la détection et l'atténuation de la vulnérabilité Outlook d'origine. D'après nos observations, toutes les méthodes spécifiées s'appliquent à la nouvelle vulnérabilité, car elles ne dépendent pas de l'URL spécifiée dans la propriété PidLidReminderFileParameter .
Nous recommandons aux organisations d'utiliser la microsegmentation pour bloquer les connexions SMB sortantes vers des adresses IP publiques distantes. En outre, nous vous recommandons de désactiver NTLM dans votre environnement ou d'ajouter des utilisateurs au groupe d'utilisateurs protégés,qui empêche l'utilisation de NTLM comme mécanisme d'authentification.
Le blocage des connexions SMB sortantes et la désactivation de NTLM peuvent contribuer à prévenir le vol d'informations d'identification. Cependant, lorsque les requêtes SMB échouent, Windows passe à WebDAV s'il est activé. Le vol d'informations d'identification ne peut pas être exploité via WebDAV, mais le téléchargement du fichier son reste possible, ce qui constitue la deuxième étape de notre chaîne RCE.
Pourquoi s'arrêter maintenant ?
Dans ce billet, nous avons détaillé le processus de recherche qui a mené à la découverte des deux contournements, y compris leur analyse des causes profondes. Comme nous l'avons montré, le code d'analyse des chemins de Windows est complexe et peut souvent mener à des vulnérabilités. Les chercheurs en sécurité qui rencontrent un code de traitement des chemins sont encouragés à réfléchir à la surface d'attaque qu'il présente.
Outre le contournement de MapUrlToZone, dans le contexte d'Outlook, nous ne pouvons pas exclure la possibilité que ces vulnérabilités puissent également mener à l'utilisation de contournements Mark-of-the-Web (MotW).
Outre la possibilité de divulguer les informations d'identification NTLM, nous avons également la possibilité de télécharger et de lire un fichier son arbitraire. Vous pouvez maintenant lire La partie 2 de cette série de blogs,qui détaille la vulnérabilité d'analyse sonore.