new: [code] MISP Galaxy supports most models

This commit is contained in:
Christophe Vandeplas 2023-12-20 11:29:33 +01:00
parent f12df578ab
commit 8b8100611c
No known key found for this signature in database
GPG Key ID: BDC48619FFDC5A5B
2 changed files with 232 additions and 32 deletions

View File

@ -12,55 +12,60 @@ import json
import uuid import uuid
import os import os
DISARM_DESCRIPTION = 'DISARM is a framework designed for describing and understanding disinformation incidents.'
DISARM_CATEGORY = 'disarm'
DISARM_AUTHORS = ['DISARM Project']
DISARM_SOURCE = 'https://github.com/DISARMFoundation/DISARMframeworks'
CORE_UUID = "9d6bd9d2-2cd3-4900-b61a-06cd64df3996"
class DisarmGalaxy: class DisarmGalaxy:
def __init__(self, out_path=os.path.join('..', '..', 'misp-galaxy')): def __init__(self, out_path=os.path.join('..', '..', 'misp-galaxy')):
self.disarm = Disarm() self.disarm = Disarm()
self.out_path = out_path self.out_path = out_path
def generate_disarm_galaxy(self):
galaxy = {'name': 'DISARM Techniques',
'type': 'disarm',
'description': 'DISARM is a framework designed for describing and understanding disinformation incidents.',
'uuid': str(uuid.uuid5(uuid.UUID("9319371e-2504-4128-8410-3741cebbcfd3"), 'disarm-galaxy-techniques')),
'version': 1,
'icon': 'map',
'namespace': 'disarm',
'kill_chain_order': {
'disarm-tactics': []
}}
for k, v in self.disarm.tactics.items():
galaxy['kill_chain_order']['disarm-tactics'].append(f'{v}')
self.write_json_file(os.path.join(self.out_path, 'galaxies', 'disarm-techniques.json'), galaxy)
def write_json_file(self, fname, file_data): def write_json_file(self, fname, file_data):
with open(fname, 'w') as f: with open(fname, 'w') as f:
json.dump(file_data, f, indent=2, sort_keys=True, ensure_ascii=False) json.dump(file_data, f, indent=2, sort_keys=True, ensure_ascii=False)
f.write('\n') f.write('\n')
def generate_disarm_clusters(self): def generate_disarm_techniques_galaxy(self):
cluster = {'authors': ['DISARM Project'], galaxy = {'name': 'Techniques',
'category': 'disarm', 'type': 'disarm-techniques',
'description': 'DISARM is a framework designed for describing and understanding disinformation incidents.', 'description': DISARM_DESCRIPTION,
'name': 'DISARM Techniques', 'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-galaxy-techniques')),
'source': 'https://github.com/misinfosecproject/amitt_framework', 'version': 1,
'type': 'disarm', 'icon': 'map',
'uuid': str(uuid.uuid5(uuid.UUID("9319371e-2504-4128-8410-3741cebbcfd3"), 'disarm-cluster-techniques')), 'namespace': 'disarm',
'kill_chain_order': {
'tactics': []
}}
for k, v in self.disarm.tactics.items():
galaxy['kill_chain_order']['tactics'].append(f'{v}')
self.write_json_file(os.path.join(self.out_path, 'galaxies', 'disarm-techniques.json'), galaxy)
def generate_disarm_techniques_clusters(self):
cluster = {'authors': DISARM_AUTHORS,
'category': DISARM_CATEGORY,
'description': DISARM_DESCRIPTION,
'name': 'Techniques',
'source': DISARM_SOURCE,
'type': 'disarm-techniques',
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-cluster-techniques')),
'values': [], 'values': [],
'version': 1} 'version': 1}
values = [] values = []
df = self.disarm.df_techniques df = self.disarm.df_techniques
for i in range(len(df)): for i in range(len(df)):
t = { t = {
'uuid': str(uuid.uuid5(uuid.UUID("9319371e-2504-4128-8410-3741cebbcfd3"), df.values[i][0])), 'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), df.values[i][0])),
'value': f"{df.values[i][1]}", 'value': df.values[i][1],
'description': df.values[i][4], 'description': df.values[i][4],
'meta': { 'meta': {
'external_id': df.values[i][0], 'external_id': df.values[i][0],
'kill_chain': [ 'kill_chain': [
f'disarm-tactics:{self.disarm.tactics[df.values[i][3]]}' f'tactics:{self.disarm.tactics[df.values[i][3]]}'
], ],
'refs': [ 'refs': [
f'https://github.com/DISARMFoundation/DISARMframeworks/blob/main/generated_pages/techniques/{df.values[i][0]}.md' f'https://github.com/DISARMFoundation/DISARMframeworks/blob/main/generated_pages/techniques/{df.values[i][0]}.md'
@ -72,14 +77,206 @@ class DisarmGalaxy:
cluster['values'] = sorted(values, key=lambda x: x['meta']['external_id']) cluster['values'] = sorted(values, key=lambda x: x['meta']['external_id'])
self.write_json_file(os.path.join(self.out_path, 'clusters', 'disarm-techniques.json'), cluster) self.write_json_file(os.path.join(self.out_path, 'clusters', 'disarm-techniques.json'), cluster)
def generate_disarm_countermeasures_galaxy(self):
galaxy = {'name': 'Countermeasures',
'type': 'disarm-countermeasures',
'description': DISARM_DESCRIPTION,
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-galaxy-counters')),
'version': 1,
'icon': 'shield-alt',
'namespace': 'disarm',
'kill_chain_order': {
'tactics': [],
'responsetypes': [],
'metatechniques': []
}}
for k, v in self.disarm.tactics.items():
galaxy['kill_chain_order']['tactics'].append(f'{v}')
for k, v in self.disarm.responsetypes.items():
galaxy['kill_chain_order']['responsetypes'].append(f'{v}')
for k, v in self.disarm.metatechniques.items():
galaxy['kill_chain_order']['metatechniques'].append(f'{v}')
self.write_json_file(os.path.join(self.out_path, 'galaxies', 'disarm-countermeasures.json'), galaxy)
def generate_disarm_countermeasures_clusters(self):
cluster = {'authors': DISARM_AUTHORS,
'category': DISARM_CATEGORY,
'description': DISARM_DESCRIPTION,
'name': 'Countermeasures',
'source': DISARM_SOURCE,
'type': 'disarm-countermeasures',
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-cluster-counters')),
'values': [],
'version': 1}
values = []
df = self.disarm.df_counters
for i in range(len(df)):
kill_chain = []
if self.disarm.tactics[df.values[i][15]]:
kill_chain.append(f'tactics:{self.disarm.tactics[df.values[i][15]]}')
if self.disarm.responsetypes[df.values[i][10]]:
kill_chain.append(f'responsetypes:{self.disarm.responsetypes[df.values[i][10]]}')
if self.disarm.metatechniques[df.values[i][17]]:
kill_chain.append(f'metatechniques:{self.disarm.metatechniques[df.values[i][17]]}')
t = {
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), df.values[i][0])),
'value': df.values[i][1],
'description': df.values[i][3],
'meta': {
'external_id': df.values[i][0],
'kill_chain': kill_chain,
'refs': [
f'https://github.com/DISARMFoundation/DISARMframeworks/blob/main/generated_pages/counters/{df.values[i][0]}.md'
]
}
}
values.append(t)
cluster['values'] = sorted(values, key=lambda x: x['meta']['external_id'])
self.write_json_file(os.path.join(self.out_path, 'clusters', 'disarm-countermeasures.json'), cluster)
def generate_disarm_detections_galaxy(self):
galaxy = {'name': 'Detections',
'type': 'disarm-detections',
'description': DISARM_DESCRIPTION,
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-galaxy-detections')),
'version': 1,
'icon': 'bell',
'namespace': 'disarm',
'kill_chain_order': {
'tactics': [],
'responsetypes': [],
# 'metatechniques': []
}}
for k, v in self.disarm.tactics.items():
galaxy['kill_chain_order']['tactics'].append(f'{v}')
for k, v in self.disarm.responsetypes.items():
galaxy['kill_chain_order']['responsetypes'].append(f'{v}')
# for k, v in self.disarm.metatechniques.items():
# galaxy['kill_chain_order']['metatechniques'].append(f'{v}')
self.write_json_file(os.path.join(self.out_path, 'galaxies', 'disarm-detections.json'), galaxy)
def generate_disarm_detections_clusters(self):
cluster = {'authors': DISARM_AUTHORS,
'category': DISARM_CATEGORY,
'description': DISARM_DESCRIPTION,
'name': 'Detections',
'source': DISARM_SOURCE,
'type': 'disarm-detections',
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-cluster-detections')),
'values': [],
'version': 1}
values = []
df = self.disarm.df_detections
for i in range(len(df)):
kill_chain = []
try:
if self.disarm.tactics[df.values[i][14]]:
kill_chain.append(f'tactics:{self.disarm.tactics[df.values[i][14]]}')
except KeyError:
pass pass
try:
if self.disarm.responsetypes[df.values[i][10]]:
kill_chain.append(f'responsetypes:{self.disarm.responsetypes[df.values[i][10]]}')
except KeyError:
pass
# Metatechnique ID is not in the array
# if self.disarm.metatechniques[df.values[i][???]]:
# kill_chain.append(f'metatechniques:{self.disarm.metatechniques[df.values[i][???]]}')
t = {
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), df.values[i][0])),
'value': df.values[i][1],
'description': df.values[i][3],
'meta': {
'external_id': df.values[i][0],
'kill_chain': kill_chain,
'refs': [
f'https://github.com/DISARMFoundation/DISARMframeworks/blob/main/generated_pages/detections/{df.values[i][0]}.md'
]
}
}
values.append(t)
cluster['values'] = sorted(values, key=lambda x: x['meta']['external_id'])
self.write_json_file(os.path.join(self.out_path, 'clusters', 'disarm-detections.json'), cluster)
def generate_disarm_actortypes_galaxy(self):
galaxy = {'name': 'Actor Types',
'type': 'disarm-actortypes',
'description': DISARM_DESCRIPTION,
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-galaxy-actortypes')),
'version': 1,
'icon': 'user-secret',
'namespace': 'disarm',
'kill_chain_order': {
'sectors': []
}}
for k, v in self.disarm.sectors.items():
galaxy['kill_chain_order']['sectors'].append(f'{v}')
self.write_json_file(os.path.join(self.out_path, 'galaxies', 'disarm-actortypes.json'), galaxy)
def generate_disarm_actortypes_clusters(self):
cluster = {'authors': DISARM_AUTHORS,
'category': DISARM_CATEGORY,
'description': DISARM_DESCRIPTION,
'name': 'Actor Types',
'source': DISARM_SOURCE,
'type': 'disarm-actortypes',
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), 'disarm-cluster-actortypes')),
'values': [],
'version': 1}
values = []
df = self.disarm.df_actortypes
for i in range(len(df)):
kill_chain = []
try:
sectors = df.values[i][3].split(',')
for sector in sectors:
sector = sector.strip()
if self.disarm.sectors[sector]:
kill_chain.append(f'sectors:{self.disarm.sectors[sector]}')
except KeyError:
pass
t = {
'uuid': str(uuid.uuid5(uuid.UUID(CORE_UUID), df.values[i][0])),
'value': df.values[i][1],
'description': df.values[i][2],
'meta': {
'external_id': df.values[i][0],
'kill_chain': kill_chain,
'refs': [
f'https://github.com/DISARMFoundation/DISARMframeworks/blob/main/generated_pages/actortypes/{df.values[i][0]}.md'
]
}
}
values.append(t)
cluster['values'] = sorted(values, key=lambda x: x['meta']['external_id'])
self.write_json_file(os.path.join(self.out_path, 'clusters', 'disarm-actortypes.json'), cluster)
def main(): def main():
disarm_galaxy = DisarmGalaxy() disarm_galaxy = DisarmGalaxy()
disarm_galaxy.generate_disarm_galaxy() disarm_galaxy.generate_disarm_techniques_galaxy()
disarm_galaxy.generate_disarm_clusters() disarm_galaxy.generate_disarm_techniques_clusters()
disarm_galaxy.generate_disarm_countermeasures_galaxy()
disarm_galaxy.generate_disarm_countermeasures_clusters()
disarm_galaxy.generate_disarm_detections_galaxy()
disarm_galaxy.generate_disarm_detections_clusters()
disarm_galaxy.generate_disarm_actortypes_galaxy()
disarm_galaxy.generate_disarm_actortypes_clusters()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -123,6 +123,7 @@ class Disarm:
self.it = self.create_incident_technique_crosstable(metadata['incidenttechniques']) self.it = self.create_incident_technique_crosstable(metadata['incidenttechniques'])
self.df_tactics = metadata['tactics'] self.df_tactics = metadata['tactics']
self.df_playbooks = metadata['playbooks'] self.df_playbooks = metadata['playbooks']
self.df_sectors = metadata['sectors']
# Add columns containing lists of techniques and counters to the tactics dataframe # Add columns containing lists of techniques and counters to the tactics dataframe
self.df_techniques_per_tactic = self.df_techniques.groupby('tactic_id')['disarm_id'].apply(list).reset_index().rename({'disarm_id':'technique_ids'}, axis=1) self.df_techniques_per_tactic = self.df_techniques.groupby('tactic_id')['disarm_id'].apply(list).reset_index().rename({'disarm_id':'technique_ids'}, axis=1)
@ -136,8 +137,10 @@ class Disarm:
self.techniques = self.make_object_dictionary(self.df_techniques) self.techniques = self.make_object_dictionary(self.df_techniques)
self.counters = self.make_object_dictionary(self.df_counters) self.counters = self.make_object_dictionary(self.df_counters)
self.metatechniques = self.make_object_dictionary(self.df_metatechniques) self.metatechniques = self.make_object_dictionary(self.df_metatechniques)
self.responsetypes = self.make_object_dictionary(self.df_responsetypes)
self.actortypes = self.make_object_dictionary(self.df_actortypes) self.actortypes = self.make_object_dictionary(self.df_actortypes)
self.resources = self.make_object_dictionary(self.df_resources) self.resources = self.make_object_dictionary(self.df_resources)
self.sectors = self.make_object_dictionary(self.df_sectors)
# Create the data table for each framework file # Create the data table for each framework file
self.num_tactics = len(self.df_tactics) self.num_tactics = len(self.df_tactics)