new: [fight] new MITRE FiGHT galaxy fixes #986

pull/1012/head
Christophe Vandeplas 2024-06-17 12:21:12 +02:00
parent d0dfa453d9
commit a1658b3712
No known key found for this signature in database
GPG Key ID: BDC48619FFDC5A5B
7 changed files with 17854 additions and 30 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
{
"description": "MITRE Five-G Hierarchy of Threats (FiGHT™) is a globally accessible knowledge base of adversary tactics and techniques that are used or could be used against 5G networks.",
"icon": "bell",
"name": "MITRE FiGHT Data Sources",
"namespace": "mitre",
"type": "mitre-fight",
"uuid": "4ccc2400-55e4-42c2-bb8d-1d41883cef46",
"version": 1
}

View File

@ -0,0 +1,9 @@
{
"description": "MITRE Five-G Hierarchy of Threats (FiGHT™) is a globally accessible knowledge base of adversary tactics and techniques that are used or could be used against 5G networks.",
"icon": "shield-alt",
"name": "MITRE FiGHT Mitigations",
"namespace": "mitre",
"type": "mitre-fight",
"uuid": "bcd85ca5-5ed7-4536-bca6-d16fb51adf55",
"version": 1
}

View File

@ -0,0 +1,28 @@
{
"description": "MITRE Five-G Hierarchy of Threats (FiGHT™) is a globally accessible knowledge base of adversary tactics and techniques that are used or could be used against 5G networks.",
"icon": "map",
"kill_chain_order": {
"fight": [
"Reconnaissance",
"Resource-Development",
"Initial-Access",
"Execution",
"Persistence",
"Privilege-Escalation",
"Defense-Evasion",
"Credential-Access",
"Discovery",
"Lateral-Movement",
"Collection",
"Command-and-Control",
"Exfiltration",
"Impact",
"Fraud"
]
},
"name": "MITRE FiGHT Techniques",
"namespace": "mitre",
"type": "mitre-fight",
"uuid": "c22c8c18-0ccd-4033-b2dd-804ad26af4b9",
"version": 1
}

View File

@ -31,11 +31,9 @@ uuid_seed = '8666d04b-977a-434b-82b4-f36271ec1cfb'
fight_url = 'https://fight.mitre.org/fight.yaml'
tactics = {} # key = ID, value = tactic
phases_ids = []
techniques_ids = []
techniques = []
relations = {}
mitigations = []
data_sources = []
r = requests.get(fight_url)
fight = yaml.safe_load(r.text)
@ -55,15 +53,27 @@ def clean_ref(text: str) -> str:
return soup.get_text().strip()
def save_galaxy_and_cluster(json_galaxy, json_cluster, galaxy_fname):
# save the Galaxy and Cluster file
with open(os.path.join('..', 'galaxies', galaxy_fname), 'w') as f:
# sort_keys, even if it breaks the kill_chain_order , but jq_all_the_things requires sorted keys
json.dump(json_galaxy, f, indent=2, sort_keys=True, ensure_ascii=False)
f.write('\n') # only needed for the beauty and to be compliant with jq_all_the_things
with open(os.path.join('..', 'clusters', galaxy_fname), 'w') as f:
json.dump(json_cluster, f, indent=2, sort_keys=True, ensure_ascii=False)
f.write('\n') # only needed for the beauty and to be compliant with jq_all_the_things
# tactics
for item in fight['tactics']:
tactics[item['id']] = item['name'].replace(' ', '-')
# techniques
for item in fight['techniques']:
technique = {
'value': item['name'],
'description': item['description'],
element = {
'value': item['name'].strip(),
'description': item['description'].strip(),
'uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['id'])),
'meta': {
'kill_chain': [],
@ -75,46 +85,85 @@ for item in fight['techniques']:
keys_to_skip = ['id', 'name', 'references', 'tactics']
for keys in item.keys():
if keys not in keys_to_skip:
technique['meta'][keys] = item[keys]
element['meta'][keys] = item[keys]
try:
for ref in item['references']:
technique['meta']['refs'].append(clean_ref(ref))
element['meta']['refs'].append(clean_ref(ref))
except KeyError:
pass
for tactic in item['tactics']:
technique['meta']['kill_chain'].append(f"fight:{tactics[tactic]}")
element['meta']['kill_chain'].append(f"fight:{tactics[tactic]}")
for mitigation in item['mitigations']:
technique['meta']['refs'].append(f"https://fight.mitre.org/mitigations/{mitigation['fgmid']}")
element['meta']['refs'].append(f"https://fight.mitre.org/mitigations/{mitigation['fgmid']}")
# add relationship
technique['related'].append({
element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), mitigation['fgmid'])),
'type': 'mitigated-by'
})
for detection in item['detections']:
technique['meta']['refs'].append(f"https://fight.mitre.org/data%20sources/{detection['fgdsid']}")
element['meta']['refs'].append(f"https://fight.mitre.org/data%20sources/{detection['fgdsid']}")
# add relationship
technique['related'].append({
element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), detection['fgdsid'])),
'type': 'detected-by'
})
try:
technique['related'].append({
element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['subtechnique-of'])),
'type': 'subtechnique-of'
})
except KeyError:
pass
techniques.append(technique)
techniques.append(element)
# TODO mitigations
# TODO data sources
# mitigations
for item in fight['mitigations']:
element = {
'value': item['name'].strip(),
'description': item['description'].strip(),
'uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['id'])),
'meta': {
'kill_chain': [],
'refs': [f"https://fight.mitre.org/mitigations/{item['id']}"],
'external_id': item['id']
},
'related': []
}
# rel to techniques
for technique in item['techniques']:
element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), technique)),
'type': 'mitigates'
})
mitigations.append(element)
# data sources / detections
for item in fight['data sources']:
element = {
'value': item['name'].strip(),
'description': item['description'].strip(),
'uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['id'])),
'meta': {
'kill_chain': [],
'refs': [f"https://fight.mitre.org/data%sources/{item['id']}"],
'external_id': item['id']
},
'related': []
}
# rel to techniques
for technique in item['techniques']:
element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), technique)),
'type': 'detects'
})
data_sources.append(element)
kill_chain_tactics = {'fight': []}
@ -122,14 +171,15 @@ for tactic_id, value in tactics.items():
kill_chain_tactics['fight'].append(value)
galaxy_fname = 'mitre-fight.json'
galaxy_type = "mitre-fight"
galaxy_name = "MITRE FiGHT"
galaxy_description = 'MITRE Five-G Hierarchy of Threats (FiGHT™) is a globally accessible knowledge base of adversary tactics and techniques that are used or could be used against 5G networks.'
galaxy_source = 'https://fight.mitre.org/'
# techniques
galaxy_name = "MITRE FiGHT Techniques"
json_galaxy = {
'description': galaxy_description,
'icon': "user-shield",
'icon': "map",
'kill_chain_order': kill_chain_tactics,
'name': galaxy_name,
'namespace': "mitre",
@ -140,7 +190,7 @@ json_galaxy = {
json_cluster = {
'authors': ["MITRE"],
'category': 'attach-pattern',
'category': 'attack-pattern',
'name': galaxy_name,
'description': galaxy_description,
'source': galaxy_source,
@ -149,16 +199,59 @@ json_cluster = {
'values': list(techniques),
'version': 1
}
save_galaxy_and_cluster(json_galaxy, json_cluster, 'mitre-fight-techniques.json')
# mitigations
galaxy_name = "MITRE FiGHT Mitigations"
json_galaxy = {
'description': galaxy_description,
'icon': "shield-alt",
# 'kill_chain_order': kill_chain_tactics,
'name': galaxy_name,
'namespace': "mitre",
'type': galaxy_type,
'uuid': "bcd85ca5-5ed7-4536-bca6-d16fb51adf55",
'version': 1
}
# save the Galaxy and Cluster file
with open(os.path.join('..', 'galaxies', galaxy_fname), 'w') as f:
# sort_keys, even if it breaks the kill_chain_order , but jq_all_the_things requires sorted keys
json.dump(json_galaxy, f, indent=2, sort_keys=True, ensure_ascii=False)
f.write('\n') # only needed for the beauty and to be compliant with jq_all_the_things
json_cluster = {
'authors': ["MITRE"],
'category': 'mitigation',
'name': galaxy_name,
'description': galaxy_description,
'source': galaxy_source,
'type': galaxy_type,
'uuid': "fe20707f-2dfb-4436-8520-8fedb8c79668",
'values': list(mitigations),
'version': 1
}
save_galaxy_and_cluster(json_galaxy, json_cluster, 'mitre-fight-mitigations.json')
# data sources / detections
galaxy_name = "MITRE FiGHT Data Sources"
json_galaxy = {
'description': galaxy_description,
'icon': "bell",
# 'kill_chain_order': kill_chain_tactics,
'name': galaxy_name,
'namespace': "mitre",
'type': galaxy_type,
'uuid': "4ccc2400-55e4-42c2-bb8d-1d41883cef46",
'version': 1
}
json_cluster = {
'authors': ["MITRE"],
'category': 'data-source',
'name': galaxy_name,
'description': galaxy_description,
'source': galaxy_source,
'type': galaxy_type,
'uuid': "fb4410a1-5a39-4b30-934a-9cdfbcd4d2ad",
'values': list(data_sources),
'version': 1
}
save_galaxy_and_cluster(json_galaxy, json_cluster, 'mitre-fight-datasources.json')
with open(os.path.join('..', 'clusters', galaxy_fname), 'w') as f:
json.dump(json_cluster, f, indent=2, sort_keys=True, ensure_ascii=False)
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.")