Use ChatGPT to Search Mitre ATT&CK More Effectively

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)

Leave a comment