My python fu has never been above beginner, so writing scripts to use Mitre’s ATT&CK json files was always a hit and miss effort.
So I asked chatgpt to write it for me and after several back and forth tweaks and coding errors ‘we’ came up with these 2 which I find pretty useful.
To use the scripts, simply run “python <script>” and it will dump the results to a csv file (the first script requires you the first download the json file but the 2nd one doesn’t – see comments).
If you don’t like them exactly the way they are, paste them into chatgpt and simply ask it to make some modifications, eg:
- Add a header row
- Sort by the first column
- Only include these fields: technique_id,technique_name,tactic_name,platforms
- Use a comma as the field separator
- rather than reading from a local json file, read from the web version of enterprise-attack.json
ATT&CK_Tactic_Technique_LogSource.py
import json
# Load the MITRE ATT&CK Enterprise Matrix from the JSON file
# https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json
with open('enterprise-attack.json', 'r') as f:
data = json.load(f)
# Open a file to write the output to
with open('output.csv', 'w') as f:
# Print the header row
f.write("technique_id,technique_name,tactic_name,platforms,permissions_required\n")
# Loop through each technique in the JSON file and print its fields
for technique in data['objects']:
# Extract the technique ID and name
if 'external_references' in technique and len(technique['external_references']) > 0:
technique_id = technique['external_references'][0].get('external_id', '')
else:
technique_id = ''
technique_name = technique.get('name', '')
# Extract the required platforms, if any
platforms = ",".join(technique.get('x_mitre_platforms', []))
# Extract the required permissions, if any
permissions_required = ",".join(technique.get('x_mitre_permissions_required', []))
# Extract the tactic name, if any
tactic_name = ""
if 'kill_chain_phases' in technique and len(technique['kill_chain_phases']) > 0:
tactic_name = technique['kill_chain_phases'][0].get('phase_name', '')
# Write the technique fields to the output file in CSV format
if technique_id and technique_name:
f.write(f"{technique_id},{technique_name},{tactic_name},{platforms},{permissions_required}\n")
# Read the contents of the output file into a list of lines
with open('output.csv', 'r') as f:
lines = f.readlines()
# Sort the lines based on the technique_id column
lines_sorted = sorted(lines[1:], key=lambda x: x.split(',')[0])
# Write the sorted lines back to the output file
with open('output.csv', 'w') as f:
f.write(lines[0])
f.writelines(lines_sorted)
ATT&CK_All_Raw_Fields.py
import json
import urllib.request
# Load the JSON file from the URL
url = "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json"
response = urllib.request.urlopen(url)
data = json.loads(response.read())
# Create a list of all the field names
field_names = []
for technique in data["objects"]:
for field in technique:
if field not in field_names:
field_names.append(field)
# Add a header column to the field names
field_names_with_header = ["Header"] + field_names
# Write the data to a file with ";" as the delimiter
with open("enterprise-attack.txt", "w") as txt_file:
# Write the header row
header_row = ";".join(field_names_with_header) + "\n"
txt_file.write(header_row)
# Write the data rows
for i, technique in enumerate(data["objects"]):
values = [str(technique.get(field, "")).replace("\n", "") for field in field_names]
row = f";T{i+1}" + ";" + ";".join(values) + "\n"
txt_file.write(row)