MITRE ATT&CK is the universal language of cybersecurity. Every SOC, every threat report, every security vendor references it. And the entire knowledge base is available through a free API.
No API key. No authentication. Pure STIX/TAXII data.
What Is ATT&CK?
ATT&CK catalogs real-world adversary tactics and techniques — not theoretical attacks, but exactly how APT groups like Lazarus, Fancy Bear, and Turla actually operate.
14 Tactics. 200+ Techniques. 130+ Threat Groups. All documented with real-world examples.
Accessing the Data
ATT&CK data is hosted on GitHub in STIX 2.1 format and also available via TAXII server:
\`python
import requests
Direct GitHub access (simplest method)
def get_attack_data():
"""Download the entire ATT&CK Enterprise dataset."""
url = "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json"
response = requests.get(url, timeout=60)
data = response.json()
# Count objects by type
type_counts = {}
for obj in data["objects"]:
obj_type = obj["type"]
type_counts[obj_type] = type_counts.get(obj_type, 0) + 1
print("ATT&CK Enterprise dataset:")
for t, c in sorted(type_counts.items(), key=lambda x: -x[1]):
print(f" {t}: {c}")
return data
data = get_attack_data()
`\
Search for Techniques
\`python
def search_techniques(data, keyword):
"""Search ATT&CK techniques by keyword."""
techniques = [
obj for obj in data["objects"]
if obj["type"] == "attack-pattern"
and not obj.get("revoked", False)
and keyword.lower() in obj.get("name", "").lower()
]
for tech in techniques[:10]:
# Get ATT&CK ID
ext_refs = tech.get("external_references", [])
attack_id = next((r["external_id"] for r in ext_refs
if r.get("source_name") == "mitre-attack"), "?")
name = tech["name"]
desc = tech.get("description", "")[:100]
# Get tactic (kill chain phase)
phases = [p["phase_name"] for p in tech.get("kill_chain_phases", [])]
print(f"\n{attack_id}: {name}")
print(f" Tactics: {', '.join(phases)}")
print(f" {desc}...")
return techniques
Find all phishing techniques
search_techniques(data, "phishing")
Find all credential access techniques
search_techniques(data, "credential")
`\
Look Up Threat Groups
\`python
def get_threat_groups(data, limit=10):
"""List known APT groups from ATT&CK."""
groups = [
obj for obj in data["objects"]
if obj["type"] == "intrusion-set"
and not obj.get("revoked", False)
]
print(f"Total threat groups: {len(groups)}")
for group in groups[:limit]:
ext_refs = group.get("external_references", [])
group_id = next((r["external_id"] for r in ext_refs
if r.get("source_name") == "mitre-attack"), "?")
name = group["name"]
aliases = group.get("aliases", [])[:3]
desc = group.get("description", "")[:120]
print(f"\n{group_id}: {name}")
if aliases:
print(f" Aliases: {', '.join(aliases)}")
print(f" {desc}...")
get_threat_groups(data)
`\
Map a Group's Techniques
\`python
def group_techniques(data, group_name):
"""Find all techniques used by a specific threat group."""
# Find the group
group = next(
(obj for obj in data["objects"]
if obj["type"] == "intrusion-set"
and obj["name"].lower() == group_name.lower()),
None
)
if not group:
print(f"Group '{group_name}' not found")
return
group_id = group["id"]
Find relationships (group -> technique)
relationships = [
obj for obj in data["objects"]
if obj["type"] == "relationship"
and obj.get("source_ref") == group_id
and obj.get("relationship_type") == "uses"
]
Resolve technique names
technique_ids = [r["target_ref"] for r in relationships]
techniques = [
obj for obj in data["objects"]
if obj["id"] in technique_ids
and obj["type"] == "attack-pattern"
]
print(f"\n{group_name} uses {len(techniques)} known techniques:")
for tech in techniques[:15]:
ext_refs = tech.get("external_references", [])
attack_id = next((r["external_id"] for r in ext_refs
if r.get("source_name") == "mitre-attack"), "?")
print(f" {attack_id}: {tech['name']}")
See what techniques APT29 (Cozy Bear) uses
group_techniques(data, "APT29")
`\
Build a Detection Coverage Map
\`python
def coverage_report(data, detected_techniques):
"""Show how many ATT&CK techniques your detections cover."""
all_techniques = [
obj for obj in data["objects"]
if obj["type"] == "attack-pattern"
and not obj.get("revoked", False)
and not obj.get("x_mitre_deprecated", False)
]
total = len(all_techniques)
covered = len([t for t in detected_techniques if t in
[next((r["external_id"] for r in obj.get("external_references", [])
if r.get("source_name") == "mitre-attack"), None)
for obj in all_techniques]])
print(f"Detection Coverage: {covered}/{total} ({covered/total*100:.1f}%)")
Group by tactic
tactic_coverage = {}
for tech in all_techniques:
for phase in tech.get("kill_chain_phases", []):
tactic = phase["phase_name"]
ext_refs = tech.get("external_references", [])
tid = next((r["external_id"] for r in ext_refs
if r.get("source_name") == "mitre-attack"), None)
if tactic not in tactic_coverage:
tactic_coverage[tactic] = {"total": 0, "covered": 0}
tactic_coverage[tactic]["total"] += 1
if tid in detected_techniques:
tactic_coverage[tactic]["covered"] += 1
print("\nCoverage by tactic:")
for tactic, counts in sorted(tactic_coverage.items()):
pct = counts["covered"]/counts["total"]*100 if counts["total"] else 0
bar = "█" * int(pct/5) + "░" * (20 - int(pct/5))
print(f" {tactic:<30} {bar} {pct:.0f}%")
Example: your SIEM detects these techniques
my_detections = ["T1566.001", "T1059.001", "T1053.005", "T1078", "T1021.001"]
coverage_report(data, my_detections)
`\
What You Can Build
- Threat modeling — map your defenses against the ATT&CK matrix
- Detection gap analysis — find which techniques you can't detect
- Threat reports — auto-tag incidents with ATT&CK IDs
- Training tools — quiz SOC analysts on techniques
- Risk scoring — weight risks based on technique prevalence
The entire cybersecurity industry runs on ATT&CK. Now you can programmatically access it.
More free security APIs and tools on my GitHub.
Top comments (0)