{"id":19883638,"url":"https://github.com/muchdogesec/disarm2stix","last_synced_at":"2025-07-28T11:06:36.464Z","repository":{"id":252096847,"uuid":"809660686","full_name":"muchdogesec/disarm2stix","owner":"muchdogesec","description":"A command line tool that turns the DISARM framework into STIX 2.1 Objects.","archived":false,"fork":false,"pushed_at":"2025-01-23T06:38:12.000Z","size":692,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-02T00:06:19.274Z","etag":null,"topics":["disarm","stix2"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/muchdogesec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-03T07:52:34.000Z","updated_at":"2025-06-18T12:54:25.000Z","dependencies_parsed_at":"2024-08-07T18:17:14.155Z","dependency_job_id":"e650e579-a072-4ad4-872c-4bc730f4bfa6","html_url":"https://github.com/muchdogesec/disarm2stix","commit_stats":null,"previous_names":["muchdogesec/disarm2stix"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/muchdogesec/disarm2stix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muchdogesec%2Fdisarm2stix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muchdogesec%2Fdisarm2stix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muchdogesec%2Fdisarm2stix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muchdogesec%2Fdisarm2stix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/muchdogesec","download_url":"https://codeload.github.com/muchdogesec/disarm2stix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muchdogesec%2Fdisarm2stix/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267505099,"owners_count":24098346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["disarm","stix2"],"created_at":"2024-11-12T17:21:44.093Z","updated_at":"2025-07-28T11:06:36.441Z","avatar_url":"https://github.com/muchdogesec.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# disarm2stix\n\nA command line tool that turns the DISARM framework into STIX 2.1 Objects.\n\n## Before you begin\n\nWe host a full web API that includes all objects created by location2stix, [CTIButler](https://www.ctibutler.com/).\n\n## Overview\n\n![](docs/disarm2stix.png)\n\nThe [DISARM Framework](https://www.disarm.foundation/framework) in parts aims to provide a single knowledge-base for disinformation classifications.\n\nIn the way MITRE ATT\u0026CK has provided a standard for contextual information about adversary tactics and techniques based on real-world observations, DISARM aims to do the same for disinformation.\n\nThis code is heavily based on the DISARM Foundations [DISARM-STIX2 repository](https://github.com/DISARMFoundation/DISARM-STIX2/). I decided to create a seperate codebase as that repository does not seem to be actively maintained.\n\nThe code in this repository;\n\n1. Takes the latest DISARM data (`.xls` file)\n2. Converts them to STIX 2.1 Objects\n3. Stores the STIX 2.1 Objects in the file store\n\n## Install\n\n```shell\n# get code\ngit clone https://github.com/muchdogesec/disarm2stix\ncd disarm2stix\n# create venv\npython3 -m venv disarm2stix_venv\nsource disarm2stix_venv/bin/activate\n# install requirements\npip3 install -r requirements.txt\n```\n\n### Versioning\n\nMake sure to set the `DISARM_VERSION` correctly (see section \"Shortcomings of this code\" in this readme).\n\nLine 1 of this file defines the DISARM version number.\n\nLine 2 of this file defines the datetime (`YYYY-MM-DD`) the specified version on line 1 was published (will be used as `modified` time of objects.\n\n## Run\n\nGenerate the STIX objects in the `stix2_objects/` folder;\n\n```shell \npython3 disarm2stix.py\n```\n\nOn each run, all objects will be completely regenerated.\n\n## How it works\n\nThe DISARM foundation maintain an Excel copy of the DISARM Framework here:\n\n```shell\nhttps://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/main/DISARM_MASTER_DATA/DISARM_FRAMEWORKS_MASTER.xlsx\n```\n\nThis is downloaded on each request, and is used to generate the STIX 2.1 objects. Currently only the `techniques` and `tactics` tabs are used by this script.\n\n## Mapping information\n\ndisarm2stix converts the corresponding DISARM object into the following STIX 2.1 object shown in the following table.\n\n| DISARM    | STIX2                 |\n|-----------|-----------------------|\n| Matrix    | `x-mitre-matrix`      |\n| Tactic    | `x-mitre-tactic`      |\n| Technique | `attack-pattern`      |\n\nThis conversion (especially the STIX custom objects `x-`) is heavily inspired by MITRE ATT\u0026CK STIX 2.1 Objects (see note on ATT\u0026CK navigator).\n\nNote, this code only considers the DISARM Red Framework at present.\n\nYou can see the high level structure of how the STIX objects are linked together here:\n\nhttps://miro.com/app/board/uXjVKpP-IGw=/?share_link_id=561813119363\n\n### Marking Definition / Identity\n\nThese are hardcoded and imported from our [stix4doge repository](https://github.com/muchdogesec/stix4doge). Specifically these objects;\n\n* Marking Definition: https://raw.githubusercontent.com/muchdogesec/stix4doge/main/objects/marking-definition/disarm2stix.json\n* Identity: https://raw.githubusercontent.com/muchdogesec/stix4doge/main/objects/identity/disarm2stix.json\n\n### Collection\n\nLists all objects in the bundle (except itself);\n\n```json\n{\n    \"type\": \"x-mitre-collection\",\n    \"spec_version\": \"2.1\",\n    \"id\": \"x-mitre-collection--\u003cUUID V5\u003e\",\n    \"created_by_ref\": \"\u003cIMPORTED IDENTITY OBJECT\u003e\",\n    \"created\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"modified\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"name\": \"DISARM Red Framework\",\n    \"description\": \"Incident creator TTPs.\",\n    \"x_mitre_contents\": [\n        {\n          \"object_ref\": \"OBJECT ID\",\n          \"object_modified\": \"OBJECT MODIFIED\"\n        },\n        {\n          \"object_ref\": \"OBJECT ID\",\n          \"object_modified\": \"OBJECT MODIFIED\"\n        }\n    ],\n    \"external_references\": [\n        {\n            \"source_name\": \"DISARM\",\n            \"url\": \"https://www.disarm.foundation/\",\n            \"external_id\": \"DISARM\"\n        }\n    ],\n    \"object_marking_refs\": [\n        \"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487\",\n        \"\u003cIMPORTED MARKING DEFINITION OBJECT\u003e\"\n    ]\n}\n```\n\nTo generate the id, a UUIDv5 is generated using the namespace `8700e156-6ce9-5090-8589-f9d0aef7bdb7` and `DISARM Red Framework` which will always create the UUID `03e1a731-175d-5181-ba28-8be2e2159da9` = `x-mitre-collection--03e1a731-175d-5181-ba28-8be2e2159da9`\n\n### Matrix\n\n```json\n{\n    \"type\": \"x-mitre-matrix\",\n    \"spec_version\": \"2.1\",\n    \"id\": \"x-mitre-matrix--\u003cUUID V5\u003e\",\n    \"created_by_ref\": \"\u003cIMPORTED IDENTITY OBJECT\u003e\",\n    \"created\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"modified\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"name\": \"DISARM Red Framework\",\n    \"description\": \"Incident creator TTPs.\",\n    \"tactic_refs\": [\n        \"\u003cLIST OF ALL x-mitre-tactic IN BUNDLE\u003e\",\n\t],\n    \"external_references\": [\n        {\n            \"source_name\": \"DISARM\",\n            \"url\": \"https://www.disarm.foundation/\",\n            \"external_id\": \"DISARM\"\n        }\n    ],\n    \"object_marking_refs\": [\n        \"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487\",\n        \"\u003cIMPORTED MARKING DEFINITION OBJECT\u003e\"\n    ]\n}\n```\n\nTo generate the id, a UUIDv5 is generated using the namespace `8700e156-6ce9-5090-8589-f9d0aef7bdb7` and `DISARM Red Framework` which will always create the UUID `03e1a731-175d-5181-ba28-8be2e2159da9` = `x-mitre-matrix--03e1a731-175d-5181-ba28-8be2e2159da9`\n\n### Tactic\n\n```json\n{\n    \"type\": \"x-mitre-tactic\",\n    \"spec_version\": \"2.1\",\n    \"id\": \"x-mitre-tactic--\u003cUUID V5\u003e\",\n    \"created_by_ref\": \"\u003cIMPORTED IDENTITY OBJECT\u003e\",\n    \"created\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"modified\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"name\": \"\u003cname\u003e\",\n    \"description\": \"\u003csummary\u003e\",\n    \"external_references\": [\n        {\n           \"source_name\": \"DISARM\",\n           \"url\": \"https://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/main/generated_pages/tactics/\u003ctactic.disarm_id\u003e.md\",\n           \"external_id\": \"\u003ctactic.disarm_id\u003e\"\n        }\n    ],\n    \"object_marking_refs\": [\n        \"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487\",\n        \"\u003cIMPORTED MARKING DEFINTION OBJECTS\u003e\"\n    ],\n    \"x_mitre_shortname\": \"\u003cmachine friendly name\u003e\"\n}\n```\n\nTo generate the id, a UUIDv5 is generated using the namespace `8700e156-6ce9-5090-8589-f9d0aef7bdb7` and `\u003ctactic.disarm_id\u003e`.\n\ne.g. `TA05` = `10ccaa61-bf44-56ec-b1a7-3fc01942ec6d` = `x-mitre-tactic--10ccaa61-bf44-56ec-b1a7-3fc01942ec6d`\n\n### Technique\n\n```json\n{\n    \"type\": \"attack-pattern\",\n    \"spec_version\": \"2.1\",\n    \"id\": \"attack-pattern--\u003cUUID V5\u003e\",\n    \"created_by_ref\": \"\u003cIMPORTED IDENTITY OBJECT\u003e\",\n    \"created\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"modified\": \"\u003cDATE IN DISARM_VERSION FILE\u003e\",\n    \"name\": \"\u003cname\u003e\",\n    \"description\": \"\u003csummary\u003e\",\n    \"external_references\": [\n       {\n            \"source_name\": \"DISARM\",\n            \"url\": \"https://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/main/generated_pages/techniques/\u003ctechnique.disarm_id\u003e.md\",\n            \"external_id\": \"\u003ctechnique.disarm_id\u003e\"\n        }\n    ],\n    \"kill_chain_phases\": [\n       {\n           \"kill_chain_name\": \"DISARM\",\n           \"phase_name\": \"\u003cparent tactic machine friendly name\u003e\"\n        }\n    ],\n    \"x_mitre_is_subtechnique\": \"\u003cboolean, if subtechique\u003e\",\n    \"x_mitre_platforms\": [\n        \"Windows\",\n        \"Linux\",\n        \"Mac\"\n    ],\n    \"x_mitre_version\": \"2.1\",\n    \"object_marking_refs\": [\n        \"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487\",\n        \"\u003cIMPORTED MARKING DEFINTION OBJECTS\u003e\"\n    ]\n}\n```\n\nAn object is determined to be a subtechnique if the `\u003ctechnique.disarm_id\u003e` contains a `.`. e.g. is a subtechnique `T0019.002`, is not a subtechnique `T0019`.\n\nTo generate the id, a UUIDv5 is generated using the namespace `8700e156-6ce9-5090-8589-f9d0aef7bdb7` and `\u003ctechnique.disarm_id\u003e`.\n\ne.g. `T0086.003` = `00dc0ed2-b16d-5f33-bad3-cc54fb7be6a9` = `attack-pattern--00dc0ed2-b16d-5f33-bad3-cc54fb7be6a9`\n\n### Relationships\n\nDISARM contains a hierachical structure of data where a technique can have a child (a subtechnique). e.g parent = T0019 and child = T0019.002.\n\nYou can identify a subtechnique if the techniques `attack-pattern` object has a `x_mitre_is_subtechnique` equal to `true`. If this is the case, the following relationship is created;\n\n```json\n{\n    \"type\": \"relationship\",\n    \"spec_version\": \"2.1\",\n    \"id\": \"relationship--\u003cUUIDV5 GENERATION LOGIC\u003e\",\n    \"created_by_ref\": \"\u003cIMPORTED IDENTITY OBJECT\u003e\",\n    \"created\": \"\u003cCREATED TIME OF MOST RECENT DISARM OBJECT IN PAIR\u003e\",\n    \"modified\": \"\u003cCREATED TIME OF MOST RECENT DISARM OBJECT IN PAIR\u003e\",\n    \"relationship_type\": \"subtechnique-of\",\n    \"source_ref\": \"attack-pattern--\u003cCHILD OBJECT\u003e\",\n    \"target_ref\": \"attack-pattern--\u003cPARENT OBJECT\u003e\",\n    \"object_marking_refs\": [\n        \"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487\",\n        \"\u003cIMPORTED MARKING DEFINTION OBJECTS\u003e\"\n    ],\n}\n```\n\nTo generate the id of the SRO, a UUIDv5 is generated using the namespace `8700e156-6ce9-5090-8589-f9d0aef7bdb7` and `\u003csource_ref\u003e+\u003ctarget_ref\u003e`.\n\ne.g. `attack-pattern--bc07b77c-7af3-5471-9a11-09e458fbad1e+attack-pattern--8df661b8-5f4f-5e3e-bad8-371e0099e447` = `016a0f81-731e-5b3b-8fc3-8d0111fbf1c1` = `relationship--016a0f81-731e-5b3b-8fc3-8d0111fbf1c1`\n\n### Bundle\n\ndisarm2stix also creates a STIX 2.1 Bundle JSON object containing all the other STIX 2.1 Objects created at each run. The Bundle takes the format;\n\n```json\n{\n    \"type\": \"bundle\",\n    \"id\": \"bundle--\u003cUUIDV5 GENERATION LOGIC\u003e\",\n    \"objects\": [\n        \"\u003cALL STIX JSON OBJECTS\u003e\"\n    ]\n}\n```\n\nTo generate the id, a UUIDv5 is generated using the namespace `8700e156-6ce9-5090-8589-f9d0aef7bdb7` and the MD5 file hash of all sorted objects in the bundle.\n\nUnlike the other STIX Objects, this means on every update a new bundle ID will be generated (as the date changes in the UUIDv5 generation). This means each saved bundle provides a historic snapshot of the old versions, should a user ever need to retrieve them.\n\n### MITRE ATT\u0026CK Navigator integration\n\nThe output of this script is designed to work with MITRE ATT\u0026CK Navigator.\n\nhttps://github.com/mitre-attack/attack-navigator\n\nYou can upload the bundle to MITRE ATT\u0026CK Navigator as follows;\n\n1. Go to https://mitre-attack.github.io/attack-navigator/ (or your own Navigator install)\n2. Select \"create new layer\"\n3. Select \"more options\"\n4. Enter the URL of your bundle in \"Collection or STIX bundle URL\"\n5. Enter \"Bundle version number\" (can be any number)\n6. Enter \"Bundle domain\"\n\n## Shortcomings of this code\n\nDISARM is versioned, but it is not easy to determine versions in a programmatic way.\n\n[It appears versioning is done mostly in blog posts](https://medium.com/disarming-disinformation/disarm-update-version-1-3-9dfcf2a29864).\n\nAs such the `DISARM_VERSION` needs to be manually updated with both the version and `modified` time. The `created` time is hard coded as `2020-01-01T00:00:00.000Z` for all objects.\n\nIt is possible to grab specific version URL of the .xlsx file (using historic commits) and run this script using them. To do this, go into `helpers/file.py` and modify the variable `xlsx_url`.\n\nhttps://github.com/DISARMFoundation/DISARMframeworks/commits/main/DISARM_MASTER_DATA/DISARM_FRAMEWORKS_MASTER.xlsx\n\nFor reference, here are the available versions and corresponding .xlsx files to use;\n\n* 1.2 (2023-08-10): https://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/382df9325af25e650667f81a3ff0575b2307b949/DISARM_MASTER_DATA/DISARM_FRAMEWORKS_MASTER.xlsx \n* 1.3 (2023-09-13): https://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/62680c33d5cd1fabbc5aec4fa6390a0180ed3ea2/DISARM_MASTER_DATA/DISARM_FRAMEWORKS_MASTER.xlsx\n* 1.4 (2024-03-13): https://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/f1ac3b04ee17388d9ccc1ada5ad4ed1160f01fe0/DISARM_MASTER_DATA/DISARM_FRAMEWORKS_MASTER.xlsx\n* 1.5 (2024-08-02): https://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/40151ce8a570f365d0e5903ab191ea58f0309af3/DISARM_MASTER_DATA/DISARM_FRAMEWORKS_MASTER.xlsx\n* 1.6 (2024-11-22): https://raw.githubusercontent.com/DISARMFoundation/DISARMframeworks/084362afe5d1faa8b89f75250b795095df25c476/DISARM_MASTER_DATA/DISARM_FRAMEWORKS_MASTER.xlsx\n\n## Useful supporting tools\n\n* Existing STIX 2.1 schemas: [cti-stix2-json-schemas](https://github.com/oasis-open/cti-stix2-json-schemas): OASIS TC Open Repository: Non-normative schemas and examples for STIX 2\n* To generate STIX 2.1 extensions: [stix2 Python Lib](https://stix2.readthedocs.io/en/latest/)\n* STIX 2.1 specifications for objects: [STIX 2.1 docs](https://docs.oasis-open.org/cti/stix/v2.1/stix-v2.1.html)\n* [DISARM Framework](https://www.disarm.foundation/framework)\n\n## Support\n\n[Minimal support provided via the DOGESEC community](https://community.dogesec.com/).\n\n## License\n\n[Apache 2.0](/LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuchdogesec%2Fdisarm2stix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuchdogesec%2Fdisarm2stix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuchdogesec%2Fdisarm2stix/lists"}