Query Details
//This query takes incidents from Defender, checks MITRE technique and then creates attack navigator format for upload to https://mitre-attack.github.io/attack-navigator/
//Query Based on work from https://gokhansobay.medium.com/how-can-you-quickly-review-your-defender-rules-mitre-coverage-with-the-att-ck-navigator-map-6dbc84e73b63
let dynamicAttributes_first = dynamic({
"name": "layer",
"versions": {
"attack": "17",
"navigator": "5.0.1",
"layer": "4.5"
},
"domain": "enterprise-attack",
"description": "",
"filters": {
"platforms": [
"Windows",
"Linux",
"macOS",
"Network",
"PRE",
"Containers",
"Office 365",
"SaaS",
"Google Workspace",
"IaaS",
"Azure AD"
]
}
});
let dynamicAttributes_last = dynamic({
"gradient": {
"colors": [
"#ff6666ff",
"#ffe766ff",
"#8ec843ff"
],
"minValue": 0,
"maxValue": 100
},
"legendItems": [],
"metadata": [],
"links": [],
"showTacticRowBackground": false,
"tacticRowBackground": "#dddddd",
"selectTechniquesAcrossTactics": true,
"selectSubtechniquesWithParent": false,
"selectVisibleTechniques": false
});
let TechniqueID =SecurityIncident
| where TimeGenerated > ago(90d)
| summarize arg_max(TimeGenerated,AdditionalData) by IncidentNumber
| mv-expand AdditionalData
| where tostring(AdditionalData) contains "techniques"
| where parse_json(tostring(AdditionalData.techniques)) <> "[]" //Remove Empty
| distinct tostring(AdditionalData.techniques);
AlertInfo
| where TimeGenerated > ago(90d)
//| where DetectionSource == "Custom detection" //you can filter your source detection method
| extend ParsedAttack = parse_json(AttackTechniques)
| mv-expand ParsedAttack
| extend techniqueID = extract("T[0-9]+(?:\\.[0-9]+)?", 0, tostring(ParsedAttack))
| extend tactic = Category
| extend color = "#e60d0d" //red background
| extend comment = ""
| extend enabled = true
//| extend metadata = dynamic([])
//| extend links = dynamic([])
| extend showSubtechniques = true
| project-away ParsedAttack
| distinct techniqueID, tactic, color, comment, enabled, showSubtechniques //tostring(metadata), tostring(links)
| summarize techniques = make_list(pack(
'techniqueID', techniqueID, //the important point here is that this ID value highlights what we have as coverage in our custom map.
// 'tactic', tactic,
'color', color,
'comment', comment,
'enabled', enabled,
// 'metadata', metadata,
// 'links', links,
'showSubtechniques', showSubtechniques
))
| extend jsonOutput = bag_merge(dynamicAttributes_first, pack('techniques', techniques))
| extend finalOutput = bag_merge(jsonOutput, dynamicAttributes_last)
| project ourjsonOutput = tostring(finalOutput)
This query is designed to analyze security incidents from Microsoft Defender and map them to the MITRE ATT&CK framework. It then formats the data for use with the MITRE ATT&CK Navigator, a tool that helps visualize and assess security coverage.
Here's a simplified breakdown of what the query does:
Setup Dynamic Attributes:
dynamicAttributes_first) for the ATT&CK Navigator, such as the version of the ATT&CK framework, the platforms involved (e.g., Windows, Linux, macOS), and other configuration details.dynamicAttributes_last) like color gradients for visualization, and other display options.Extract Techniques from Incidents:
Process Alert Information:
Compile Techniques:
Merge and Format Data:
ourjsonOutput) is ready for upload to the MITRE ATT&CK Navigator, allowing users to visualize their security coverage against the MITRE framework.In essence, this query helps security analysts understand which MITRE techniques are covered by their Defender alerts and visualize this coverage using the ATT&CK Navigator tool.

Jay Kerai
Released: May 8, 2025
Tables
Keywords
Operators