# DeTT&CT scores ATT&CK coverage instead of collecting it

> DeTT&CT turns hand written YAML files about log sources, detections and visibility into scored ATT&CK Navigator layers, so a blue team can compare its own coverage with a threat actor's behaviour. It is a reporting instrument, not a detector.

**rabobank-cdc/DeTTECT** — Detect Tactics, Techniques & Combat Threats

- Repository: https://github.com/rabobank-cdc/DeTTECT
- Stars: 2,350 · Forks: 350
- Language: SCSS
- License: GPL-3.0
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/rabobank-cdc-dettect

## What DeTT&CT measures, and who that is for

DeTT&CT collects no telemetry and detects nothing on its own. It reads YAML files that you write about your own environment, then turns those files into scored views of how well you would see an attack. The unit of work is the ATT&CK technique: you score data sources, detections and visibility against techniques, and the point of the exercise is to compare those numbers against the behaviours of a named threat actor.

That framing decides who benefits. A detection engineer holding an inventory of log sources, a set of EQL rules and a rough idea of which adversaries matter gets a defensible report out of it. A team with none of those inputs gets layers with empty cells. Nothing in the project fills those cells for you, and no sensor connects to your estate.

Scope is the whole ATT&CK set rather than a single platform, spanning the Enterprise, ICS and Mobile domains, with output aimed at MITRE's ATT&CK Navigator and at spreadsheets. Rabobank, the Dutch National Police and the Cyber Security Sharing & Analytics alliance sponsored the work behind those domains, which tells you where the coverage came from and who to ask when a domain behaves oddly.

## One entry point, many specialised modules at the top level

The flat file layout names the pipeline. `dettect.py` is the entry point you invoke, `generic.py` and `generic_mode.py` hold the general analysis mode, `technique_mapping.py`, `data_source_mapping.py` and `group_mapping.py` keep the mapping tables for techniques, log sources and adversary groups, and `navigator_layer.py` emits the JSON layer files the Navigator consumes. `file_output.py` handles what lands on disk, `eql_yaml.py` deals with the query side, `attack_taxii_client.py` is the TAXII path, and `constants.py` holds shared values.

Two more modules sit at the top level without explanation here: `health.py` and `upgrade.py`. The README does not describe what `health.py` checks, nor does it document the arguments of `upgrade.py`, so anyone planning around them has to read the source or the wiki.

Data lives beside the code rather than inside the package. A `data/` directory, a `sample-data/` directory you can copy, and a `threat-actor-data/` directory carry the shipped content, `tests/` exists for the test suite, and `scoring_table.xlsx` at the root holds the scoring tables for detections, data sources and visibility.

## Building the image and pointing the CLI at an input directory

There is no `pip install` line for the tool itself in the README. The documented entry point for setup is the Getting-started page on the project Wiki, and the practical path the repository supports is the container. The Dockerfile starts from a slim Debian Python image, copies the tree to `/opt/DeTTECT`, and marks the container so the editor knows it is running inside it:

```bash
FROM python:3.10-slim-bullseye
ENV DeTTECT_DOCKER_CONTAINER 1
EXPOSE 8080/tcp
```

Two directories are created at build time and their roles are fixed by the comments in the Dockerfile: `input` holds the data source, technique and group YAML administration files, and `output` receives everything the run produces, such as ATT&CK Navigator layer files.

```bash
RUN pip install --no-cache-dir -r requirements.txt
RUN mkdir -p input
RUN mkdir -p output
```

With those in place, a first real run is one command. In general mode with the `-ds` flag, the CLI ranks which data sources inside ATT&CK cover the most techniques, which is a reasonable starting point for deciding where to invest in log collection:

```bash
python dettect.py generic -ds
```

What you should see is an analysis of your own YAML, not of any live system. Nothing in that invocation contacts an endpoint, a SIEM or a network sensor.

## Pinned dependencies expose the input formats the tool expects

Every requirement is pinned with an exact version, which makes an install reproducible and removes any automatic patch-level upgrade path:

```text
simplejson==3.19.3
plotly==5.24.1
pandas==2.2.3
xlsxwriter==3.2.0
ruamel.yaml==0.18.6
eql==0.9.19
stix2==3.0.1
taxii2-client==2.3.0
```

Three of those pins describe what DeTT&CT can read. A pin at 0.9.19 on Event Query Language matches the module named `eql_yaml.py`, so EQL rules are a supported input. The 3.0.1 pin on stix2 covers STIX handling, and the 2.3.0 pin on taxii2-client sits next to `attack_taxii_client.py`, so technique and group data can be pulled over TAXII rather than only read from local files.

The remaining pins describe the output side: `pandas` and `plotly` for statistics and charts, `xlsxwriter` for the spreadsheet exports, `ruamel.yaml` for round-tripping the administration files without reordering them, and `simplejson` for the layer output. Because the pins are exact rather than ranges, moving to a newer ATT&CK content set or a newer STIX package is a manual edit of this file, and `upgrade.py` exists in the repository without documented usage.

## The image label reads 1.9.0 while the project sits at 2.2.0

One detail in the build file contradicts the rest of the repository. The Dockerfile carries this label:

```bash
LABEL version="1.9.0"
```

Meanwhile the README points at 2.2.0 as the current line, and that build was published on 2026-01-21, after 2.1.0 from 2025-04-30 and 2.0.0 from 2024-11-22. The repository itself is not frozen: the last push was on 2026-09-14.

Read literally, the image tag is a stale label rather than a claim about the code inside the image, since the build copies the working tree and installs from `requirements.txt`. Still, it is the kind of label that automation reads, and anyone automating around DeTT&CT containers should verify the running code version directly instead of trusting that metadata.

## Every score is an assertion you typed, not a measurement

The scoring tables for detections, data sources and visibility ship as a spreadsheet, and the YAML administration files hold the judgements. The CLI reads those judgements, applies the tables and renders the result. It cannot tell you that a log source you rated highly is silently truncated at midnight, and it cannot tell you that a detection rule never fires.

Two practical limits follow. First, the effort scales with the size of your mapping: every technique you care about needs entries across several files before any comparison means anything. Second, the output is only as current as the last edit of those files, and the README documents no process, review cadence or rollback for them.

There is a small hint about output hygiene, at least. The project asks that layers be opened in the Navigator with a URL that sets `comment_underline=false` and `metadata_underline=false`, so that metadata the CLI writes is not flagged with a yellow underline. That instruction exists because fields in the generated layer do get flagged, and it is the only formatting guidance given for the Navigator output.

## Navigator draws the layers, DeTT&CT has to build them first

MITRE's ATT&CK Navigator is the obvious alternative and does something much narrower. It takes a layer JSON that you author or generate yourself, colours it, and lets you compare layers. It performs no scoring, keeps no administration files, and has no opinion about data source quality or on which of your detections actually fire. DeTT&CT sits upstream: it produces those layer files from YAML plus a scoring table, and the Navigator is its viewer.

Automation is the other path, and it is not in this repository. Dettectinator, a separate third party project, is a Python library and command line tool whose plugins read detections from a SIEM or EDR and create or update the DeTT&CT YAML file. In other words, if you want your coverage files populated from real tooling rather than by hand, that integration arrives from outside this codebase and has to be evaluated on its own terms.

## Conclusion

DeTT&CT fits teams that already keep ATT&CK mappings in YAML and want scoring and comparison layered on top of them. It does not fit teams with no technique inventory, no log source inventory or no appetite for hand maintained administration files, because every number it renders originates in those files. Before adopting, check two things: whether your detections can be expressed as the EQL and STIX inputs its pinned dependencies expect, and whether the wiki Getting-started page still matches the v2.2.0 command surface you will run. The GPL-3.0 terms govern what you may redistribute from it.

## FAQ

### What is DeTT&CT used for?

It scores and compares data log source quality, visibility coverage, detection coverage and threat actor behaviours across the Enterprise, ICS and Mobile ATT&CK domains, and it reports statistics on the number of techniques covered per data source.

### How do I install DeTT&CT?

The README sends you to the Getting-started page on the project Wiki rather than giving an install command for the CLI itself. The Dockerfile shows the container route: a python:3.10-slim-bullseye base, a pip install of the pinned requirements, an input directory for your YAML files and an output directory for layer files, with port 8080 exposed for the editor.

### Does DeTT&CT read detections from my SIEM or EDR?

Not from this repository. That integration comes from Dettectinator, a separate third party Python library and CLI whose plugins read detections from a SIEM or EDR and create or update the DeTT&CT YAML file.

### Where do the scores in the output actually come from?

They come from the YAML administration files you write, graded against the scoring tables shipped as scoring_table.xlsx for detections, data sources and visibility. The CLI reads those files, applies the tables and writes ATT&CK Navigator layer files and spreadsheet exports.

## Sources

- [Issues](https://github.com/rabobank-cdc/DeTTECT/issues)
- [License: GPL-3.0](https://github.com/rabobank-cdc/DeTTECT/blob/master/LICENSE)
- [rabobank-cdc/DeTTECT on GitHub](https://github.com/rabobank-cdc/DeTTECT)
- [README](https://github.com/rabobank-cdc/DeTTECT/blob/master/README.md)
- [Releases](https://github.com/rabobank-cdc/DeTTECT/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rabobank-cdc-dettect
