mirror of
https://github.com/MISP/misp-galaxy.git
synced 2024-11-22 23:07:19 +00:00
new: [d3fend] added relationships to ATT&CK
This commit is contained in:
parent
a4afac9a97
commit
2b3d62705d
4 changed files with 34309 additions and 11 deletions
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
|
@ -1,6 +1,15 @@
|
||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "gen_mitre_d3fend",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"args": "",
|
||||||
|
"cwd": "${fileDirname}"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "gen_mitre",
|
"name": "gen_mitre",
|
||||||
"type": "debugpy",
|
"type": "debugpy",
|
||||||
|
|
34192
clusters/mitre-d3fend.json
Normal file
34192
clusters/mitre-d3fend.json
Normal file
File diff suppressed because it is too large
Load diff
49
galaxies/mitre-d3fend.json
Normal file
49
galaxies/mitre-d3fend.json
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"description": "A knowledge graph of cybersecurity countermeasures.",
|
||||||
|
"icon": "user-shield",
|
||||||
|
"kill_chain_order": {
|
||||||
|
"Model": [
|
||||||
|
"Asset-Inventory",
|
||||||
|
"Network-Mapping",
|
||||||
|
"Operational-Activity-Mapping",
|
||||||
|
"System-Mapping"
|
||||||
|
],
|
||||||
|
"Harden": [
|
||||||
|
"Application-Hardening",
|
||||||
|
"Credential-Hardening",
|
||||||
|
"Message-Hardening",
|
||||||
|
"Platform-Hardening"
|
||||||
|
],
|
||||||
|
"Detect": [
|
||||||
|
"File-Analysis",
|
||||||
|
"Identifier-Analysis",
|
||||||
|
"Message-Analysis",
|
||||||
|
"Network-Traffic-Analysis",
|
||||||
|
"Platform-Monitoring",
|
||||||
|
"Process-Analysis",
|
||||||
|
"User-Behavior-Analysis"
|
||||||
|
],
|
||||||
|
"Isolate": [
|
||||||
|
"Execution-Isolation",
|
||||||
|
"Network-Isolation"
|
||||||
|
],
|
||||||
|
"Deceive": [
|
||||||
|
"Decoy-Environment",
|
||||||
|
"Decoy-Object"
|
||||||
|
],
|
||||||
|
"Evict": [
|
||||||
|
"Credential-Eviction",
|
||||||
|
"File-Eviction",
|
||||||
|
"Process-Eviction"
|
||||||
|
],
|
||||||
|
"Restore": [
|
||||||
|
"Restore-Access",
|
||||||
|
"Restore-Object"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": "MITRE D3FEND",
|
||||||
|
"namespace": "mitre",
|
||||||
|
"type": "mitre-d3fend",
|
||||||
|
"uuid": "77d1bbfa-2982-4e0a-9238-1dae4a48c5b4",
|
||||||
|
"version": 1
|
||||||
|
}
|
|
@ -1,4 +1,22 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# A simple convertor of the MITRE D3FEND to a MISP Galaxy datastructure.
|
||||||
|
# Copyright (C) 2024 Christophe Vandeplas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
|
@ -7,15 +25,16 @@ import uuid
|
||||||
d3fend_url = 'https://d3fend.mitre.org/ontologies/d3fend.json'
|
d3fend_url = 'https://d3fend.mitre.org/ontologies/d3fend.json'
|
||||||
d3fend_full_mappings_url = 'https://d3fend.mitre.org/api/ontology/inference/d3fend-full-mappings.json'
|
d3fend_full_mappings_url = 'https://d3fend.mitre.org/api/ontology/inference/d3fend-full-mappings.json'
|
||||||
|
|
||||||
|
# we love eating lots of memory
|
||||||
|
r = requests.get(d3fend_url)
|
||||||
|
d3fend_json = r.json()
|
||||||
|
|
||||||
|
r = requests.get(d3fend_full_mappings_url)
|
||||||
|
d3fend_mappings_json = r.json()
|
||||||
|
|
||||||
|
with open('../clusters/mitre-attack-pattern.json', 'r') as mitre_f:
|
||||||
|
mitre = json.load(mitre_f)
|
||||||
|
|
||||||
try:
|
|
||||||
with open('d3fend.json', 'r') as f:
|
|
||||||
d3fend_json = json.load(f)
|
|
||||||
except Exception:
|
|
||||||
r = requests.get(d3fend_url)
|
|
||||||
with open('d3fend.json', 'w') as f:
|
|
||||||
f.write(r.text)
|
|
||||||
d3fend_json = r.json()
|
|
||||||
|
|
||||||
uuid_seed = '35527064-12b4-4b73-952b-6d76b9f1b1e3'
|
uuid_seed = '35527064-12b4-4b73-952b-6d76b9f1b1e3'
|
||||||
|
|
||||||
|
@ -23,6 +42,7 @@ tactics = {} # key = tactic, value = phases
|
||||||
phases_ids = []
|
phases_ids = []
|
||||||
techniques_ids = []
|
techniques_ids = []
|
||||||
techniques = []
|
techniques = []
|
||||||
|
relations = {}
|
||||||
|
|
||||||
|
|
||||||
def get_as_list(item):
|
def get_as_list(item):
|
||||||
|
@ -103,6 +123,33 @@ def find_kill_chain_of(original_item):
|
||||||
return find_kill_chain_of(data[parent_class])
|
return find_kill_chain_of(data[parent_class])
|
||||||
|
|
||||||
|
|
||||||
|
def find_mitre_uuid_from_technique_id(technique_id):
|
||||||
|
for item in mitre['values']:
|
||||||
|
if item['meta']['external_id'] == technique_id:
|
||||||
|
return item['uuid']
|
||||||
|
print("No MITRE UUID found for technique_id: ", technique_id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# relationships
|
||||||
|
for item in d3fend_mappings_json['results']['bindings']:
|
||||||
|
d3fend_technique = item['def_tech_label']['value']
|
||||||
|
attack_technique = item['off_tech_label']['value']
|
||||||
|
attack_technique_id = item['off_tech']['value'].split('#')[-1]
|
||||||
|
# print(f"Mapping: {d3fend_technique} -> {attack_technique} ({attack_technique_id})")
|
||||||
|
dest_uuid = find_mitre_uuid_from_technique_id(attack_technique_id)
|
||||||
|
if dest_uuid:
|
||||||
|
rel_type = item['def_artifact_rel_label']['value']
|
||||||
|
if d3fend_technique not in relations:
|
||||||
|
relations[d3fend_technique] = []
|
||||||
|
relations[d3fend_technique].append(
|
||||||
|
{
|
||||||
|
'dest-uuid': dest_uuid,
|
||||||
|
'type': rel_type
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# first convert as dict with key = @id
|
# first convert as dict with key = @id
|
||||||
data = {}
|
data = {}
|
||||||
for item in d3fend_json['@graph']:
|
for item in d3fend_json['@graph']:
|
||||||
|
@ -162,7 +209,9 @@ while seen_new:
|
||||||
# synonyms
|
# synonyms
|
||||||
if 'd3f:synonym' in item:
|
if 'd3f:synonym' in item:
|
||||||
technique['meta']['synonyms'] = get_as_list(item['d3f:synonym'])
|
technique['meta']['synonyms'] = get_as_list(item['d3f:synonym'])
|
||||||
# TODO relations
|
# relations
|
||||||
|
if item['rdfs:label'] in relations:
|
||||||
|
technique['related'] = relations[item['rdfs:label']]
|
||||||
|
|
||||||
techniques.append(technique)
|
techniques.append(technique)
|
||||||
print(f"Technique: {item['rdfs:label']} - {item['d3f:d3fend-id']}")
|
print(f"Technique: {item['rdfs:label']} - {item['d3f:d3fend-id']}")
|
||||||
|
@ -175,7 +224,7 @@ galaxy_description = 'A knowledge graph of cybersecurity countermeasures.'
|
||||||
galaxy_source = 'https://d3fend.mitre.org/'
|
galaxy_source = 'https://d3fend.mitre.org/'
|
||||||
json_galaxy = {
|
json_galaxy = {
|
||||||
'description': galaxy_description,
|
'description': galaxy_description,
|
||||||
'icon': "map",
|
'icon': "user-shield",
|
||||||
'kill_chain_order': kill_chain_tactics,
|
'kill_chain_order': kill_chain_tactics,
|
||||||
'name': galaxy_name,
|
'name': galaxy_name,
|
||||||
'namespace': "mitre",
|
'namespace': "mitre",
|
||||||
|
@ -208,4 +257,3 @@ with open(os.path.join('..', 'clusters', galaxy_fname), 'w') as f:
|
||||||
f.write('\n') # only needed for the beauty and to be compliant with jq_all_the_things
|
f.write('\n') # only needed for the beauty and to be compliant with jq_all_the_things
|
||||||
|
|
||||||
print("All done, please don't forget to ./jq_all_the_things.sh, commit, and then ./validate_all.sh.")
|
print("All done, please don't forget to ./jq_all_the_things.sh, commit, and then ./validate_all.sh.")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue