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

This commit is contained in:
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' fight_url = 'https://fight.mitre.org/fight.yaml'
tactics = {} # key = ID, value = tactic tactics = {} # key = ID, value = tactic
phases_ids = []
techniques_ids = []
techniques = [] techniques = []
relations = {} mitigations = []
data_sources = []
r = requests.get(fight_url) r = requests.get(fight_url)
fight = yaml.safe_load(r.text) fight = yaml.safe_load(r.text)
@ -55,15 +53,27 @@ def clean_ref(text: str) -> str:
return soup.get_text().strip() 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 # tactics
for item in fight['tactics']: for item in fight['tactics']:
tactics[item['id']] = item['name'].replace(' ', '-') tactics[item['id']] = item['name'].replace(' ', '-')
# techniques # techniques
for item in fight['techniques']: for item in fight['techniques']:
technique = { element = {
'value': item['name'], 'value': item['name'].strip(),
'description': item['description'], 'description': item['description'].strip(),
'uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['id'])), 'uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['id'])),
'meta': { 'meta': {
'kill_chain': [], 'kill_chain': [],
@ -75,46 +85,85 @@ for item in fight['techniques']:
keys_to_skip = ['id', 'name', 'references', 'tactics'] keys_to_skip = ['id', 'name', 'references', 'tactics']
for keys in item.keys(): for keys in item.keys():
if keys not in keys_to_skip: if keys not in keys_to_skip:
technique['meta'][keys] = item[keys] element['meta'][keys] = item[keys]
try: try:
for ref in item['references']: for ref in item['references']:
technique['meta']['refs'].append(clean_ref(ref)) element['meta']['refs'].append(clean_ref(ref))
except KeyError: except KeyError:
pass pass
for tactic in item['tactics']: 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']: 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 # add relationship
technique['related'].append({ element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), mitigation['fgmid'])), 'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), mitigation['fgmid'])),
'type': 'mitigated-by' 'type': 'mitigated-by'
}) })
for detection in item['detections']: 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 # add relationship
technique['related'].append({ element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), detection['fgdsid'])), 'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), detection['fgdsid'])),
'type': 'detected-by' 'type': 'detected-by'
}) })
try: try:
technique['related'].append({ element['related'].append({
'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['subtechnique-of'])), 'dest-uuid': str(uuid.uuid5(uuid.UUID(uuid_seed), item['subtechnique-of'])),
'type': 'subtechnique-of' 'type': 'subtechnique-of'
}) })
except KeyError: except KeyError:
pass pass
techniques.append(technique) techniques.append(element)
# TODO mitigations # mitigations
# TODO data sources 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': []} kill_chain_tactics = {'fight': []}
@ -122,14 +171,15 @@ for tactic_id, value in tactics.items():
kill_chain_tactics['fight'].append(value) kill_chain_tactics['fight'].append(value)
galaxy_fname = 'mitre-fight.json'
galaxy_type = "mitre-fight" 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_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/' galaxy_source = 'https://fight.mitre.org/'
# techniques
galaxy_name = "MITRE FiGHT Techniques"
json_galaxy = { json_galaxy = {
'description': galaxy_description, 'description': galaxy_description,
'icon': "user-shield", 'icon': "map",
'kill_chain_order': kill_chain_tactics, 'kill_chain_order': kill_chain_tactics,
'name': galaxy_name, 'name': galaxy_name,
'namespace': "mitre", 'namespace': "mitre",
@ -140,7 +190,7 @@ json_galaxy = {
json_cluster = { json_cluster = {
'authors': ["MITRE"], 'authors': ["MITRE"],
'category': 'attach-pattern', 'category': 'attack-pattern',
'name': galaxy_name, 'name': galaxy_name,
'description': galaxy_description, 'description': galaxy_description,
'source': galaxy_source, 'source': galaxy_source,
@ -149,16 +199,59 @@ json_cluster = {
'values': list(techniques), 'values': list(techniques),
'version': 1 '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 json_cluster = {
with open(os.path.join('..', 'galaxies', galaxy_fname), 'w') as f: 'authors': ["MITRE"],
# sort_keys, even if it breaks the kill_chain_order , but jq_all_the_things requires sorted keys 'category': 'mitigation',
json.dump(json_galaxy, f, indent=2, sort_keys=True, ensure_ascii=False) 'name': galaxy_name,
f.write('\n') # only needed for the beauty and to be compliant with jq_all_the_things '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.") print("All done, please don't forget to ./jq_all_the_things.sh, commit, and then ./validate_all.sh.")