-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse_evtx_account_changes.py
117 lines (105 loc) · 3.87 KB
/
parse_evtx_account_changes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#! /usr/bin/env python3
# Extract Common Windows Account Change Events
# from the Security.evtx log file
#
# Requires Python-evtx https://github.com/williballenthin/python-evtx
# and BeautifulSoup
# Event IDs can be added or removed by editing the "evtxs" variable
import sys
import re
import mmap
import contextlib
import argparse
from bs4 import BeautifulSoup, element
from Evtx.Evtx import FileHeader
from Evtx.Views import evtx_file_xml_view
evtxs = {1102: 'Log Cleared',
4704: 'A User Right was Assigned',
4705: 'A User Right was Removed',
4720: 'A New User Account Created',
4722: 'A New User Account Enabled',
4725: 'User Account Disabled',
4726: 'User Account Deleted',
4728: 'Member Added to Global Group',
4731: 'A Security-enabled Group Created',
4732: 'A Member was Added to Security-enabled Local Group',
4733: 'An Account was removed from Local Security-enabled Group',
4734: 'A Security-enabled Local Group was Deleted',
4740: 'Account Locked out',
4748: 'Local Group Deleted',
4756: 'Member Added to Universal Group',
4765: 'SID History added to Account',
4766: 'SID History add attempted on Account',
4767: 'User Account Unlocked',
4781: 'Account Name Changed',
4793: 'Password Policy Checking API called',
4794: 'Attempted Admin Password Change! Directory Services Restore Mode(DSRM)'
}
event_info_names = ('Date',
'EventID',
'Description',
'Computer'
)
event_data_names = ('LogonType',
'AuthenticationPackageName',
'LmPackageName',
'LogonProcessName',
'SubjectUserSID',
'IpAddress',
'IpPort',
'WorkstationName',
'SubjectUserSid',
'SubjectUserName',
'SubjectDomainName',
'SubjectLogonId',
'TargetUserSid',
'TargetUserName',
'TargetDomainName',
'TargetLogonId',
'LogonGuid',
'TransmittedServices',
'KeyLength',
'ProcessName',
'ProcessId'
)
def main():
parser = argparse.ArgumentParser(description=
"Extract Common Windows Account Change Events",
usage='parse_evtx_account_changes.py Security.evtx -n')
parser.add_argument("evtx", type=str,
help='Security.evtx ')
parser.add_argument("-n", "--NoHeader", default=False, action="store_true",
help="Do not print Header")
args = parser.parse_args()
header = (','.join(map(str,event_info_names + event_data_names)))
if not args.NoHeader:
print(header)
with open(args.evtx, 'r') as f:
with contextlib.closing(mmap.mmap(f.fileno(), 0,
access=mmap.ACCESS_READ)) as buf:
fh = FileHeader(buf, 0x0)
for xml, record in evtx_file_xml_view(fh):
soup = BeautifulSoup(xml, "lxml")
Date = soup.event.system.timecreated['systemtime']
Date = Date[:-7]
EventID = int(soup.event.system.eventid.string)
Computer = soup.event.system.computer.string
if EventID in evtxs:
event_info = "%s,%s,%s,%s," % (Date,EventID,evtxs[EventID],Computer)
try:
event_data = {}
for child in soup.eventdata.children:
if type(child) is element.Tag:
event_data[child['name']] = ' '.join(child.text.split())
event_data_result = []
for value in event_data_names:
result = event_data.get(value)
if result is None:
result = ''
event_data_result.append(result)
output = ((event_info) + ','.join(map(str,event_data_result)))
print(output)
except:
pass
if __name__ == "__main__":
main()