HTB - TombWatcher

Description


Assume breach: starting with a low‑privileged domain user, the attacker discovers they can write an SPN to a peer account and crack the resulting service ticket. Those new credentials let them self‑add to an “Infrastructure”‑level group that exposes plaintext gMSA passwords. With the gMSA password, they change the password of a server account that owns another privileged identity, then seize that identity and pivot to the domain controller over WinRM. Holding full control rights on AD CS and permission to resurrect tombstoned objects, they restore a dormant certificate‑administration account and exploit AD CS ESC15 to mint a certificate for Domain Admins—securing complete control of the forest.

Enumeration


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

Before I began, I exported IP, Username, Password, and Domain to variables for easy usage

Then, I started with normal Nmap Scan to find all open ports

Nmap Scan

Exported all open ports to a variable and ran the script and version detection scans

Summary

I always update /etc/hosts before I attack the domain to avoid any tooling issues

With valid domain credentials, I started with an enumeration of SMB, looking for accessible shares, but only found the default ones

The webpage at http://10.10.11.72/ is the default IIS page with nothing to do with it

With nothing to do with HTTP & SMBI moved to enumerate the domain looking for escalation paths, so I fired bloodhound.py for automated enumeration and powerview.py for manual enumeration

Note: PowerView can get escalation paths that bloodhound can't

First, you need to install PowerView with pip3 Inside the Python virtual environment

Start PowerView.py with GUI dashboard

From the dashboard, I could get useful information and find that CA is installed on the domain

Alternatively, I used netexec to find the CA

From bloodhound-GUII saw that Henry can add a Service Principal Name (SPN) to Alfred user, so I could perform targetedkerberoast attack by requesting the service ticket for him and cracking it offline to get the password. Alfred can then add himself to infrastructure group

Infrastructure group can read the GMSA password of ansible_E_DEV$

ansible_e_dev$ Can change the password for SAM user, then sam Can write Ownership on john user who can access the machine via winRM

The same privileges can be shown with PowerView

WriteSPN & AddSelf

WriteOwner

ForceChangePassword

The tool failed to get ReadGMSAPassword from infrastructure group, however, it shows additional privileges of john user that bloodhound didn't show

Bloodhound:

PowerView:

User John can Reanimate-Tombstones which means he is able to restore deleted AD Objects from AD Recycle bin and this shows the powerful of manual enumeration and not rely completely in automated tools

  • To summarize the attack path:

    1. Henry -> WriteSPN -> Alfred

    2. Alfred -> AddSelf -> Infrastructure

    3. Infrastructure -> ReadGMSAPassword -> ansible_e_dev$

    4. ansible_e_dev$ -> ChangePassword -> SAM

    5. SAM -> WriteOwner -> John

    6. John -> winRM/FullControl (ADCS)/Reanimate-Tombstones -> DC01

Foothold


I will show how to perform the attack path using bloodyAD. PowerView.py can do the same job, too.

With bloodyAD

WriteSPN

Crack the hash

AddSelf

Read GMSA Password

Force Change Password

WriteOwner

After gaining ownership of a user, I can grant myself FullControl on him.

Then, change the password for him or perform a shadow credentials attack:

I prefer to perform shadow credentials attack as it follows OPSEC consideration

Change Password

shadow credentials


With PowerView

Access the box via winRM

User Flag: d286ae125c33b9xxxxxxxxxxxxxxxx

Lateral Movement


With Reanimate-Tombstones, I could restore deleted AD objects, but first I should look for them. With the PowerShell command Get-ADObject I could find the object with isDeleted attribute.

I focused on the last entry because the first one CN=Deleted Objects,DC=tombwatcher,DC=htb is just the default container. I wanted to check the most recently deleted object, which would appear last in the list.

I could then restore the object with its GUID

The user cert_admin is restored into ADCS OU, which I have GenericAll on it with the user JohnSo I can take control of cert_admin user

Privilege Escalation


With cert_admin cred, I looked for a vulnerable template using the latest version of certipy and found the WebServer template is vulnerable to ESC15

I used Certipy Wikiarrow-up-right to perform the attack (Version 1 Template Behavior):

Access the box after obtaining DA privileges

Root Flag: 468983500bae8axxxxxxxxxxxxxx

Last updated