From cdbf03aad90e9d85850043fb52e43dc601bb29c4 Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 29 Jun 2024 10:45:51 -0400 Subject: [PATCH 01/11] added new updates for dump json --- scripts/evtx_dump_json.py | 96 ++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 788436a..13d22f9 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -4,82 +4,94 @@ # # 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. # 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. -# -# Requires: -# - xmltodict >= 0.12.0 -import os -import json - -import xmltodict import Evtx.Evtx as evtx +import Evtx.Views as e_views + +# Added packages +import os +import xmltodict +import json def main(): import argparse - - parser = argparse.ArgumentParser(description="Dump a binary EVTX file into XML.") - parser.add_argument("evtx", type=str, action="store", help="Path to the Windows EVTX event log file") - parser.add_argument("-o", "--output", type=str, action="store", help="Path of output JSON file") + parser = argparse.ArgumentParser( + description="Dump a binary EVTX file into XML.") + parser.add_argument("evtx", type=str,action='store', + help="Path to the Windows EVTX event log file") + parser.add_argument("-o","--output",type=str, action='store', + help="Path of output JSON file") args = parser.parse_args() with evtx.Evtx(args.evtx) as log: # Instantiate the final json object - final_json = [] + final_json=[] # Loop through each record in the evtx log for record in log.records(): # Convert the record to a dictionary for ease of parsing - data_dict = xmltodict.parse(record.xml()) + data_dict=xmltodict.parse(record.xml()) - # Loop through each key,value pair of the System section of the evtx logs and extract the EventRecordID - for event_system_key, event_system_value in data_dict["Event"]["System"].items(): - if event_system_key == "EventRecordID": - json_subline = {} - firstline = {event_system_key: event_system_value} + # Create first line of System Data based on the EventRecordID + json_subline={} + json_subline.update({'EventRecordID':data_dict['Event']['System']['EventRecordID']}) - # Add information to the JSON object for this specific log - json_subline.update(firstline) # add the event ID to JSON subline - # Loop through each key, value pair of the EventData section of the evtx logs - for event_data_key, event_data_value in data_dict["Event"]["EventData"].items(): - for values in event_data_value: + # Loop through each key,value pair of the System section of the evtx logs + for event_system_key, event_system_value in data_dict['Event']['System'].items(): - # Loop through each subvalue within the EvenData section to extract necessary information - for event_data_subkey, event_data_subvalue in values.items(): - if event_data_subkey == "@Name": - data_name = event_data_subvalue - else: - data_value = event_data_subvalue + if not (event_system_key=="EventRecordID") or not (event_system_key=="Execution"): - # Add information to the JSON object for this specific log - json_subline.update({data_name: data_value}) + # For nested dictionaries, loop through each and extract key information + if isinstance(event_system_value,dict): + for event_system_subkey,event_system_subvalue in event_system_value.items(): - # Print the JSON object for the specific log if not requested to output to file - if not args.output: - print(json_subline) + if event_system_key=="EventID" or event_system_key=="TimeCreated": + json_subline.update({event_system_key: event_system_subvalue}) + if event_system_key=="Security": + json_subline.update({event_system_subkey[1:]: event_system_subvalue}) + else: + json_subline.update({event_system_key: event_system_value}) + + # Loop through each key, value pair of the EventData section of the evtx logs + if data_dict['Event']['EventData']!= None: + for event_data_key, event_data_value in data_dict['Event']['EventData'].items(): + for values in event_data_value: + + # Loop through each subvalue within the EvenData section to extract necessary information + for event_data_subkey,event_data_subvalue in values.items(): + if event_data_subkey=="@Name": + data_name=event_data_subvalue + else: + data_value=event_data_subvalue + + # Add information to the JSON object for this specific log + json_subline.update({data_name: data_value}) + # Add specific log JSON object to the final JSON object if not final_json: - final_json = [json_subline] + final_json=[json_subline] else: final_json.append(json_subline) # If output is desired - if args.output: + if (args.output): # Output the JSON data - if os.path.splitext(args.output)[1] == ".json": - json_file = args.output + if (os.path.splitext(args.output)[1] == ".json"): + json_file=args.output else: - json_file = args.output + ".json" + json_file=args.output +".json" # Write to JSON file - with open(json_file, "w") as outfile: - json.dump(final_json, outfile) - + with open(json_file,"w") as outfile: + json.dump(final_json,outfile) + else: + print(json.dumps(final_json)) if __name__ == "__main__": main() From 2a7036a30ae23e0f1aa73b65852ea19be01931c9 Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 29 Jun 2024 14:07:04 -0400 Subject: [PATCH 02/11] added dataset to test and finished update to dump json to address missing data within System xml --- .../Microsoft-Windows-Sysmon-Operational.evtx | Bin 0 -> 1118208 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/Microsoft-Windows-Sysmon-Operational.evtx diff --git a/tests/Microsoft-Windows-Sysmon-Operational.evtx b/tests/Microsoft-Windows-Sysmon-Operational.evtx new file mode 100644 index 0000000000000000000000000000000000000000..866d30169a4e62bb756c54792e5210e74b4fdbba GIT binary patch literal 1118208 zcmeFa34C2wb?<*PTDBt(giMe@PDsckTb?BwlgJtpC$?j3$4)>=P;5D#EiA_afmDHn zA&&x`XepGYlp*k^X=n=#!~f3%N`ZeN@CP14UTH%g&@hⅇ$F*`u)Cp?X7!t?~!yR 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 zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv zh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltvh!ltv_&@E? zu>b%70Kg!B>oM#vgbWxkV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd H0RwL!UCDU) literal 0 HcmV?d00001 From 6d2fac6bf01a80b774ed166d1dd58c4cfc7eeddf Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 13 Jul 2024 13:04:37 -0400 Subject: [PATCH 03/11] fixed formatting issues related to spacing and reverted changes that did not impact code logic --- scripts/evtx_dump_json.py | 47 ++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 13d22f9..88325b6 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -5,38 +5,39 @@ # 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. # 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. -import Evtx.Evtx as evtx -import Evtx.Views as e_views +# +# Requires: +# - xmltodict >= 0.12.0 -# Added packages import os -import xmltodict import json +import xmltodict + +import Evtx.Evtx as evtx +import Evtx.Views as e_views + def main(): import argparse - parser = argparse.ArgumentParser( - description="Dump a binary EVTX file into XML.") - parser.add_argument("evtx", type=str,action='store', - help="Path to the Windows EVTX event log file") - parser.add_argument("-o","--output",type=str, action='store', - help="Path of output JSON file") + parser = argparse.ArgumentParser(description="Dump a binary EVTX file into XML.") + parser.add_argument("evtx", type=str,action='store', help="Path to the Windows EVTX event log file") + parser.add_argument("-o","--output",type=str, action='store', help="Path of output JSON file") args = parser.parse_args() with evtx.Evtx(args.evtx) as log: # Instantiate the final json object - final_json=[] + final_json = [] # Loop through each record in the evtx log for record in log.records(): # Convert the record to a dictionary for ease of parsing - data_dict=xmltodict.parse(record.xml()) + data_dict = xmltodict.parse(record.xml()) # Create first line of System Data based on the EventRecordID - json_subline={} + json_subline = {} json_subline.update({'EventRecordID':data_dict['Event']['System']['EventRecordID']}) @@ -49,9 +50,9 @@ def main(): if isinstance(event_system_value,dict): for event_system_subkey,event_system_subvalue in event_system_value.items(): - if event_system_key=="EventID" or event_system_key=="TimeCreated": + if event_system_key == "EventID" or event_system_key == "TimeCreated": json_subline.update({event_system_key: event_system_subvalue}) - if event_system_key=="Security": + if event_system_key == "Security": json_subline.update({event_system_subkey[1:]: event_system_subvalue}) else: @@ -64,28 +65,28 @@ def main(): # Loop through each subvalue within the EvenData section to extract necessary information for event_data_subkey,event_data_subvalue in values.items(): - if event_data_subkey=="@Name": - data_name=event_data_subvalue + if event_data_subkey == "@Name": + data_name = event_data_subvalue else: - data_value=event_data_subvalue - + data_value = event_data_subvalue + # Add information to the JSON object for this specific log json_subline.update({data_name: data_value}) # Add specific log JSON object to the final JSON object if not final_json: - final_json=[json_subline] + final_json = [json_subline] else: final_json.append(json_subline) # If output is desired - if (args.output): + if args.output: # Output the JSON data if (os.path.splitext(args.output)[1] == ".json"): - json_file=args.output + json_file = args.output else: - json_file=args.output +".json" + json_file = args.output +".json" # Write to JSON file with open(json_file,"w") as outfile: From 86394f09a0c539d635619e00a1d58b463fba3e59 Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 13 Jul 2024 13:06:26 -0400 Subject: [PATCH 04/11] missed a few extra changes from logic review --- scripts/evtx_dump_json.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 88325b6..29082d4 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -4,7 +4,6 @@ # # 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. # 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. - # # Requires: # - xmltodict >= 0.12.0 @@ -15,7 +14,6 @@ import xmltodict import Evtx.Evtx as evtx -import Evtx.Views as e_views def main(): @@ -83,10 +81,10 @@ def main(): if args.output: # Output the JSON data - if (os.path.splitext(args.output)[1] == ".json"): + if os.path.splitext(args.output)[1] == ".json": json_file = args.output else: - json_file = args.output +".json" + json_file = args.output + ".json" # Write to JSON file with open(json_file,"w") as outfile: From 541e1a1b1923841e0666ff1328d665859d8f0b08 Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 13 Jul 2024 13:08:15 -0400 Subject: [PATCH 05/11] final changes to code to align with current master --- scripts/evtx_dump_json.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 29082d4..1b58a58 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -7,7 +7,6 @@ # # Requires: # - xmltodict >= 0.12.0 - import os import json @@ -19,8 +18,8 @@ def main(): import argparse parser = argparse.ArgumentParser(description="Dump a binary EVTX file into XML.") - parser.add_argument("evtx", type=str,action='store', help="Path to the Windows EVTX event log file") - parser.add_argument("-o","--output",type=str, action='store', help="Path of output JSON file") + parser.add_argument("evtx",type=str,action="store",help="Path to the Windows EVTX event log file") + parser.add_argument("-o","--output",type=str, action="store",help="Path of output JSON file") args = parser.parse_args() with evtx.Evtx(args.evtx) as log: From 3224c75539263933206977410cb309f1c10d425e Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 13 Jul 2024 13:09:03 -0400 Subject: [PATCH 06/11] alright now its final --- scripts/evtx_dump_json.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 1b58a58..33cba8a 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -11,12 +11,13 @@ import json import xmltodict +import argparse import Evtx.Evtx as evtx def main(): - import argparse + parser = argparse.ArgumentParser(description="Dump a binary EVTX file into XML.") parser.add_argument("evtx",type=str,action="store",help="Path to the Windows EVTX event log file") parser.add_argument("-o","--output",type=str, action="store",help="Path of output JSON file") From 4436e29f8de69cc24d8420c64b0f76425e7d6e2a Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 13 Jul 2024 14:10:14 -0400 Subject: [PATCH 07/11] added sysmon evtx for testing of json dump --- .../Microsoft-Windows-Sysmon-Operational.evtx | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{ => data}/Microsoft-Windows-Sysmon-Operational.evtx (100%) diff --git a/tests/Microsoft-Windows-Sysmon-Operational.evtx b/tests/data/Microsoft-Windows-Sysmon-Operational.evtx similarity index 100% rename from tests/Microsoft-Windows-Sysmon-Operational.evtx rename to tests/data/Microsoft-Windows-Sysmon-Operational.evtx From 1a6c4c3e08941a8dde3bfc786a451880c62d464e Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 27 Jul 2024 16:32:43 -0400 Subject: [PATCH 08/11] fixed EventData key issue and added UserData loop --- scripts/__init__.py | 0 scripts/evtx_dump_json.py | 31 ++++++++++++++++++------------- tests/conftest.py | 2 +- tests/fixtures.py | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 scripts/__init__.py diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 33cba8a..3280f04 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -9,21 +9,16 @@ # - xmltodict >= 0.12.0 import os import json - +import sys import xmltodict import argparse import Evtx.Evtx as evtx -def main(): - - parser = argparse.ArgumentParser(description="Dump a binary EVTX file into XML.") - parser.add_argument("evtx",type=str,action="store",help="Path to the Windows EVTX event log file") - parser.add_argument("-o","--output",type=str, action="store",help="Path of output JSON file") - args = parser.parse_args() +def main(evtx_file,output): - with evtx.Evtx(args.evtx) as log: + with evtx.Evtx(evtx_file) as log: # Instantiate the final json object final_json = [] @@ -38,7 +33,6 @@ def main(): json_subline = {} json_subline.update({'EventRecordID':data_dict['Event']['System']['EventRecordID']}) - # Loop through each key,value pair of the System section of the evtx logs for event_system_key, event_system_value in data_dict['Event']['System'].items(): @@ -57,7 +51,7 @@ def main(): json_subline.update({event_system_key: event_system_value}) # Loop through each key, value pair of the EventData section of the evtx logs - if data_dict['Event']['EventData']!= None: + if "EventData" in data_dict['Event'].keys() and data_dict['Event']['EventData'] != None: for event_data_key, event_data_value in data_dict['Event']['EventData'].items(): for values in event_data_value: @@ -70,7 +64,12 @@ def main(): # Add information to the JSON object for this specific log json_subline.update({data_name: data_value}) - + + # Loop through each key, value pair in UserData section, if present + if "UserData" in data_dict["Event"].keys(): + for user_data_key,user_data_value in data_dict['Event']['UserData'].items(): + json_subline.update({user_data_key: user_data_value}) + # Add specific log JSON object to the final JSON object if not final_json: final_json = [json_subline] @@ -78,7 +77,7 @@ def main(): final_json.append(json_subline) # If output is desired - if args.output: + if output: # Output the JSON data if os.path.splitext(args.output)[1] == ".json": @@ -93,4 +92,10 @@ def main(): print(json.dumps(final_json)) if __name__ == "__main__": - main() + + parser = argparse.ArgumentParser(description="Dump a binary EVTX file into JSON.") + parser.add_argument("evtx",type=str,action="store",help="Path to the Windows EVTX event log file") + parser.add_argument("-o","--output",type=str, action="store",help="Path of output JSON file") + args = parser.parse_args() + + main(args.evtx,args.output) diff --git a/tests/conftest.py b/tests/conftest.py index 37f4339..68ffcab 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,4 +13,4 @@ # see the following for a discussion: # https://www.revsys.com/tidbits/pytest-fixtures-are-magic/ # https://lobste.rs/s/j8xgym/pytest_fixtures_are_magic -from fixtures import * # noqa: F403 [unable to detect undefined names] +from fixtures import * # noqa: F403 [unable to detect undefined names] \ No newline at end of file diff --git a/tests/fixtures.py b/tests/fixtures.py index 131c0ac..7512f02 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -74,4 +74,4 @@ def data_path(): """ cd = os.path.dirname(__file__) datadir = os.path.join(cd, "data") - return datadir + return datadir \ No newline at end of file From 0ae849a749c0813c79c6789a52c0fb6658fbcbda Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sat, 27 Jul 2024 16:33:11 -0400 Subject: [PATCH 09/11] removed init.py --- scripts/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 scripts/__init__.py diff --git a/scripts/__init__.py b/scripts/__init__.py deleted file mode 100644 index e69de29..0000000 From b8c274483f48f19b255b9bd959eb2c73ff42e7f4 Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sun, 8 Sep 2024 15:57:21 -0400 Subject: [PATCH 10/11] fixed issue found with System evtx logs and string Data section --- scripts/evtx_dump_json.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 3280f04..09d2eaf 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -48,22 +48,42 @@ def main(evtx_file,output): json_subline.update({event_system_subkey[1:]: event_system_subvalue}) else: + # Add information to the JSON object for this specific log json_subline.update({event_system_key: event_system_value}) # Loop through each key, value pair of the EventData section of the evtx logs if "EventData" in data_dict['Event'].keys() and data_dict['Event']['EventData'] != None: for event_data_key, event_data_value in data_dict['Event']['EventData'].items(): - for values in event_data_value: - # Loop through each subvalue within the EvenData section to extract necessary information - for event_data_subkey,event_data_subvalue in values.items(): + # Check to see if the EventData Data contains a list + if isinstance(event_data_value,list) and event_data_key!="@Name": + for values in event_data_value: + + # Loop through each subvalue within the EvenData section to extract necessary information + for event_data_subkey,event_data_subvalue in values.items(): + if event_data_subkey == "@Name": + data_name = event_data_subvalue + else: + data_value = event_data_subvalue + + # Add information to the JSON object for this specific log + json_subline.update({data_name: data_value}) + + # Check to see if EventData contains a dictionary + if isinstance(event_data_value,dict) and event_data_key!="@Name": + for event_data_subkey,event_data_subvalue in event_data_value.items(): if event_data_subkey == "@Name": data_name = event_data_subvalue - else: - data_value = event_data_subvalue - + else: + data_value=event_data_subvalue + # Add information to the JSON object for this specific log json_subline.update({data_name: data_value}) + + # Check to see if EventData contains a string + if isinstance(event_data_value,str) and event_data_key!="@Name": + beautify_event_data_value=event_data_value.replace("","").replace("\n"," ").replace("","") + json_subline.update({event_data_key: beautify_event_data_value}) # Loop through each key, value pair in UserData section, if present if "UserData" in data_dict["Event"].keys(): From 42a8aa476c2a44d29ea32b3d6e9443f01ebc577c Mon Sep 17 00:00:00 2001 From: ajread4 Date: Sun, 8 Sep 2024 15:59:17 -0400 Subject: [PATCH 11/11] fixed spacing --- scripts/evtx_dump_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/evtx_dump_json.py b/scripts/evtx_dump_json.py index 09d2eaf..d8e3e50 100644 --- a/scripts/evtx_dump_json.py +++ b/scripts/evtx_dump_json.py @@ -75,7 +75,7 @@ def main(evtx_file,output): if event_data_subkey == "@Name": data_name = event_data_subvalue else: - data_value=event_data_subvalue + data_value = event_data_subvalue # Add information to the JSON object for this specific log json_subline.update({data_name: data_value})