HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Windows Hello for Business WHfBShadow CredentialsmsDS-KeyCredentialLinkActive Directory SecurityEvent 5136Detection

Shadow Credentials: Detecting the msDS-KeyCredentialLink Attack Hiding in Your WHfB Deployment

IA
Imran Awan
31 July 2026

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.

Note: This is a defensive guide for the team that owns Active Directory. We describe the mechanism at a conceptual level so you can reason about it, then spend the rest of the post on detection and hardening. If you have not read the msDS-KeyCredentialLink deep dive, start there.

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.

Watch out: Attackers reach this attribute with well-known tooling (Whisker, pyWhisker, Certipy, and the DSInternals module). You do not need to know how those work to defend - you need to know that the write permission is the vulnerability, and the attribute change is the detectable event. Both are things you control.

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:

Computer Configuration Policies Windows Settings › Security Settings › Advanced Audit Policy DS Access › Audit Directory Service Changes

Here is what a Shadow Credentials write looks like in the event - note the AttributeLDAPDisplayName and the account in SubjectUserName:

⚠ Security — Event ID 5136
Subject → Account Name: helpdesk-svc  # who made the change
Object → DN: CN=Domain Admin,OU=Admins,DC=contoso,DC=com
Attribute → LDAP Display Name: msDS-KeyCredentialLink
Operation → Type: Value Added

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.

Gotcha: Expect legitimate 5136 noise. Microsoft Entra Connect writes this attribute constantly during normal hybrid key-trust sync, and so does normal WHfB enrolment. The signal is not "any write" - it is a write performed by an account that is not your Entra Connect service account or a sanctioned key-management process, especially a write that targets a privileged account. Baseline the legitimate writers first, then alert on everything else.

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.

Watch out: Protect Tier 0 hardest. A write grant over Domain Admins, the Key Admins groups themselves, or the AdminSDHolder object is a direct domain-compromise path. Members of protected groups are also covered by AdminSDHolder, so a delegation that "works" on a normal user may be stripped on a privileged one - verify Tier 0 objects specifically rather than assuming.

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.

Command Prompt (on a domain controller)
C:\> auditpol /get /subcategory:"Directory Service Changes" System audit policy Category/Subcategory Setting DS Access Directory Service Changes Success # good - 5136 will fire
Tip: Combine this with the key-count audit from the previous post. If your 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

PowerShell Scripts — Shadow Credentials Detection

Script for this post is in Daily-Tasks.

Get-ShadowCredentialSignals.ps1 — read-only: reports the audit-policy state and pulls recent Event 5136 writes to msDS-KeyCredentialLink for review
View all scripts on GitHub
Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Windows Hello for Business
Where Windows Hello for Business Keys Really Live: The…
The WHfB public key lives in one AD attribute - msDS-KeyCredentialLink - and almost…
Windows Hello for Business
dsregcmd /status Decoded: The Complete Field Reference for WHfB…
One command answers more WHfB questions than any portal - and its forty-plus fields come…
Windows Hello for Business
The Complete Windows Hello for Business Event ID Catalog (Across…
WHfB logs to three different places with cryptic IDs and no index. This catalog maps…