attack
This project is a LinkML model of MITRE ATT&CK v20.0 as The MITRE Corporation (MITRE) publishes it in STIX 2.1, with the extensions the ATT&CK Data Model (ADM) v4.11.7 defines. It covers the techniques, tactics, groups, campaigns, software, mitigations, assets, detection strategies, analytics, data components and data sources of the Enterprise, Mobile and ICS domains, and the matrices, collections and relationships that join them. Each class extends the lmodel/stix class it builds on.
- Schema documentation, generated from the schema
- About: how the elements are named and what the model leaves out
attack.yaml: the schema
Validating data
Section titled “Validating data”linkml-validate -s src/attack/schema/attack.yaml -C AttackTechnique technique.json
checks one object against the JSON Schema generated from the schema, and
-C AttackBundle checks a bundle. tests/test_data.py holds every example
to it. A whole ATT&CK release is large: just test-attack-data validates each
object of the pinned bundles on its own, against the class its type names.
Validate an object before loading it into either model in
src/attack/datamodel/. LinkML 1.12.1 generates models that check less:
- The dataclasses check required fields and enum values, but no pattern.
- The Pydantic models also check the patterns a field carries itself, such
as the form of
x_mitre_versionand of an object’sid, but not the form of a STIX timestamp. - Neither applies the relationship rules, and both read a bundle’s objects as
the base class
StixObject, so load a bundle’s objects one at a time, each as its own class.
No validator checks these rules of the ADM. tests/attack_rules.py checks
them over the examples, the extract under tests/data/attack-stix-data/ and,
in just test-attack-data, every object of the bundles:
- the first external reference of an object carries its ATT&CK ID, in the
form its class’s
attack_id_patternannotation gives, and a technique’s first reference namesmitre-attackas its source; - a technique’s ID has a sub-technique’s form exactly when
x_mitre_is_subtechniqueis true; - the first alias of a group, campaign or piece of software is its name;
- each citation of a campaign names one of its external references;
- a property with an
attack_domainsannotation appears only on an object of one of those domains, one withattack_excluded_domainsnever on an object of those, and one withattack_tacticonly beside a kill chain phase of that tactic; - a technique has at least one kill chain phase;
- no text of an object, such as a name, a description or an external reference’s source, is empty or only whitespace;
- a list of platforms, analytics, log sources, log source references or mutable elements names each item once;
- a bundle starts with its one collection, whose contents, like every relationship’s ends, are objects of the bundle;
- each kill chain phase of a technique names a tactic of its bundle;
- a sub-technique’s parent is a technique that is not one, whose ID the sub-technique’s extends and whose tactics it shares;
- a sub-technique has exactly one parent, and its platforms are among its parent’s;
- each log source reference of an analytic names a data component of its bundle, and a log and channel that the data component lists.
Where MITRE’s data breaks one of them, tests/test_upstream.py lists the
departure with its reason. The last two rules it lists by the ATT&CK ID of
each object that breaks them, and just test-attack-data fails both on a
new breach and on a listed one that no longer occurs.