Sur les systèmes Windows, l'injection de DLL dans le service IKEEXT est un sujet qui remonte à la fin de l'année 2012. Il s'agit d'une faiblesse donnant lieu à une élévation de privilèges sous certaines conditions. Introduit sous Vista, ce problème n'a cependant été corrigé qu'à partir de Windows 8.1. Or, les systèmes Windows 7/Server 2008 R2 sont, encore aujourd'hui, largement présents dans les entreprises et force est de constater que son exploitation est toujours aussi simple et efficace.
1. Problématique
Lorsqu’il s’agit d’élever ses privilèges sous Windows, une technique classique consiste à injecter une bibliothèque dynamique (ou DLL) dans un programme s’exécutant avec des droits plus élevés. En théorie, il faut donc qu’un logiciel tiers soit installé sur la machine et qu’il soit vulnérable à ce type d’attaque.
C’est ici que le service IKEEXT intervient. Ce dernier est nativement intégré au système d’exploitation de Microsoft (à partir de NT 6.0) et implémente les protocoles IKE (Internet Key Exchange) et AuthIP (Authenticated internet Protocol). Il assure ainsi l’établissement de sessions VPN au moyen de tunnels IPSec (Internet Protocol Security).
Dans le cadre de cet article, les caractéristiques suivantes nous intéresseront tout particulièrement.
- il est exécuté en tant qu’« AUTORITE NT\Système » ;
- il tente de charger une DLL non présente par défaut ;
- le chemin de recherche de cette DLL n’est pas défini et elle est chargée par son nom uniquement.
Afin de bien comprendre la nature de cette faiblesse du service IKEEXT, il est nécessaire de faire un rappel sur un élément clé du fonctionnement de Windows : le processus de recherche des DLL sur le système.
Si la DLL est chargée simplement par son nom dans le code source de l’application et que le mode SafeDllSearchMode est activé (clé de registre), le système la cherchera dans les répertoires suivants et selon cet ordre [1] :
1. le dossier depuis lequel l’application est lancée ;
2. le dossier système (C:\Windows\System32\ par défaut) ;
3. le dossier système 16 bits (C:\Windows\System\ par défaut) ;
4. le dossier Windows (C:\Windows\ par défaut) ;
5. le dossier courant ;
6. les dossiers listés dans la variable d’environnement PATH (environnement SYSTEM).
Si le mode SafeDllSearchMode est désactivé, l’ordre de recherche des DLL est légèrement différent, mais ne change rien dans le cadre du sujet traité ici. En effet, seul l’ordre des dossiers système est modifié et les chemins renseignés dans le PATH seront quant à eux toujours traités en dernier.
Cela signifie que si nous créons une DLL « malicieuse » et que nous parvenons à la placer dans un de ces répertoires, elle sera alors chargée et exécutée par notre fameux service IKEEXT, dans le contexte de l’utilisateur « AUTORITE NT\Système ». Les cinq premiers répertoires présentent peu d’intérêt, car non accessibles en écriture par défaut à un utilisateur standard. En revanche, la variable d’environnement « PATH » est quant à elle susceptible d’évoluer et pourrait éventuellement contenir un chemin vers un dossier dont nous contrôlons le contenu.
2. Contexte
Les versions suivantes de Windows [2]sont vulnérables :
Version |
Poste de travail |
Serveur |
NT6.0 |
Windows Vista |
Windows Server 2008 |
NT6.1 |
Windows 7 |
Windows Server 2008 R2 |
NT6.2 |
Windows 8 |
Windows Server 2012 |
Cette vulnérabilité a été découverte il y a maintenant plus de 4 ans par le « High-Tech Bridge Security Research Lab » [3]. Plusieurs CVE ont alors été référencées :
- CVE-2012-5377 : ActivePerl 5.16.1.1601 ;
- CVE-2012-5378 : Active Tcl 8.5.12 ;
- CVE-2012-5379 : Active Python 3.2.2.3 ;
- CVE-2012-5380 : Ruby 1.9.3-p194 ;
- CVE-2012-5381 : PHP 5.3.17 ;
- CVE-2012-5382 : Zend Server 5.6.0 SP4 ;
- CVE-2012-5383 : Oracle MySQL 5.5.28.
Suite à cette découverte, la position de Microsoft a été de dire que la vulnérabilité n’était pas inhérente au système d’exploitation, mais était plutôt introduite lors de l’installation de certains logiciels tiers. Ce qui, dans les faits, n’est pas incorrect. Dès lors, aucune CVE concernant les produits de Microsoft n’a été publiée. En revanche, chaque application permettant d’exploiter cette faiblesse devrait théoriquement faire l’objet d’un identifiant unique. On comprendra alors que la liste établie plus haut ne peut être exhaustive.
Et pour cause ! Ce cas se présente quasiment à chaque fois qu’un logiciel s’installe à la racine de la partition système C:\. En effet, à cet endroit, les répertoires nouvellement créés sont automatiquement accessibles en écriture à tous les utilisateurs authentifiés, contrairement à C:\Program Files\ par exemple, où les droits des nouveaux dossiers sont hérités.
L’ampleur et le potentiel de cette faille sont d’autant plus élevés que la présence des systèmes listés dans le tableau précédent est grande. À titre d’exemple, Windows Server 2008 (R2) bénéficie encore d’une utilisation massive, avec une part de marché évaluée à 45% dans le monde au début du second semestre 2016 [4]. Par ailleurs, le passage à Windows 10 est souvent considéré avec frilosité par les administrateurs système. Ainsi, encore aujourd’hui, la probabilité de présence de cette vulnérabilité reste non négligeable. C’est d’ailleurs ce que constatent souvent les ingénieurs de NES lors de tests effectués sur des postes de travail ou en environnements virtualisés par exemple.
Afin d’illustrer ce qui va suivre, nous avons choisi d’utiliser une machine virtuelle sur laquelle est installé le système d’exploitation Windows 7 Pro. Par ailleurs, il est important de noter que le système n’est pas vulnérable dans sa configuration par défaut. L’outil Python 2.7.12 sera donc installé en activant l’option ajoutant le chemin d’installation de Python dans la variable PATH. Deux comptes seront créés : un administrateur « NesAdmin » et un utilisateur standard « Nes ».
3. Détection de la vulnérabilité
Tout d’abord, il est nécessaire d’analyser les actions effectuées par le service IKEEXT lors de son démarrage. Pour cela, l’outil « Process Monitor » de la suite « Sysinternals » [5] a été utilisé. Après avoir lancé manuellement le service, nous obtenons le résultat suivant :
Fig. 1 : Analyse du chargement des DLL par le service IKEEXT.
Nous observons que le service IKEEXT tente de charger une bibliothèque dynamique nommée wlbsctrl.dll. Comme expliqué en introduction, le système la recherche d’abord dans ses dossiers puis il consulte finalement tous ceux listés dans la variable d’environnement « PATH » s’il ne l’a pas trouvée avant. Nous noterons en particulier la présence des chemins C:\Python27\ et C:\Python27\Scripts\.
L’étape suivante consiste à vérifier si au moins l’un de ces dossiers est accessible en écriture à notre utilisateur standard « Nes ». Pour cela, il suffit de tenter de créer un simple fichier texte vide dans l’un de ces répertoires. Dans notre cas, cette action est par exemple possible dans C:\Python27\Scripts. À partir de là, nous savons que le système est vulnérable.
Afin d’automatiser ce processus de détection et de recueillir d’autres informations sur le système, un script PowerShell a été spécialement développé. Voyons ce qu’il nous indique dans le cas de notre machine :
C:\Users\Nes\Desktop>powershell -Exec Bypass -File Invoke-IkeextCheck.ps1
[*] Checking OS version…
[+] The version of Windows is vulnerable
[*] Checking IKEEXT service status…
[+] IKEEXT service is running!
[*] Checking IKEEXT service start mode…
[+] IKEEXT service start mode is set to ‘AUTO’!
[*] Checking folders permissions in system environment PATH…
[+] Access granted: ‘C:\Python27\’
[+] Access granted: ‘C:\Python27\Scripts’
[-] Access denied: ‘C:\Windows\system32’
[-] Access denied: ‘C:\Windows’
[-] Access denied: ‘C:\Windows\System32\Wbem’
[-] Access denied: ‘C:\Windows\System32\WindowsPowerShell\v1.0\’
[+] At least one writable folder has been found!
[*] Checking ‘wlbsctrl.dll’ existence…
[+] ‘wlbsctrl.dll’ was not found in the system folders!
[+] THE MACHINE IS VULNERABLE!!! :)
[*] Store your malicious DLL into one of the above folders and reboot.
L’outil parvient à la même conclusion : la machine est bel et bien vulnérable.
4. Exploitation
Nous entrons à présent dans la phase la plus intéressante : l’exploitation. Celle-ci se déroulera en trois étapes.
1. Créer une DLL malicieuse.
2. Copier la DLL dans le dossier C:\Python27\Scripts\.
3. Redémarrer le service IKEEXT.
Les choix effectués lors de la conception de la DLL dépendent fortement du scénario d’exploitation et du contexte dans lequel on se trouve. Certains choisiront par exemple d’y intégrer un « reverse shell » (notamment grâce à l’outil msfvenom de la suite Metasploit). Ici, nous avons préféré implémenter un code qui soit le plus flexible possible afin de s’adapter à chaque situation sans avoir à recompiler les sources.
Pour ce faire, la charge réelle du code d’exploitation sera déportée dans un script BATCH que l’on nommera arbitrairement payload.bat. Le code de la DLL devra alors réaliser les opérations suivantes :
1. Obtenir de manière dynamique le chemin absolu du répertoire depuis lequel elle a été chargée. La méthode GetModuleFileNameW répond parfaitement à cette problématique.
2. Construire la ligne de commandes cmd.exe /c C:\CHEMIN\VERS\payload.bat.
3. Créer un nouveau processus à partir du résultat obtenu, grâce à la méthode « CreateProcess ».
Une fois le code implémenté, deux points d’attention doivent être vérifiés avant de compiler :
- L’architecture-cible doit être respectée : 32 bits ou 64 bits.
- Le projet doit être compilé de manière statique afin d’assurer la portabilité du code.
Une fois cette étape-clé réalisée, la suite est relativement simple, il faut renommer le fichier DLL ( wlbsctrl.dll) puis le déposer dans l’un des dossiers repérés précédemment. Ici, nous avons choisi le répertoire C:\Python27\Scripts\. Un fichier payload.bat est également créé au même endroit. Ce script BATCH contiendra les commandes nécessaires à la création d’un compte administrateur local que l’on nommera « NesHacker ».
La dernière étape consiste à redémarrer le service IKEEXT. Il essaiera alors à nouveau de charger la bibliothèque dynamique wlbsctrl.dll, mais, cette fois-ci, il trouvera celle que nous avons créée, dans le dossier C:\Python27\Scripts\. Le problème est que ce service ne peut être démarré ou arrêté que par un administrateur. En tant qu’utilisateur standard, la seule solution est donc de redémarrer complètement la machine.
Afin de valider de manière visuelle le fonctionnement du code d’exploitation, nous avons cependant choisi de redémarrer manuellement le service en utilisant le compte « NesAdmin ». Grâce à cette méthode, il est possible d’exécuter « Process Monitor » en parallèle pour analyser son comportement lors de son démarrage.
Cette nouvelle analyse montre que le service parvient à charger notre DLL depuis le répertoire C:\Python27\Scripts\. Un nouveau processus cmd.exe exécutant C:\Python27\Scripts\payload.bat est alors créé.
Finalement, de retour dans la session de l’utilisateur standard, nous pouvons vérifier que l’utilisateur « NesHacker » a effectivement été ajouté et qu’il est présent dans le groupe des administrateurs locaux, preuve que l’attaque a fonctionné.
C:\Users\Nes>net user
comptes d’utilisateurs de \\NESADMIN-PC
----------------------------------------------------------------------------------------------------
Administrateur Invité Nes
NesAdmin NesHacker
La commande s’est terminée correctement.
C:\Users\Nes>net localgroup Administrateurs
Nom alias Administrateurs
Commentaires Les membres du groupe Administrateurs disposent d’un accès complet et illimité à l’ordinateur et au domaine
Membres
----------------------------------------------------------------------------------------------------
Administrateur
NesAdmin
NesHacker
La commande s’est terminée correctement.
L’attaquant dispose désormais d’un compte Administrateur local et contrôle donc complètement la machine.
5. Correctif
Avant de considérer l’un des correctifs qui vont suivre, il est important de rappeler que Microsoft n’a pas reconnu cette faiblesse du service IKEEXT comme étant une vulnérabilité et n’a donc pas déployé de correctif. La firme de Redmond justifie ce point de vue par le fait que, par défaut, le système d’exploitation n’est pas vulnérable. C’est en effet l’installation d’un logiciel tiers avec un défaut de configuration des permissions sur ses dossiers qui rend cette faiblesse exploitable.
Toutefois, nous allons voir que le géant américain n’est pas resté si indifférent que cela face à cette faille potentiellement critique. Pour s’en rendre compte, revenons tout d’abord sur le processus de recherche de la DLL wlbsctrl.dll sous Windows 7 Professionnel. Comme illustré en introduction, la DLL en question est en effet recherchée dans les répertoires système puis dans les dossiers inscrits dans le « PATH ».
Refaisons maintenant cet exercice sous Windows 10 Professionnel et observons ce qu’il se passe :
Fig. 2 : Analyse du chargement des DLL du service IKEEXT sous Windows 10 Pro.
La différence est de taille ! Cette fois-ci, le système se contente de chercher dans le dossier C:\Windows\System32\ alors que le fichier n’y est toujours pas présent manifestement, le résultat étant toujours « NAME NOT FOUND ». Il semblerait donc qu’un correctif ait tout de même été appliqué sur les versions plus récentes du système d’exploitation.
La première solution que nous pourrions envisager serait alors d’effectuer une mise à niveau de l’ensemble du parc de machines vers Windows 10. Toutefois, un tel chantier peut poser de nombreux autres problèmes, voire présenter des risques qui ne sont pas encore maîtrisés à ce jour. On pensera notamment aux problèmes de confidentialité, mis en lumière par de nombreux chercheurs en sécurité, et appuyés au plus haut niveau par la CNIL avec l’annonce de la mise en demeure de Microsoft le 20 juillet dernier [6].
Une solution plus simple et efficace à court ou moyen terme consiste à vérifier les permissions de tous les dossiers inscrits dans la variable d’environnement PATH du système de chaque machine. Cette liste peut être facilement obtenue en accédant à la clé de registre suivante :
\HKEY_LOCAL_MACHINES\SYSTEM\CurrentControlSet\Control\Session Manager\Environnement.
La vérification pourra alors être automatisée grâce à un script PowerShell et les droits d’écriture seront retirés aux utilisateurs le cas échéant.
Bien qu’efficace, cette solution peut poser un autre problème dans certaines situations. Nous avons en effet rencontré plusieurs cas où le fait de retirer les droits d’écriture à l’utilisateur entraîne le dysfonctionnement de l’application concernée. Une solution plus radicale consiste alors à désactiver totalement le service IKEEXT, même si Microsoft recommande le contraire, car cela empêchera l’utilisation du protocole IPSec dans ce contexte. Dans le cas d’utilisateurs nomades, il serait alors nécessaire de vérifier l’éventuelle présence d’effets de bords avec les clients VPN utilisés.
En définitive, si vous utilisez toujours Windows 7 ou Windows Server 2008 R2, méfiez-vous des logiciels tiers qui seront installés. Ils risqueraient de faire tomber l’épée de Damoclès qui pèse toujours sur ces systèmes d’exploitation. Par ailleurs, à chaque fois que nous avons rencontré cette vulnérabilité, il s’agissait d’une application différente, non listée dans les CVE mentionnées précédemment. Cela montre que toute application, même la plus anodine, peut très bien fragiliser l’ensemble du système.
6. Pour aller plus loin…
Dans le cadre d’un test d’intrusion, le scénario d’exploitation décrit plus haut présente un inconvénient de taille : la machine doit être redémarrée. Or l’un des principaux objectifs d’une élévation de privilèges en local sur un serveur Windows est d’extraire les mots de passe grâce à l’excellent outil Mimikatz [7] pour éventuellement obtenir celui d’un administrateur du domaine. Le problème est que, lors du redémarrage, ils sont effacés de la mémoire.
Si le mode de démarrage du service IKEEXT est « automatique », nous ne pourrons pas y faire grand-chose. En revanche, dans sa configuration par défaut sous Windows Server 2008 R2, il est en mode « manuel » et donc non démarré à l’initialisation du système. Par conséquent, si nous parvenons à le déclencher depuis une session déjà ouverte, le code d’exploitation fonctionnera sans que le redémarrage complet du serveur ne soit nécessaire.
Fig. 3 : État du service IKEEXT sous Windows Server 2008 R2.
Il existe en fait une méthode assez simple pour parvenir à cette fin. Rappelons-nous que ce service est utilisé lors de la création de tunnels VPN IPSec. Or nul besoin d’être administrateur local pour établir un tel tunnel. En théorie, nous devrions pouvoir démarrer ce service en créant une simple connexion VPN.
Cette opération s’effectue depuis le « Centre Réseau et partage », en cliquant sur le lien Configurer une nouvelle connexion ou un nouveau réseau et en sélectionnant Connexion à un espace de travail. L’assistant affiche ensuite une fenêtre de configuration du profil. Nous allons simplement renseigner le champ Adresse Internet avec l’adresse IP de l’interface de bouclage : 127.0.0.1.
Fig. 4 : Configuration du profil VPN.
Dans la dernière fenêtre, nous rentrons un nom d’utilisateur et un mot de passe quelconques puis nous cliquons sur le bouton Se connecter. Windows va alors tenter d’initier la connexion, mais comme il n’y a aucun serveur VPN en écoute sur la machine, l’opération va bien évidemment échouer.
Après consultation de la console services.msc, nous observons que l’état du service IKEEXT est désormais « Démarré ». Cette technique a donc permis de le déclencher. Nous pouvons également observer une deuxième chose : le « Type de démarrage » est passé de « Manuel » à « Automatique ». Autrement dit, à partir de maintenant, il ne pourra être à nouveau exploité qu’en redémarrant complètement la machine.
Bien qu’efficace, cette méthode nécessite d’avoir un accès à l’interface graphique de la machine (grâce à une session « Terminal Services » par exemple). Or ce n’est pas toujours le cas, en particulier lors d’un test d’intrusion où l’on aurait obtenu un « reverse shell » par exemple. Nous allons voir que la même opération peut en fait être effectuée entièrement à partir d’une « invite de commandes ».
Les deux commandes suivantes permettent de constater que le service est arrêté (« STATE : 1 STOPPED ») et en mode de démarrage manuel (« START_TYPE : 3 DEMAND_START »).
C:\Users\Nes>sc qc ikeext
[SC] QueryServiceConfig réussite(s)
SERVICE_NAME: ikeext
TYPE : 20 WIN32_SHARE_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Windows\system32\svchost.exe -k netsvcs
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Module de génération de clés IKE et AuthIP
DEPENDENCIES : BFE
SERVICE_START_NAME : LocalSystem
C:\Users\Nes>sc query ikeext
SERVICE_NAME : ikeext
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 1 STOPPED
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
La suite est similaire à ce qui a été décrit précédemment. Nous devons en effet créer un profil de connexion, mais cette fois-ci, il prendra la forme d’un fichier texte, que l’on nommera rasphone.pbk.
C:\Users\Nes>echo [IKEEXTPOC]^
Plus ?
Plus ? MEDIA=rastapi^
Plus ?
Plus ? Port=VPN2-0^
Plus ?
Plus ? Device=Wan Miniport (IKEv2)^
Plus ?
Plus ? DEVICE=vpn^
Plus ?
Plus ? PhoneNumber=127.0.0.1 > rasphone.pbk
C:\Users\Nes>type rasphone.pbk
[IKEEXTPOC]
MEDIA=rastapi
Port=VPN2-0
Device=Wan Miniport (IKEv2)
DEVICE=vpn
PhoneNumber=127.0.0.1
Une fois le profil de connexion créé, il ne reste plus qu’à l’utiliser à partir de l’outil « rasdial » en spécifiant son chemin avec l’option /PHONEBOOK.
C:\Users\Nes>rasdial IKEEXTPOC test test /PHONEBOOK:c:\Users\Nes\rasphone.pbk
Connexion à IKEEXTPOC en cours…
Vérification du nom d’utilisateur et du mot de passe…
Connexion en cours à IKEEXTPOC…
Connexion en cours à IKEEXTPOC…
Connexion en cours à IKEEXTPOC…
Erreur d’Accès distant 800 – La connexion à distance n’a pas été établie car les tunnels VPN essayés ont échoué. Le serveur VPN est peut-être inaccessible. Si cette connexion tente d’utiliser un tunnel L2TP/IPSec, les paramètres de sécurité requis pour cette négociation sont peut-être incorrectement configurés.
Pour plus d’information sur cette erreur :
Entrez la commande ‘hh netcfg.chm’
Dans l’aide, cliquez sur Dépannage, puis sur Messages d’erreur, puis sur 800
Grâce à cette ligne de commandes, le système va tenter d’établir une connexion VPN à partir des paramètres fournis dans le fichier rasphone.bpk. Nous obtiendrons alors la même erreur que précédemment, mais le service IKEEXT aura bien démarré, ce qui était notre objectif.
C:\Users\Nes>sc qc ikeext
[SC] QueryServiceConfig réussite(s)
SERVICE_NAME : ikeext
TYPE : 20 WIN32_SHARE_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Windows\system32\svchost.exe -k netsvcs
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Module de génération de clés IKE et AuthIP
DEPENDENCIES : BFE
SERVICE_START_NAME : LocalSystem
C:\Users\Nes>sc query ikeext
SERVICE_NAME : ikeext
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
Pour terminer, peu importe la méthode retenue puisqu’au final elles permettent toutes deux d’exécuter l’attaque sans passer par un redémarrage et donc de conserver l’état de la mémoire vive de la machine. Il ne reste alors plus qu’à récolter les mots de passe sur la machine fraîchement compromise.
Références
[1] Dynamic-Link Library Search Order : https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx
[2] Microsoft Operating System Versions : https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms724832(v=vs.85).aspx
[3] High-Tech Bridge Security Research Lab, Privilege Escalation Vulnerability in Microsoft Windows : https://www.htbridge.com/advisory/HTB23108
[4] Spiceworks : au moins une entreprise sur deux dans le monde utilise encore Windows Server 2003 : http://www.developpez.com/actu/101333/Spiceworks-au-moins-une-entreprise-sur-deux-dans-le-monde-utilise-encore-Windows-Server-2003-quels-systemes-serveur-utilisez-vous-en-entreprise/
[5] Suite d’outils « Sysinternals » : https://technet.microsoft.com/fr-fr/sysinternals/bb842062
[6] Windows 10 : la CNIL met publiquement en demeure MICROSOFT CORPORATION de se conformer, dans un délai de trois mois, à la loi Informatique et Libertés : https://www.cnil.fr/fr/windows-10-la-cnil-met-publiquement-en-demeure-microsoft-corporation-de-se-conformer-dans-un-delai
[7] Blog de Gentil Kiwi : http://blog.gentilkiwi.com/mimikatz