|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# This file is part of python-evtx. |
| 3 | +# Written by AJ Read (ajread4) with help/inspiration from the evtx_dump.py file written by Willi Ballenthin. |
| 4 | +# |
| 5 | +# Purpose: User can dump evtx data into JSON format to either the command line or a JSON file in new line delimited format/JSON array. |
| 6 | +# Details: The JSON object is created with only the EventRecordID from the System section of the evtx XML and all of the information within the EventData section. |
| 7 | + |
| 8 | +import Evtx.Evtx as evtx |
| 9 | +import Evtx.Views as e_views |
| 10 | + |
| 11 | +# Added packages |
| 12 | +import os |
| 13 | +import xmltodict |
| 14 | +import json |
| 15 | + |
| 16 | + |
| 17 | +def main(): |
| 18 | + import argparse |
| 19 | + parser = argparse.ArgumentParser( |
| 20 | + description="Dump a binary EVTX file into XML.") |
| 21 | + parser.add_argument("evtx", type=str,action='store', |
| 22 | + help="Path to the Windows EVTX event log file") |
| 23 | + parser.add_argument("-o","--output",type=str, action='store', |
| 24 | + help="Path of output JSON file") |
| 25 | + args = parser.parse_args() |
| 26 | + |
| 27 | + with evtx.Evtx(args.evtx) as log: |
| 28 | + |
| 29 | + # Instantiate the final json object |
| 30 | + final_json=[] |
| 31 | + |
| 32 | + # Loop through each record in the evtx log |
| 33 | + for record in log.records(): |
| 34 | + |
| 35 | + # Convert the record to a dictionary for ease of parsing |
| 36 | + data_dict=xmltodict.parse(record.xml()) |
| 37 | + |
| 38 | + # Loop through each key,value pair of the System section of the evtx logs and extract the EventRecordID |
| 39 | + for event_system_key, event_system_value in data_dict['Event']['System'].items(): |
| 40 | + if (event_system_key=="EventRecordID"): |
| 41 | + json_subline={} |
| 42 | + firstline={event_system_key:event_system_value} |
| 43 | + |
| 44 | + # Add information to the JSON object for this specific log |
| 45 | + json_subline.update(firstline) #add the event ID to JSON subline |
| 46 | + |
| 47 | + # Loop through each key, value pair of the EventData section of the evtx logs |
| 48 | + for event_data_key, event_data_value in data_dict['Event']['EventData'].items(): |
| 49 | + for values in event_data_value: |
| 50 | + |
| 51 | + # Loop through each subvalue within the EvenData section to extract necessary information |
| 52 | + for event_data_subkey,event_data_subvalue in values.items(): |
| 53 | + if event_data_subkey=="@Name": |
| 54 | + data_name=event_data_subvalue |
| 55 | + else: |
| 56 | + data_value=event_data_subvalue |
| 57 | + |
| 58 | + # Add information to the JSON object for this specific log |
| 59 | + json_subline.update({data_name: data_value}) |
| 60 | + |
| 61 | + # Print the JSON object for the specific log if not requested to output to file |
| 62 | + if not args.output: |
| 63 | + print(json_subline) |
| 64 | + |
| 65 | + # Add specific log JSON object to the final JSON object |
| 66 | + if not final_json: |
| 67 | + final_json=[json_subline] |
| 68 | + else: |
| 69 | + final_json.append(json_subline) |
| 70 | + |
| 71 | + # If output is desired |
| 72 | + if (args.output): |
| 73 | + |
| 74 | + # Output the JSON data |
| 75 | + if (os.path.splitext(args.output)[1] == ".json"): |
| 76 | + json_file=args.output |
| 77 | + else: |
| 78 | + json_file=args.output +".json" |
| 79 | + |
| 80 | + # Write to JSON file |
| 81 | + with open(json_file,"w") as outfile: |
| 82 | + json.dump(final_json,outfile) |
| 83 | + |
| 84 | +if __name__ == "__main__": |
| 85 | + main() |
0 commit comments