Adversaries may manipulate endpoint agent health status to mask their presence and evade detection. SOC teams should proactively hunt for this behavior to identify potential tampering with endpoint security configurations and uncover hidden malicious activity.
KQL Query
let configurationIDs = dynamic([
"scid-2000",
"scid-2001",
"scid-5001",
"scid-6001",
"scid-2002",
"scid-5002",
"scid-6002",
"scid-2003",
"scid-5092",
"scid-2010",
"scid-2011",
"scid-5095",
"scid-6095",
"scid-2012",
"scid-5090",
"scid-6090",
"scid-91",
"scid-2013",
"scid-5091",
"scid-6091",
"scid-2014",
"scid-2016",
"scid-5094",
"scid-6094"
]);
DeviceTvmSecureConfigurationAssessment
| where ConfigurationId in (configurationIDs)
| extend Test = case(
ConfigurationId == "scid-2000", "SensorEnabled",
ConfigurationId == "scid-2001", "SensorDataCollectionWin", //windows
ConfigurationId == "scid-5001", "SensorDataCollectionMac", //macOS
ConfigurationId == "scid-6001", "SensorDataCollectionLin", //linux
ConfigurationId == "scid-2002", "ImpairedCommunicationsWin", //windows
ConfigurationId == "scid-5002", "ImpairedCommunicationsMac", //macOS
ConfigurationId == "scid-6002", "ImpairedCommunicationsLin", //linux
ConfigurationId == "scid-2003", "TamperProtectionWin", //windows
ConfigurationId == "scid-5092", "TamperProtectionMac", //macOS
ConfigurationId == "scid-2010", "AntivirusEnabled",
ConfigurationId == "scid-2011", "AntivirusSignatureVersionWin", //windows
ConfigurationId == "scid-5095", "AntivirusSignatureVersionMac", //macOS
ConfigurationId == "scid-6095", "AntivirusSignatureVersionLin", //linux
ConfigurationId == "scid-2012", "RealtimeProtectionWin", //windows
ConfigurationId == "scid-5090", "RealtimeProtectionMac", //macOS
ConfigurationId == "scid-6090", "RealtimeProtectionLin", //linux
ConfigurationId == "scid-91" , "BehaviorMonitoring",
ConfigurationId == "scid-2013", "PUAProtectionWin", // windows
ConfigurationId == "scid-5091", "PUAProtectionMac", //macOS
ConfigurationId == "scid-6091", "PUAProtectionLin", //linux
ConfigurationId == "scid-2014", "AntivirusReporting",
ConfigurationId == "scid-2016", "CloudProtectionWin", //windows
ConfigurationId == "scid-5094", "CloudProtectionMac", //macOS
ConfigurationId == "scid-6094", "CloudProtectionLin", //linux
"N/A"),
Result = case(IsApplicable == 0, "N/A", IsCompliant == 1, "GOOD", "BAD")
| extend packed = pack(Test, Result)
| summarize Tests = make_bag(packed), DeviceName = any(DeviceName) by DeviceId, OSPlatform
| evaluate bag_unpack(Tests)
| extend CloudProtection = case(
OSPlatform startswith "Windows", CloudProtectionWin,
OSPlatform has "macOS", CloudProtectionMac,
OSPlatform has "Linux", CloudProtectionLin,
"NULL")
| extend PUAProtection = case(
OSPlatform startswith "Windows", PUAProtectionWin,
OSPlatform has "macOS", PUAProtectionMac,
OSPlatform has "Linux", PUAProtectionLin,
"NULL")
| extend TamperProtection = case(
OSPlatform startswith "Windows", TamperProtectionWin,
OSPlatform has "macOS", TamperProtectionMac,
//OSPlatform has "Linux", TamperProtectionLin,
"NULL")
| extend SensorDataCollection = case(
OSPlatform startswith "Windows", SensorDataCollectionWin,
OSPlatform has "macOS", SensorDataCollectionMac,
OSPlatform has "Linux", SensorDataCollectionLin,
"NULL")
| extend ImpairedCommunications = case(
OSPlatform startswith "Windows", ImpairedCommunicationsWin,
OSPlatform has "macOS", ImpairedCommunicationsMac,
OSPlatform has "Linux", ImpairedCommunicationsLin,
"NULL")
| extend RealtimeProtection = case(
OSPlatform startswith "Windows", RealtimeProtectionWin,
OSPlatform has "macOS", RealtimeProtectionMac,
OSPlatform has "Linux", RealtimeProtectionLin,
"NULL")
| extend AntivirusSignatureVersion = case(
OSPlatform startswith "Windows", AntivirusSignatureVersionWin,
OSPlatform has "macOS", AntivirusSignatureVersionMac,
OSPlatform has "Linux", AntivirusSignatureVersionLin,
"NULL")
| project-away *Win, *Mac, *Lin
id: 64c0f54f-9a8d-4630-95c8-aa2751e5da0c
name: Endpoint Agent Health Status Report
description: |
This query will provide a report of many of the best practice configurations for Defender ATP deployment. Special Thanks to Gilad Mittelman for the initial inspiration and concept.
Any tests which are reporting "BAD" as a result imply that the associated capability is not configured per best practice recommendation.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceTvmSecureConfigurationAssessment
tactics:
- Misconfiguration
query: |
let configurationIDs = dynamic([
"scid-2000",
"scid-2001",
"scid-5001",
"scid-6001",
"scid-2002",
"scid-5002",
"scid-6002",
"scid-2003",
"scid-5092",
"scid-2010",
"scid-2011",
"scid-5095",
"scid-6095",
"scid-2012",
"scid-5090",
"scid-6090",
"scid-91",
"scid-2013",
"scid-5091",
"scid-6091",
"scid-2014",
"scid-2016",
"scid-5094",
"scid-6094"
]);
DeviceTvmSecureConfigurationAssessment
| where ConfigurationId in (configurationIDs)
| extend Test = case(
ConfigurationId == "scid-2000", "SensorEnabled",
ConfigurationId == "scid-2001", "SensorDataCollectionWin", //windows
ConfigurationId == "scid-5001", "SensorDataCollectionMac", //macOS
ConfigurationId == "scid-6001", "SensorDataCollectionLin", //linux
ConfigurationId == "scid-2002", "ImpairedCommunicationsWin", //windows
ConfigurationId == "scid-5002", "ImpairedCommunicationsMac", //macOS
ConfigurationId == "scid-6002", "ImpairedCommunicationsLin", //linux
ConfigurationId == "scid-2003", "TamperProtectionWin", //windows
ConfigurationId == "scid-5092", "TamperProtectionMac", //macOS
ConfigurationId == "scid-2010", "AntivirusEnabled",
ConfigurationId == "scid-2011", "AntivirusSignatureVersionWin", //windows
ConfigurationId == "scid-5095", "AntivirusSignatureVersionMac", //macOS
ConfigurationId == "scid-6095", "AntivirusSignatureVersionLin", //linux
ConfigurationId == "scid-2012", "RealtimeProtectionWin", //windows
ConfigurationId == "scid-5090", "RealtimeProtectionMac", //macOS
ConfigurationId == "scid-6090", "RealtimeProtectionLin", //linux
ConfigurationId == "scid-91" , "BehaviorMonitoring",
ConfigurationId == "scid-2013", "PUAProtectionWin", // windows
ConfigurationId == "scid-5091", "PUAProtectionMac", //macOS
ConfigurationId == "scid-6091", "PUAProtectionLin", //linux
ConfigurationId == "scid-2014", "AntivirusReporting",
ConfigurationId == "scid-2016", "CloudProtectionWin", //windows
ConfigurationId == "scid-5094", "CloudProtectionMac", //macOS
ConfigurationId == "scid-6094", "CloudProtectionLin", //linux
Scenario: Scheduled Defender ATP Health Check Job
Description: A legitimate scheduled job runs to check the health status of Defender ATP components as part of routine maintenance.
Filter/Exclusion: Exclude events where the source is a known health check job, e.g., Microsoft Defender ATP Health Check or Defender ATP Health Status Job.
Scenario: System Update or Patching Process
Description: During a Windows update or patching event, Defender ATP may temporarily report health status changes due to service restarts or configuration updates.
Filter/Exclusion: Exclude events where the process name is svchost.exe or wuauclt.exe and the event occurs during a known update window.
Scenario: Admin Task to Reconfigure Defender ATP Settings
Description: An administrator manually reconfigures Defender ATP settings, such as changing the update schedule or disabling certain features, which may trigger a health status report.
Filter/Exclusion: Exclude events where the user is a known admin (e.g., User = "Domain\Administrator") and the action is related to a documented configuration change.
Scenario: Integration with Third-Party Security Tools
Description: A third-party security tool (e.g., Microsoft Defender for Endpoint, CrowdStrike, or Palo Alto Networks) may interact with Defender ATP and generate health status reports as part of integration testing or synchronization.
Filter/Exclusion: Exclude events where the source is a known third-party tool or integration service (e.g., CrowdStrike or Palo Alto Networks).
Scenario: Endpoint Agent Self-Health Reporting
Description: The Defender ATP agent itself may periodically report its own health status as part of its normal operation, which can be mistaken for an alert.
Filter/Exclusion: Exclude events where the source is the Defender ATP