Created
April 24, 2014 18:28
-
-
Save maxrp/11264603 to your computer and use it in GitHub Desktop.
Simple script to reduce bulk and flatten Windows audit log exports to a simple event series
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import csv | |
# Ad hoc names for the fields from the source CSV | |
WAUDITFIELDS = ( 'id', | |
'type', | |
'facility', | |
'date', | |
'empty?', | |
'kvpairs', | |
'cruftA', | |
'cruftB', | |
) | |
# All the fields that appear in the source (names taken from WAUDITFIELDS for | |
# non-key:value type fields. | |
ALLFIELDS = ( 'Certificate Information', | |
'Client Port', | |
'facility', | |
'Logon Type', | |
'Logon ID', | |
'Account Name', | |
'Service Name', | |
'Failure Information', | |
'id', | |
'Workstation Name', | |
'Status', | |
'Service Information', | |
'Failure Code', | |
'Account For Which Logon Failed', | |
'Ticket Options', | |
'Caller Computer Name', | |
'Network Information', | |
'Certificate Thumbprint', | |
'Authentication Package', | |
'Logon Process', | |
'Failure Reason', | |
'Subject', | |
'type', | |
'Certificate Issuer Name', | |
'Package Name (NTLM only)', | |
'Client Address', | |
'empty?', | |
'Caller Process Name', | |
'Account Domain', | |
'Sub Status', | |
'Key Length', | |
'date', | |
'Process Information', | |
'Detailed Authentication Information', | |
'Source Network Address', | |
'Transited Services', | |
'Account That Was Locked Out', | |
'Account Information', | |
'Security ID', | |
'Caller Process ID', | |
'Source Port', | |
'Certificate Serial Number', | |
'Additional Information', | |
'Pre-Authentication Type', | |
) | |
# Fields we desire in the output CSV | |
OUTFIELDS = ( | |
'date', | |
'type', | |
'Account Name', | |
'Workstation Name', | |
#'Client Address', | |
'Source Network Address', | |
#'Security ID', | |
) | |
def main(): | |
with open('test.csv', 'wb') as outfile: | |
dw = csv.DictWriter(outfile, fieldnames=OUTFIELDS) | |
dw.writeheader() | |
with open('Security_Log.txt', 'r') as this_csv: | |
data = csv.DictReader(this_csv, fieldnames=WAUDITFIELDS) | |
for line in data: | |
# A row of the source is metadata & has no date skip processing | |
if line['date'] is 'None': | |
pass | |
# The field with most of the vital details, in k:v format | |
useful_data = line['kvpairs'] | |
# fields cruft{A,B} never contain anything useful and kvpairs | |
# have already been copied for further processing | |
del line['cruftA'], line['cruftB'], line['kvpairs'] | |
# Not all rows contain kvpairs | |
if useful_data: | |
# the K:V pairs are seperated by a triple space | |
for field in useful_data.split(' '): | |
ffs = field.split(':') | |
for value in ffs[1:]: | |
# remove any spaces remaining after splitting | |
key = ffs[0].strip() | |
value = value.strip() | |
if key in line: | |
# if the key exists already, append... | |
line[key] += value | |
else: | |
# ...otherwise store it | |
line[key] = value | |
for key in line.keys(): | |
# Delete all fields not expressly listed in OUTFIELDS | |
if key not in OUTFIELDS: | |
del line[key] | |
dw.writerow(line) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment