Query Details

Hunt Critical Credentials On Non Cred Guard Devices

Query

# *Hunt for critical credentials on non Credential Guard enabled devices*

## Query Information

#### MITRE ATT&CK Technique(s)

| Technique ID | Title    | Link    |
| ---  | --- | --- |
| TA0006 | Credential Access | https://attack.mitre.org/tactics/TA0006/ |


#### Description
This query searches for devices that does not have Credential Guard enabled but contains critical credentials. The output shows for how many users each non Credential Guard device has credentials, together with the list of users being exposed.


#### Risk
When critical credentials are stored on devices without Credential Guard enabled, it is more easy for adversaries to steal those credentials when the device is compromised. This is because without Credential Guard Kerberos, NTLM, and Credential Manager secrets are stored in the Local Security Authority (LSA) process called `lsass.exe`, which can be dumped with various tools like MimiKatz. With Credential Guard enabled, these secrets are protected and isolated using Virtualization-based security (VBS).


#### Author <Optional>
- **Name:** Robbe Van den Daele
- **Github:** https://github.com/RobbeVandenDaele
- **Twitter:** https://x.com/RobbeVdDaele
- **LinkedIn:** https://www.linkedin.com/in/robbe-van-den-daele-677986190/
- **Website:** https://hybridbrothers.com/

#### References

## Defender XDR
```KQL

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 desc
```

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:

  1. 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.

  2. Identify Critical Users: It then identifies users who have been marked as critical, meaning their credentials are particularly sensitive or important.

  3. 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.

  4. 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.

  5. 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 profile picture

Robbe Van den Daele

Released: November 11, 2025

Tables

ExposureGraphNodesExposureGraphEdges

Keywords

Devices

Operators

letarray_lengthextendtostringparse_jsoniffisemptydistincttoscalartodynamicsummarizemake_setmake-graphgraph-matchprojectjoinkind=inneronsummarizemake_listbysort bydesc

Actions