Manipulation des tokens d'accès

En 2015, à la BlackHat, le chercheur en sécurité informatique James Forshaw présenta un nouveau type d’élévation de privilèges basé sur l’utilisation abusive des tokens d’accès dans un environnement Windows. Un an plus tard, Steve Breen et Chris Mallz ont  développé un premier binaire mettant en place ce type d’attaque : rottenpotato.exe.

Tout au long de cet article nous allons donc voir ce que sont les tokens d’accès et surtout comme on peut les exploiter afin d’élever nos privilèges et passer NT Système !

I/ Qu’est ce qu’un token d’accès

Sur Windows, un token d’accès est un objet (une structure) qui va décrire ce que l’on appelle le contexte de sécurité d’un processus ou d’un thread. Ce contexte de sécurité va permettre au kernel Windows d’autoriser (ou non) l’accès à certaines données ou fonctions de l’API Windows à un processus ou un thread.

Ces tokens d’accès sont générés au moment de l’authentification d’un utilisateur par le système que ce soit localement (via la base SAM) ou à distance (via la base NTDS.dit).

Un token d’accès est composé :

  • du SID du compte de l’utilisateur
  • des SID’s des groupes dans lequel est l’utilisateur
  • d’un identifiant « logon SID » qui identifie la sessions de connexion actuel
  • de la liste des privilèges associés à l’utilisateur ou aux groupes de l’utilisateur

Et d’un tas d’autres données qui ne nous intéresseront par pour le moment mais que vous trouverez dans la documentation officielle de Microsoft.

A chaque fois que l’utilisateur lancera un processus ou un thread, une copie de ce token d’accès sera attribué au dit processus/thread. Le processus/thread lancé héritera donc des mêmes privilèges que l’utilisateur qui l’a lancé.

Par exemple si je liste les privilèges de l’utilisateur « ach » via la commande :

whoami /priv

token1.png

Et que je liste les privilèges d’un processus lancé par ce même utilisateur via Process Explorer :

token2.png

On verra bien que les privilèges sont les mêmes à l’exception du privilège SeChangeNotifyPrivilege qui, lui, est attribué automatiquement à tous les processus.

Il existe deux types de token d’accès : les Primary Token  qui s’appliquent à des processus et les Impersonate Tokens qui s’appliquent à des threads.

L’intérêt des Impersonate Tokens va être de pouvoir impersonifier temporairement un utilisateur afin d’exécuter des commandes avec des droits supplémentaires. Généralement ce sont les comptes de service qui vont utiliser ces Impersonate Tokens mais on y reviendra plus tard  !

Là où ça devient intéressant c’est qu’à partir du moment ou un Impersonate Token est présent dans le kernel, n’importe qui va pouvoir l’utiliser à condition de disposer d’un des deux privilèges suivants : SeAssignPrimaryTokenPrivilege ou SeImpersonatePrivilege .

L’idée ici vous l’avez compris, ça va être de voler l’Impersonate Token d’un administrateur de la machine afin d’interagir avec ses droits. Seulement il peut arriver qu’il n’y ait aucun Impersonate Token pour l’utilisateur NT Système de disponible et c’est là que l’exploit rottenpotato.exe va nous être utile. Mais avant de nous pencher sur son fonctionnement j’ai pensé qu’il serait intéressant d’analyser le fonctionnement du premier exploit de Stepve Breen : potato.exe.

II/ Potato.exe

Potato.exe est un exploit publié par Steve Breen en février 2016 qui n’a rien à voir avec les tokens d’accès dont on a parlé plus tôt. En effet l’exploit repose sur un ensemble de vulnérabilités liées aux protocoles LLMNR et NBT-NS (que j’ai déjà détaillé dans cet article : « Exploiter LLMNR et NBT-NS« ).

Pour rappel, LLMNR et NBT-NS sont deux protocoles utilisés afin de faire de la résolution de nom dans un environnement Active Directory. Ces protocoles sont utilisés si et seulement si la résolution DNS n’aboutit pas.

S’ils permettent d’assurer une résolution de nom en toute circonstances (ce qui est un bon point pour une entreprise) ils sont aussi très dangereux à utiliser puisqu’ils peuvent être manipuler par un attaquant ce qui lui permettra de :

  • Récupérer les hash Net-NTLM d’utilisateurs légitimes et les casser offline ;
  • Lancer une attaque via relai NTLM afin de s’authentifier à la place d’un utilisateur légitime et ainsi usurper son identité ainsi que ses droits ;

En partant de ce principe Potato.exe va mettre en place un faux proxy WPAD et forcer la machine à s’y authentifier en tant que NT System en trickant le service Windows Update pour qu’il émette une requête vers le proxy WPAD. Il en résulte que la machine va envoyer un hash Net-NTLM qui va être relayé par Potato.exe vers le service SMB ce qui va nous permettre d’exécuter des commandes en tant qu’NT System.

Seulement voilà, cet exploit a été patché par Windows avec le correctif MS16-075 et dorénavant il n’est plus possible d’exécuter un relai NTLM depuis le service HTTP vers le service SMB de la même machine. Heureusement pour nous, Steve Breen et Chris Mallz ont développé un second exploit qui contourne le problème : rottenpotato.exe

III/ rottenpotato.exe

Cet exploit, encore une fois, repose sur un relai NTLM.  Cette fois-ci cependant, l’exploit ne va pas relayer une authentification HTTP vers SMB mais va abuser d’un composant essentiel de Windows : COM.

COM (Component Object Model) est un élément qui revient souvent lorsque l’on parle de l’environnement Windows et c’est assez particulier puisqu’il est très peu détaillé sur Internet. Par conséquent je vous invite à lire l’un des rares articles que j’ai trouvé et qui explique correctement ce que c’est :  « Introduction to COM what it is and how to use it« .

Pour les moins motivés d’entre vous voici ce qu’il faut retenir. COM est une méthode permettant de partager du code entre différentes applications et langages. Comme vous le savez peut être, Windows est un système d’exploitation qui repose sur des librairies partagées dynamiquement. Ces librairies ce sont les DLL’s que l’on trouve génralement dans le répertoire :

c:\\Windows\*

Pour éviter d’avoir à réécrire du code, on va pouvoir charger ces librairies afin d’utiliser des fonctions déjà écrites. On gagne ainsi du temps sur le développement du binaire et de la place sur le disque dur. Or ces DLL’s sont écrites soit en C soit en C++. Qu’est ce qui se passe quand un programme en C veut utiliser une DLL écrite en C++ ? Eh bien justement ça devient compliquer. Tout l’intérêt de COM est de répondre à cette problématique en définissant un standard de binaire qui pourra être réutiliser par tous les langages.

La première étape de l’exploit repose sur une manipulation de COM qui va être utilisé afin d’exécuter un relai NTLM localement. Ensuite plusieurs opérations (manipulation d’objets, appel aux fonctions de l’API Windows) vont être effectuées. D’ailleurs si la partie technique vous intéresse je vous invite aussi à lire l’explication détaillée des créateurs de l’exploit : « Rottenpotato privilege escalation from service account to system« .

Tout ce que nous avons besoin de retenir nous, c’est que COM va tenter de s’authentifier (en tant que NT System) vers l’IP 127.0.0.1 sur le port 6666. Rottenpotato, contrôlant le port 6666, n’aura plus qu’à relayer l’authentification afin d’authentifier NT System et ainsi créer un Impersonate Token pour cet utilisateur (vraiment c’est une explication très très simplifiée de l’exploit).

La finalité de cet exploit, c’est que s’il fonctionne, un Impersonate Token représentant l’utilisateur NT System sera présent sur la machine et nous pourrons l’usurper.

IV/ Rottenpotato en live

Imaginons que l’on vient d’upload un webshell sur un serveur IIS :

token3.png

Sur la machine compromise on dispose de powershell, on va donc pouvoir utiliser un Drop&Exec qui nous permettra de récupérer un shell Meterpreter. Pour cela on utilisera le module multi/script/web_delivery :

token4.png

Ce module va tout simplement créer un exécutable en fonction du payload choisi (ici un shell meterpreter en reverse TCP) et mettre en place un serveur web ainsi qu’un handler.

Tout ce que nous aurons à faire c’est copier coller la string qu’il nous donne :

token5.png

Dans l’invite de commande de notre webshell pour qu’une session Meterpreter pop :

token6.png

Ensuite on va vérifier que nous avons les privilèges nécessaires pour manipuler les tokens d’accès (ie : SeAssignPrimaryTokenPrivilege ou SeImpersonatePrivilege). Pour cela on commencera par lancer la commande getuid puis getprivs :

token7.png

Comme prévu nous disposons des privilèges nécessaires puisque nous agissons sous le compte DefaultAppPool qui est un compte de service et, comme je vous l’avais dit, on retrouve généralement ces privilèges sur les comptes de service.

Puis il faudra loader le module Meterpreter incognito (ou utiliser l‘executable incognito) qui va nous permettre de manipuler les tokens déjà présents sur la machine et les lister :

load incognito # Pour charger le module
list_tokens -u # Pour lister les tokens présents

token8.png

Pour le moment aucun token ne nous intéresse. On va donc pouvoir passer à l’exploitation  ! Première étape : uploader l’exploit. Encore une fois c’est très simple lorsque l’on dispose d’un shell meterpreter :

cd %TMP%
upload /path/to/rottenpotato.exe

Il ne nous restera plus qu’à l’exécuter :

execute -fc rottenpotato.exe

Et relancer la commande :

list_tokens -u

Pour voir apparaître le token NT System !

token9.png

Dernière étape, impersonifier le token « AUTORITE NT\System » via la commande suivante :

impersonate_token "AUTORITE NT\Système"

token10.png

Et voilà, nous sommes administrateur local de la machine  !

IV/ JuicyPotato.exe

Comme nous l’avons vu dans la deuxième partie de cet article, rottenpotato va se mettre en écoute sur le port 6666 et relayer une authentification NTLM en abusant de COM. Or si le port ou l’objet COM n’est pas accessible l’exploit échoue. Heureusement pour nous un dernier binaire a été développé : JuiciPotato.exe !

JuicyPotato.exe est une version boostée de l’exploit rottenpotato puisqu’il propose tout un tas d’options permettant de rendre l’exploit quasiment imbloquable.

Avec JuicyPotato on pourra ainsi modifier le port d’écoute local, modifier l’objet COM à requêter (d’ailleurs les créateurs de l’outil ont listé un nombre assez conséquent d’objets que l’on peut manipuler).

Enfin on pourra lancer des processus en ayant le token impersonifié déjà intégré. En bref JuicyPotato est une version très largement améliorée que vous pourrez télécharger ici !