Hunt for critical credentials on non Credential Guard enabled devices
Hunt Critical Credentials On Non Cred Guard Devices
Query
let no_credguard_devices = (
ExposureGraphNodes
// Get devices with credential guard misconfiguration
| where array_length(NodeProperties.rawData.hasGuardMisconfigurations) > 0
// Get interesting data
| extend DeviceName = tostring(parse_json(NodeProperties)["rawData"]["deviceName"]),
DeviceId = tostring(EntityIds.id)
| extend DeviceName = iff(isempty(DeviceName), NodeName, DeviceName)
// Search for distinct devices
| distinct NodeId, DeviceName
);
let critical_users = toscalar(
// Search for critical users
ExposureGraphNodes
| where NodeLabel == "user"
| extend CriticalityLevel = todynamic(NodeProperties).rawData.criticalityLevel.criticalityLevel
| extend RuleNames = todynamic(NodeProperties).rawData.criticalityLevel.ruleNames
| where CriticalityLevel == 0
| distinct NodeName, NodeId, tostring(CriticalityLevel), tostring(RuleNames)
| summarize make_set(NodeName)
);
// Make graph for max of 3 edges, where we start from a device and end with an user
ExposureGraphEdges
| make-graph SourceNodeId --> TargetNodeId with ExposureGraphNodes on NodeId
| graph-match (SourceNode)-[anyEdge*1..3]->(TargetNode)
where SourceNode.NodeLabel in ("device", "microsoft.compute/virtualmachines") and TargetNode.NodeLabel == "user" and TargetNode.NodeName in ( critical_users )
project SourceNodeName = SourceNode.NodeName,
SourceNodeId = SourceNode.NodeId,
Edges = anyEdge.EdgeLabel,
TargetNodeId = TargetNode.NodeId,
TargetNodeName = TargetNode.NodeName,
TargetNodeLabel = TargetNode.NodeLabel,
TargetCriticalityLevel = TargetNode.NodeProperties.rawData.criticalityLevel.criticalityLevel,
TargetRuleNames = TargetNode.NodeProperties.rawData.criticalityLevel.ruleNames
| distinct SourceNodeId, SourceNodeName, TargetNodeId, TargetNodeName, tostring(TargetCriticalityLevel), tostring(TargetRuleNames)
// Only return devices that does not have a TPM fully enabled
| join kind=inner no_credguard_devices on $left.SourceNodeId == $right.NodeId
// Make list of users per device
| summarize UserList = make_list(TargetNodeName) by DeviceName
// Count amount of exposed users per device
| extend UserCount = array_length(UserList)
| sort by UserCount descAbout this query
Explanation
This query is designed to identify devices that do not have Credential Guard enabled and are storing critical user credentials. Credential Guard is a security feature that helps protect credentials by isolating them in a secure environment. Without it, credentials are more vulnerable to theft if a device is compromised.
Here's a simplified breakdown of what the query does:
-
Identify Devices Without Credential Guard: The query first identifies devices that have a misconfiguration related to Credential Guard, meaning they do not have this security feature enabled.
-
Identify Critical Users: It then identifies users who have been marked as critical, meaning their credentials are particularly sensitive or important.
-
Graph Analysis: The query constructs a graph to find relationships between devices and users. It looks for paths in the data where a device is connected to a critical user, indicating that the device holds credentials for that user.
-
Filter and Summarize: The query filters the results to only include devices without Credential Guard and summarizes the data to show how many critical users' credentials are stored on each device.
-
Output: The final output lists devices along with the number of critical users whose credentials are stored on them, sorted by the number of exposed users in descending order.
The risk highlighted by this query is that devices without Credential Guard are more susceptible to credential theft, as sensitive information can be extracted from the lsass.exe process using tools like MimiKatz. The query helps security teams identify and prioritize devices that need remediation to protect against potential credential theft.
Details

Robbe Van den Daele
Released: November 11, 2025
Tables
Keywords
Operators