npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
Use this skill when:
- Updating the organization's threat model with profiles of adversary groups recently observed targeting your sector
- Preparing an executive briefing on APT groups that align with geopolitical events affecting your business
- Enabling SOC analysts to understand attacker objectives and TTPs to improve detection tuning
Do not use this skill for real-time incident attribution — attribution during active incidents should be deprioritized in favor of containment. Profile refinement occurs post-incident.
Prerequisites
- Access to MITRE ATT&CK Groups database (https://attack.mitre.org/groups/)
- Commercial threat intelligence subscription (Mandiant Advantage, CrowdStrike Falcon Intelligence, or Recorded Future)
- Sector-specific ISAC membership for targeted intelligence (FS-ISAC, H-ISAC, E-ISAC)
- Structured profile template (see workflow below)
Workflow
Step 1: Identify Relevant Threat Actors
Cross-reference your organization's sector, geography, and technology stack against known adversary targeting patterns. Sources:
- MITRE ATT&CK Groups: 130+ documented nation-state and criminal groups with TTP mappings
- CrowdStrike Annual Threat Report: adversary naming by nation-state (BEAR=Russia, PANDA=China, KITTEN=Iran, CHOLLIMA=North Korea)
- Mandiant M-Trends: annual report with sector-specific targeting statistics
- CISA Known Exploited Vulnerabilities (KEV) catalog: identifies vulnerabilities actively exploited by specific threat actors
Shortlist 5–10 groups most likely to target your organization based on sector alignment and recent activity.
Step 2: Collect Profile Data
For each adversary, document across standard dimensions:
Identity: ATT&CK Group ID (e.g., G0016 for APT29), aliases (Cozy Bear, The Dukes, Midnight Blizzard), suspected nation-state sponsor
Motivations: Espionage, financial gain, disruption, intellectual property theft
Targeting: Sectors, geographies, organization sizes, technology targets (OT/IT, cloud, supply chain)
Capabilities: Custom malware (e.g., APT29's SUNBURST, MiniDuke), exploitation of 0-days vs. known CVEs, supply chain attack capability
Campaign History: Notable operations with dates (SolarWinds 2020, Exchange Server 2021, etc.)
TTPs by ATT&CK Phase: Document top 5 techniques per tactic phase
Step 3: Map TTPs to ATT&CK
Using mitreattack-python:
from mitreattack.stix20 import MitreAttackData
mitre = MitreAttackData("enterprise-attack.json")
apt29 = mitre.get_object_by_attack_id("G0016", "groups")
techniques = mitre.get_techniques_used_by_group(apt29)
profile = {}
for item in techniques:
tech = item["object"]
tid = tech["external_references"][0]["external_id"]
tactic = [p["phase_name"] for p in tech.get("kill_chain_phases", [])]
profile[tid] = {"name": tech["name"], "tactics": tactic}Step 4: Assess Detection Coverage Against Profile
Compare the adversary's technique list against your detection coverage matrix (from ATT&CK Navigator layer). Identify:
- Techniques used by this group where you have no detection (critical gaps)
- Techniques where you have partial coverage (logging but no alerting)
- Compensating controls where detection is not feasible (network segmentation as mitigation for lateral movement)
Step 5: Package Profile for Distribution
Structure the final profile for different audiences:
- Executive summary (1 page): Who, motivation, recent campaigns, top risk to our organization, recommended priority actions
- SOC analyst brief (3–5 pages): Full TTP list with detection status, IOC list, hunt hypotheses
- Technical appendix: YARA rules, Sigma detections, STIX JSON object for TIP import
Classify TLP:AMBER for internal distribution; seek ISAC approval before external sharing.
Key Concepts
| Term | Definition |
|---|---|
| APT | Advanced Persistent Threat — well-resourced, sophisticated adversary (typically nation-state or sophisticated criminal) conducting long-term targeted operations |
| TTPs | Tactics, Techniques, Procedures — behavioral fingerprint of an adversary group, more durable than IOCs which change frequently |
| Aliases | Threat actors receive different names from different vendors (APT29 = Cozy Bear = The Dukes = Midnight Blizzard = YTTRIUM) |
| Attribution | Process of associating an attack with a specific threat actor; requires multiple independent corroborating data points and carries inherent uncertainty |
| Cluster | A group of related intrusion activity that may or may not be attributable to a single actor; used when attribution is uncertain |
| Intrusion Set | STIX SDO type representing a grouped set of adversarial behaviors with common objectives, even if actor identity is unknown |
Tools & Systems
- MITRE ATT&CK Groups: Free, community-maintained database of 130+ documented adversary groups with referenced campaign reports
- Mandiant Advantage Threat Intelligence: Commercial platform with detailed APT profiles, malware families, and campaign analysis
- CrowdStrike Falcon Intelligence: Commercial feed with adversary-centric profiles and real-time attribution updates
- Recorded Future Threat Intelligence: Combines OSINT, dark web, and technical intelligence for adversary profiling
- OpenCTI: Graph-based visualization of threat actor relationships, tooling, and campaign linkages
Common Pitfalls
- IOC-centric profiles: Building profiles around IP addresses and domains rather than TTPs means the profile becomes stale within weeks as infrastructure rotates.
- Vendor alias confusion: Conflating two different threat actor groups due to shared malware or infrastructure leads to incorrect threat model assumptions.
- Binary attribution: Treating attribution as certain when it is probabilistic. Always qualify attribution confidence level (Low/Medium/High).
- Neglecting insider and criminal groups: Overemphasis on nation-state APTs while ignoring ransomware groups (Cl0p, LockBit, ALPHV) which represent higher probability threats for most organizations.
- Profile staleness: Adversary TTPs evolve. Profiles not updated quarterly may miss technique changes, new malware, or targeting shifts.
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md2.2 KB
API Reference: Threat Actor Profiling Agent
Overview
Builds threat actor profiles from MITRE ATT&CK STIX data using the stix2 MemoryStore. Queries intrusion-set objects for TTPs, software, and relationships, enabling group comparison and tactic mapping.
Dependencies
| Package | Version | Purpose |
|---|---|---|
| stix2 | >= 3.0 | STIX 2.1 object store and filtering |
| requests | >= 2.28 | ATT&CK STIX data download |
Data Source
MITRE ATT&CK Enterprise STIX bundle from https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json. Cached locally at /tmp/enterprise-attack.json.
Core Functions
load_attack_data(cache_path)
Downloads and caches ATT&CK STIX data into a stix2 MemoryStore.
- Returns:
MemoryStoreinstance
list_threat_groups(src)
Lists all intrusion-set objects with name, aliases, and description.
- Returns:
list[dict]sorted by name
get_group_profile(src, group_name)
Full profile: description, aliases, techniques with ATT&CK IDs, software (malware/tools), external references.
- Search: Exact match on name, then fuzzy match on name and aliases
- Returns:
dictwith techniques, software, references
get_group_techniques_by_tactic(src, group_name)
Organizes a group's techniques by ATT&CK tactic (kill chain phase).
- Returns:
dictwith tactics mapped to technique lists
compare_groups(src, group_names)
Compares multiple groups: shared techniques, technique counts, software counts.
- Returns:
dictwithshared_techniquesand per-group statistics
STIX Object Types Queried
| Type | ATT&CK Concept |
|---|---|
| intrusion-set | Threat actor group |
| attack-pattern | ATT&CK technique |
| malware | Malware family |
| tool | Legitimate tool used by attacker |
| relationship | Links between groups, techniques, software |
Usage
python agent.py APT29
python agent.py "Lazarus Group"Example Output Fields
{
"name": "APT29",
"aliases": ["NOBELIUM", "Cozy Bear", "The Dukes"],
"techniques": [{"name": "Phishing", "technique_id": "T1566"}],
"software": [{"name": "Cobalt Strike", "type": "tool"}]
}Scripts 1
agent.py6.9 KB
#!/usr/bin/env python3
"""Threat actor profiling agent using MITRE ATT&CK STIX data and STIX2 library."""
import json
import sys
import os
try:
from stix2 import MemoryStore, Filter
import requests
except ImportError:
print("Install: pip install stix2 requests")
sys.exit(1)
ATTACK_STIX_URL = "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json"
def load_attack_data(cache_path="/tmp/enterprise-attack.json"):
"""Load MITRE ATT&CK STIX data from cache or download."""
if os.path.exists(cache_path):
with open(cache_path, "r") as f:
data = json.load(f)
else:
resp = requests.get(ATTACK_STIX_URL, timeout=60)
resp.raise_for_status()
data = resp.json()
with open(cache_path, "w") as f:
json.dump(data, f)
return MemoryStore(stix_data=data["objects"])
def list_threat_groups(src):
"""List all threat actor groups in ATT&CK."""
groups = src.query([Filter("type", "=", "intrusion-set")])
result = []
for g in groups:
aliases = getattr(g, "aliases", [])
result.append({
"id": g.id,
"name": g.name,
"aliases": aliases if aliases else [],
"description": (g.description[:200] + "...") if hasattr(g, "description") and g.description else "",
"created": str(g.created),
"modified": str(g.modified),
})
return sorted(result, key=lambda x: x["name"])
def get_group_profile(src, group_name):
"""Build a comprehensive profile for a specific threat actor group."""
groups = src.query([
Filter("type", "=", "intrusion-set"),
Filter("name", "=", group_name),
])
if not groups:
groups = src.query([Filter("type", "=", "intrusion-set")])
groups = [g for g in groups if group_name.lower() in g.name.lower()
or any(group_name.lower() in a.lower() for a in getattr(g, "aliases", []))]
if not groups:
return {"error": f"Group '{group_name}' not found"}
group = groups[0]
profile = {
"name": group.name,
"id": group.id,
"aliases": getattr(group, "aliases", []),
"description": getattr(group, "description", ""),
"created": str(group.created),
"modified": str(group.modified),
"external_references": [],
}
for ref in getattr(group, "external_references", []):
if hasattr(ref, "source_name"):
profile["external_references"].append({
"source": ref.source_name,
"url": getattr(ref, "url", ""),
"external_id": getattr(ref, "external_id", ""),
})
relationships = src.query([
Filter("type", "=", "relationship"),
Filter("source_ref", "=", group.id),
])
profile["techniques"] = []
profile["software"] = []
for rel in relationships:
target = src.get(rel.target_ref)
if target:
if target.type == "attack-pattern":
technique = {
"name": target.name,
"technique_id": "",
"description": rel.description[:200] if hasattr(rel, "description") and rel.description else "",
}
for ref in getattr(target, "external_references", []):
if hasattr(ref, "external_id") and ref.external_id.startswith("T"):
technique["technique_id"] = ref.external_id
profile["techniques"].append(technique)
elif target.type in ("malware", "tool"):
profile["software"].append({
"name": target.name,
"type": target.type,
"description": (target.description[:200] + "...") if hasattr(target, "description") and target.description else "",
})
return profile
def get_group_techniques_by_tactic(src, group_name):
"""Map a group's techniques organized by ATT&CK tactic."""
profile = get_group_profile(src, group_name)
if "error" in profile:
return profile
tactic_map = {}
techniques = src.query([Filter("type", "=", "attack-pattern")])
tech_lookup = {}
for t in techniques:
for ref in getattr(t, "external_references", []):
if hasattr(ref, "external_id") and ref.external_id.startswith("T"):
tech_lookup[t.name] = {
"id": ref.external_id,
"tactics": [p["phase_name"] for p in getattr(t, "kill_chain_phases", [])],
}
for tech in profile["techniques"]:
info = tech_lookup.get(tech["name"], {})
for tactic in info.get("tactics", ["unknown"]):
tactic_map.setdefault(tactic, []).append({
"technique": tech["name"],
"id": info.get("id", tech.get("technique_id", "")),
})
return {"group": group_name, "tactics": tactic_map}
def compare_groups(src, group_names):
"""Compare techniques and tools across multiple threat actor groups."""
profiles = {}
for name in group_names:
p = get_group_profile(src, name)
if "error" not in p:
profiles[name] = p
all_techniques = {}
for name, profile in profiles.items():
for tech in profile["techniques"]:
tech_name = tech["name"]
all_techniques.setdefault(tech_name, set()).add(name)
shared = {t: list(g) for t, g in all_techniques.items() if len(g) > 1}
return {
"groups": list(profiles.keys()),
"shared_techniques": shared,
"technique_counts": {n: len(p["techniques"]) for n, p in profiles.items()},
"software_counts": {n: len(p["software"]) for n, p in profiles.items()},
}
def print_profile(profile):
print(f"Threat Actor Profile: {profile['name']}")
print("=" * 50)
if profile.get("aliases"):
print(f"Aliases: {', '.join(profile['aliases'])}")
print(f"\nDescription:\n{profile.get('description', '')[:500]}")
print(f"\nTechniques ({len(profile.get('techniques', []))}):")
for t in profile.get("techniques", [])[:20]:
print(f" [{t.get('technique_id', 'N/A'):8s}] {t['name']}")
print(f"\nSoftware ({len(profile.get('software', []))}):")
for s in profile.get("software", []):
print(f" [{s['type']:7s}] {s['name']}")
print(f"\nReferences:")
for r in profile.get("external_references", [])[:5]:
print(f" {r['source']}: {r.get('url', r.get('external_id', ''))}")
if __name__ == "__main__":
group_name = sys.argv[1] if len(sys.argv) > 1 else "APT29"
print("Loading MITRE ATT&CK data...")
src = load_attack_data()
profile = get_group_profile(src, group_name)
if "error" in profile:
print(profile["error"])
print("\nAvailable groups:")
for g in list_threat_groups(src)[:20]:
print(f" {g['name']}: {', '.join(g['aliases'][:3])}")
else:
print_profile(profile)