TLDR: Introducing a
certipy parse
command to perform stealthy offline AD CS enumeration based on local registry data.
Ever since Will Schroeder and Lee Christensen from SpecterOps have released their seminal Active Directory Certificate Services (AD CS) research, it has been a popular avenue for Windows domain privilege escalation used by security professionals and threat actors alike.
Such attack paths usually begin with the enumeration of published certificate templates by means of LDAP queries to a domain controller (or COM / RPC requests to a certificate authority). However, in mature environments LDAP traffic is monitored, both on the client (API hooking, ETW) as well as server side (query logging, SACL based audit policies), for known tool behavior and malicious activities. To evade these detections, attackers use selective queries, obfuscate their requests, leverage native utilities and have developed new enumeration techniques with corresponding tooling based on alternative protocols (ADWS).
Wouldn’t it be convenient to use another – less monitored – data source to learn the same information?
Registry Certificate Template Cache
This is what Cedric Van Bockhaven and Max Grim from Outflank have presented in their The Registry Rundown talk at Troopers. They discovered that the local registry contains a certificate template cache:
AD CS is a gift that keeps on giving (ESC13, ESC14, ESC15) with new misconfigurations being discovered on a regular basis. It therefore seemed natural to plug this new data source into an existing analysis framework to reuse its capabilities and structured data output.
Extend Existing Tooling
This idea was realized by introducing a new certipy
command to parse TrustedSec’s reg_query BOF output as well as the text-based Windows registry (.reg) file format.
Using the reg_query
BOF
Assuming you have code execution as a low privileged user on a domain-joined Windows machine, collect the cached certificate template meta data from the local registry using:
beacon> reg_query_recursive HKU .DEFAULT\Software\Microsoft\Cryptography\CertificateTemplateCache
One missing piece of information is whether the certificate template is actually published to a certificate authority. This still has to be queried via LDAP:
beacon> ldapsearch "(objectclass=pKIEnrollmentService)" --attributes certificateTemplates --dn "CN=Configuration,DC=ludus,DC=domain" --ldaps
Passing the returned comma separated list of published template names, the previously captured registry query output and a set of SIDs, belonging to owned principals, allows familiar analysis using certipy:
$ certipy parse -format bof -domain ludus.domain -ca ludus-CA -published "ESC13, ESC9, ESC7_CERTMGR, ESC4, ESC3_CRA, ESC3, ESC2, ESC1, DirectoryEmailReplication, DomainControllerAuthentication, KerberosAuthentication, EFSRecovery, EFS, DomainController, WebServer, Machine, User, SubCA, Administrator" -sids "S-1-5-21-3291837554-245906837-2404182060-513,S-1-5-21-3291837554-245906837-2404182060-1104" beacon.log
Using regedit.exe
If you instead have interactive access to a compromised client and want to use the native regedit.exe
utility to live off the land and better blend into the target environment, you can File > Export the relevant registry branch to a .reg
file.
Changing the -format
to reg
allows parsing of this too:
$ certipy parse -format reg -domain ludus.domain -ca ludus-CA -published "ESC13, ESC9, ESC7_CERTMGR, ESC4, ESC3_CRA, ESC3, ESC2, ESC1, DirectoryEmailReplication, DomainControllerAuthentication, KerberosAuthentication, EFSRecovery, EFS, DomainController, WebServer, Machine, User, SubCA, Administrator" -sids "S-1-5-21-3291837554-245906837-2404182060-513,S-1-5-21-3291837554-245906837-2404182060-1104" adcs.reg
What’s next?
Of course, being aware of available certificate templates is only the first step. Obtaining a valid certificate while avoiding possible honey pots, detections based on suspicious ticket options during PKINIT or Kerberos traffic from an unusual process is left as an exercise for the sophisticated attacker.
As for detection, the same mechanism (a custom SACL on the relevant registry keys) as for detecting local SCCM reconnaissance can be employed.
Happy red teaming.
Leave a Reply