Think of the ATT&CK Workbench as a local, editable extension of core ATT&CK.

With the Workbench you can:

  • Annotate the official ATT&CK dataset to match your local knowledge
  • Create an aligned dataset (same object model) for internal use
  • And share that dataset with colleagues or other tools

In this post I’ll walk through common use cases: installing the Workbench, importing ATT&CK, creating objects, linking them to core techniques, and publishing collections.


Install and run

I use Docker locally. Follow the Docker instructions in the Workbench repo or install manually if you prefer.

mkdir attack-workbench
cd attack-workbench
git clone https://github.com/center-for-threat-informed-defense/attack-workbench-frontend.git
git clone https://github.com/center-for-threat-informed-defense/attack-workbench-collection-manager.git
git clone https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api.git
cd attack-workbench-frontend
docker-compose up

Open http://localhost in a browser and you’ll see the Workbench UI.


Creating an organisation

On first run you’ll be prompted to create an Organization Identity.

ATT&CK Workbench Identity

Your organization identity is used to attribute the STIX objects you create or update. Practically, the Workbench generates a STIX 2.1 Identity object and references it in objects you author — making it easy to track who created or modified items in shared collections.


Importing MITRE’s version of ATT&CK

Out of the box, the Workbench is empty. The first thing most users do is import MITRE’s official ATT&CK Collections.

ATT&CK Workbench Techniques

A Collection is a set of related ATT&CK objects (for example, a particular release of Enterprise ATT&CK). MITRE publishes an index of collections (a Collection Index) — each collection entry points to a STIX bundle for a domain/version.

Here’s an example Collection Index:

{
    "id": "10296991-439b-4202-90a3-e38812613ad4",
    "name": "MITRE ATT&CK",
    "description": "MITRE ATT&CK is a globally-accessible knowledge base of adversary tactics and techniques based on real-world observations. The ATT&CK knowledge base is used as a foundation for the development of specific threat models and methodologies in the private sector, in government, and in the cybersecurity product and service community.",
    "created": "2018-01-17T12:56:55.080000+00:00",
    "modified": "2022-05-24T14:00:00.188000+00:00",
    "collections": [
        {
            "id": "x-mitre-collection--402e24b4-436e-4936-b19b-2038648f489",
            "created": "2018-01-17T12:56:55.080Z",
            "versions": [
                {
                    "version": "15.1",
                    "url": "https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master/enterprise-attack/enterprise-attack-15.1.json",
                    "modified": "2024-05-02T14:00:00.188Z"
                },
                {
                    "version": "15.0",
                    "url": "https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master/enterprise-attack/enterprise-attack-15.0.json",
                    "modified": "2024-04-23T14:00:00.188Z"
                }
            ]
        }
    ]
}

To import MITRE’s data into Workbench:

  1. CollectionsImported CollectionsAdd a Collection Index
  2. Paste https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master/index.json
  3. Click Preview and then Add
  4. Then pick the domain (Enterprise / Mobile / ICS) and the version you want, and click the download icon.

ATT&CK Workbench Import

ATT&CK Workbench Imported

ATT&CK Workbench Import Collection

ATT&CK Workbench Imported Workbench Technique

Tip: you can subscribe the Workbench to Collection Indexes, so new published versions become visible automatically.


Annotating ATT&CK

Workbench enables users to annotate their local copy of ATT&CK with note-taking capabilities. Notes are an excellent way to capture additional context about an object in your knowledge base and can be applied to matrices, techniques, tactics, mitigations, groups, and software.

ATT&CK Workbench Annotating Techniques


Creating new ATT&CK Objects

Often you’ll want to add new Software, Groups, or Mitigations that link back to MITRE techniques. You generally do not want to create entirely new matrices — instead, extend the domain data with new objects that link to core techniques.

Example use case: Palo Alto Unit 42’s “Popping Eagle” report describes a second-stage malware called Going Eagle. It isn’t in MITRE’s software list, so it’s a good candidate for a custom Software (malware) object.

ATT&CK Workbench Create Software

When creating a new software object, the Workbench asks whether it’s Software (Tool) or Software (Malware). If you’re unsure, the STIX 2.1 definitions are a good reference:

  • Tools — legitimate software that can be used by attackers (system/admin utilities, etc.).
  • Malware — malicious code inserted into systems.

We classified Going Eagle as malware after reading the report.

ATT&CK Workbench Create Software

I can now fill in the required and optional fields for the object:

  • type: Software (Malware)
    • STIX Property: type
    • Note: already set as a result of creation
  • name: name of the Object
    • STIX Property: name
  • ID
    • STIX Property: external_references.external_id
    • Note: must follow ATT&CK Object ID structure (must start with S)
  • version
    • STIX Property: x_mitre_version
  • platforms
    • STIX Property: x_mitre_platforms
  • contributors
    • STIX Property: x_mitre_contributors
    • Note: A list of strings detailing contributors, e.g. David G (is not a reference to an Identity Object)
  • associated software
    • STIX Property: x_mitre_aliases (software name), external_references.source_name (software name) and external_references.description (software description)
  • description
    • STIX Property: description
  • domains
    • STIX Property: x_mitre_domains

Here is the STIX Malware SDO generated by the Workbench;

{
    "labels": [],
    "x_mitre_platforms": [
        "Windows"
    ],
    "x_mitre_domains": [
        "enterprise-attack"
    ],
    "x_mitre_contributors": [
        "david",
        "greenwood"
    ],
    "x_mitre_aliases": [
        "my software"
    ],
    "object_marking_refs": [],
    "type": "malware",
    "id": "malware--ee25ab98-d40c-46c1-8fbe-eed63ca48f7b",
    "created": "2022-02-11T08:53:40.731Z",
    "modified": "2022-02-28T18:52:19.031Z",
    "x_mitre_version": "0.1",
    "external_references": [
        {
            "source_name": "mitre-attack",
            "external_id": "S9001",
            "url": "https://attack.mitre.org/software/S9001"
        },
        {
            "source_name": "my software",
            "description": "just some software"
        }
    ],
    "x_mitre_deprecated": false,
    "revoked": false,
    "description": "* Original package name Eagle2.5-Client-Dll (outlined in red in Figure 6).\n* Original function names (like main.StartEagle).\n* Packages from Go standard and extended library (like bufio, log, x/net).\n* Packages from other resources like GitHub repositories (outlined in yellow and green in Figure 6).",
    "spec_version": "2.1",
    "created_by_ref": "identity--d1dd6b52-23b7-490c-b54f-810fb1136752",
    "name": "Going Eagle",
    "is_family": true,
    "x_mitre_attack_spec_version": "2.1.0",
    "x_mitre_modified_by_ref": "identity--d1dd6b52-23b7-490c-b54f-810fb1136752"
}

Linking objects with relationships

To make your software show up in the right contexts (e.g., technique pages), create STIX relationships — e.g., malware -> uses -> attack-pattern.

For example, I know from the Popping Eagle report some of the MITRE ATT&CK Techniques the Malware leverages.

When editing the Software Object, after it has been created, I can create the supported Relationships for the STIX 2.1 Object type, in this case, Malware.

ATT&CK Workbench Popping Eagle Technique

ATT&CK Workbench Join Objects with Relationship

Here is the STIX SRO generated by the Workbench;

{
    "x_mitre_domains": [],
    "object_marking_refs": [],
    "type": "relationship",
    "id": "relationship--25624dc3-abfc-4186-b242-16d37742bf68",
    "created": "2022-06-28T13:09:39.457Z",
    "modified": "2022-06-28T13:09:39.457Z",
    "x_mitre_version": "0.1",
    "external_references": [],
    "x_mitre_deprecated": false,
    "revoked": false,
    "description": "Here's how Going Eagle uses it",
    "spec_version": "2.1",
    "relationship_type": "uses",
    "source_ref": "malware--ee25ab98-d40c-46c1-8fbe-eed63ca48f7b",
    "target_ref": "attack-pattern--707399d6-ab3e-4963-9315-d9d3818cd6a0",
    "x_mitre_attack_spec_version": "2.1.0",
    "created_by_ref": "identity--d1dd6b52-23b7-490c-b54f-810fb1136752",
    "x_mitre_modified_by_ref": "identity--d1dd6b52-23b7-490c-b54f-810fb1136752"
}

After you link objects, move them through the workflow: Work In Progress → Awaiting Review → Reviewed.

ATT&CK Workbench workflow

You can also revoke or deprecate objects when required.


Working Programmatically with the Workbench

The Workbench ships with an API that covers all the functions to work with data; view (GET), create (POST), update (PUT), and delete (DELETE actions).

You can access the docs when the Workbench is running at; localhost/api-docs/.

ATT&CK Workbench API

I can use the GET /api/software Endpoint to retrieve the Software Object (Tool) I created, Going Eagle, using the search Parameter;

curl -X GET "http://localhost/api/software?search=Going%20Eagle"

The response is returned in JSON structured into various sections;

  • stix: contains the full STIX 2.1 Object for the Software (STIX malware Object).
  • workspace: this contains Workbench information, including workflow status
  • created_by_identity: contains a nested stix Identity Object (for creator)
  • modified_by_identity: in case Objects are modified by another user (and thus new major STIX version created) a nested stix object which contains the STIX Identity Object of editor

I can also GET the Relationship I created, using the sourceRef parameter now that I know the STIX id of the malware Object.

curl -X GET "http://localhost/api/relationships?sourceRef=malware--ee25ab98-d40c-46c1-8fbe-eed63ca48f7b"

You can also create Objects. Here is an example request using a dummy Technique to demonstrate…

curl -X POST "http://localhost/api/techniques" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{\"workspace\":{\"workflow\":{\"state\":\"awaiting-review\"},\"attackId\":\"TZ998\",\"collections\":[]},\"stix\":{\"type\":\"attack-pattern\",\"spec_version\":\"2.1\",\"created\":\"2022-06-29T06:58:09.436Z\",\"modified\":\"2022-06-29T06:58:09.436Z\",\"created_by_ref\":\"identity--d1dd6b52-23b7-490c-b54f-810fb1136752\",\"revoked\":false,\"external_references\":[{\"source_name\":\"mitre-attack\",\"description\":\"This is a technique external references description\",\"url\":\"string\",\"external_id\":\"TZ998\"}],\"name\":\"A new technique\",\"description\":\"This is a technique description.\",\"x_mitre_modified_by_ref\":\"identity--d1dd6b52-23b7-490c-b54f-810fb1136752\",\"x_mitre_contributors\":[\"DOGESEC DEMO\"],\"x_mitre_platforms\":[\"Windows\"],\"x_mitre_deprecated\":false,\"x_mitre_domains\":[\"enterprise-attack\"],\"x_mitre_detection\":\"Here is how to find it\",\"x_mitre_version\":\"1.0\",\"x_mitre_attack_spec_version\":\"2.1.0\"}}'

Finally to update an Object, I can use the PUT endpoints.

As an example, I will update the Technique I just created. The structure of the URL for a PUT request on an Object is as follows

curl -X PUT "http://localhost/api/techniques/<STIX_ID>/modified/<MODIFIED_DATE>"

Note, <STIX_ID> is the entire STIX ID (e.g. attack-pattern--92081b2d-bb81-47f0-9714-a06a5d60e461) and <MODIFIED_DATE> is the modified_time currently assigned to the STIX Object you want to changes (in my case, what I received in the response when creating the Object) – it is not the modified_time you want to set (you must set this in the request body under the modified_time field).

For example,

curl -X PUT "http://localhost/api/techniques/attack-pattern--92081b2d-bb81-47f0-9714-a06a5d60e461/modified/2022-06-29T06:58:09.436Z"

If you do not know the modified_time of the Object, you can obtain it by making a GET request for the latest version of it which will print the STIX Object with the modified_time Property:

curl -X GET "http://localhost/api/techniques/attack-pattern--92081b2d-bb81-47f0-9714-a06a5d60e461?versions=latest"

In the body of the request you need to pass all Object Properties (whether you want to update them or not), this includes the id Property. If you do not want to make changes to a Property you must pass it as it currently exists. If you want to change it, simply change the Property value.

To remove optional Properties you can simply omit them from the body of the request. Be careful, all x_mitre custom Properties are optional, but deleting them (omitting them from the body) will cause issues with ATT&CK integration.

In this example request body I am updating only updating the name and modified_time Properties of my Technique Object;

curl -X PUT "http://localhost/api/techniques/attack-pattern--92081b2d-bb81-47f0-9714-a06a5d60e461/modified/2022-06-29T06:58:09.436Z" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"workspace":{"workflow":{"state":"awaiting-review"},"attackId":"TZ998","collections":[]},"stix":{"type":"attack-pattern","spec_version":"2.1","created":"2022-06-29T06:58:09.436Z","modified":"2022-06-29T07:58:09.436Z","id":"attack-pattern--92081b2d-bb81-47f0-9714-a06a5d60e461","created_by_ref":"identity--d1dd6b52-23b7-490c-b54f-810fb1136752","revoked":false,"external_references":[{"source_name":"mitre-attack","description":"This is a technique external references description","url":"string","external_id":"TZ998"}],"name":"A new name for this technique","description":"This is a technique description.","x_mitre_modified_by_ref":"identity--d1dd6b52-23b7-490c-b54f-810fb1136752","x_mitre_contributors":["DOGESEC DEMO"],"x_mitre_platforms":["Windows"],"x_mitre_deprecated":false,"x_mitre_domains":["enterprise-attack"],"x_mitre_detection":"Here is how to find it","x_mitre_version":"1.0","x_mitre_attack_spec_version":"2.1.0"}}'

Sharing and Collaborating with Workbench

As you have already seen it is possible to import Collections to Workbench.

It is also possible to create your own that can be used to share and collaborate from.

Create a custom collection from objects you’ve authored:

  • CollectionsMy Collections → Create New Collection
  • Add objects to the collection and save it

To make your collection importable by other Workbenches, host the collection JSON at a public URL and publish a Collection Index pointing to it (the same structure MITRE uses). Share the Collection Index URL so other users can import your collection.

ATT&CK Workbench custom collection

ATT&CK Workbench add object to custom collection

ATT&CK Workbench add object to custom collection

ATT&CK Workbench custom collection

It is also possible to share your collections using a TAXII Server, but I won’t cover that in this post.


Final notes & best practices

  • Don’t reinvent matrices. Extend existing domains with new software, groups, or mitigations and link them to core techniques.
  • Use strong attribution. Create meaningful Identity objects for organizations that publish or modify data — it preserves provenance.
  • Review before publishing. Use the Workbench workflow and have peers verify relationships and descriptions.
  • Host Collections publicly if you want others to import them. Provide a Collection Index or TAXII Server so other Workbenches can discover your bundle

CTI Butler

The CTI Search Engine.

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.