Skip to content

Commit fc8ed9b

Browse files
author
Willi Ballenthin
authored
Merge pull request #82 from ajread4/add_json
Add JSON dump functionality
2 parents 7d172a5 + b0204d1 commit fc8ed9b

4 files changed

Lines changed: 88 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ python-evtx operates on event log files from Windows operating systems newer tha
2929

3030
Examples
3131
--------
32-
Provided with the parsing module `Evtx` are three scripts that mimic the tools distributed with Parse-Evtx. `evtx_info.py` prints metadata about the event log and verifies the checksums of each chunk. `evtx_templates.py` builds and prints the templates used throughout the event log. Finally, `evtx_dump.py` parses the event log and transforms the binary XML into a human readable ASCII XML format.
32+
Provided with the parsing module `Evtx` are four scripts that mimic the tools distributed with Parse-Evtx. `evtx_info.py` prints metadata about the event log and verifies the checksums of each chunk. `evtx_templates.py` builds and prints the templates used throughout the event log. `evtx_dump.py` parses the event log and transforms the binary XML into a human readable ASCII XML format. Finally, `evtx_dump_json.py` parses event logs, similar to `evtx_dump.py` and transforms the binary XML into JSON with the added capability to output the JSON array to a file.
3333

3434
Note the length of the `evtx_dump.py` script: its only 20 lines. Now, review the contents and notice the complete implementation of the logic:
3535

scripts/evtx_dump.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import Evtx.Evtx as evtx
2121
import Evtx.Views as e_views
2222

23-
2423
def main():
2524
import argparse
2625

scripts/evtx_dump_json.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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()

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
install_requires=[
2525
'six',
2626
'hexdump==3.3',
27+
'xmltodict==0.13.0', #added deps for evtx_dump_json.py script
2728

2829
# pin deps for python 2, see #67
2930
'more_itertools==5.0.0',
@@ -40,6 +41,7 @@
4041
]
4142
},
4243
scripts=['scripts/evtx_dump.py',
44+
'scripts/evtx_dump_json.py'
4345
'scripts/evtx_dump_chunk_slack.py',
4446
'scripts/evtx_eid_record_numbers.py',
4547
'scripts/evtx_extract_record.py',

0 commit comments

Comments
 (0)