Hide keyboard shortcuts

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 

34 

35MSRPC_UUID_EVEN = uuidtup_to_bin(('82273FDC-E32A-18C3-3F78-827929DC23EA','0.0')) 

36 

37class DCERPCSessionError(DCERPCException): 

38 def __init__(self, error_string=None, error_code=None, packet=None): 

39 DCERPCException.__init__(self, error_string, error_code, packet) 

40 

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 

49 

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 

60 

61# 2.2.7 EVENTLOG_HANDLE_A and EVENTLOG_HANDLE_W 

62#EVENTLOG_HANDLE_A 

63EVENTLOG_HANDLE_W = LPWSTR 

64 

65# 2.2.9 Constants Used in Method Definitions 

66MAX_STRINGS = 0x00000100 

67MAX_SINGLE_EVENT = 0x0003FFFF 

68MAX_BATCH_BUFF = 0x0007FFFF 

69 

70# 3.1.4.7 ElfrReadELW (Opnum 10) 

71EVENTLOG_SEQUENTIAL_READ = 0x00000001 

72EVENTLOG_SEEK_READ = 0x00000002 

73 

74EVENTLOG_FORWARDS_READ = 0x00000004 

75EVENTLOG_BACKWARDS_READ = 0x00000008 

76 

77################################################################################ 

78# STRUCTURES 

79################################################################################ 

80 

81class IELF_HANDLE(NDRSTRUCT): 

82 structure = ( 

83 ('Data','20s=""'), 

84 ) 

85 def getAlignment(self): 

86 return 1 

87 

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 ) 

118 

119# 2.2.4 EVENTLOG_FULL_INFORMATION 

120class EVENTLOG_FULL_INFORMATION(NDRSTRUCT): 

121 structure = ( 

122 ('dwFull', ULONG), 

123 ) 

124 

125# 2.2.8 RPC_CLIENT_ID 

126class RPC_CLIENT_ID(NDRSTRUCT): 

127 structure = ( 

128 ('UniqueProcess', ULONG), 

129 ('UniqueThread', ULONG), 

130 ) 

131 

132# 2.2.12 RPC_STRING 

133class RPC_STRING(NDRSTRUCT): 

134 structure = ( 

135 ('Length','<H=0'), 

136 ('MaximumLength','<H=0'), 

137 ('Data',LPSTR), 

138 ) 

139 

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) 

145 

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=' ') 

150 

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) 

157 

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 ) 

168 

169class ElfrClearELFWResponse(NDRCALL): 

170 structure = ( 

171 ('ErrorCode', NTSTATUS), 

172 ) 

173 

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 ) 

181 

182class ElfrBackupELFWResponse(NDRCALL): 

183 structure = ( 

184 ('ErrorCode', NTSTATUS), 

185 ) 

186 

187# 3.1.4.21 ElfrCloseEL (Opnum 2) 

188class ElfrCloseEL(NDRCALL): 

189 opnum = 2 

190 structure = ( 

191 ('LogHandle', IELF_HANDLE), 

192 ) 

193 

194class ElfrCloseELResponse(NDRCALL): 

195 structure = ( 

196 ('LogHandle', IELF_HANDLE), 

197 ('ErrorCode', NTSTATUS), 

198 ) 

199 

200# 3.1.4.18 ElfrNumberOfRecords (Opnum 4) 

201class ElfrNumberOfRecords(NDRCALL): 

202 opnum = 4 

203 structure = ( 

204 ('LogHandle', IELF_HANDLE), 

205 ) 

206 

207class ElfrNumberOfRecordsResponse(NDRCALL): 

208 structure = ( 

209 ('NumberOfRecords', ULONG), 

210 ('ErrorCode', NTSTATUS), 

211 ) 

212 

213# 3.1.4.19 ElfrOldestRecord (Opnum 5) 

214class ElfrOldestRecord(NDRCALL): 

215 opnum = 5 

216 structure = ( 

217 ('LogHandle', IELF_HANDLE), 

218 ) 

219 

220class ElfrOldestRecordResponse(NDRCALL): 

221 structure = ( 

222 ('OldestRecordNumber', ULONG), 

223 ('ErrorCode', NTSTATUS), 

224 ) 

225 

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 ) 

236 

237class ElfrOpenELWResponse(NDRCALL): 

238 structure = ( 

239 ('LogHandle', IELF_HANDLE), 

240 ('ErrorCode', NTSTATUS), 

241 ) 

242 

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 ) 

253 

254class ElfrRegisterEventSourceWResponse(NDRCALL): 

255 structure = ( 

256 ('LogHandle', IELF_HANDLE), 

257 ('ErrorCode', NTSTATUS), 

258 ) 

259 

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 ) 

269 

270class ElfrOpenBELWResponse(NDRCALL): 

271 structure = ( 

272 ('LogHandle', IELF_HANDLE), 

273 ('ErrorCode', NTSTATUS), 

274 ) 

275 

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 ) 

285 

286class ElfrReadELWResponse(NDRCALL): 

287 structure = ( 

288 ('Buffer', NDRUniConformantArray), 

289 ('NumberOfBytesRead', ULONG), 

290 ('MinNumberOfBytesNeeded', ULONG), 

291 ('ErrorCode', NTSTATUS), 

292 ) 

293 

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 ) 

313 

314class ElfrReportEventWResponse(NDRCALL): 

315 structure = ( 

316 ('RecordNumber', PULONG), 

317 ('TimeWritten', PULONG), 

318 ('ErrorCode', NTSTATUS), 

319 ) 

320 

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} 

336 

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) 

347 

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) 

356 

357def hElfrCloseEL(dce, logHandle): 

358 request = ElfrCloseEL() 

359 request['LogHandle'] = logHandle 

360 resp = dce.request(request) 

361 return resp 

362 

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) 

371 

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) 

380 

381def hElfrClearELFW(dce, logHandle = '', backupFileName = NULL): 

382 request = ElfrClearELFW() 

383 request['LogHandle'] = logHandle 

384 request['BackupFileName'] = backupFileName 

385 return dce.request(request) 

386 

387def hElfrBackupELFW(dce, logHandle = '', backupFileName = NULL): 

388 request = ElfrBackupELFW() 

389 request['LogHandle'] = logHandle 

390 request['BackupFileName'] = backupFileName 

391 return dce.request(request) 

392 

393def hElfrNumberOfRecords(dce, logHandle): 

394 request = ElfrNumberOfRecords() 

395 request['LogHandle'] = logHandle 

396 resp = dce.request(request) 

397 return resp 

398 

399def hElfrOldestRecordNumber(dce, logHandle): 

400 request = ElfrOldestRecord() 

401 request['LogHandle'] = logHandle 

402 resp = dce.request(request) 

403 return resp