Skip to main content

Programmatic queries on MITRE ATT&CK threat actor techniques with natural language support

Project description

attack-query

PyPI version PyPI downloads Python 3.10+ License: MIT Ruff

Programmatic queries on MITRE ATT&CK threat actor techniques with natural language support.

Features

  • Cross-matrix support: Query Enterprise, Mobile, or ICS ATT&CK matrices
  • Natural language queries: "techniques used by APT28 or APT29 but not APT33"
  • Set operations: Union (or), intersection (and), difference (but not), complement (NOT used by)
  • Tactics queries: Query which tactics a group uses (derived from techniques)
  • Sub-technique support: Query parent/child technique relationships (T1566.001)
  • Group alias resolution: Use aliases like "Fancy Bear" instead of "APT28"
  • Software/Tool queries: Query malware and tools used by groups or implementing techniques
  • Mitigation queries: Find countermeasures for techniques or see what a mitigation covers
  • Data source queries: Explore detection data sources and data components for detection coverage
  • Campaign queries: Explore ATT&CK campaigns, attributed groups, and techniques used
  • Timeline queries: Filter campaigns and techniques by year or date range
  • Version selection: Query specific ATT&CK versions (e.g., v12.0, v15.1)
  • Similarity scoring: Find groups with similar technique profiles (Jaccard, Overlap, Cosine)
  • Smart mode: LLM-assisted query parsing for ambiguous queries (optional)
  • Fuzzy matching: Helpful suggestions when you make typos
  • Navigator export: Generate ATT&CK Navigator layer files
  • Heatmap generation: Visualize technique overlap across groups
  • Offline support: Cache data locally for offline use
  • Type-safe: Full type annotations with strict mypy checking

Installation

Using UV (recommended)

# Install from source
uv pip install git+https://github.com/swoodeng/attack-query.git

# Or clone and install in development mode
git clone https://github.com/swoodeng/attack-query.git
cd attack-query
uv pip install -e ".[dev]"

Using pip

pip install git+https://github.com/swoodeng/attack-query.git

Quick Start

Command Line

# Union: techniques used by ANY of the groups
attack-query "techniques used by APT28 or APT29"

# Intersection: techniques used by ALL groups
attack-query "techniques used by APT28 and APT29"
attack-query "techniques employed by APT28, APT29, and APT33"  # Alternative phrasing

# Difference: exclude techniques from certain groups
attack-query "techniques used by APT28 or APT29 but not APT33"
attack-query "techniques used by APT28 but not by APT29"       # "but not by" also works

# Verbose output (includes tactics)
attack-query "techniques used by APT28" -v

# Complement: techniques NOT used by a group
attack-query "techniques NOT used by APT28"

# Sub-technique queries
attack-query "sub-techniques of T1566"
attack-query "parent of T1566.001"

# Group alias resolution
attack-query "who is Fancy Bear"
attack-query "aliases of APT28"

# Software/Tool queries
attack-query "software used by APT28"
attack-query "groups using Mimikatz"
attack-query "techniques for Cobalt Strike"
attack-query "software using T1566"
attack-query "software info Mimikatz"

# Mixed software + group queries
attack-query "techniques used by Mimikatz but not APT29"           # Software minus group
attack-query "techniques used by software Mimikatz and group APT28" # Explicit qualifiers
attack-query "techniques used by both Cobalt Strike and APT28"      # Intersection

# Tactics queries
attack-query "tactics used by APT28"             # Tactics from group's techniques
attack-query "tactics used by APT28 and APT29"   # Tactics shared by both groups
attack-query "tactics used by APT28 or APT29"    # Tactics from either group
attack-query "tactics not used by APT28"         # Tactics NOT used by a group

# Mitigation queries
attack-query "mitigations for T1566"
attack-query "how to mitigate T1566"
attack-query "techniques mitigated by M1031"
attack-query "mitigation info M1017"

# Data source queries
attack-query "data sources"
attack-query "data source info Process"
attack-query "data components"
attack-query "data component info Process Creation"
attack-query "techniques detectable by Process Creation"

# Campaign queries
attack-query "campaigns"                          # List all campaigns
attack-query "campaigns by APT28"                 # Campaigns attributed to a group
attack-query "techniques in C0027"                # Techniques used in a campaign
attack-query "campaign info C0027"                # Campaign details

# Timeline queries
attack-query "campaigns in 2023"                  # Campaigns active in a year
attack-query "campaigns between 2022 and 2024"    # Campaigns in date range
attack-query "techniques used in 2023"            # Techniques from campaigns in year

# Similarity scoring
attack-query "groups similar to APT28"            # Find groups with similar TTPs
attack-query "similarity APT28 APT29"             # Detailed metrics between two groups
attack-query "groups like APT28 threshold 0.5"    # With minimum similarity score
attack-query "groups similar to APT28 using cosine"  # Different similarity metric

# Export formats
attack-query "techniques used by APT28" --format csv       # CSV output
attack-query "techniques used by APT28" --format md        # Markdown table
attack-query "techniques used by APT28" --format layer     # Navigator layer JSON
attack-query "techniques used by APT28" --json             # JSON output

# Use a specific ATT&CK version
attack-query --version 12.0 "techniques used by APT28"

# Use a different matrix (Mobile or ICS)
attack-query --matrix mobile "techniques used by APT28"
attack-query --matrix ics "techniques used by ALLANITE"

# List available versions
attack-query --list-versions

# Interactive mode
attack-query

Python API

from attack_query import ATTACKDataStore, ATTACKQueryEngine, Matrix

# Load latest ATT&CK data (Enterprise matrix by default)
store = ATTACKDataStore()
store.load()

# Or load a specific version
store = ATTACKDataStore(version="12.0")
store.load()

# Or load a different matrix (Mobile or ICS)
store = ATTACKDataStore(matrix=Matrix.MOBILE)
store.load()

store = ATTACKDataStore(matrix="ics")  # Also accepts string
store.load()

# Create query engine
engine = ATTACKQueryEngine(store)

# Get techniques used by a group
apt28_techniques = engine.get_group_techniques("APT28")

# Set operations
shared = engine.techniques_intersection(["APT28", "APT29"])
unique_to_apt28_29 = engine.techniques_difference(
    include_groups=["APT28", "APT29"],
    exclude_groups=["APT33"]
)

# Compare groups
comparison = engine.compare_groups("APT28", "APT29")
print(f"Jaccard similarity: {comparison['jaccard_similarity']:.1%}")

# Export to Navigator
layer = engine.export_navigator_layer(
    unique_to_apt28_29,
    name="Unique to APT28/29"
)

Natural Language Parser

from attack_query import ATTACKDataStore, ATTACKQueryEngine, NLQueryParser

store = ATTACKDataStore()
store.load()
engine = ATTACKQueryEngine(store)
parser = NLQueryParser(engine)

# Parse and execute natural language queries
# 'or' = union, 'and' = intersection, 'but not' = difference
results = parser.parse_and_execute(
    "techniques used by APT28 or APT29 but not APT33"
)

# Access results
for technique in results["techniques"]:
    print(f"{technique['id']}: {technique['name']}")

Supported Query Patterns

Pattern Example Set Operation
Single group techniques used by APT28
Union (ANY) techniques used by APT28 or APT29 A ∪ B
Intersection (ALL) techniques used by APT28 and APT29 A ∩ B
Comma-list with and techniques employed by APT28, APT29, and APT33 A ∩ B ∩ C
Union with exclusion techniques used by APT28 or APT29 but not APT33 (A ∪ B) − C
Intersection with exclusion techniques used by APT28 and APT29 but not APT33 (A ∩ B) − C
Complement techniques NOT used by APT28 Ā (all − A)
Sub-techniques sub-techniques of T1566
Parent technique parent of T1566.001
Group alias lookup who is Fancy Bear
List aliases aliases of APT28
Tactic filter techniques used by APT28 for initial access
Tactics by group tactics used by APT28
Tactics intersection tactics used by APT28 and APT29 A ∩ B
Tactics union tactics used by APT28 or APT29 A ∪ B
Tactics complement tactics not used by APT28 Ā (all − A)
Reverse lookup groups using T1566 x ∈ A
Comparison compare APT28 and APT29 Shows ∩, A−B, B−A
Software by group software used by APT28
Groups by software groups using Mimikatz
Techniques by software techniques for Cobalt Strike
Software by technique software using T1566
Software info software info Mimikatz
Mixed: software + group techniques used by Mimikatz but not APT29 S − G
Mixed: explicit qualifiers techniques used by software X and group Y S ∩ G
Mixed: both keyword techniques used by both Cobalt Strike and APT28 S ∩ G
Mitigations for technique mitigations for T1566
Techniques by mitigation techniques mitigated by M1031
Mitigation info mitigation info M1017
List data sources data sources
Data source info data source info Process
List data components data components
Data component info data component info Process Creation
Techniques by data component techniques detectable by Process Creation
List campaigns campaigns
Campaigns by group campaigns by APT28
Techniques in campaign techniques in C0027
Campaign info campaign info C0027
Campaigns in year campaigns in 2023
Campaigns in range campaigns between 2022 and 2024
Techniques in year techniques used in 2023
Techniques in range techniques between 2022 and 2024
Group techniques in year techniques used by APT28 in 2023 Campaign-based
Group techniques in range techniques used by APT28 between 2022 and 2024 Campaign-based
Similar groups groups similar to APT28
Group similarity similarity APT28 APT29 Jaccard, Overlap, Cosine
Similarity with threshold groups like APT28 threshold 0.5
Similarity with metric groups similar to APT28 using cosine
Export to CSV --format csv
Export to Markdown --format md
Export to Navigator --format layer

Matrix Selection

The tool supports all three ATT&CK matrices:

Matrix Flag Description
Enterprise --matrix enterprise (default) Techniques for Windows, Linux, macOS, Cloud, etc.
Mobile --matrix mobile Techniques for Android and iOS
ICS --matrix ics Techniques for Industrial Control Systems
# Query Mobile ATT&CK (default is Enterprise)
attack-query --matrix mobile "techniques used by APT28"

# Query ICS ATT&CK
attack-query --matrix ics "techniques used by ALLANITE"

# Combine with version selection
attack-query --matrix mobile --version 12.0 "groups"

Version Selection

The tool supports specific ATT&CK versions for reproducibility:

# List available versions
attack-query --list-versions

# Use ATT&CK v12.0 (October 2022)
attack-query --version 12.0 "techniques used by APT28"

Caching Behavior

Data Type Cache Duration Example Location
Specific version Permanent (immutable) ~/.cache/attack/enterprise-attack-12.0.json
Latest version 7 days ~/.cache/attack/mobile-attack-latest.json

Each matrix is cached separately, so you can work with Enterprise and Mobile data without re-downloading.

Smart Mode (LLM-Assisted)

Enable smart mode for LLM-assisted query parsing. Useful for ambiguous or non-standard queries.

Installation

# Install with smart mode dependencies
pip install attack-query[smart]

Usage

# Use smart mode with default model (ollama:llama3.2)
attack-query --smart "what attacks does fancy bear do"

# Specify a different model
attack-query --smart --model ollama:mistral "show me APT28 tools"
attack-query --smart --model openai:gpt-4o-mini "phishing techniques by russian groups"

Configuration

# Environment variables
export ATTACK_QUERY_COMPLETION_MODEL=ollama:llama3.2  # Default model
export OLLAMA_BASE_URL=http://localhost:11434         # Ollama endpoint
export OPENAI_API_KEY=sk-...                          # For OpenAI models

Supported Providers

Provider Model Examples Notes
ollama llama3.2, mistral, codellama Local, requires Ollama running
openai gpt-4o-mini, gpt-4o Cloud, requires API key

Fuzzy Matching

Even without smart mode, attack-query provides fuzzy matching suggestions when queries fail:

$ attack-query "techniques used by APT27"

❌ Error: Could not parse query
   Did you mean:
      • 'APT27' → 'APT28'
   Try pattern: techniques used by {GROUP}

Temporal Group Queries

Query techniques used by a group during a specific time period:

# Techniques used by APT28 in 2023 (based on campaign data)
attack-query "techniques used by APT28 in 2023"

# Techniques used by APT28 between 2022 and 2024
attack-query "techniques used by APT28 between 2022 and 2024"

How it works: These queries approximate temporal group activity by cross-referencing:

  1. Campaigns attributed to the group
  2. Campaign date ranges (first_seen/last_seen)
  3. Techniques used in those campaigns

⚠️ Note: Results only include techniques documented in campaigns, not all techniques attributed to the group. ATT&CK does not timestamp individual group-technique relationships.

Limitations

Direct group-technique timestamps: ATT&CK data does not include timestamps for when a specific group used a specific technique. The temporal group queries above provide an approximation based on campaign data.

Export Formats

Export query results in different formats:

Command Line

# CSV format for spreadsheets
attack-query "techniques used by APT28" --format csv > apt28.csv

# Markdown format for documentation
attack-query "techniques used by APT28" --format md > apt28.md

# Navigator layer for visualization
attack-query "techniques used by APT28" --format layer > apt28_layer.json

# JSON format for scripting
attack-query "techniques used by APT28" --json > apt28.json

# CSV with descriptions (verbose mode)
attack-query "techniques used by APT28" --format csv -v > apt28_full.csv

Interactive Mode

query> techniques used by APT28
query> export csv results.csv      # Export to CSV
query> export md results.md        # Export to Markdown
query> export layer.json           # Export to Navigator layer

Navigator Layer Export

Export query results as ATT&CK Navigator layer files:

from attack_query import ATTACKDataStore, ATTACKQueryEngine
import json

store = ATTACKDataStore()
store.load()
engine = ATTACKQueryEngine(store)

# Get techniques
techniques = engine.techniques_difference(["APT28", "APT29"], ["APT33"])

# Export as Navigator layer
layer = engine.export_navigator_layer(
    techniques,
    name="APT28/29 Unique Techniques",
    description="Techniques used by APT28 or APT29 but not APT33",
    color="#ff6666"
)

# Save to file
with open("layer.json", "w") as f:
    json.dump(layer, f, indent=2)

Then import the layer at https://mitre-attack.github.io/attack-navigator/

Development

Setup

git clone https://github.com/swoodeng/attack-query.git
cd attack-query
uv venv
source .venv/bin/activate  # or `.venv\Scripts\activate` on Windows
uv pip install -e ".[dev]"

Running Tests

pytest
pytest --cov=attack_query  # with coverage

Code Quality

ruff check src tests       # linting
ruff format src tests      # formatting
mypy src                   # type checking

Data Source

This tool uses the official MITRE ATT&CK STIX data from: https://github.com/mitre-attack/attack-stix-data

License

MIT License - see LICENSE for details.

Related Projects

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

attack_query-0.7.0.tar.gz (92.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

attack_query-0.7.0-py3-none-any.whl (49.4 kB view details)

Uploaded Python 3

File details

Details for the file attack_query-0.7.0.tar.gz.

File metadata

  • Download URL: attack_query-0.7.0.tar.gz
  • Upload date:
  • Size: 92.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for attack_query-0.7.0.tar.gz
Algorithm Hash digest
SHA256 25f39e0c7c1481cb21ffc151e429ad67ed33d1400eee14e0a60422da95a24ecc
MD5 9f8b72ed807c7a5b8000333982d68635
BLAKE2b-256 dcfd1f9f2eda851028dc62ca1609f206999ff85f9806064019afaee88f6480bd

See more details on using hashes here.

File details

Details for the file attack_query-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: attack_query-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 49.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for attack_query-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e78dd6fe16debc52112ebc2abc0889447b6014e2e9e1c2b241b384cb516ec690
MD5 399359c723d8ca64e0cae3d1fff49427
BLAKE2b-256 487051996fe119c1aeeef4f2778ad30afbec421bb8f2f8967942ad49489beb9c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page