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