Each rewritten description now states both what the skill does (concrete
capability, named tools/artifacts) and an explicit when-to-use trigger,
improving agent discovery/activation. Grounded in each skill's own body;
changes confined to the `description` field only (bodies and all other
frontmatter untouched). Produced by a gated audit->rewrite->recheck loop
(548 -> 0 flagged) with a sampled anti-invention check (0 ungrounded).
Schema: 817/817 pass. Framework-ID gate: 0 defects.
Query ATT&CK data with attackcti, mitreattack-python, and stix2, then build MITRE ATT&CK Navigator layers and multi-layer heatmap overlays mapping one or more APT groups' TTPs for detection-gap analysis. Use to compare threat-actor technique coverage, find gaps in detection engineering, or produce Navigator visualizations for threat-intel reporting.
cybersecurity
threat-intelligence
mitre-attack
navigator
apt
threat-actor
ttp-analysis
heatmap
detection-gap
threat-intelligence
1.0
mahipal
Apache-2.0
Executable Denylisting
Execution Isolation
File Metadata Consistency Validation
Content Format Conversion
File Content Analysis
ID.RA-01
ID.RA-05
DE.CM-01
DE.AE-02
T1059.001
T1071.001
T1003.001
T1486
T1547.001
Analyzing APT Group with MITRE ATT&CK Navigator
Overview
MITRE ATT&CK Navigator is a web-based tool for annotating and exploring ATT&CK matrices, enabling analysts to visualize threat actor technique coverage, compare multiple APT groups, identify detection gaps, and build threat-informed defense strategies. This skill covers querying ATT&CK data programmatically, mapping APT group TTPs to Navigator layers, creating multi-layer overlays for gap analysis, and generating actionable intelligence reports for detection engineering teams.
When to Use
When investigating security incidents that require analyzing apt group with mitre navigator
When building detection rules or threat hunting queries for this domain
When SOC analysts need structured procedures for this analysis type
When validating security monitoring coverage for related attack techniques
Prerequisites
Python 3.9+ with attackcti, mitreattack-python, stix2, requests libraries
Understanding of ATT&CK Enterprise matrix: 14 Tactics, 200+ Techniques, Sub-techniques
Access to threat intelligence reports or MISP/OpenCTI for threat actor data
Familiarity with STIX 2.1 Intrusion Set and Attack Pattern objects
Key Concepts
ATT&CK Navigator Layers
Navigator layers are JSON files that annotate ATT&CK techniques with scores, colors, comments, and metadata. Each layer can represent a single APT group's technique usage, a detection capability map, or a combined overlay. Layer version 4.5 supports enterprise-attack, mobile-attack, and ics-attack domains with filtering by platform (Windows, Linux, macOS, Cloud, Azure AD, Office 365, SaaS).
APT Group Profiles in ATT&CK
ATT&CK catalogs over 140 threat groups with documented technique usage. Each group profile includes aliases, targeted sectors, associated campaigns, software used, and technique mappings with procedure-level detail. Groups are identified by G-codes (e.g., G0016 for APT29, G0007 for APT28, G0032 for Lazarus Group).
Multi-Layer Analysis
The Navigator supports loading multiple layers simultaneously, allowing analysts to overlay threat actor TTPs against detection coverage to identify gaps, compare multiple APT groups to find common techniques worth prioritizing, and track technique coverage changes over time.
Workflow
Step 1: Query ATT&CK Data for APT Group
fromattackctiimportattack_clientimportjsonlift=attack_client()# Get all threat groupsgroups=lift.get_groups()print(f"Total ATT&CK groups: {len(groups)}")# Find APT29 (Cozy Bear / Midnight Blizzard)apt29=next((gforgingroupsifg.get('name')=='APT29'),None)ifapt29:print(f"Group: {apt29['name']}")print(f"Aliases: {apt29.get('aliases',[])}")print(f"Description: {apt29.get('description','')[:300]}")# Get techniques used by APT29 (G0016)techniques=lift.get_techniques_used_by_group("G0016")print(f"APT29 uses {len(techniques)} techniques")technique_map={}fortechintechniques:tech_id=""forrefintech.get("external_references",[]):ifref.get("source_name")=="mitre-attack":tech_id=ref.get("external_id","")breakiftech_id:tactics=[p.get("phase_name","")forpintech.get("kill_chain_phases",[])]technique_map[tech_id]={"name":tech.get("name",""),"tactics":tactics,"description":tech.get("description","")[:500],"platforms":tech.get("x_mitre_platforms",[]),"data_sources":tech.get("x_mitre_data_sources",[]),}
Step 2: Generate Navigator Layer JSON
defcreate_navigator_layer(group_name,technique_map,color="#ff6666"):techniques_list=[]fortech_id,infointechnique_map.items():fortacticininfo["tactics"]:techniques_list.append({"techniqueID":tech_id,"tactic":tactic,"color":color,"comment":info["name"],"enabled":True,"score":100,"metadata":[{"name":"group","value":group_name},{"name":"platforms","value":", ".join(info["platforms"])},],})layer={"name":f"{group_name} TTP Coverage","versions":{"attack":"16.1","navigator":"5.1.0","layer":"4.5"},"domain":"enterprise-attack","description":f"Techniques attributed to {group_name}","filters":{"platforms":["Linux","macOS","Windows","Cloud","Azure AD","Office 365","SaaS","Google Workspace"]},"sorting":0,"layout":{"layout":"side","aggregateFunction":"average","showID":True,"showName":True,"showAggregateScores":False,"countUnscored":False,},"hideDisabled":False,"techniques":techniques_list,"gradient":{"colors":["#ffffff",color],"minValue":0,"maxValue":100},"legendItems":[{"label":f"Used by {group_name}","color":color},{"label":"Not observed","color":"#ffffff"},],"showTacticRowBackground":True,"tacticRowBackground":"#dddddd","selectTechniquesAcrossTactics":True,"selectSubtechniquesWithParent":False,"selectVisibleTechniques":False,}returnlayerlayer=create_navigator_layer("APT29",technique_map)withopen("apt29_layer.json","w")asf:json.dump(layer,f,indent=2)print("[+] Layer saved: apt29_layer.json")
Step 3: Compare Multiple APT Groups
groups_to_compare={"G0016":"APT29","G0007":"APT28","G0032":"Lazarus Group"}group_techniques={}forgid,gnameingroups_to_compare.items():techs=lift.get_techniques_used_by_group(gid)tech_ids=set()fortintechs:forrefint.get("external_references",[]):ifref.get("source_name")=="mitre-attack":tech_ids.add(ref.get("external_id",""))group_techniques[gname]=tech_idscommon_to_all=set.intersection(*group_techniques.values())print(f"Techniques common to all groups: {len(common_to_all)}")fortidinsorted(common_to_all):print(f" {tid}")forgname,techsingroup_techniques.items():others=set.union(*[tforn,tingroup_techniques.items()ifn!=gname])unique=techs-othersprint(f"\nUnique to {gname}: {len(unique)} techniques")
Step 4: Detection Gap Analysis with Layer Overlay
# Define your current detection capabilitiesdetected_techniques={"T1059","T1059.001","T1071","T1071.001","T1566","T1566.001","T1547","T1547.001","T1053","T1053.005","T1078","T1027",}actor_techniques=set(technique_map.keys())covered=actor_techniques.intersection(detected_techniques)gaps=actor_techniques-detected_techniquesprint(f"=== Detection Gap Analysis for APT29 ===")print(f"Actor techniques: {len(actor_techniques)}")print(f"Detected: {len(covered)} ({len(covered)/len(actor_techniques)*100:.0f}%)")print(f"Gaps: {len(gaps)} ({len(gaps)/len(actor_techniques)*100:.0f}%)")# Create gap layer (red = undetected, green = detected)gap_techniques=[]fortech_idinactor_techniques:info=technique_map.get(tech_id,{})fortacticininfo.get("tactics",[""]):color="#66ff66"iftech_idindetected_techniqueselse"#ff3333"gap_techniques.append({"techniqueID":tech_id,"tactic":tactic,"color":color,"comment":f"{'DETECTED'iftech_idindetected_techniqueselse'GAP'}: {info.get('name','')}","enabled":True,"score":100iftech_idindetected_techniqueselse0,})gap_layer={"name":"APT29 Detection Gap Analysis","versions":{"attack":"16.1","navigator":"5.1.0","layer":"4.5"},"domain":"enterprise-attack","description":"Green = detected, Red = gap","techniques":gap_techniques,"gradient":{"colors":["#ff3333","#66ff66"],"minValue":0,"maxValue":100},"legendItems":[{"label":"Detected","color":"#66ff66"},{"label":"Detection Gap","color":"#ff3333"},],}withopen("apt29_gap_layer.json","w")asf:json.dump(gap_layer,f,indent=2)