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 @author: Jamie Levy (gleeda)
26 @license: GNU General Public License 2.0 or later
27 @contact: jamie.levy@gmail.com
28 @organization: Volatile Systems
29 """
30 import ntpath
31
32 from rekall import obj
33 from rekall import scan
34 from rekall.plugins.windows.registry import registry
35 from rekall.plugins.windows.registry import getsids
36 from rekall_lib import utils
37
38
39
40 evt_log_types = {
41 'EVTLogHeader' : [0x30, {
42 'HeaderSize' : [0x0, ['unsigned int']],
43 'Magic' : [0x4, ['String', dict(length=4)]],
44
45
46 'OffsetOldest' : [0x10, ['int']],
47
48
49 'OffsetNextToWrite' : [0x14, ['int']],
50 'NextID' : [0x18, ['int']],
51 'OldestID' : [0x1c, ['int']],
52
53
54 'MaxSize' : [0x20, ['int']],
55
56
57 'RetentionTime' : [0x28, ['int']],
58
59
60 'RecordSize' : [0x2c, ['int']],
61 }],
62
63 'EVTRecordStruct' : [0x38, {
64 'RecordLength' : [0x0, ['int']],
65 'Magic' : [0x4, ['String', dict(length=4)]],
66 'RecordNumber' : [0x8, ['int']],
67
68 'TimeGenerated' : [0xc, ['UnixTimeStamp']],
69 'TimeWritten' : [0x10, ['UnixTimeStamp']],
70
71
72 'EventID' : [0x14, ['unsigned short']],
73 'EventType' : [0x18, ['Enumeration', dict(
74 target='unsigned short',
75 choices={0x01: "Error",
76 0x02: "Warning",
77 0x04: "Info",
78 0x08: "Success",
79 0x10: "Failure"})]],
80
81
82 'NumStrings' : [0x1a, ['unsigned short']],
83 'EventCategory' : [0x1c, ['unsigned short']],
84 'ReservedFlags' : [0x1e, ['unsigned short']],
85 'ClosingRecordNum' : [0x20, ['int']],
86
87
88 'StringOffset' : [0x24, ['int']],
89
90
91 'SidLength' : [0x28, ['int']],
92
93
94 'SidOffset' : [0x2c, ['int']],
95
96
97 'DataLength' : [0x30, ['int']],
98
99
100 'DataOffset' : [0x34, ['int']],
101
102 'Source': [0x38, ['UnicodeString', dict(
103 length=lambda x: x.RecordLength)]],
104
105
106 'Computer': [lambda x: x.Source.obj_offset + x.Source.obj_size,
107 ['UnicodeString', dict(
108 length=lambda x: x.RecordLength)]],
109
110 'Sid': [lambda x: x.obj_offset + x.SidOffset.v(), ['_SID']],
111
112 'Data':[lambda x: x.obj_offset + x.StringOffset.v(), [
113 "ListArray", dict(
114 target="UnicodeString",
115 target_args=dict(encoding="utf16"),
116 maximum_size=lambda x: x.RecordLength,
117 count=lambda x: x.NumStrings)]],
118 }],
119
120 "_SID": [None, {
121 "IdentifierAuthority": [None, ["Enumeration", dict(
122 choices={
123 "\x00\x00\x00\x00\x00\x00": "Null Authority",
124 "\x00\x00\x00\x00\x00\x01": "World Authority",
125 "\x00\x00\x00\x00\x00\x02": "Local Authority",
126 "\x00\x00\x00\x00\x00\x03": "Creator Authority",
127 "\x00\x00\x00\x00\x00\x04": "NonUnique Authority",
128 "\x00\x00\x00\x00\x00\x05": "NT Authority",
129 },
130 target="String",
131 target_args=dict(length=6, term=None)
132 )]],
133 "NumericIdentifier": [0x4, ["unsigned be int"]],
134 "SubAuthority": [None, ["Array", dict(
135 target="unsigned long",
136 count=lambda x: x.SubAuthorityCount)]],
137 }],
138 }
139
140
141
142 -class _SID(obj.Struct):
143 """A Pretty printing implementation of sids.
144
145 Reference:
146 http://www.sekchek.com/downloads/white-papers/windows-about-sids.pdf
147 """
149 """Format the Sid using SDDL Notation."""
150 components = [self.Revision, self.NumericIdentifier]
151 components.extend(self.SubAuthority)
152
153 result = u"S-" + u"-".join([str(x) for x in components])
154
155
156 friendly_name = self.obj_context.get("sid_cache", {}).get(result)
157 if friendly_name:
158 result = u"%s (%s)" % (result, friendly_name)
159
160 return result
161
164 """An implementation for parsing event logs."""
165
166 @classmethod
170
173 checks = [('StringCheck', dict(needle="LfLe"))]
174
175 - def scan(self, offset, maxlen=None, context=None):
176 for hit in super(EVTScanner, self).scan(offset, maxlen=maxlen):
177 event_offset = hit - self.profile.get_obj_offset(
178 "EVTRecordStruct", "Magic")
179
180 event = self.profile.EVTRecordStruct(
181 offset=event_offset, vm=self.address_space, context=context)
182
183
184 if (1500000000 > event.TimeGenerated > 1000000000 and
185 1500000000 > event.TimeWritten > 1000000000):
186 yield event
187
188
189 -class EvtLogs(registry.RegistryPlugin):
190 """Extract Windows Event Logs (XP/2003 only)"""
191
192 name = "evtlogs"
193 mode = "mode_xp"
194
199
201 """Search for event log files in memory.
202
203 We search for processes called 'services.exe' with a vad to and open
204 file ending with '.evt'.
205 """
206 ps_plugin = self.get_plugin("pslist", proc_regex="services.exe")
207
208 for task in ps_plugin.filter_processes():
209 for vad in task.RealVadRoot.traverse():
210 try:
211 filename = vad.ControlArea.FilePointer.FileName
212 if utils.SmartUnicode(filename).lower().endswith(".evt"):
213 yield task, vad
214 except AttributeError:
215 pass
216
223
254
256 if self.plugin_args.verbosity > 5:
257 self.PrecacheSids()
258
259 renderer.table_header([("TimeWritten", "timestamp", ""),
260 ("Filename", "filename", ""),
261 ("Computer", "computer", ""),
262 ("Sid", "sid", ""),
263 ("Source", "source", ""),
264 ("Event Id", "event_id", ""),
265 ("Event Type", "event_type", ""),
266 ("Message", "message", "")])
267
268 for task, vad in self.FindEVTFiles():
269 filename = ntpath.basename(
270 utils.SmartUnicode(vad.ControlArea.FilePointer.FileName))
271
272 for event in self.ScanEvents(vad, task.get_process_address_space()):
273 args = ";".join(
274 repr(utils.SmartStr(x)) for x in event.Data)
275
276 renderer.table_row(
277 event.TimeWritten,
278 filename,
279 event.Computer,
280 event.Sid,
281 event.Source,
282 event.EventID,
283 event.EventType,
284 args)
285