Skip to content

Instantly share code, notes, and snippets.

@maxrp
Created April 24, 2014 18:28
Show Gist options
  • Save maxrp/11264603 to your computer and use it in GitHub Desktop.
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
#!/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