I teased this in my last post, and as promised here is is.

So lets start off by giving credit where credit is due; the team behind D3FEND built a comprehensive graph model of defensive knowledge: techniques, artefacts, and relationships that describe how defenders respond to specific adversary behaviors.

Conceptually, it is strong.

Practically, it is harder to use.

The issue is not the model itself.

The issue is how it fits into the existing CTI ecosystem.

Most CTI platforms, including ours, standardise on STIX 2.1 as the common language for representing, exchanging, and reasoning about intelligence.

D3FEND, as published, does not slot cleanly into that world.

That makes it difficult to:

  • use D3FEND consistently across tools
  • integrate defensive knowledge into existing CTI workflows
  • treat defensive techniques as first-class CTI objects rather than external reference material

As a result, D3FEND often remains something people read about, rather than something they actively use.

The solution is to model D3FEND using STIX.

Not by flattening it into text fields or static mappings, but by expressing its concepts as proper STIX objects that can live inside existing tooling.

This post is an introduction to that problem, and the approach we took to solve it.


In this post

This post explains why modelling D3FEND as STIX is necessary, and how we approached doing it without flattening or oversimplifying the model.

We cover:

  • why D3FEND does not naturally fit into a STIX 2.1 ecosystem
  • why ATT&CK provided a useful structural reference point
  • what we mean by making D3FEND STIX-native, not just STIX-shaped
  • how we map D3FEND matrices, tactics, and techniques into existing STIX object types
  • how artefacts are represented so they can participate in the graph
  • how relationships are derived from OWL restrictions rather than direct fields
  • a proof-of-concept implementation

What we actually mean by modelling D3FEND as STIX

We wanted D3FEND to behave like first-class CTI data inside STIX-native tooling.

That means:

  • D3FEND concepts become real STIX objects
  • relationships are explicit, queryable, and consistent
  • the resulting bundle can be ingested by platforms that already understand STIX 2.1

So the goal was not “make something STIX-shaped”.

The goal was to make D3FEND interoperable.


Why ATT&CK was the obvious inspiration

When we started thinking about how to make D3FEND usable in a STIX-native world, we did not start from a blank page.

We already had a very strong precedent.

ATT&CK works not just because of its content, but because of its structure.

Conceptually, D3FEND and ATT&CK are already closely aligned.

That conceptual symmetry matters, because it means the mental model is already familiar. People who understand one can reason about the other without having to relearn everything from scratch.

But the inspiration was not just conceptual. ATT&CK is also deeply understood programmatically.

Over time, tools across the CTI ecosystem have learned how to:

  • ingest ATT&CK as STIX
  • store it as structured graph data
  • query it consistently
  • enrich it with additional context
  • and present it visually and analytically

From that perspective, the question was not: How do we invent a new way to represent defensive knowledge?

The question was: How do we express D3FEND in a way that existing tools already know how to handle?

ATT&CK provided a proven answer to that question.

Not as something to copy blindly, but as a structural reference point for how complex security knowledge can be made interoperable.

If a platform already supports ATT&CK as STIX, it should be able to ingest and work with D3FEND with minimal extra logic.

That is why we reused object types and properties that tools already understand.


The matrix: a single entry point for the framework

To make D3FEND feel like a coherent framework inside tooling, we start with a matrix object.

We model D3FEND as an x-mitre-matrix (a custom STIX object used by ATT&CK), because that type is already widely understood by tools, and it provides a simple entry point to the rest of the model.

The key property here is tactic_refs.

That list defines the tactics and the display order of the matrix.

In other words, this object is not just metadata.

It is the spine that makes the rest of the framework navigable.

{
	"type": "x-mitre-matrix",
	"spec_version": "2.1",
	"id": "x-mitre-matrix--00c1d7a9-ae23-585c-b3d1-a1295765de46",
	"created_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"created": "2025-12-16T00:12:00.000Z",
	"modified": "2025-12-16T00:12:00.000Z",
	"name": "D3FEND\u2122 - A knowledge graph of cybersecurity countermeasures",
	"description": "D3FEND is a framework which encodes a countermeasure knowledge base as a knowledge graph. The graph contains the types and relations that define key concepts in the cybersecurity countermeasure domain and the relations necessary to link those concepts to each other. Each of these concepts and relations are linked to references in the cybersecurity literature.",
	"tactic_refs": [
		"x-mitre-tactic--099ae1c4-95fe-5822-8942-613dad0dfd97",
		"x-mitre-tactic--bb808cca-f70d-5a1e-84e4-2ecba69fff38",
		"x-mitre-tactic--80c6d422-cc53-50b9-bb96-c7e64face646",
		"x-mitre-tactic--e65569cd-cb01-56db-af31-037455c1b8a5",
		"x-mitre-tactic--fb91e4b6-71f5-5ff1-8857-e792271670af",
		"x-mitre-tactic--0ccbac0d-777f-534b-b376-30041ad22a00",
		"x-mitre-tactic--ec1c58a8-367a-5f4c-8138-30e77687f26c"
	],
	"external_references": [
		{
			"source_name": "mitre-d3fend",
			"url": "https://d3fend.mitre.org/",
			"external_id": "mitre-d3fend"
		},
		{
			"source_name": "license",
			"external_id": "MIT"
		},
		{
			"source_name": "version",
			"url": "http://d3fend.mitre.org/ontologies/d3fend/1.3.0/d3fend.owl",
			"external_id": "1.3.0"
		}
	],
	"object_marking_refs": [
		"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
		"marking-definition--6923e7d4-e142-508c-aefc-b5f4dd27dc22"
	],
	"x_mitre_deprecated": false,
	"x_mitre_domains": [
		"d3fend"
	],
	"x_mitre_modified_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"x_mitre_version": "0.1"
}

Tactics: kept simple, kept compatible

D3FEND tactics map cleanly to x-mitre-tactic (a custom STIX object used by ATT&CK).

The source data already gives us what we need:

  • a stable @id
  • a label
  • a definition
  • and display metadata

We keep the mapping deliberately conservative:

  • name from rdfs:label
  • description from d3f:definition
  • x_mitre_shortname as a machine-friendly lowercase form of the label
  • external references pointing back to the D3FEND tactic page

The important design choice is that tactics remain tactics.

We do not invent new object types for them, because the ecosystem already has a strong concept of what a tactic is.

{
	"type": "x-mitre-tactic",
	"spec_version": "2.1",
	"id": "x-mitre-tactic--fb91e4b6-71f5-5ff1-8857-e792271670af",
	"created_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"created": "2025-12-16T00:12:00.000Z",
	"modified": "2025-12-16T00:12:00.000Z",
	"name": "Deceive",
	"description": "The deceive tactic is used to advertise, entice, and allow potential attackers access to an observed or controlled environment.",
	"external_references": [
		{
			"source_name": "mitre-d3fend",
			"url": "https://d3fend.mitre.org/tactic/d3f:Deceive",
			"external_id": "d3f:Deceive"
		}
	],
	"object_marking_refs": [
		"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
		"marking-definition--6923e7d4-e142-508c-aefc-b5f4dd27dc22"
	],
	"x_mitre_shortname": "deceive",
	"x_mitre_deprecated": false,
	"x_mitre_domains": [
		"d3fend"
	],
	"x_mitre_modified_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"x_mitre_version": "0.1"
}

Techniques: course of actions, deviation from ATT&CK

Here, we deliberately diverge from ATT&CK.

In ATT&CK, techniques are represented using attack-pattern STIX objects. Attack patterns describe adversary tradecraft — ways an adversary attempts to achieve an objective.

That semantic choice is a poor fit for D3FEND, which is defender-centric. A D3FEND “technique” is closer to a defensive measure or recommended action than it is to adversary behavior.

So for D3FEND techniques we use course-of-action.

A Course of Action represents defensive guidance: something a defender can do (or implement) to reduce risk, improve detection, or mitigate adversary activity. Like attack-pattern, it:

  • supports rich names and descriptions
  • supports external references cleanly
  • is widely indexed and displayed by CTI tooling

Most importantly, we can still make it behave like a “technique-like” object for tools that expect ATT&CK-style structures.

Making course-of-action render like a technique

We attach D3FEND techniques to tactics using kill_chain_phases, and preserve hierarchy using the same technique/sub-technique conventions used in ATT&CK.

We also set x_mitre_domains (an ATT&CK-specific property) on D3FEND technique objects. This gives tools a simple way to separate D3FEND content from other domains without inventing new types.

In short: we use the STIX type that best matches D3FEND semantics, while keeping the properties and relationships that existing “technique-aware” tooling understands.

{
	"type": "course-of-action",
	"spec_version": "2.1",
	"id": "course-of-action--8001c805-0860-5a0b-ad5f-70231796d303",
	"created_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"created": "2025-12-16T00:12:00.000Z",
	"modified": "2025-12-16T00:12:00.000Z",
	"name": "System File Analysis",
	"description": "Monitoring system files such as authentication databases, configuration files, system logs, and system executables for modification or tampering.\n\n## How it works\nThis technique ensures the integrity of system owned file resources. System files can impact the behavior below the user level.\n\n\n## Considerations\n* Need to manage the size of log file analysis.\n* False positives are a concern with this technique and filtering will need to be given additional thought.\n* A baseline or snapshot of file checksums should be established for future comparison.",
  "x_kill_chain_phases": [
    {
      "kill_chain_name": "d3fend",
      "phase_name": "detect"
    }
  ],
	"external_references": [
		{
			"source_name": "mitre-d3fend",
			"url": "https://d3fend.mitre.org/technique/d3f:SystemFileAnalysis",
			"external_id": "D3-SFA"
		},
		{
			"source_name": "CAR-2019-07-001: Access Permission Modification",
			"description": "Adversaries sometimes modify object access rights at the operating system level. There are varying motivations behind this action - they may not want some files/objects to be changed on systems for persistence reasons and therefore provide admin only rights; also, they may want files to be accessible with lower levels of permissions.",
			"url": "https://car.mitre.org/analytics/CAR-2019-07-001/"
		},
		{
			"source_name": "CAR-2013-01-002: Autorun Differences",
			"description": "The Sysinternals tool Autoruns checks the registry and file system for known identify persistence mechanisms. It will output any tools identified, including built-in or added-on Microsoft functionality and third party software. Many of these locations are known by adversaries and used to obtain Persistence. Running Autoruns periodically in an environment makes it possible to collect and monitor its output for differences, which may include the removal or addition of persistent tools. Depending on the persistence mechanism and location, legitimate software may be more likely to make changes than an adversary tool. Thus, this analytic may result in significant noise in a highly dynamic environment. While Autoruns is a convenient method to scan for programs using persistence mechanisms its scanning nature does not conform well to streaming based analytics. This analytic could be replaced with one that draws from sensors that collect registry and file information if streaming analytics are desired.\n\nUtilizes the Sysinternals autoruns tool (ignoring validated Microsoft entries). Primarily not a detection analytic by itself but through analysis of results by an analyst can be used for such. Building another analytic on top of this one identifying unusual entries would likely be a beneficial alternative.",
			"url": "https://car.mitre.org/analytics/CAR-2013-01-002/"
		},
		{
			"source_name": "CAR-2016-04-002: User Activity from Clearing Event Logs",
			"description": "It is unlikely that event log data would be cleared during normal operations, and it is likely that malicious attackers may try to cover their tracks by clearing an event log. When an event log gets cleared, it is suspicious. Alerting when a \"Clear Event Log\" is generated could point to this intruder technique. Centrally collecting events has the added benefit of making it much harder for attackers to cover their tracks. Event Forwarding permits sources to forward multiple copies of a collected event to multiple collectors, thus enabling redundant event collection. Using a redundant event collection model can minimize the single point of failure risk.",
			"url": "https://car.mitre.org/analytics/CAR-2016-04-002/"
		}
	],
	"object_marking_refs": [
		"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
		"marking-definition--6923e7d4-e142-508c-aefc-b5f4dd27dc22"
	],
	"x_mitre_deprecated": false,
	"x_mitre_domains": [
		"d3fend"
	],
	"x_mitre_is_subtechnique": true,
	"x_mitre_modified_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"x_mitre_platforms": [
		"-"
	],
	"x_mitre_version": "0.1"
}

Note: the phase_name value must match the x_mitre_shortname of the tactic you want this technique to be classified under.

A note on x_mitre_is_subtechnique

You may notice that some D3FEND techniques are marked with x_mitre_is_subtechnique set to true, even when they do not feel like narrow or low-level techniques.

This flag is purely structural.

In the STIX and ATT&CK data model, a sub-technique is simply a technique that specialises another technique.

It does not imply lower importance or greater specificity in absolute terms.

In this case, System File Analysis is modelled as a sub-technique because it is a specialisation of a broader defensive technique higher up the hierarchy (Operating System Monitoring).

We use x_mitre_is_subtechnique to preserve the original D3FEND technique hierarchy, so tools that already understand technique and sub-technique relationships can render and query it correctly.


Artefacts: represented as Indicators, with a deliberate hack

Artefacts are where STIX and D3FEND diverge most.

D3FEND treats artefacts as first-class concepts.

STIX does not have a native object type that maps cleanly to “an abstract class of thing in an environment”.

So we made a pragmatic choice.

We represent artefacts as Indicator objects, and we use:

  • pattern_type set to d3fend
  • pattern set to the original @id

This is not because artefacts are Indicators.

It is because Indicator is a widely supported STIX object that:

  • can carry name and description cleanly
  • is accepted by most ingestion pipelines
  • can participate in relationships in a predictable way

The pattern is effectively used as an id carrier, not as an actual detection pattern.

It is a compromise, but it is a useful one.

It allows artefacts to exist as proper nodes in the graph, and it allows techniques to link to them using the same relationship machinery as everything else.

{
	"type": "indicator",
	"spec_version": "2.1",
	"id": "indicator--60884624-43e9-5eb3-8e47-a352837deb96",
	"created_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"created": "2025-12-16T00:12:00.000Z",
	"modified": "2025-12-16T00:12:00.000Z",
	"name": "File",
	"description": "A file maintained in computer-readable form.",
	"indicator_types": [
		"unknown"
	],
	"pattern": "d3f:File",
	"pattern_type": "d3fend",
	"valid_from": "2025-12-16T00:12:00Z",
	"external_references": [
		{
			"source_name": "mitre-d3fend",
			"url": "https://d3fend.mitre.org/dao/artifact/d3f:File",
			"external_id": "d3f:File"
		},
		{
			"source_name": "rdfs-seeAlso",
			"url": "http://wordnet-rdf.princeton.edu/id/06521201-n"
		}
	],
	"object_marking_refs": [
		"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
		"marking-definition--6923e7d4-e142-508c-aefc-b5f4dd27dc22"
	],
	"x_mitre_domains": [
		"d3fend"
	]
}

Why not use SCOs for artefacts

A natural question is why we did not model artefacts as STIX Cyber-observable Objects.

SCOs are designed to represent specific observed instances in real data: a particular file, a particular process, a particular registry key, a particular network connection.

D3FEND artefacts are not instances.

They are abstract classes of things that defensive techniques operate on.

File in D3FEND is not a file you observed on a host.

It is the concept of a file as a defensive target.

If we used SCOs here, we would be mixing two different levels of meaning:

  • the ontology level of D3FEND
  • the observed instance level of STIX observables

It also would not help interoperability.

Many CTI platforms treat SCOs as incident level data, not as framework nodes in a matrix.

So we used Indicators as a pragmatic carrier type: it is widely supported, can participate in relationships, and can be ingested consistently.

We treat the pattern as an identifier carrier, not as an executable detection pattern.


Relationships: the real work happens in OWL restrictions

D3FEND is published as an OWL-based model.

In practice, that means important links are not always direct properties on an object.

They are often expressed through restrictions.

For example, a technique might not directly say:

  • enables Detect
  • analyzes File

Instead, those links can appear via rdfs:subClassOf entries that point to owl:Restriction objects.

Those restrictions then define:

  • which property is being asserted
  • and which target object it points to

So the conversion logic does not just read fields.

It resolves the graph.

For each restriction we can resolve, we create a STIX relationship object linking the technique to the target concept.

This is what turns D3FEND from a list of pages into a queryable graph inside STIX.

{
	"type": "relationship",
	"spec_version": "2.1",
	"id": "relationship--75918864-09fb-5911-a1a4-a78c06b4028c",
	"created_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5",
	"created": "2025-12-16T00:12:00.000Z",
	"modified": "2025-12-16T00:12:00.000Z",
	"relationship_type": "enables",
	"description": "Credential Hardening enables Harden",
	"source_ref": "course-of-action--4f49c3e8-59f1-5f6d-9b43-57f527fc12bb",
	"target_ref": "x-mitre-tactic--bb808cca-f70d-5a1e-84e4-2ecba69fff38",
	"external_references": [
		{
			"source_name": "mitre-d3fend",
			"url": "https://d3fend.mitre.org/technique/d3f:CredentialHardening",
			"external_id": "D3-CH"
		},
		{
			"source_name": "mitre-d3fend",
			"url": "https://d3fend.mitre.org/tactic/d3f:Harden",
			"external_id": "d3f:Harden"
		}
	],
	"object_marking_refs": [
		"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
		"marking-definition--6923e7d4-e142-508c-aefc-b5f4dd27dc22"
	],
	"x_mitre_deprecated": false,
	"x_mitre_modified_by_ref": "identity--9779a2db-f98c-5f4b-8d08-8ee04e02dbb5"
}

A graphical summary


Current shortfalls

This mapping is deliberately focused.

Right now, the script does not attempt to model every D3FEND concept.

It produces:

  • a matrix
  • tactics
  • techniques
  • artefacts as Indicators
  • and relationships between them

It does not yet cover all D3FEND object types.

There is also a practical limitation around timestamps. created and modified are tied to the D3FEND release date, which makes sense for a static export, but it is not enough to model updates over time in a STIX-native way.

Those are solvable problems, but they are out of scope for the initial goal: make D3FEND usable as structured CTI data inside STIX 2.1 tooling.


Proof of concept: d3fend2stix

Everything described in this post is implemented as a working proof of concept, d3fend2stix.

The code lives here.

This is not a finished library or a polished integration.

It is a WIP reference implementation that shows how the mapping works in practice.

You can use it to:

  • generate STIX 2.1 objects from the D3FEND ontology
  • inspect how tactics, techniques, artefacts, and relationships are represented
  • experiment with ingesting D3FEND into STIX-native tooling
  • validate or challenge the design decisions described above

The goal of the project is not to declare a final or canonical mapping.

The goal is to make the problem concrete, so defensive knowledge can be treated as something you can generate, link, and reason about, rather than something that only exists as documentation.

If you are working with D3FEND, STIX, or CTI tooling more broadly, consider this an invitation to experiment and provide feedback.

Once we’re happy with the final structure, expect to see D3FEND used across our tools.


CTI Butler

The most important cyber threat intelligence knowledgebases.

Discuss this post

Head on over to the dogesec community to discuss this post.

dogesec community

Posted by:

David Greenwood

David Greenwood, Do Only Good Everyday



Never miss an update


Sign up to receive new articles in your inbox as they published.

Your subscription could not be saved. Please try again.
Your subscription has been successful.