Appearance
The MACATable format is MACAT's native TOML-based format for defining and sharing procedures and simulations. It extends concepts from the Atomic Red Team atomic format with additional fields for file attachments, defense recommendations, threat profiles, and more.
There are two file types:
- .toml — plain text, can optionally embed file content as base64
- .mcz — compressed archive (tar.xz) containing a .toml plus external files
JSON Schemas are available for editor validation and autocomplete:
To use with Taplo (or the Even Better TOML VS Code extension), add this as the first line of your .toml file:
toml
#:schema https://docs.macat.io/schemas/macatable-simulation.schema.jsonDocument Types
A MACATable TOML file is one of two types.
Simulation
A named collection of procedures to execute together:
toml
id = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
name = "My Simulation"
version = 1
description = "Optional description"
tags = ["red-team", "apt"]
[[procedures]]
# ...| Field | Type | Required | Description |
|---|---|---|---|
id | UUID string | Yes | Unique identifier |
name | string | Yes | Simulation name |
version | integer | No | Version number (default: 1) |
description | string | No | Description |
tags | string array | No | Tags for categorization |
procedures | array | Yes | Procedures in this simulation |
variables | array | No | Variables shared across the simulation |
Library Export
A set of standalone procedures not tied to a simulation:
toml
version = 1
[[lib_procedures]]
# ...| Field | Type | Required | Description |
|---|---|---|---|
version | integer | No | Version number (default: 1) |
lib_procedures | array | Yes | Procedures in this export |
Procedures
Procedure definitions are the same in both document types. They appear as [[procedures]] in simulations and [[lib_procedures]] in library exports.
toml
[[procedures]]
id = "11111111-2222-3333-4444-555555555555"
name = "Scheduled Task Creation"
description = "Creates a scheduled task for persistence"
primary_technique = "T1053.005"
primary_tactic = "persistence"
mitre_tactics_ref = ["persistence", "execution"]
src_type = "macat"
supported_platforms = ["windows"]
threat_profile_ids = ["intrusion-set--abc123"]
possible_defenses = ["edr", "siem"]
tags = ["ransomware", "priority-0"]| Field | Type | Required | Description |
|---|---|---|---|
id | UUID string | Yes | Unique identifier |
name | string | Yes | Procedure name |
description | string | No | Description |
primary_technique | string | No | MITRE ATT&CK technique ID (e.g., T1053.005) |
primary_tactic | string | No | Primary MITRE ATT&CK tactic |
mitre_tactics_ref | string array | No | Related MITRE ATT&CK tactics |
src_type | string | No | "macat" or "art" |
supported_platforms | string array | No | e.g., windows, linux, macos |
threat_profile_ids | string array | No | STIX identity references |
possible_defenses | string array | No | Defense tool types that may detect this |
tags | string array | No | Tags for categorization |
Procedure Steps
Steps define the commands to execute. Both procedure_steps (main execution) and cleanup_steps (post-execution cleanup) use the same structure.
toml
[[procedures.procedure_steps]]
executor = "powershell"
command = "schtasks /create /tn #{task_name} /tr calc.exe /sc daily"
name = "Create Scheduled Task"
description = "Creates a daily scheduled task"
order = 0
privilege = true| Field | Type | Required | Description |
|---|---|---|---|
executor | string | Yes | powershell, cmd, bash, sh, or file_extractor |
command | string | No | Command to execute (default: empty). Supports #{variable} substitution. |
name | string | No | Step name |
description | string | No | Step description |
order | integer | No | Execution order |
privilege | boolean | No | Requires elevated privileges |
parameters | object | No | Key-value parameters for parameter-based executors |
Parameter-Based Executors
Some executors like file_extractor use parameters instead of a command string:
toml
[[procedures.procedure_steps]]
executor = "file_extractor"
order = 1
[procedures.procedure_steps.parameters]
file_ref = "payload"
destination = "C:\\ProgramData"
extract_mode = "auto"Parameter values also support #{variable} substitution.
Cleanup Steps
Same structure, run after execution to undo changes:
toml
[[procedures.cleanup_steps]]
executor = "powershell"
command = "schtasks /delete /tn #{task_name} /f"
order = 0Dependency Checks
Run before procedure steps to verify prerequisites are met:
toml
[[procedures.dependency_checks]]
dependency_check_executor = "powershell"
dependency_check_command = "Get-Command schtasks"
dependency_check_command_privilege = false
dependency_not_found_command = "Write-Host 'schtasks not available'"
name = "Check schtasks"
order = 0| Field | Type | Required | Description |
|---|---|---|---|
dependency_check_executor | string | Yes | Executor type for the check |
dependency_check_command | string | Yes | Command to verify the prerequisite |
dependency_check_command_privilege | boolean | No | Requires elevated privileges |
dependency_not_found_command | string | No | Command to run if the check fails |
name | string | No | Check name |
description | string | No | Check description |
order | integer | No | Execution order |
Variables
Configurable inputs referenced in commands using #{variable_name} syntax:
toml
[[procedures.variables]]
name = "task_name"
var_type = "string"
default = "MACATTask"
value = "CustomTask"
description = "Name of the scheduled task to create"| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Variable name, referenced as #{name} in commands |
var_type | string | Yes | Type (e.g., string, integer) |
default | string | No | Default value |
value | string | No | Current value, overrides default when set |
description | string | No | Description shown in the UI |
File References
Files can be attached to procedures and referenced by name. The key in the [procedures.files] table is the reference name used in step parameters (e.g., file_ref = "payload").
Database Reference
For files uploaded to MACAT's file storage:
toml
[procedures.files.payload]
location = "db"
name = "agent.exe"
folder = "/uploads"
required = true
sha256 = "e3b0c44..."Embedded
Base64-encoded file content stored inline in the TOML:
toml
[procedures.files.payload]
location = "embedded"
name = "agent.exe"
content = "TVqQAAMAAAA..."
size = 2048
sha256 = "e3b0c44..."
required = trueArchive
File stored inside an MCZ archive:
toml
[procedures.files.payload]
location = "archive"
name = "agent.exe"
path_in_archive = "files/agent.exe"
sha256 = "e3b0c44..."
required = true| Field | Type | Required | Description |
|---|---|---|---|
location | string | Yes | "db", "embedded", or "archive" |
name | string | Yes | Filename |
folder | string | No | Folder path (db) |
content | string | No | Base64-encoded content (embedded) |
path_in_archive | string | No | Path within MCZ (archive) |
size | integer | No | Original file size in bytes |
sha256 | string | No | SHA256 hash |
source | string | No | Origin (e.g., user_upload) |
required | boolean | No | Required for execution (default: true) |
Detection and Prevention
Optional rules or recommendations attached to a procedure:
toml
[[procedures.detection]]
content_type = "sigma"
content = """
title: Scheduled Task Creation
detection:
selection:
EventID: 4698
"""
[[procedures.prevention]]
content = "Block scheduled task creation via AppLocker policy"| Field | Type | Required | Description |
|---|---|---|---|
content_type | string | No | Format type (e.g., sigma, yara) |
content | string | Yes | Rule or recommendation content |
MCZ Archive Format
MCZ files are tar.xz compressed archives containing a procedure TOML and its associated files. The file extension is .mcz.
Structure
procedure_name.mcz (tar.xz)
+-- manifest.toml
+-- procedure.toml
+-- files/
+-- agent.exe
+-- config.jsonmanifest.toml
toml
[package]
format_version = "1.0"
created_at = "2025-01-01T00:00:00Z"
created_by = "MACAT v0.3.0"
encryption = "none"
[contents]
procedure_file = "procedure.toml"
files_dir = "files"
file_count = 2
total_size = 1048576| Field | Type | Description |
|---|---|---|
package.format_version | string | Archive format version (currently "1.0") |
package.created_at | string | RFC 3339 timestamp |
package.created_by | string | Creator identifier |
package.encryption | string | Encryption scheme (currently "none") |
contents.procedure_file | string | Filename of the procedure TOML |
contents.files_dir | string | Directory containing files |
contents.file_count | integer | Number of files |
contents.total_size | integer | Total size of all files in bytes |
Import and Export Behavior
When exporting to MCZ:
- Files with
location = "db"are extracted from the database - File content is stored in the
files/directory - File references are updated to
location = "archive"withpath_in_archiveset - Duplicate filenames are handled automatically
When importing from MCZ:
- Files are extracted from the archive
- Content is compressed and stored in MACAT's database
- File references are updated to
location = "db" - Duplicate files are deduplicated by name and folder
Full Example
toml
id = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
name = "Persistence Campaign"
version = 1
description = "Test persistence mechanisms"
tags = ["persistence", "detection-engineering"]
[[procedures]]
id = "11111111-2222-3333-4444-555555555555"
name = "Scheduled Task Creation"
description = "Creates a scheduled task for persistence"
primary_technique = "T1053.005"
primary_tactic = "persistence"
mitre_tactics_ref = ["persistence", "execution"]
supported_platforms = ["windows"]
possible_defenses = ["edr", "siem"]
tags = ["ransomware"]
[[procedures.procedure_steps]]
executor = "powershell"
command = "schtasks /create /tn #{task_name} /tr calc.exe /sc daily"
order = 0
privilege = true
[[procedures.cleanup_steps]]
executor = "powershell"
command = "schtasks /delete /tn #{task_name} /f"
order = 0
[[procedures.dependency_checks]]
dependency_check_executor = "powershell"
dependency_check_command = "Get-Command schtasks"
name = "Check schtasks"
order = 0
[[procedures.variables]]
name = "task_name"
var_type = "string"
default = "MACATTask"
description = "Name of the scheduled task"
[[procedures.detection]]
content_type = "sigma"
content = """
title: Scheduled Task Creation
detection:
selection:
EventID: 4698
"""