MITRE ATT&CK python library for accessing, querying, and manipulating ATT&CK threat intelligence data.
—
Download specific ATT&CK releases, manage version information, and access historical ATT&CK data. This module provides comprehensive tools for managing different versions of ATT&CK data, downloading from official sources, and working with version-specific datasets for analysis and comparison.
Core functions for downloading ATT&CK STIX data from official sources.
def download_stix(stix_version: str, domain: str, download_dir: str, release: str, known_hash: str) -> str:
"""
Download specific ATT&CK release data.
Args:
stix_version (str): STIX format version ("2.0" or "2.1")
domain (str): ATT&CK domain ("enterprise-attack", "mobile-attack", "ics-attack")
download_dir (str): Directory to save downloaded files
release (str): Specific ATT&CK version to download (e.g., "14.1")
known_hash (str): Expected SHA256 hash for verification
Returns:
str: Path to downloaded file
Raises:
ValueError: If hash verification fails
requests.RequestException: If download fails
"""
def download_domains(domains: List[str], download_dir: str, all_versions: bool,
stix_version: str, attack_versions: List[str] = None) -> Dict[str, List[str]]:
"""
Download multiple ATT&CK domains.
Args:
domains (List[str]): List of domains to download
download_dir (str): Directory to save downloaded files
all_versions (bool): Whether to download all available versions
stix_version (str): STIX format version
attack_versions (List[str], optional): Specific versions to download
Returns:
Dict[str, List[str]]: Mapping of domains to downloaded file paths
"""
def download_attack_stix() -> None:
"""
Main CLI function for downloading ATT&CK data.
Provides interactive interface for selecting domains, versions, and output locations.
"""Access version metadata and release information.
LATEST_VERSION: str = "17.1"
"""Current latest ATT&CK version."""
STIX20: Dict[str, str]
"""
SHA256 hashes for all STIX 2.0 releases.
Keys are version strings, values are SHA256 hashes.
"""
STIX21: Dict[str, str]
"""
SHA256 hashes for all STIX 2.1 releases.
Keys are version strings, values are SHA256 hashes.
"""
def get_attack_version(domain: str, stix_version: str = "2.0", stix_file: str = None,
stix_content: str = None) -> str:
"""
Determine ATT&CK version from file content or metadata.
Args:
domain (str): ATT&CK domain being analyzed
stix_version (str): STIX format version. Defaults to "2.0"
stix_file (str, optional): Path to STIX file to analyze
stix_content (str, optional): Raw STIX content to analyze
Returns:
str: Detected ATT&CK version (e.g., "14.1")
Note:
Either stix_file or stix_content must be provided.
"""Utilities for validating downloaded data and version integrity.
def verify_file_hash(filepath: str, expected_hash: str) -> bool:
"""
Verify downloaded file integrity using SHA256 hash.
Args:
filepath (str): Path to file to verify
expected_hash (str): Expected SHA256 hash
Returns:
bool: True if hash matches, False otherwise
"""
def get_available_versions(stix_version: str) -> List[str]:
"""
Get list of all available ATT&CK versions for given STIX format.
Args:
stix_version (str): STIX format version ("2.0" or "2.1")
Returns:
List[str]: Sorted list of available version strings
"""
def is_version_available(version: str, stix_version: str) -> bool:
"""
Check if specific ATT&CK version is available for download.
Args:
version (str): ATT&CK version to check
stix_version (str): STIX format version
Returns:
bool: True if version is available
"""from mitreattack.download_stix import download_stix, LATEST_VERSION, STIX20
# Download latest Enterprise ATT&CK in STIX 2.0 format
download_path = download_stix(
stix_version="2.0",
domain="enterprise-attack",
download_dir="./attack_data/",
release=LATEST_VERSION,
known_hash=STIX20[LATEST_VERSION]
)
print(f"Downloaded: {download_path}")from mitreattack.download_stix import download_domains
# Download multiple domains for specific versions
downloaded_files = download_domains(
domains=["enterprise-attack", "mobile-attack", "ics-attack"],
download_dir="./multi_domain_data/",
all_versions=False,
stix_version="2.1",
attack_versions=["14.1", "15.0", "15.1"]
)
for domain, files in downloaded_files.items():
print(f"{domain}: {len(files)} files downloaded")
for file_path in files:
print(f" - {file_path}")from mitreattack.download_stix import download_domains, get_available_versions
# Get all available versions
available_versions = get_available_versions("2.0")
print(f"Available versions: {available_versions}")
# Download all versions for enterprise domain
all_files = download_domains(
domains=["enterprise-attack"],
download_dir="./historical_data/",
all_versions=True,
stix_version="2.0"
)
print(f"Downloaded {len(all_files['enterprise-attack'])} historical versions")from mitreattack.release_info import get_attack_version
import json
# Detect version from downloaded file
detected_version = get_attack_version(
domain="enterprise-attack",
stix_version="2.0",
stix_file="./attack_data/enterprise-attack-v14.1.json"
)
print(f"Detected ATT&CK version: {detected_version}")
# Detect version from raw content
with open("./attack_data/enterprise-attack.json", "r") as f:
stix_content = f.read()
version_from_content = get_attack_version(
domain="enterprise-attack",
stix_version="2.0",
stix_content=stix_content
)
print(f"Version from content: {version_from_content}")from mitreattack.download_stix import verify_file_hash
from mitreattack.release_info import STIX20
# Verify downloaded file integrity
file_path = "./attack_data/enterprise-attack-v14.1.json"
expected_hash = STIX20["14.1"]
if verify_file_hash(file_path, expected_hash):
print("File integrity verified - hash matches")
else:
print("WARNING: File hash does not match expected value")from mitreattack.download_stix import get_available_versions, is_version_available
# Check what versions are available
stix20_versions = get_available_versions("2.0")
stix21_versions = get_available_versions("2.1")
print(f"STIX 2.0 versions: {len(stix20_versions)}")
print(f"STIX 2.1 versions: {len(stix21_versions)}")
# Check specific version availability
version_to_check = "15.1"
if is_version_available(version_to_check, "2.0"):
print(f"Version {version_to_check} is available in STIX 2.0")
else:
print(f"Version {version_to_check} is not available in STIX 2.0")# Interactive download with domain and version selection
download_attack_stix
# Download latest versions of all domains
download_attack_stix --domains enterprise-attack mobile-attack ics-attack --latest
# Download specific versions
download_attack_stix --domains enterprise-attack --versions 14.1,15.0,15.1 --stix-version 2.1
# Download to specific directory
download_attack_stix --domains enterprise-attack --output ./my_attack_data/ --latest
# Download with verification
download_attack_stix --domains enterprise-attack --verify-hashes --latestimport os
from pathlib import Path
from mitreattack.download_stix import download_domains, get_available_versions, verify_file_hash
from mitreattack.release_info import STIX20, STIX21
def setup_attack_data_repository(base_dir: str, stix_version: str = "2.0"):
"""
Set up a complete ATT&CK data repository with all versions and domains.
"""
base_path = Path(base_dir)
base_path.mkdir(parents=True, exist_ok=True)
# Get available versions
versions = get_available_versions(stix_version)
print(f"Setting up repository with {len(versions)} versions")
# Download all domains for all versions
domains = ["enterprise-attack", "mobile-attack", "ics-attack"]
downloaded_files = download_domains(
domains=domains,
download_dir=str(base_path),
all_versions=True,
stix_version=stix_version
)
# Verify all downloaded files
hash_dict = STIX20 if stix_version == "2.0" else STIX21
verified_count = 0
for domain, file_list in downloaded_files.items():
for file_path in file_list:
# Extract version from filename for hash lookup
for version, expected_hash in hash_dict.items():
if version in file_path:
if verify_file_hash(file_path, expected_hash):
verified_count += 1
else:
print(f"WARNING: Hash mismatch for {file_path}")
break
print(f"Repository setup complete:")
print(f" Total files: {sum(len(files) for files in downloaded_files.values())}")
print(f" Verified files: {verified_count}")
print(f" Location: {base_path}")
return downloaded_files
# Set up complete ATT&CK data repository
repository_files = setup_attack_data_repository("./complete_attack_repo/", "2.0")from mitreattack.stix20 import MitreAttackData
from mitreattack.download_stix import download_stix
from mitreattack.release_info import STIX20
def compare_technique_counts_across_versions(versions: List[str]):
"""
Compare technique counts across different ATT&CK versions.
"""
results = {}
for version in versions:
# Download specific version
file_path = download_stix(
stix_version="2.0",
domain="enterprise-attack",
download_dir="./version_comparison/",
release=version,
known_hash=STIX20[version]
)
# Load and analyze
attack_data = MitreAttackData(file_path)
techniques = attack_data.get_techniques()
subtechniques = attack_data.get_subtechniques()
results[version] = {
"techniques": len(techniques),
"subtechniques": len(subtechniques),
"total": len(techniques) + len(subtechniques)
}
print(f"Version {version}: {results[version]['total']} total techniques")
return results
# Compare technique evolution
versions_to_compare = ["12.1", "13.1", "14.1", "15.1"]
comparison_results = compare_technique_counts_across_versions(versions_to_compare)
for version, counts in comparison_results.items():
print(f"Version {version}: {counts['techniques']} techniques, {counts['subtechniques']} sub-techniques")Install with Tessl CLI
npx tessl i tessl/pypi-mitreattack-python