In the last post we opened up msDS-KeyCredentialLink - the Active Directory (AD) attribute where Windows Hello for Business (WHfB) public keys live. Here is the uncomfortable part nobody mentions: that same attribute is one of the most abused persistence and privilege-escalation primitives in on-premises AD. The technique is called Shadow Credentials, and if you run WHfB key trust or hybrid, your directory already has the attribute an attacker needs. This post is about defence - how to detect the attack and how to shut down the paths that make it possible. No exploit recipes; just what a defender needs.
The problem: a write permission you did not know was dangerous
Here is the mechanism in plain terms. WHfB lets a user authenticate with a key pair whose public key sits in their msDS-KeyCredentialLink attribute. Public Key Cryptography for Initial Authentication (PKINIT) lets a domain controller (DC) issue a Kerberos ticket to whoever proves possession of the matching private key.
Now combine those two facts. If an attacker can write to the msDS-KeyCredentialLink attribute of a target account - a user, or worse, a computer or a privileged account - they can add their own key credential. They now hold a private key that AD accepts as that account. They authenticate as the target, request a ticket, and can even recover the target's NTLM hash along the way. No password reset, no obvious footprint, and the planted key persists across the target's password changes. That is Shadow Credentials.
The permission that enables it is not "Domain Admin." It is any of these on the target object: GenericAll, GenericWrite, WriteProperty on the attribute, or write access to the object's whole property set. Delegation sprawl - a helpdesk group with broad write rights over an Organizational Unit (OU), a misconfigured Role-Based Access Control (RBAC) model - hands this out far more often than anyone realises.
Why it happens: nobody audits who can write the attribute
WHfB deployments legitimately need something to write this attribute: Microsoft Entra Connect (in hybrid key trust) and the Key Admins / Enterprise Key Admins groups. That is expected and fine. The problem is everything else that can write it by accident - inherited OU permissions, over-broad delegations, stale admin groups with GenericWrite on user objects. Those extra writers are the attack surface, and because the attribute is invisible in day-to-day administration, nobody ever reviews them.
How to verify: turn on the one audit event that catches it
The single most valuable detection is Security Event ID 5136 - "A directory service object was modified" - filtered to the msDS-KeyCredentialLink attribute. When anyone writes a key credential, a 5136 fires on the DC that processed it, naming the account that made the change, the target object, and the value.
Two things must be true for 5136 to appear. First, the Audit Directory Service Changes subcategory must be enabled on your DCs. Second, a System Access Control List (SACL) must audit "Write" on the object. Enable the subcategory via Group Policy on the Domain Controllers OU:
Here is what a Shadow Credentials write looks like in the event - note the AttributeLDAPDisplayName and the account in SubjectUserName:
A change operation typically produces two 5136 events sharing one Correlation ID: a "Value Deleted" (the old value) then a "Value Added" (the new one). For detection, alert on Value Added to msDS-KeyCredentialLink - that is the new key being planted.
The fix: cut the write paths, then watch what remains
Step 1 - Find every principal that can write the attribute
Before you can reduce the attack surface you have to see it. Enumerate which non-standard principals hold write access to msDS-KeyCredentialLink (or blanket rights like GenericAll / GenericWrite) across your user and computer objects. Attack-path tools like BloodHound label this the AddKeyCredentialLink edge; you can also read the Access Control Lists (ACLs) directly with PowerShell. The audit script for this post does exactly this enumeration, read-only.
Step 2 - Remove the delegations you cannot justify
For every writer that is not Entra Connect, a Key Admin, or an explicitly sanctioned process, ask "why does this principal need to write key credentials on these objects?" Almost always the answer is "it does not - it inherited a broad grant." Tighten the OU delegation so only the accounts that must write this attribute can.
Step 3 - Monitor the two groups that are supposed to write it
Membership of Key Admins and Enterprise Key Admins is effectively "can write key credentials anywhere." Treat both as Tier 0. Alert on any membership change (Security Event ID 4728 / 4732 / 4756), and review the members quarterly. If a group has members you cannot account for, that is your incident.
Proof it worked
You have three signals that the control is real. First, auditpol /get /subcategory:"Directory Service Changes" on a DC returns Success. Second, a deliberate test write to a lab account's msDS-KeyCredentialLink produces a 5136 in the Security log within seconds. Third, your enumeration of non-standard writers returns a short, explainable list - not pages of inherited grants.
msDS-KeyCredentialLink baseline is clean and understood, a Shadow Credentials attack shows up as two anomalies at once - a surprise 5136 "Value Added" by an unexpected account, and a key count that ticks up on an account whose owner did not just provision Hello. Two correlated signals beat one noisy alert.References
- Event 5136: A directory service object was modified
- Audit Directory Service Changes
- Active Directory security groups (Key Admins / Enterprise Key Admins)
- Enterprise access model (tiering) - Microsoft
Script for this post is in Daily-Tasks.