Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/even.py : 57%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Impacket - Collection of Python classes for working with network protocols.
2#
3# SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved.
4#
5# This software is provided under a slightly modified version
6# of the Apache Software License. See the accompanying LICENSE file
7# for more information.
8#
9# Description:
10# [MS-EVEN] Interface implementation
11#
12# Best way to learn how to use these calls is to grab the protocol standard
13# so you understand what the call does, and then read the test case located
14# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC
15#
16# Some calls have helper functions, which makes it even easier to use.
17# They are located at the end of this file.
18# Helper functions start with "h"<name of the call>.
19# There are test cases for them too.
20#
21# Author:
22# Alberto Solino (@agsolino)
23# Itamar Mizrahi (@MrAnde7son)
24#
25from __future__ import division
26from __future__ import print_function
27from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDR, NDRPOINTERNULL, NDRUniConformantArray
28from impacket.dcerpc.v5.dtypes import ULONG, LPWSTR, RPC_UNICODE_STRING, LPSTR, NTSTATUS, NULL, PRPC_UNICODE_STRING, PULONG, USHORT, PRPC_SID, LPBYTE
29from impacket.dcerpc.v5.lsad import PRPC_UNICODE_STRING_ARRAY
30from impacket.structure import Structure
31from impacket import nt_errors
32from impacket.uuid import uuidtup_to_bin
33from impacket.dcerpc.v5.rpcrt import DCERPCException
35MSRPC_UUID_EVEN = uuidtup_to_bin(('82273FDC-E32A-18C3-3F78-827929DC23EA','0.0'))
37class DCERPCSessionError(DCERPCException):
38 def __init__(self, error_string=None, error_code=None, packet=None):
39 DCERPCException.__init__(self, error_string, error_code, packet)
41 def __str__( self ):
42 key = self.error_code
43 if key in nt_errors.ERROR_MESSAGES:
44 error_msg_short = nt_errors.ERROR_MESSAGES[key][0]
45 error_msg_verbose = nt_errors.ERROR_MESSAGES[key][1]
46 return 'EVEN SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
47 else:
48 return 'EVEN SessionError: unknown error code: 0x%x' % self.error_code
50################################################################################
51# CONSTANTS
52################################################################################
53# 2.2.2 EventType
54EVENTLOG_SUCCESS = 0x0000
55EVENTLOG_ERROR_TYPE = 0x0001
56EVENTLOG_WARNING_TYPE = 0x0002
57EVENTLOG_INFORMATION_TYPE = 0x0004
58EVENTLOG_AUDIT_SUCCESS = 0x0008
59EVENTLOG_AUDIT_FAILURE = 0x0010
61# 2.2.7 EVENTLOG_HANDLE_A and EVENTLOG_HANDLE_W
62#EVENTLOG_HANDLE_A
63EVENTLOG_HANDLE_W = LPWSTR
65# 2.2.9 Constants Used in Method Definitions
66MAX_STRINGS = 0x00000100
67MAX_SINGLE_EVENT = 0x0003FFFF
68MAX_BATCH_BUFF = 0x0007FFFF
70# 3.1.4.7 ElfrReadELW (Opnum 10)
71EVENTLOG_SEQUENTIAL_READ = 0x00000001
72EVENTLOG_SEEK_READ = 0x00000002
74EVENTLOG_FORWARDS_READ = 0x00000004
75EVENTLOG_BACKWARDS_READ = 0x00000008
77################################################################################
78# STRUCTURES
79################################################################################
81class IELF_HANDLE(NDRSTRUCT):
82 structure = (
83 ('Data','20s=""'),
84 )
85 def getAlignment(self):
86 return 1
88# 2.2.3 EVENTLOGRECORD
89class EVENTLOGRECORD(Structure):
90 structure = (
91 ('Length','<L=0'),
92 ('Reserved','<L=0'),
93 ('RecordNumber','<L=0'),
94 ('TimeGenerated','<L=0'),
95 ('TimeWritten','<L=0'),
96 ('EventID','<L=0'),
97 ('EventType','<H=0'),
98 ('NumStrings','<H=0'),
99 ('EventCategory','<H=0'),
100 ('ReservedFlags','<H=0'),
101 ('ClosingRecordNumber','<L=0'),
102 ('StringOffset','<L=0'),
103 ('UserSidLength','<L=0'),
104 ('UserSidOffset','<L=0'),
105 ('DataLength','<L=0'),
106 ('DataOffset','<L=0'),
107 ('SourceName','z'),
108 ('Computername','z'),
109 ('UserSidPadding',':'),
110 ('_UserSid','_-UserSid', 'self["UserSidLength"]'),
111 ('UserSid',':'),
112 ('Strings',':'),
113 ('_Data','_-Data', 'self["DataLength"]'),
114 ('Data',':'),
115 ('Padding',':'),
116 ('Length2','<L=0'),
117 )
119# 2.2.4 EVENTLOG_FULL_INFORMATION
120class EVENTLOG_FULL_INFORMATION(NDRSTRUCT):
121 structure = (
122 ('dwFull', ULONG),
123 )
125# 2.2.8 RPC_CLIENT_ID
126class RPC_CLIENT_ID(NDRSTRUCT):
127 structure = (
128 ('UniqueProcess', ULONG),
129 ('UniqueThread', ULONG),
130 )
132# 2.2.12 RPC_STRING
133class RPC_STRING(NDRSTRUCT):
134 structure = (
135 ('Length','<H=0'),
136 ('MaximumLength','<H=0'),
137 ('Data',LPSTR),
138 )
140 def __setitem__(self, key, value):
141 if key == 'Data' and isinstance(value, NDR) is False:
142 self['Length'] = len(value)
143 self['MaximumLength'] = len(value)
144 return NDRSTRUCT.__setitem__(self, key, value)
146 def dump(self, msg = None, indent = 0):
147 if msg is None: msg = self.__class__.__name__
148 if msg != '':
149 print("%s" % msg, end=' ')
151 if isinstance(self.fields['Data'] , NDRPOINTERNULL):
152 print(" NULL", end=' ')
153 elif self.fields['Data']['ReferentID'] == 0:
154 print(" NULL", end=' ')
155 else:
156 return self.fields['Data'].dump('',indent)
158################################################################################
159# RPC CALLS
160################################################################################
161# 3.1.4.9 ElfrClearELFW (Opnum 0)
162class ElfrClearELFW(NDRCALL):
163 opnum = 0
164 structure = (
165 ('LogHandle', IELF_HANDLE),
166 ('BackupFileName', PRPC_UNICODE_STRING),
167 )
169class ElfrClearELFWResponse(NDRCALL):
170 structure = (
171 ('ErrorCode', NTSTATUS),
172 )
174# 3.1.4.11 ElfrBackupELFW (Opnum 1)
175class ElfrBackupELFW(NDRCALL):
176 opnum = 1
177 structure = (
178 ('LogHandle', IELF_HANDLE),
179 ('BackupFileName', RPC_UNICODE_STRING),
180 )
182class ElfrBackupELFWResponse(NDRCALL):
183 structure = (
184 ('ErrorCode', NTSTATUS),
185 )
187# 3.1.4.21 ElfrCloseEL (Opnum 2)
188class ElfrCloseEL(NDRCALL):
189 opnum = 2
190 structure = (
191 ('LogHandle', IELF_HANDLE),
192 )
194class ElfrCloseELResponse(NDRCALL):
195 structure = (
196 ('LogHandle', IELF_HANDLE),
197 ('ErrorCode', NTSTATUS),
198 )
200# 3.1.4.18 ElfrNumberOfRecords (Opnum 4)
201class ElfrNumberOfRecords(NDRCALL):
202 opnum = 4
203 structure = (
204 ('LogHandle', IELF_HANDLE),
205 )
207class ElfrNumberOfRecordsResponse(NDRCALL):
208 structure = (
209 ('NumberOfRecords', ULONG),
210 ('ErrorCode', NTSTATUS),
211 )
213# 3.1.4.19 ElfrOldestRecord (Opnum 5)
214class ElfrOldestRecord(NDRCALL):
215 opnum = 5
216 structure = (
217 ('LogHandle', IELF_HANDLE),
218 )
220class ElfrOldestRecordResponse(NDRCALL):
221 structure = (
222 ('OldestRecordNumber', ULONG),
223 ('ErrorCode', NTSTATUS),
224 )
226# 3.1.4.3 ElfrOpenELW (Opnum 7)
227class ElfrOpenELW(NDRCALL):
228 opnum = 7
229 structure = (
230 ('UNCServerName', EVENTLOG_HANDLE_W),
231 ('ModuleName', RPC_UNICODE_STRING),
232 ('RegModuleName', RPC_UNICODE_STRING),
233 ('MajorVersion', ULONG),
234 ('MinorVersion', ULONG),
235 )
237class ElfrOpenELWResponse(NDRCALL):
238 structure = (
239 ('LogHandle', IELF_HANDLE),
240 ('ErrorCode', NTSTATUS),
241 )
243# 3.1.4.5 ElfrRegisterEventSourceW (Opnum 8)
244class ElfrRegisterEventSourceW(NDRCALL):
245 opnum = 8
246 structure = (
247 ('UNCServerName', EVENTLOG_HANDLE_W),
248 ('ModuleName', RPC_UNICODE_STRING),
249 ('RegModuleName', RPC_UNICODE_STRING),
250 ('MajorVersion', ULONG),
251 ('MinorVersion', ULONG),
252 )
254class ElfrRegisterEventSourceWResponse(NDRCALL):
255 structure = (
256 ('LogHandle', IELF_HANDLE),
257 ('ErrorCode', NTSTATUS),
258 )
260# 3.1.4.1 ElfrOpenBELW (Opnum 9)
261class ElfrOpenBELW(NDRCALL):
262 opnum = 9
263 structure = (
264 ('UNCServerName', EVENTLOG_HANDLE_W),
265 ('BackupFileName', RPC_UNICODE_STRING),
266 ('MajorVersion', ULONG),
267 ('MinorVersion', ULONG),
268 )
270class ElfrOpenBELWResponse(NDRCALL):
271 structure = (
272 ('LogHandle', IELF_HANDLE),
273 ('ErrorCode', NTSTATUS),
274 )
276# 3.1.4.7 ElfrReadELW (Opnum 10)
277class ElfrReadELW(NDRCALL):
278 opnum = 10
279 structure = (
280 ('LogHandle', IELF_HANDLE),
281 ('ReadFlags', ULONG),
282 ('RecordOffset', ULONG),
283 ('NumberOfBytesToRead', ULONG),
284 )
286class ElfrReadELWResponse(NDRCALL):
287 structure = (
288 ('Buffer', NDRUniConformantArray),
289 ('NumberOfBytesRead', ULONG),
290 ('MinNumberOfBytesNeeded', ULONG),
291 ('ErrorCode', NTSTATUS),
292 )
294# 3.1.4.13 ElfrReportEventW (Opnum 11)
295class ElfrReportEventW(NDRCALL):
296 opnum = 11
297 structure = (
298 ('LogHandle', IELF_HANDLE),
299 ('Time', ULONG),
300 ('EventType', USHORT),
301 ('EventCategory', USHORT),
302 ('EventID', ULONG),
303 ('NumStrings', USHORT),
304 ('DataSize', ULONG),
305 ('ComputerName', RPC_UNICODE_STRING),
306 ('UserSID', PRPC_SID),
307 ('Strings', PRPC_UNICODE_STRING_ARRAY),
308 ('Data', LPBYTE),
309 ('Flags', USHORT),
310 ('RecordNumber', PULONG),
311 ('TimeWritten', PULONG),
312 )
314class ElfrReportEventWResponse(NDRCALL):
315 structure = (
316 ('RecordNumber', PULONG),
317 ('TimeWritten', PULONG),
318 ('ErrorCode', NTSTATUS),
319 )
321################################################################################
322# OPNUMs and their corresponding structures
323################################################################################
324OPNUMS = {
325 0 : (ElfrClearELFW, ElfrClearELFWResponse),
326 1 : (ElfrBackupELFW, ElfrBackupELFWResponse),
327 2 : (ElfrCloseEL, ElfrCloseELResponse),
328 4 : (ElfrNumberOfRecords, ElfrNumberOfRecordsResponse),
329 5 : (ElfrOldestRecord, ElfrOldestRecordResponse),
330 7 : (ElfrOpenELW, ElfrOpenELWResponse),
331 8 : (ElfrRegisterEventSourceW, ElfrRegisterEventSourceWResponse),
332 9 : (ElfrOpenBELW, ElfrOpenBELWResponse),
333 10 : (ElfrReadELW, ElfrReadELWResponse),
334 11 : (ElfrReportEventW, ElfrReportEventWResponse),
335}
337################################################################################
338# HELPER FUNCTIONS
339################################################################################
340def hElfrOpenBELW(dce, backupFileName = NULL):
341 request = ElfrOpenBELW()
342 request['UNCServerName'] = NULL
343 request['BackupFileName'] = backupFileName
344 request['MajorVersion'] = 1
345 request['MinorVersion'] = 1
346 return dce.request(request)
348def hElfrOpenELW(dce, moduleName = NULL, regModuleName = NULL):
349 request = ElfrOpenELW()
350 request['UNCServerName'] = NULL
351 request['ModuleName'] = moduleName
352 request['RegModuleName'] = regModuleName
353 request['MajorVersion'] = 1
354 request['MinorVersion'] = 1
355 return dce.request(request)
357def hElfrCloseEL(dce, logHandle):
358 request = ElfrCloseEL()
359 request['LogHandle'] = logHandle
360 resp = dce.request(request)
361 return resp
363def hElfrRegisterEventSourceW(dce, moduleName = NULL, regModuleName = NULL):
364 request = ElfrRegisterEventSourceW()
365 request['UNCServerName'] = NULL
366 request['ModuleName'] = moduleName
367 request['RegModuleName'] = regModuleName
368 request['MajorVersion'] = 1
369 request['MinorVersion'] = 1
370 return dce.request(request)
372def hElfrReadELW(dce, logHandle = '', readFlags = EVENTLOG_SEEK_READ|EVENTLOG_FORWARDS_READ,
373 recordOffset = 0, numberOfBytesToRead = MAX_BATCH_BUFF):
374 request = ElfrReadELW()
375 request['LogHandle'] = logHandle
376 request['ReadFlags'] = readFlags
377 request['RecordOffset'] = recordOffset
378 request['NumberOfBytesToRead'] = numberOfBytesToRead
379 return dce.request(request)
381def hElfrClearELFW(dce, logHandle = '', backupFileName = NULL):
382 request = ElfrClearELFW()
383 request['LogHandle'] = logHandle
384 request['BackupFileName'] = backupFileName
385 return dce.request(request)
387def hElfrBackupELFW(dce, logHandle = '', backupFileName = NULL):
388 request = ElfrBackupELFW()
389 request['LogHandle'] = logHandle
390 request['BackupFileName'] = backupFileName
391 return dce.request(request)
393def hElfrNumberOfRecords(dce, logHandle):
394 request = ElfrNumberOfRecords()
395 request['LogHandle'] = logHandle
396 resp = dce.request(request)
397 return resp
399def hElfrOldestRecordNumber(dce, logHandle):
400 request = ElfrOldestRecord()
401 request['LogHandle'] = logHandle
402 resp = dce.request(request)
403 return resp