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) 2021 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-DCOM] 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# 

24# ToDo: 

25# [X] Use the same DCE connection for all the calls. Right now is connecting to the remote machine 

26# for each call, making it slower. 

27# [X] Implement a ping mechanism, otherwise the garbage collector at the server shuts down the objects if 

28# not used, returning RPC_E_DISCONNECTED 

29# 

30 

31from __future__ import division 

32from __future__ import print_function 

33import socket 

34from struct import pack 

35from threading import Timer, current_thread 

36 

37from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRTLSTRUCT, UNKNOWNDATA 

38from impacket.dcerpc.v5.dtypes import LPWSTR, ULONGLONG, HRESULT, GUID, USHORT, WSTR, DWORD, LPLONG, LONG, PGUID, ULONG, \ 

39 UUID, WIDESTR, NULL 

40from impacket import hresult_errors, LOG 

41from impacket.uuid import string_to_bin, uuidtup_to_bin, generate 

42from impacket.dcerpc.v5.rpcrt import TypeSerialization1, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_NONE, \ 

43 RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_WINNT, DCERPCException 

44from impacket.dcerpc.v5 import transport 

45 

46CLSID_ActivationContextInfo = string_to_bin('000001a5-0000-0000-c000-000000000046') 

47CLSID_ActivationPropertiesIn = string_to_bin('00000338-0000-0000-c000-000000000046') 

48CLSID_ActivationPropertiesOut = string_to_bin('00000339-0000-0000-c000-000000000046') 

49CLSID_CONTEXT_EXTENSION = string_to_bin('00000334-0000-0000-c000-000000000046') 

50CLSID_ContextMarshaler = string_to_bin('0000033b-0000-0000-c000-000000000046') 

51CLSID_ERROR_EXTENSION = string_to_bin('0000031c-0000-0000-c000-000000000046') 

52CLSID_ErrorObject = string_to_bin('0000031b-0000-0000-c000-000000000046') 

53CLSID_InstanceInfo = string_to_bin('000001ad-0000-0000-c000-000000000046') 

54CLSID_InstantiationInfo = string_to_bin('000001ab-0000-0000-c000-000000000046') 

55CLSID_PropsOutInfo = string_to_bin('00000339-0000-0000-c000-000000000046') 

56CLSID_ScmReplyInfo = string_to_bin('000001b6-0000-0000-c000-000000000046') 

57CLSID_ScmRequestInfo = string_to_bin('000001aa-0000-0000-c000-000000000046') 

58CLSID_SecurityInfo = string_to_bin('000001a6-0000-0000-c000-000000000046') 

59CLSID_ServerLocationInfo = string_to_bin('000001a4-0000-0000-c000-000000000046') 

60CLSID_SpecialSystemProperties = string_to_bin('000001b9-0000-0000-c000-000000000046') 

61IID_IActivation = uuidtup_to_bin(('4d9f4ab8-7d1c-11cf-861e-0020af6e7c57','0.0')) 

62IID_IActivationPropertiesIn = uuidtup_to_bin(('000001A2-0000-0000-C000-000000000046','0.0')) 

63IID_IActivationPropertiesOut = uuidtup_to_bin(('000001A3-0000-0000-C000-000000000046','0.0')) 

64IID_IContext = uuidtup_to_bin(('000001c0-0000-0000-C000-000000000046','0.0')) 

65IID_IObjectExporter = uuidtup_to_bin(('99fcfec4-5260-101b-bbcb-00aa0021347a','0.0')) 

66IID_IRemoteSCMActivator = uuidtup_to_bin(('000001A0-0000-0000-C000-000000000046','0.0')) 

67IID_IRemUnknown = uuidtup_to_bin(('00000131-0000-0000-C000-000000000046','0.0')) 

68IID_IRemUnknown2 = uuidtup_to_bin(('00000143-0000-0000-C000-000000000046','0.0')) 

69IID_IUnknown = uuidtup_to_bin(('00000000-0000-0000-C000-000000000046','0.0')) 

70IID_IClassFactory = uuidtup_to_bin(('00000001-0000-0000-C000-000000000046','0.0')) 

71 

72class DCERPCSessionError(DCERPCException): 

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

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

75 

76 def __str__( self ): 

77 if self.error_code in hresult_errors.ERROR_MESSAGES: 

78 error_msg_short = hresult_errors.ERROR_MESSAGES[self.error_code][0] 

79 error_msg_verbose = hresult_errors.ERROR_MESSAGES[self.error_code][1] 

80 return 'DCOM SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 

81 else: 

82 return 'DCOM SessionError: unknown error code: 0x%x' % self.error_code 

83 

84################################################################################ 

85# CONSTANTS 

86################################################################################ 

87# 2.2.1 OID 

88OID = ULONGLONG 

89 

90class OID_ARRAY(NDRUniConformantArray): 

91 item = OID 

92 

93class POID_ARRAY(NDRPOINTER): 

94 referent = ( 

95 ('Data', OID_ARRAY), 

96 ) 

97 

98# 2.2.2 SETID 

99SETID = ULONGLONG 

100 

101# 2.2.4 error_status_t 

102error_status_t = ULONG 

103 

104# 2.2.6 CID 

105CID = GUID 

106 

107# 2.2.7 CLSID 

108CLSID = GUID 

109 

110# 2.2.8 IID 

111IID = GUID 

112PIID = PGUID 

113 

114# 2.2.9 IPID 

115IPID = GUID 

116 

117# 2.2.10 OXID 

118OXID = ULONGLONG 

119 

120# 2.2.18 OBJREF 

121FLAGS_OBJREF_STANDARD = 0x00000001 

122FLAGS_OBJREF_HANDLER = 0x00000002 

123FLAGS_OBJREF_CUSTOM = 0x00000004 

124FLAGS_OBJREF_EXTENDED = 0x00000008 

125 

126# 2.2.18.1 STDOBJREF 

127SORF_NOPING = 0x00001000 

128 

129# 2.2.20 Context 

130CTXMSHLFLAGS_BYVAL = 0x00000002 

131 

132# 2.2.20.1 PROPMARSHALHEADER 

133CPFLAG_PROPAGATE = 0x00000001 

134CPFLAG_EXPOSE = 0x00000002 

135CPFLAG_ENVOY = 0x00000004 

136 

137# 2.2.22.2.1 InstantiationInfoData 

138ACTVFLAGS_DISABLE_AAA = 0x00000002 

139ACTVFLAGS_ACTIVATE_32_BIT_SERVER = 0x00000004 

140ACTVFLAGS_ACTIVATE_64_BIT_SERVER = 0x00000008 

141ACTVFLAGS_NO_FAILURE_LOG = 0x00000020 

142 

143# 2.2.22.2.2 SpecialPropertiesData 

144SPD_FLAG_USE_CONSOLE_SESSION = 0x00000001 

145 

146# 2.2.28.1 IDL Range Constants 

147MAX_REQUESTED_INTERFACES = 0x8000 

148MAX_REQUESTED_PROTSEQS = 0x8000 

149MIN_ACTPROP_LIMIT = 1 

150MAX_ACTPROP_LIMIT = 10 

151 

152################################################################################ 

153# STRUCTURES 

154################################################################################ 

155class handle_t(NDRSTRUCT): 

156 structure = ( 

157 ('context_handle_attributes',ULONG), 

158 ('context_handle_uuid',UUID), 

159 ) 

160 

161 def __init__(self, data=None, isNDR64=False): 

162 NDRSTRUCT.__init__(self, data, isNDR64) 

163 self['context_handle_uuid'] = b'\x00'*16 

164 

165 def isNull(self): 

166 return self['context_handle_uuid'] == b'\x00'*16 

167 

168# 2.2.11 COMVERSION 

169class COMVERSION(NDRSTRUCT): 

170 default_major_version = 5 

171 default_minor_version = 7 

172 

173 structure = ( 

174 ('MajorVersion',USHORT), 

175 ('MinorVersion',USHORT), 

176 ) 

177 

178 @classmethod 

179 def set_default_version(cls, major_version=None, minor_version=None): 

180 # Set default dcom version for all new COMVERSION objects. 

181 if major_version is not None: 

182 cls.default_major_version = major_version 

183 if minor_version is not None: 

184 cls.default_minor_version = minor_version 

185 

186 def __init__(self, data = None,isNDR64 = False): 

187 NDRSTRUCT.__init__(self, data, isNDR64) 

188 if data is None: 188 ↛ exitline 188 didn't return from function '__init__', because the condition on line 188 was never false

189 self['MajorVersion'] = self.default_major_version 

190 self['MinorVersion'] = self.default_minor_version 

191 

192class PCOMVERSION(NDRPOINTER): 

193 referent = ( 

194 ('Data', COMVERSION), 

195 ) 

196 

197# 2.2.13.1 ORPC_EXTENT 

198# This MUST contain an array of bytes that form the extent data.  

199# The array size MUST be a multiple of 8 for alignment reasons. 

200class BYTE_ARRAY(NDRUniConformantArray): 

201 item = 'c' 

202 

203class ORPC_EXTENT(NDRSTRUCT): 

204 structure = ( 

205 ('id',GUID), 

206 ('size',ULONG), 

207 ('data',BYTE_ARRAY), 

208 ) 

209 

210# 2.2.13.2 ORPC_EXTENT_ARRAY 

211# ThisMUSTbeanarrayofORPC_EXTENTs.ThearraysizeMUSTbeamultipleof2for alignment reasons. 

212class PORPC_EXTENT(NDRPOINTER): 

213 referent = ( 

214 ('Data', ORPC_EXTENT), 

215 ) 

216 

217class EXTENT_ARRAY(NDRUniConformantArray): 

218 item = PORPC_EXTENT 

219 

220class PEXTENT_ARRAY(NDRPOINTER): 

221 referent = ( 

222 ('Data', EXTENT_ARRAY), 

223 ) 

224 

225class ORPC_EXTENT_ARRAY(NDRSTRUCT): 

226 structure = ( 

227 ('size',ULONG), 

228 ('reserved',ULONG), 

229 ('extent',PEXTENT_ARRAY), 

230 ) 

231 

232class PORPC_EXTENT_ARRAY(NDRPOINTER): 

233 referent = ( 

234 ('Data', ORPC_EXTENT_ARRAY), 

235 ) 

236 

237# 2.2.13.3 ORPCTHIS 

238class ORPCTHIS(NDRSTRUCT): 

239 structure = ( 

240 ('version',COMVERSION), 

241 ('flags',ULONG), 

242 ('reserved1',ULONG), 

243 ('cid',CID), 

244 ('extensions',PORPC_EXTENT_ARRAY), 

245 ) 

246 

247# 2.2.13.4 ORPCTHAT 

248class ORPCTHAT(NDRSTRUCT): 

249 structure = ( 

250 ('flags',ULONG), 

251 ('extensions',PORPC_EXTENT_ARRAY), 

252 ) 

253 

254# 2.2.14 MInterfacePointer 

255class MInterfacePointer(NDRSTRUCT): 

256 structure = ( 

257 ('ulCntData',ULONG), 

258 ('abData',BYTE_ARRAY), 

259 ) 

260 

261# 2.2.15 PMInterfacePointerInternal 

262class PMInterfacePointerInternal(NDRPOINTER): 

263 referent = ( 

264 ('Data', MInterfacePointer), 

265 ) 

266 

267# 2.2.16 PMInterfacePointer 

268class PMInterfacePointer(NDRPOINTER): 

269 referent = ( 

270 ('Data', MInterfacePointer), 

271 ) 

272 

273class PPMInterfacePointer(NDRPOINTER): 

274 referent = ( 

275 ('Data', PMInterfacePointer), 

276 ) 

277 

278# 2.2.18 OBJREF 

279class OBJREF(NDRSTRUCT): 

280 commonHdr = ( 

281 ('signature',ULONG), 

282 ('flags',ULONG), 

283 ('iid',GUID), 

284 ) 

285 def __init__(self, data = None,isNDR64 = False): 

286 NDRSTRUCT.__init__(self, data, isNDR64) 

287 if data is None: 

288 self['signature'] = 0x574F454D 

289 

290# 2.2.18.1 STDOBJREF 

291class STDOBJREF(NDRSTRUCT): 

292 structure = ( 

293 ('flags',ULONG), 

294 ('cPublicRefs',ULONG), 

295 ('oxid',OXID), 

296 ('oid',OID), 

297 ('ipid',IPID), 

298 ) 

299 

300# 2.2.18.4 OBJREF_STANDARD 

301class OBJREF_STANDARD(OBJREF): 

302 structure = ( 

303 ('std',STDOBJREF), 

304 ('saResAddr',':'), 

305 ) 

306 def __init__(self, data = None,isNDR64 = False): 

307 OBJREF.__init__(self, data, isNDR64) 

308 if data is None: 308 ↛ 309line 308 didn't jump to line 309, because the condition on line 308 was never true

309 self['flags'] = FLAGS_OBJREF_STANDARD 

310 

311# 2.2.18.5 OBJREF_HANDLER 

312class OBJREF_HANDLER(OBJREF): 

313 structure = ( 

314 ('std',STDOBJREF), 

315 ('clsid',CLSID), 

316 ('saResAddr',':'), 

317 ) 

318 def __init__(self, data = None,isNDR64 = False): 

319 OBJREF.__init__(self, data, isNDR64) 

320 if data is None: 

321 self['flags'] = FLAGS_OBJREF_HANDLER 

322 

323# 2.2.18.6 OBJREF_CUSTOM 

324class OBJREF_CUSTOM(OBJREF): 

325 structure = ( 

326 ('clsid',CLSID), 

327 ('cbExtension',ULONG), 

328 ('ObjectReferenceSize',ULONG), 

329 ('pObjectData',':'), 

330 ) 

331 def __init__(self, data = None,isNDR64 = False): 

332 OBJREF.__init__(self, data, isNDR64) 

333 if data is None: 

334 self['flags'] = FLAGS_OBJREF_CUSTOM 

335 

336# 2.2.18.8 DATAELEMENT 

337class DATAELEMENT(NDRSTRUCT): 

338 structure = ( 

339 ('dataID',GUID), 

340 ('cbSize',ULONG), 

341 ('cbRounded',ULONG), 

342 ('Data',':'), 

343 ) 

344 

345class DUALSTRINGARRAYPACKED(NDRSTRUCT): 

346 structure = ( 

347 ('wNumEntries',USHORT), 

348 ('wSecurityOffset',USHORT), 

349 ('aStringArray',':'), 

350 ) 

351 def getDataLen(self, data, offset=0): 

352 return self['wNumEntries']*2 

353 

354# 2.2.18.7 OBJREF_EXTENDED 

355class OBJREF_EXTENDED(OBJREF): 

356 structure = ( 

357 ('std',STDOBJREF), 

358 ('Signature1',ULONG), 

359 ('saResAddr',DUALSTRINGARRAYPACKED), 

360 ('nElms',ULONG), 

361 ('Signature2',ULONG), 

362 ('ElmArray',DATAELEMENT), 

363 ) 

364 def __init__(self, data = None, isNDR64 = False): 

365 OBJREF.__init__(self, data, isNDR64) 

366 if data is None: 

367 self['flags'] = FLAGS_OBJREF_EXTENDED 

368 self['Signature1'] = 0x4E535956 

369 self['Signature1'] = 0x4E535956 

370 self['nElms'] = 0x4E535956 

371 

372# 2.2.19 DUALSTRINGARRAY 

373class USHORT_ARRAY(NDRUniConformantArray): 

374 item = '<H' 

375 

376class PUSHORT_ARRAY(NDRPOINTER): 

377 referent = ( 

378 ('Data', USHORT_ARRAY), 

379 ) 

380 

381class DUALSTRINGARRAY(NDRSTRUCT): 

382 structure = ( 

383 ('wNumEntries',USHORT), 

384 ('wSecurityOffset',USHORT), 

385 ('aStringArray',USHORT_ARRAY), 

386 ) 

387 

388class PDUALSTRINGARRAY(NDRPOINTER): 

389 referent = ( 

390 ('Data',DUALSTRINGARRAY), 

391 ) 

392 

393# 2.2.19.3 STRINGBINDING 

394class STRINGBINDING(NDRSTRUCT): 

395 structure = ( 

396 ('wTowerId',USHORT), 

397 ('aNetworkAddr',WIDESTR), 

398 ) 

399 

400# 2.2.19.4 SECURITYBINDING 

401class SECURITYBINDING(NDRSTRUCT): 

402 structure = ( 

403 ('wAuthnSvc',USHORT), 

404 ('Reserved',USHORT), 

405 ('aPrincName',WIDESTR), 

406 ) 

407 

408# 2.2.20.1 PROPMARSHALHEADER 

409class PROPMARSHALHEADER(NDRSTRUCT): 

410 structure = ( 

411 ('clsid',CLSID), 

412 ('policyId',GUID), 

413 ('flags',ULONG), 

414 ('cb',ULONG), 

415 ('ctxProperty',':'), 

416 ) 

417 

418class PROPMARSHALHEADER_ARRAY(NDRUniConformantArray): 

419 item = PROPMARSHALHEADER 

420 

421# 2.2.20 Context 

422class Context(NDRSTRUCT): 

423 structure = ( 

424 ('MajorVersion',USHORT), 

425 ('MinVersion',USHORT), 

426 ('ContextId',GUID), 

427 ('Flags',ULONG), 

428 ('Reserved',ULONG), 

429 ('dwNumExtents',ULONG), 

430 ('cbExtents',ULONG), 

431 ('MshlFlags',ULONG), 

432 ('Count',ULONG), 

433 ('Frozen',ULONG), 

434 ('PropMarshalHeader',PROPMARSHALHEADER_ARRAY), 

435 ) 

436 

437# 2.2.21.3 ErrorInfoString 

438class ErrorInfoString(NDRSTRUCT): 

439 structure = ( 

440 ('dwMax',ULONG), 

441 ('dwOffSet',ULONG), 

442 ('dwActual',IID), 

443 ('Name',WSTR), 

444 ) 

445 

446# 2.2.21.2 Custom-Marshaled Error Information Format 

447class ORPC_ERROR_INFORMATION(NDRSTRUCT): 

448 structure = ( 

449 ('dwVersion',ULONG), 

450 ('dwHelpContext',ULONG), 

451 ('iid',IID), 

452 ('dwSourceSignature',ULONG), 

453 ('Source',ErrorInfoString), 

454 ('dwDescriptionSignature',ULONG), 

455 ('Description',ErrorInfoString), 

456 ('dwHelpFileSignature',ULONG), 

457 ('HelpFile',ErrorInfoString), 

458 ) 

459 

460# 2.2.21.5 EntryHeader 

461class EntryHeader(NDRSTRUCT): 

462 structure = ( 

463 ('Signature',ULONG), 

464 ('cbEHBuffer',ULONG), 

465 ('cbSize',ULONG), 

466 ('reserved',ULONG), 

467 ('policyID',GUID), 

468 ) 

469 

470class EntryHeader_ARRAY(NDRUniConformantArray): 

471 item = EntryHeader 

472 

473# 2.2.21.4 Context ORPC Extension 

474class ORPC_CONTEXT(NDRSTRUCT): 

475 structure = ( 

476 ('SignatureVersion',ULONG), 

477 ('Version',ULONG), 

478 ('cPolicies',ULONG), 

479 ('cbBuffer',ULONG), 

480 ('cbSize',ULONG), 

481 ('hr',ULONG), 

482 ('hrServer',ULONG), 

483 ('reserved',ULONG), 

484 ('EntryHeader',EntryHeader_ARRAY), 

485 ('PolicyData',':'), 

486 ) 

487 def __init__(self, data = None, isNDR64 = False): 

488 NDRSTRUCT.__init__(self, data, isNDR64) 

489 if data is None: 

490 self['SignatureVersion'] = 0x414E554B 

491 

492# 2.2.22.1 CustomHeader 

493class CLSID_ARRAY(NDRUniConformantArray): 

494 item = CLSID 

495 

496class PCLSID_ARRAY(NDRPOINTER): 

497 referent = ( 

498 ('Data', CLSID_ARRAY), 

499 ) 

500 

501class DWORD_ARRAY(NDRUniConformantArray): 

502 item = DWORD 

503 

504class PDWORD_ARRAY(NDRPOINTER): 

505 referent = ( 

506 ('Data', DWORD_ARRAY), 

507 ) 

508 

509class CustomHeader(TypeSerialization1): 

510 structure = ( 

511 ('totalSize',DWORD), 

512 ('headerSize',DWORD), 

513 ('dwReserved',DWORD), 

514 ('destCtx',DWORD), 

515 ('cIfs',DWORD), 

516 ('classInfoClsid',CLSID), 

517 ('pclsid',PCLSID_ARRAY), 

518 ('pSizes',PDWORD_ARRAY), 

519 ('pdwReserved',LPLONG), 

520 #('pdwReserved',LONG), 

521 ) 

522 def getData(self, soFar = 0): 

523 self['headerSize'] = len(TypeSerialization1.getData(self, soFar)) + len( 

524 TypeSerialization1.getDataReferents(self, soFar)) 

525 self['cIfs'] = len(self['pclsid']) 

526 return TypeSerialization1.getData(self, soFar) 

527 

528# 2.2.22 Activation Properties BLOB 

529class ACTIVATION_BLOB(NDRTLSTRUCT): 

530 structure = ( 

531 ('dwSize',ULONG), 

532 ('dwReserved',ULONG), 

533 ('CustomHeader',CustomHeader), 

534 ('Property',UNKNOWNDATA), 

535 ) 

536 def getData(self, soFar = 0): 

537 self['dwSize'] = len(self['CustomHeader'].getData(soFar)) + len( 

538 self['CustomHeader'].getDataReferents(soFar)) + len(self['Property']) 

539 self['CustomHeader']['totalSize'] = self['dwSize'] 

540 return NDRTLSTRUCT.getData(self) 

541 

542# 2.2.22.2.1 InstantiationInfoData 

543class IID_ARRAY(NDRUniConformantArray): 

544 item = IID 

545 

546class PIID_ARRAY(NDRPOINTER): 

547 referent = ( 

548 ('Data', IID_ARRAY), 

549 ) 

550 

551class InstantiationInfoData(TypeSerialization1): 

552 structure = ( 

553 ('classId',CLSID), 

554 ('classCtx',DWORD), 

555 ('actvflags',DWORD), 

556 ('fIsSurrogate',LONG), 

557 ('cIID',DWORD), 

558 ('instFlag',DWORD), 

559 ('pIID',PIID_ARRAY), 

560 ('thisSize',DWORD), 

561 ('clientCOMVersion',COMVERSION), 

562 ) 

563 

564# 2.2.22.2.2 SpecialPropertiesData 

565class SpecialPropertiesData(TypeSerialization1): 

566 structure = ( 

567 ('dwSessionId',ULONG), 

568 ('fRemoteThisSessionId',LONG), 

569 ('fClientImpersonating',LONG), 

570 ('fPartitionIDPresent',LONG), 

571 ('dwDefaultAuthnLvl',DWORD), 

572 ('guidPartition',GUID), 

573 ('dwPRTFlags',DWORD), 

574 ('dwOrigClsctx',DWORD), 

575 ('dwFlags',DWORD), 

576 ('Reserved0',DWORD), 

577 ('Reserved0',DWORD), 

578 ('Reserved', '32s=""'), 

579 #('Reserved1',DWORD), 

580 #('Reserved2',ULONGLONG), 

581 #('Reserved3_1',DWORD), 

582 #('Reserved3_2',DWORD), 

583 #('Reserved3_3',DWORD), 

584 #('Reserved3_4',DWORD), 

585 #('Reserved3_5',DWORD), 

586 ) 

587 

588# 2.2.22.2.3 InstanceInfoData 

589class InstanceInfoData(TypeSerialization1): 

590 structure = ( 

591 ('fileName',LPWSTR), 

592 ('mode',DWORD), 

593 ('ifdROT',PMInterfacePointer), 

594 ('ifdStg',PMInterfacePointer), 

595 ) 

596 

597# 2.2.22.2.4.1 customREMOTE_REQUEST_SCM_INFO 

598class customREMOTE_REQUEST_SCM_INFO(NDRSTRUCT): 

599 structure = ( 

600 ('ClientImpLevel',DWORD), 

601 ('cRequestedProtseqs',USHORT), 

602 ('pRequestedProtseqs',PUSHORT_ARRAY), 

603 ) 

604 

605class PcustomREMOTE_REQUEST_SCM_INFO(NDRPOINTER): 

606 referent = ( 

607 ('Data', customREMOTE_REQUEST_SCM_INFO), 

608 ) 

609 

610# 2.2.22.2.4 ScmRequestInfoData 

611class ScmRequestInfoData(TypeSerialization1): 

612 structure = ( 

613 ('pdwReserved',LPLONG), 

614 ('remoteRequest',PcustomREMOTE_REQUEST_SCM_INFO), 

615 ) 

616 

617# 2.2.22.2.5 ActivationContextInfoData 

618class ActivationContextInfoData(TypeSerialization1): 

619 structure = ( 

620 ('clientOK',LONG), 

621 ('bReserved1',LONG), 

622 ('dwReserved1',DWORD), 

623 ('dwReserved2',DWORD), 

624 ('pIFDClientCtx',PMInterfacePointer), 

625 ('pIFDPrototypeCtx',PMInterfacePointer), 

626 ) 

627 

628# 2.2.22.2.6 LocationInfoData 

629class LocationInfoData(TypeSerialization1): 

630 structure = ( 

631 ('machineName',LPWSTR), 

632 ('processId',DWORD), 

633 ('apartmentId',DWORD), 

634 ('contextId',DWORD), 

635 ) 

636 

637# 2.2.22.2.7.1 COSERVERINFO 

638class COSERVERINFO(NDRSTRUCT): 

639 structure = ( 

640 ('dwReserved1',DWORD), 

641 ('pwszName',LPWSTR), 

642 ('pdwReserved',LPLONG), 

643 ('dwReserved2',DWORD), 

644 ) 

645 

646class PCOSERVERINFO(NDRPOINTER): 

647 referent = ( 

648 ('Data', COSERVERINFO), 

649 ) 

650 

651# 2.2.22.2.7 SecurityInfoData 

652class SecurityInfoData(TypeSerialization1): 

653 structure = ( 

654 ('dwAuthnFlags',DWORD), 

655 ('pServerInfo',PCOSERVERINFO), 

656 ('pdwReserved',LPLONG), 

657 ) 

658 

659# 2.2.22.2.8.1 customREMOTE_REPLY_SCM_INFO 

660class customREMOTE_REPLY_SCM_INFO(NDRSTRUCT): 

661 structure = ( 

662 ('Oxid',OXID), 

663 ('pdsaOxidBindings',PDUALSTRINGARRAY), 

664 ('ipidRemUnknown',IPID), 

665 ('authnHint',DWORD), 

666 ('serverVersion',COMVERSION), 

667 ) 

668 

669class PcustomREMOTE_REPLY_SCM_INFO(NDRPOINTER): 

670 referent = ( 

671 ('Data', customREMOTE_REPLY_SCM_INFO), 

672 ) 

673 

674# 2.2.22.2.8 ScmReplyInfoData 

675class ScmReplyInfoData(TypeSerialization1): 

676 structure = ( 

677 ('pdwReserved',DWORD), 

678 ('remoteReply',PcustomREMOTE_REPLY_SCM_INFO), 

679 ) 

680 

681# 2.2.22.2.9 PropsOutInfo 

682class HRESULT_ARRAY(NDRUniConformantArray): 

683 item = HRESULT 

684 

685class PHRESULT_ARRAY(NDRPOINTER): 

686 referent = ( 

687 ('Data', HRESULT_ARRAY), 

688 ) 

689 

690class MInterfacePointer_ARRAY(NDRUniConformantArray): 

691 item = MInterfacePointer 

692 

693class PMInterfacePointer_ARRAY(NDRUniConformantArray): 

694 item = PMInterfacePointer 

695 

696class PPMInterfacePointer_ARRAY(NDRPOINTER): 

697 referent = ( 

698 ('Data', PMInterfacePointer_ARRAY), 

699 ) 

700 

701class PropsOutInfo(TypeSerialization1): 

702 structure = ( 

703 ('cIfs',DWORD), 

704 ('piid',PIID_ARRAY), 

705 ('phresults',PHRESULT_ARRAY), 

706 ('ppIntfData',PPMInterfacePointer_ARRAY), 

707 ) 

708 

709# 2.2.23 REMINTERFACEREF 

710class REMINTERFACEREF(NDRSTRUCT): 

711 structure = ( 

712 ('ipid',IPID), 

713 ('cPublicRefs',LONG), 

714 ('cPrivateRefs',LONG), 

715 ) 

716 

717class REMINTERFACEREF_ARRAY(NDRUniConformantArray): 

718 item = REMINTERFACEREF 

719 

720# 2.2.24 REMQIRESULT 

721class REMQIRESULT(NDRSTRUCT): 

722 structure = ( 

723 ('hResult',HRESULT), 

724 ('std',STDOBJREF), 

725 ) 

726 

727# 2.2.25 PREMQIRESULT 

728class PREMQIRESULT(NDRPOINTER): 

729 referent = ( 

730 ('Data', REMQIRESULT), 

731 ) 

732 

733# 2.2.26 REFIPID 

734REFIPID = GUID 

735 

736################################################################################ 

737# RPC CALLS 

738################################################################################ 

739class DCOMCALL(NDRCALL): 

740 commonHdr = ( 

741 ('ORPCthis', ORPCTHIS), 

742 ) 

743 

744class DCOMANSWER(NDRCALL): 

745 commonHdr = ( 

746 ('ORPCthat', ORPCTHAT), 

747 ) 

748 

749# 3.1.2.5.1.1 IObjectExporter::ResolveOxid (Opnum 0) 

750class ResolveOxid(NDRCALL): 

751 opnum = 0 

752 structure = ( 

753 ('pOxid', OXID), 

754 ('cRequestedProtseqs', USHORT), 

755 ('arRequestedProtseqs', USHORT_ARRAY), 

756 ) 

757 

758class ResolveOxidResponse(NDRCALL): 

759 structure = ( 

760 ('ppdsaOxidBindings', PDUALSTRINGARRAY), 

761 ('pipidRemUnknown', IPID), 

762 ('pAuthnHint', DWORD), 

763 ('ErrorCode', error_status_t), 

764 ) 

765 

766# 3.1.2.5.1.2 IObjectExporter::SimplePing (Opnum 1) 

767class SimplePing(NDRCALL): 

768 opnum = 1 

769 structure = ( 

770 ('pSetId', SETID), 

771 ) 

772 

773class SimplePingResponse(NDRCALL): 

774 structure = ( 

775 ('ErrorCode', error_status_t), 

776 ) 

777 

778# 3.1.2.5.1.3 IObjectExporter::ComplexPing (Opnum 2) 

779class ComplexPing(NDRCALL): 

780 opnum = 2 

781 structure = ( 

782 ('pSetId', SETID), 

783 ('SequenceNum', USHORT), 

784 ('cAddToSet', USHORT), 

785 ('cDelFromSet', USHORT), 

786 ('AddToSet', POID_ARRAY), 

787 ('DelFromSet', POID_ARRAY), 

788 ) 

789 

790class ComplexPingResponse(NDRCALL): 

791 structure = ( 

792 ('pSetId', SETID), 

793 ('pPingBackoffFactor', USHORT), 

794 ('ErrorCode', error_status_t), 

795 ) 

796 

797# 3.1.2.5.1.4 IObjectExporter::ServerAlive (Opnum 3) 

798class ServerAlive(NDRCALL): 

799 opnum = 3 

800 structure = ( 

801 ) 

802 

803class ServerAliveResponse(NDRCALL): 

804 structure = ( 

805 ('ErrorCode', error_status_t), 

806 ) 

807 

808# 3.1.2.5.1.5 IObjectExporter::ResolveOxid2 (Opnum 4) 

809class ResolveOxid2(NDRCALL): 

810 opnum = 4 

811 structure = ( 

812 ('pOxid', OXID), 

813 ('cRequestedProtseqs', USHORT), 

814 ('arRequestedProtseqs', USHORT_ARRAY), 

815 ) 

816 

817class ResolveOxid2Response(NDRCALL): 

818 structure = ( 

819 ('ppdsaOxidBindings', PDUALSTRINGARRAY), 

820 ('pipidRemUnknown', IPID), 

821 ('pAuthnHint', DWORD), 

822 ('pComVersion', COMVERSION), 

823 ('ErrorCode', error_status_t), 

824 ) 

825 

826# 3.1.2.5.1.6 IObjectExporter::ServerAlive2 (Opnum 5) 

827class ServerAlive2(NDRCALL): 

828 opnum = 5 

829 structure = ( 

830 ) 

831 

832class ServerAlive2Response(NDRCALL): 

833 structure = ( 

834 ('pComVersion', COMVERSION), 

835 ('ppdsaOrBindings', PDUALSTRINGARRAY), 

836 ('pReserved', LPLONG), 

837 ('ErrorCode', error_status_t), 

838 ) 

839 

840# 3.1.2.5.2.3.1 IActivation:: RemoteActivation (Opnum 0) 

841class RemoteActivation(NDRCALL): 

842 opnum = 0 

843 structure = ( 

844 ('ORPCthis', ORPCTHIS), 

845 ('Clsid', GUID), 

846 ('pwszObjectName', LPWSTR), 

847 ('pObjectStorage', PMInterfacePointer), 

848 ('ClientImpLevel', DWORD), 

849 ('Mode', DWORD), 

850 ('Interfaces', DWORD), 

851 ('pIIDs', PIID_ARRAY), 

852 ('cRequestedProtseqs', USHORT), 

853 ('aRequestedProtseqs', USHORT_ARRAY), 

854 ) 

855 

856class RemoteActivationResponse(NDRCALL): 

857 structure = ( 

858 ('ORPCthat', ORPCTHAT), 

859 ('pOxid', OXID), 

860 ('ppdsaOxidBindings', PDUALSTRINGARRAY), 

861 ('pipidRemUnknown', IPID), 

862 ('pAuthnHint', DWORD), 

863 ('pServerVersion', COMVERSION), 

864 ('phr', HRESULT), 

865 ('ppInterfaceData', PMInterfacePointer_ARRAY), 

866 ('pResults', HRESULT_ARRAY), 

867 ('ErrorCode', error_status_t), 

868 ) 

869 

870# 3.1.2.5.2.3.2 IRemoteSCMActivator:: RemoteGetClassObject (Opnum 3) 

871class RemoteGetClassObject(NDRCALL): 

872 opnum = 3 

873 structure = ( 

874 ('ORPCthis', ORPCTHIS), 

875 ('pActProperties', PMInterfacePointer), 

876 ) 

877 

878class RemoteGetClassObjectResponse(NDRCALL): 

879 structure = ( 

880 ('ORPCthat', ORPCTHAT), 

881 ('ppActProperties', PMInterfacePointer), 

882 ('ErrorCode', error_status_t), 

883 ) 

884 

885# 3.1.2.5.2.3.3 IRemoteSCMActivator::RemoteCreateInstance (Opnum 4) 

886class RemoteCreateInstance(NDRCALL): 

887 opnum = 4 

888 structure = ( 

889 ('ORPCthis', ORPCTHIS), 

890 ('pUnkOuter', PMInterfacePointer), 

891 ('pActProperties', PMInterfacePointer), 

892 ) 

893 

894class RemoteCreateInstanceResponse(NDRCALL): 

895 structure = ( 

896 ('ORPCthat', ORPCTHAT), 

897 ('ppActProperties', PMInterfacePointer), 

898 ('ErrorCode', error_status_t), 

899 ) 

900 

901# 3.1.1.5.6.1.1 IRemUnknown::RemQueryInterface (Opnum 3) 

902class RemQueryInterface(DCOMCALL): 

903 opnum = 3 

904 structure = ( 

905 ('ripid', REFIPID), 

906 ('cRefs', ULONG), 

907 ('cIids', USHORT), 

908 ('iids', IID_ARRAY), 

909 ) 

910 

911class RemQueryInterfaceResponse(DCOMANSWER): 

912 structure = ( 

913 ('ppQIResults', PREMQIRESULT), 

914 ('ErrorCode', error_status_t), 

915 ) 

916 

917# 3.1.1.5.6.1.2 IRemUnknown::RemAddRef (Opnum 4 ) 

918class RemAddRef(DCOMCALL): 

919 opnum = 4 

920 structure = ( 

921 ('cInterfaceRefs', USHORT), 

922 ('InterfaceRefs', REMINTERFACEREF_ARRAY), 

923 ) 

924 

925class RemAddRefResponse(DCOMANSWER): 

926 structure = ( 

927 ('pResults', DWORD_ARRAY), 

928 ('ErrorCode', error_status_t), 

929 ) 

930 

931# 3.1.1.5.6.1.3 IRemUnknown::RemRelease (Opnum 5) 

932class RemRelease(DCOMCALL): 

933 opnum = 5 

934 structure = ( 

935 ('cInterfaceRefs', USHORT), 

936 ('InterfaceRefs', REMINTERFACEREF_ARRAY), 

937 ) 

938 

939class RemReleaseResponse(DCOMANSWER): 

940 structure = ( 

941 ('ErrorCode', error_status_t), 

942 ) 

943 

944################################################################################ 

945# OPNUMs and their corresponding structures 

946################################################################################ 

947OPNUMS = { 

948} 

949 

950################################################################################ 

951# HELPER FUNCTIONS 

952################################################################################ 

953class DCOMConnection: 

954 """ 

955 This class represents a DCOM Connection. It is in charge of establishing the  

956 DCE connection against the portmap, and then launch a thread that will be  

957 pinging the objects created against the target. 

958 In theory, there should be a single instance of this class for every target 

959 """ 

960 PINGTIMER = None 

961 OID_ADD = {} 

962 OID_DEL = {} 

963 OID_SET = {} 

964 PORTMAPS = {} 

965 

966 def __init__(self, target, username='', password='', domain='', lmhash='', nthash='', aesKey='', TGT=None, TGS=None, 

967 authLevel=RPC_C_AUTHN_LEVEL_PKT_PRIVACY, oxidResolver=False, doKerberos=False, kdcHost=None): 

968 self.__target = target 

969 self.__userName = username 

970 self.__password = password 

971 self.__domain = domain 

972 self.__lmhash = lmhash 

973 self.__nthash = nthash 

974 self.__aesKey = aesKey 

975 self.__TGT = TGT 

976 self.__TGS = TGS 

977 self.__authLevel = authLevel 

978 self.__portmap = None 

979 self.__oxidResolver = oxidResolver 

980 self.__doKerberos = doKerberos 

981 self.__kdcHost = kdcHost 

982 self.initConnection() 

983 

984 @classmethod 

985 def addOid(cls, target, oid): 

986 if (target in DCOMConnection.OID_ADD) is False: 

987 DCOMConnection.OID_ADD[target] = set() 

988 DCOMConnection.OID_ADD[target].add(oid) 

989 if (target in DCOMConnection.OID_SET) is False: 

990 DCOMConnection.OID_SET[target] = {} 

991 DCOMConnection.OID_SET[target]['oids'] = set() 

992 DCOMConnection.OID_SET[target]['setid'] = 0 

993 

994 @classmethod 

995 def delOid(cls, target, oid): 

996 if (target in DCOMConnection.OID_DEL) is False: 

997 DCOMConnection.OID_DEL[target] = set() 

998 DCOMConnection.OID_DEL[target].add(oid) 

999 if (target in DCOMConnection.OID_SET) is False: 999 ↛ 1000line 999 didn't jump to line 1000, because the condition on line 999 was never true

1000 DCOMConnection.OID_SET[target] = {} 

1001 DCOMConnection.OID_SET[target]['oids'] = set() 

1002 DCOMConnection.OID_SET[target]['setid'] = 0 

1003 

1004 @classmethod 

1005 def pingServer(cls): 

1006 # Here we need to go through all the objects opened and ping them. 

1007 # ToDo: locking for avoiding race conditions 

1008 #print DCOMConnection.PORTMAPS 

1009 #print DCOMConnection.OID_SET 

1010 try: 

1011 for target in DCOMConnection.OID_SET: 

1012 addedOids = set() 

1013 deletedOids = set() 

1014 if target in DCOMConnection.OID_ADD: 

1015 addedOids = DCOMConnection.OID_ADD[target] 

1016 del(DCOMConnection.OID_ADD[target]) 

1017 

1018 if target in DCOMConnection.OID_DEL: 

1019 deletedOids = DCOMConnection.OID_DEL[target] 

1020 del(DCOMConnection.OID_DEL[target]) 

1021 

1022 objExporter = IObjectExporter(DCOMConnection.PORTMAPS[target]) 

1023 

1024 if len(addedOids) > 0 or len(deletedOids) > 0: 

1025 if 'setid' in DCOMConnection.OID_SET[target]: 

1026 setId = DCOMConnection.OID_SET[target]['setid'] 

1027 else: 

1028 setId = 0 

1029 resp = objExporter.ComplexPing(setId, 0, addedOids, deletedOids) 

1030 DCOMConnection.OID_SET[target]['oids'] -= deletedOids 

1031 DCOMConnection.OID_SET[target]['oids'] |= addedOids 

1032 DCOMConnection.OID_SET[target]['setid'] = resp['pSetId'] 

1033 else: 

1034 objExporter.SimplePing(DCOMConnection.OID_SET[target]['setid']) 

1035 except Exception as e: 

1036 # There might be exceptions when sending packets  

1037 # We should try to continue tho. 

1038 LOG.error(str(e)) 

1039 pass 

1040 

1041 DCOMConnection.PINGTIMER = Timer(120,DCOMConnection.pingServer) 

1042 try: 

1043 DCOMConnection.PINGTIMER.start() 

1044 except Exception as e: 

1045 if str(e).find('threads can only be started once') < 0: 

1046 raise e 

1047 

1048 def initTimer(self): 

1049 if self.__oxidResolver is True: 1049 ↛ 1050line 1049 didn't jump to line 1050, because the condition on line 1049 was never true

1050 if DCOMConnection.PINGTIMER is None: 

1051 DCOMConnection.PINGTIMER = Timer(120, DCOMConnection.pingServer) 

1052 try: 

1053 DCOMConnection.PINGTIMER.start() 

1054 except Exception as e: 

1055 if str(e).find('threads can only be started once') < 0: 

1056 raise e 

1057 

1058 def initConnection(self): 

1059 stringBinding = r'ncacn_ip_tcp:%s' % self.__target 

1060 rpctransport = transport.DCERPCTransportFactory(stringBinding) 

1061 

1062 if hasattr(rpctransport, 'set_credentials') and len(self.__userName) >=0: 1062 ↛ 1067line 1062 didn't jump to line 1067, because the condition on line 1062 was never false

1063 # This method exists only for selected protocol sequences. 

1064 rpctransport.set_credentials(self.__userName, self.__password, self.__domain, self.__lmhash, self.__nthash, 

1065 self.__aesKey, self.__TGT, self.__TGS) 

1066 rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost) 

1067 self.__portmap = rpctransport.get_dce_rpc() 

1068 self.__portmap.set_auth_level(self.__authLevel) 

1069 if self.__doKerberos is True: 1069 ↛ 1070line 1069 didn't jump to line 1070, because the condition on line 1069 was never true

1070 self.__portmap.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) 

1071 self.__portmap.connect() 

1072 DCOMConnection.PORTMAPS[self.__target] = self.__portmap 

1073 

1074 def CoCreateInstanceEx(self, clsid, iid): 

1075 scm = IRemoteSCMActivator(self.__portmap) 

1076 iInterface = scm.RemoteCreateInstance(clsid, iid) 

1077 self.initTimer() 

1078 return iInterface 

1079 

1080 def get_dce_rpc(self): 

1081 return DCOMConnection.PORTMAPS[self.__target] 

1082 

1083 def disconnect(self): 

1084 if DCOMConnection.PINGTIMER is not None: 1084 ↛ 1085line 1084 didn't jump to line 1085, because the condition on line 1084 was never true

1085 del(DCOMConnection.PORTMAPS[self.__target]) 

1086 del(DCOMConnection.OID_SET[self.__target]) 

1087 if len(DCOMConnection.PORTMAPS) == 0: 

1088 # This means there are no more clients using this object, kill it 

1089 DCOMConnection.PINGTIMER.cancel() 

1090 DCOMConnection.PINGTIMER.join() 

1091 DCOMConnection.PINGTIMER = None 

1092 if self.__target in INTERFACE.CONNECTIONS: 1092 ↛ 1094line 1092 didn't jump to line 1094, because the condition on line 1092 was never false

1093 del(INTERFACE.CONNECTIONS[self.__target][current_thread().name]) 

1094 self.__portmap.disconnect() 

1095 #print INTERFACE.CONNECTIONS 

1096 

1097class CLASS_INSTANCE: 

1098 def __init__(self, ORPCthis, stringBinding): 

1099 self.__stringBindings = stringBinding 

1100 self.__ORPCthis = ORPCthis 

1101 self.__authType = RPC_C_AUTHN_WINNT 

1102 self.__authLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY 

1103 def get_ORPCthis(self): 

1104 return self.__ORPCthis 

1105 def get_string_bindings(self): 

1106 return self.__stringBindings 

1107 def get_auth_level(self): 

1108 if RPC_C_AUTHN_LEVEL_NONE < self.__authLevel < RPC_C_AUTHN_LEVEL_PKT_PRIVACY: 1108 ↛ 1113line 1108 didn't jump to line 1113, because the condition on line 1108 was never false

1109 if self.__authType == RPC_C_AUTHN_WINNT: 1109 ↛ 1112line 1109 didn't jump to line 1112, because the condition on line 1109 was never false

1110 return RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 

1111 else: 

1112 return RPC_C_AUTHN_LEVEL_PKT_PRIVACY 

1113 return self.__authLevel 

1114 def set_auth_level(self, level): 

1115 self.__authLevel = level 

1116 def get_auth_type(self): 

1117 return self.__authType 

1118 def set_auth_type(self, authType): 

1119 self.__authType = authType 

1120 

1121 

1122class INTERFACE: 

1123 # class variable holding the transport connections, organized by target IP 

1124 CONNECTIONS = {} 

1125 

1126 def __init__(self, cinstance=None, objRef=None, ipidRemUnknown=None, iPid=None, oxid=None, oid=None, target=None, 

1127 interfaceInstance=None): 

1128 if interfaceInstance is not None: 

1129 self.__target = interfaceInstance.get_target() 

1130 self.__iPid = interfaceInstance.get_iPid() 

1131 self.__oid = interfaceInstance.get_oid() 

1132 self.__oxid = interfaceInstance.get_oxid() 

1133 self.__cinstance = interfaceInstance.get_cinstance() 

1134 self.__objRef = interfaceInstance.get_objRef() 

1135 self.__ipidRemUnknown = interfaceInstance.get_ipidRemUnknown() 

1136 else: 

1137 if target is None: 1137 ↛ 1138line 1137 didn't jump to line 1138, because the condition on line 1137 was never true

1138 raise Exception('No target') 

1139 self.__target = target 

1140 self.__iPid = iPid 

1141 self.__oid = oid 

1142 self.__oxid = oxid 

1143 self.__cinstance = cinstance 

1144 self.__objRef = objRef 

1145 self.__ipidRemUnknown = ipidRemUnknown 

1146 # We gotta check if we have a container inside our connection list, if not, create 

1147 if (self.__target in INTERFACE.CONNECTIONS) is not True: 

1148 INTERFACE.CONNECTIONS[self.__target] = {} 

1149 INTERFACE.CONNECTIONS[self.__target][current_thread().name] = {} 

1150 

1151 if objRef is not None: 

1152 self.process_interface(objRef) 

1153 

1154 def process_interface(self, data): 

1155 objRefType = OBJREF(data)['flags'] 

1156 objRef = None 

1157 if objRefType == FLAGS_OBJREF_CUSTOM: 

1158 objRef = OBJREF_CUSTOM(data) 

1159 elif objRefType == FLAGS_OBJREF_HANDLER: 1159 ↛ 1160line 1159 didn't jump to line 1160, because the condition on line 1159 was never true

1160 objRef = OBJREF_HANDLER(data) 

1161 elif objRefType == FLAGS_OBJREF_STANDARD: 1161 ↛ 1163line 1161 didn't jump to line 1163, because the condition on line 1161 was never false

1162 objRef = OBJREF_STANDARD(data) 

1163 elif objRefType == FLAGS_OBJREF_EXTENDED: 

1164 objRef = OBJREF_EXTENDED(data) 

1165 else: 

1166 LOG.error("Unknown OBJREF Type! 0x%x" % objRefType) 

1167 

1168 if objRefType != FLAGS_OBJREF_CUSTOM: 

1169 if objRef['std']['flags'] & SORF_NOPING == 0: 1169 ↛ 1171line 1169 didn't jump to line 1171, because the condition on line 1169 was never false

1170 DCOMConnection.addOid(self.__target, objRef['std']['oid']) 

1171 self.__iPid = objRef['std']['ipid'] 

1172 self.__oid = objRef['std']['oid'] 

1173 self.__oxid = objRef['std']['oxid'] 

1174 if self.__oxid is None: 1174 ↛ 1175line 1174 didn't jump to line 1175, because the condition on line 1174 was never true

1175 objRef.dump() 

1176 raise Exception('OXID is None') 

1177 

1178 def get_oxid(self): 

1179 return self.__oxid 

1180 

1181 def set_oxid(self, oxid): 

1182 self.__oxid = oxid 

1183 

1184 def get_oid(self): 

1185 return self.__oid 

1186 

1187 def set_oid(self, oid): 

1188 self.__oid = oid 

1189 

1190 def get_target(self): 

1191 return self.__target 

1192 

1193 def get_iPid(self): 

1194 return self.__iPid 

1195 

1196 def set_iPid(self, iPid): 

1197 self.__iPid = iPid 

1198 

1199 def get_objRef(self): 

1200 return self.__objRef 

1201 

1202 def set_objRef(self, objRef): 

1203 self.__objRef = objRef 

1204 

1205 def get_ipidRemUnknown(self): 

1206 return self.__ipidRemUnknown 

1207 

1208 def get_dce_rpc(self): 

1209 return INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['dce'] 

1210 

1211 def get_cinstance(self): 

1212 return self.__cinstance 

1213 

1214 def set_cinstance(self, cinstance): 

1215 self.__cinstance = cinstance 

1216 

1217 def is_fqdn(self): 

1218 # I will assume the following 

1219 # If I can't socket.inet_aton() then it's not an IPv4 address 

1220 # Same for ipv6, but since socket.inet_pton is not available in Windows, I'll look for ':'. There can't be 

1221 # an FQDN with ':' 

1222 # Is it isn't both, then it is a FQDN 

1223 try: 

1224 socket.inet_aton(self.__target) 

1225 except: 

1226 # Not an IPv4 

1227 try: 

1228 self.__target.index(':') 

1229 except: 

1230 # Not an IPv6, it's a FQDN 

1231 return True 

1232 return False 

1233 

1234 def connect(self, iid = None): 

1235 if (self.__target in INTERFACE.CONNECTIONS) is True: 1235 ↛ 1321line 1235 didn't jump to line 1321, because the condition on line 1235 was never false

1236 if current_thread().name in INTERFACE.CONNECTIONS[self.__target] and \ 

1237 (self.__oxid in INTERFACE.CONNECTIONS[self.__target][current_thread().name]) is True: 

1238 dce = INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['dce'] 

1239 currentBinding = INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['currentBinding'] 

1240 if currentBinding == iid: 

1241 # We don't need to alter_ctx 

1242 pass 

1243 else: 

1244 newDce = dce.alter_ctx(iid) 

1245 INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['dce'] = newDce 

1246 INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['currentBinding'] = iid 

1247 else: 

1248 stringBindings = self.get_cinstance().get_string_bindings() 

1249 # No OXID present, we should create a new connection and store it 

1250 stringBinding = None 

1251 isTargetFQDN = self.is_fqdn() 

1252 LOG.debug('Target system is %s and isFQDN is %s' % (self.get_target(), isTargetFQDN)) 

1253 for strBinding in stringBindings: 1253 ↛ 1283line 1253 didn't jump to line 1283, because the loop on line 1253 didn't complete

1254 # Here, depending on the get_target() value several things can happen 

1255 # 1) it's an IPv4 address 

1256 # 2) it's an IPv6 address 

1257 # 3) it's a NetBios Name 

1258 # we should handle all this cases accordingly 

1259 # Does this match exactly what get_target() returns? 

1260 LOG.debug('StringBinding: %s' % strBinding['aNetworkAddr']) 

1261 if strBinding['wTowerId'] == 7: 

1262 # If there's port information, let's strip it for now. 

1263 if strBinding['aNetworkAddr'].find('[') >= 0: 1263 ↛ 1267line 1263 didn't jump to line 1267, because the condition on line 1263 was never false

1264 binding, _, bindingPort = strBinding['aNetworkAddr'].partition('[') 

1265 bindingPort = '[' + bindingPort 

1266 else: 

1267 binding = strBinding['aNetworkAddr'] 

1268 bindingPort = '' 

1269 

1270 if binding.upper().find(self.get_target().upper()) >= 0: 

1271 stringBinding = 'ncacn_ip_tcp:' + strBinding['aNetworkAddr'][:-1] 

1272 break 

1273 # If get_target() is a FQDN, does it match the hostname? 

1274 elif isTargetFQDN and binding.upper().find(self.get_target().upper().partition('.')[0]) >= 0: 1274 ↛ 1280line 1274 didn't jump to line 1280, because the condition on line 1274 was never true

1275 # Here we replace the aNetworkAddr with self.get_target() 

1276 # This is to help resolving the target system name. 

1277 # self.get_target() has been resolved already otherwise we wouldn't be here whereas 

1278 # aNetworkAddr is usually the NetBIOS name and unless you have your DNS resolver 

1279 # with the right suffixes it will probably not resolve right. 

1280 stringBinding = 'ncacn_ip_tcp:%s%s' % (self.get_target(), bindingPort) 

1281 break 

1282 

1283 LOG.debug('StringBinding chosen: %s' % stringBinding) 

1284 if stringBinding is None: 1284 ↛ 1286line 1284 didn't jump to line 1286, because the condition on line 1284 was never true

1285 # Something wen't wrong, let's just report it 

1286 raise Exception('Can\'t find a valid stringBinding to connect') 

1287 

1288 dcomInterface = transport.DCERPCTransportFactory(stringBinding) 

1289 if hasattr(dcomInterface, 'set_credentials'): 1289 ↛ 1294line 1289 didn't jump to line 1294, because the condition on line 1289 was never false

1290 # This method exists only for selected protocol sequences. 

1291 dcomInterface.set_credentials(*DCOMConnection.PORTMAPS[self.__target].get_credentials()) 

1292 dcomInterface.set_kerberos(DCOMConnection.PORTMAPS[self.__target].get_rpc_transport().get_kerberos(), 

1293 DCOMConnection.PORTMAPS[self.__target].get_rpc_transport().get_kdcHost()) 

1294 dcomInterface.set_connect_timeout(300) 

1295 dce = dcomInterface.get_dce_rpc() 

1296 

1297 if iid is None: 1297 ↛ 1298line 1297 didn't jump to line 1298, because the condition on line 1297 was never true

1298 raise Exception('IID is None') 

1299 else: 

1300 dce.set_auth_level(self.__cinstance.get_auth_level()) 

1301 dce.set_auth_type(self.__cinstance.get_auth_type()) 

1302 

1303 dce.connect() 

1304 

1305 if iid is None: 1305 ↛ 1306line 1305 didn't jump to line 1306, because the condition on line 1305 was never true

1306 raise Exception('IID is None') 

1307 else: 

1308 dce.bind(iid) 

1309 

1310 if self.__oxid is None: 1310 ↛ 1313line 1310 didn't jump to line 1313, because the condition on line 1310 was never true

1311 #import traceback 

1312 #traceback.print_stack() 

1313 raise Exception("OXID NONE, something wrong!!!") 

1314 

1315 INTERFACE.CONNECTIONS[self.__target][current_thread().name] = {} 

1316 INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid] = {} 

1317 INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['dce'] = dce 

1318 INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['currentBinding'] = iid 

1319 else: 

1320 # No connection created 

1321 raise Exception('No connection created') 

1322 

1323 def request(self, req, iid = None, uuid = None): 

1324 req['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

1325 req['ORPCthis']['flags'] = 0 

1326 self.connect(iid) 

1327 dce = self.get_dce_rpc() 

1328 try: 

1329 resp = dce.request(req, uuid) 

1330 except Exception as e: 

1331 if str(e).find('RPC_E_DISCONNECTED') >= 0: 1331 ↛ 1332line 1331 didn't jump to line 1332, because the condition on line 1331 was never true

1332 msg = str(e) + '\n' 

1333 msg += "DCOM keep-alive pinging it might not be working as expected. You can't be idle for more than 14 minutes!\n" 

1334 msg += "You should exit the app and start again\n" 

1335 raise DCERPCException(msg) 

1336 else: 

1337 raise 

1338 return resp 

1339 

1340 def disconnect(self): 

1341 return INTERFACE.CONNECTIONS[self.__target][current_thread().name][self.__oxid]['dce'].disconnect() 

1342 

1343 

1344# 3.1.1.5.6.1 IRemUnknown Methods 

1345class IRemUnknown(INTERFACE): 

1346 def __init__(self, interface): 

1347 self._iid = IID_IRemUnknown 

1348 #INTERFACE.__init__(self, interface.get_cinstance(), interface.get_objRef(), interface.get_ipidRemUnknown(), 

1349 # interface.get_iPid(), target=interface.get_target()) 

1350 INTERFACE.__init__(self, interfaceInstance=interface) 

1351 self.set_oxid(interface.get_oxid()) 

1352 

1353 def RemQueryInterface(self, cRefs, iids): 

1354 # For now, it only supports a single IID 

1355 request = RemQueryInterface() 

1356 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

1357 request['ORPCthis']['flags'] = 0 

1358 request['ripid'] = self.get_iPid() 

1359 request['cRefs'] = cRefs 

1360 request['cIids'] = len(iids) 

1361 for iid in iids: 

1362 _iid = IID() 

1363 _iid['Data'] = iid 

1364 request['iids'].append(_iid) 

1365 resp = self.request(request, IID_IRemUnknown, self.get_ipidRemUnknown()) 

1366 #resp.dump() 

1367 

1368 return IRemUnknown2( 

1369 INTERFACE(self.get_cinstance(), None, self.get_ipidRemUnknown(), resp['ppQIResults']['std']['ipid'], 

1370 oxid=resp['ppQIResults']['std']['oxid'], oid=resp['ppQIResults']['std']['oxid'], 

1371 target=self.get_target())) 

1372 

1373 def RemAddRef(self): 

1374 request = RemAddRef() 

1375 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

1376 request['ORPCthis']['flags'] = 0 

1377 request['cInterfaceRefs'] = 1 

1378 element = REMINTERFACEREF() 

1379 element['ipid'] = self.get_iPid() 

1380 element['cPublicRefs'] = 1 

1381 request['InterfaceRefs'].append(element) 

1382 resp = self.request(request, IID_IRemUnknown, self.get_ipidRemUnknown()) 

1383 return resp 

1384 

1385 def RemRelease(self): 

1386 request = RemRelease() 

1387 request['ORPCthis'] = self.get_cinstance().get_ORPCthis() 

1388 request['ORPCthis']['flags'] = 0 

1389 request['cInterfaceRefs'] = 1 

1390 element = REMINTERFACEREF() 

1391 element['ipid'] = self.get_iPid() 

1392 element['cPublicRefs'] = 1 

1393 request['InterfaceRefs'].append(element) 

1394 resp = self.request(request, IID_IRemUnknown, self.get_ipidRemUnknown()) 

1395 DCOMConnection.delOid(self.get_target(), self.get_oid()) 

1396 return resp 

1397 

1398# 3.1.1.5.7 IRemUnknown2 Interface 

1399class IRemUnknown2(IRemUnknown): 

1400 def __init__(self, interface): 

1401 IRemUnknown.__init__(self, interface) 

1402 self._iid = IID_IRemUnknown2 

1403 

1404# 3.1.2.5.1 IObjectExporter Methods 

1405class IObjectExporter: 

1406 def __init__(self, dce): 

1407 self.__portmap = dce 

1408 

1409 # 3.1.2.5.1.1 IObjectExporter::ResolveOxid (Opnum 0) 

1410 def ResolveOxid(self, pOxid, arRequestedProtseqs): 

1411 self.__portmap.connect() 

1412 self.__portmap.bind(IID_IObjectExporter) 

1413 request = ResolveOxid() 

1414 request['pOxid'] = pOxid 

1415 request['cRequestedProtseqs'] = len(arRequestedProtseqs) 

1416 for protSeq in arRequestedProtseqs: 

1417 request['arRequestedProtseqs'].append(protSeq) 

1418 resp = self.__portmap.request(request) 

1419 Oxids = b''.join(pack('<H', x) for x in resp['ppdsaOxidBindings']['aStringArray']) 

1420 strBindings = Oxids[:resp['ppdsaOxidBindings']['wSecurityOffset']*2] 

1421 

1422 done = False 

1423 stringBindings = list() 

1424 while not done: 

1425 if strBindings[0:1] == b'\x00' and strBindings[1:2] == b'\x00': 

1426 done = True 

1427 else: 

1428 binding = STRINGBINDING(strBindings) 

1429 stringBindings.append(binding) 

1430 strBindings = strBindings[len(binding):] 

1431 

1432 return stringBindings 

1433 

1434 # 3.1.2.5.1.2 IObjectExporter::SimplePing (Opnum 1) 

1435 def SimplePing(self, setId): 

1436 self.__portmap.connect() 

1437 self.__portmap.bind(IID_IObjectExporter) 

1438 request = SimplePing() 

1439 request['pSetId'] = setId 

1440 resp = self.__portmap.request(request) 

1441 return resp 

1442 

1443 # 3.1.2.5.1.3 IObjectExporter::ComplexPing (Opnum 2) 

1444 def ComplexPing(self, setId = 0, sequenceNum = 0, addToSet = [], delFromSet = []): 

1445 self.__portmap.connect() 

1446 #self.__portmap.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) 

1447 self.__portmap.bind(IID_IObjectExporter) 

1448 request = ComplexPing() 

1449 request['pSetId'] = setId 

1450 request['SequenceNum'] = setId 

1451 request['cAddToSet'] = len(addToSet) 

1452 request['cDelFromSet'] = len(delFromSet) 

1453 if len(addToSet) > 0: 1453 ↛ 1454line 1453 didn't jump to line 1454, because the condition on line 1453 was never true

1454 for oid in addToSet: 

1455 oidn = OID() 

1456 oidn['Data'] = oid 

1457 request['AddToSet'].append(oidn) 

1458 else: 

1459 request['AddToSet'] = NULL 

1460 

1461 if len(delFromSet) > 0: 1461 ↛ 1462line 1461 didn't jump to line 1462, because the condition on line 1461 was never true

1462 for oid in delFromSet: 

1463 oidn = OID() 

1464 oidn['Data'] = oid 

1465 request['DelFromSet'].append(oidn) 

1466 else: 

1467 request['DelFromSet'] = NULL 

1468 resp = self.__portmap.request(request) 

1469 return resp 

1470 

1471 # 3.1.2.5.1.4 IObjectExporter::ServerAlive (Opnum 3) 

1472 def ServerAlive(self): 

1473 self.__portmap.connect() 

1474 self.__portmap.bind(IID_IObjectExporter) 

1475 request = ServerAlive() 

1476 resp = self.__portmap.request(request) 

1477 return resp 

1478 

1479 # 3.1.2.5.1.5 IObjectExporter::ResolveOxid2 (Opnum 4) 

1480 def ResolveOxid2(self,pOxid, arRequestedProtseqs): 

1481 self.__portmap.connect() 

1482 self.__portmap.bind(IID_IObjectExporter) 

1483 request = ResolveOxid2() 

1484 request['pOxid'] = pOxid 

1485 request['cRequestedProtseqs'] = len(arRequestedProtseqs) 

1486 for protSeq in arRequestedProtseqs: 

1487 request['arRequestedProtseqs'].append(protSeq) 

1488 resp = self.__portmap.request(request) 

1489 Oxids = b''.join(pack('<H', x) for x in resp['ppdsaOxidBindings']['aStringArray']) 

1490 strBindings = Oxids[:resp['ppdsaOxidBindings']['wSecurityOffset']*2] 

1491 

1492 done = False 

1493 stringBindings = list() 

1494 while not done: 

1495 if strBindings[0:1] == b'\x00' and strBindings[1:2] == b'\x00': 

1496 done = True 

1497 else: 

1498 binding = STRINGBINDING(strBindings) 

1499 stringBindings.append(binding) 

1500 strBindings = strBindings[len(binding):] 

1501 

1502 return stringBindings 

1503 

1504 # 3.1.2.5.1.6 IObjectExporter::ServerAlive2 (Opnum 5) 

1505 def ServerAlive2(self): 

1506 self.__portmap.connect() 

1507 self.__portmap.bind(IID_IObjectExporter) 

1508 request = ServerAlive2() 

1509 resp = self.__portmap.request(request) 

1510 

1511 Oxids = b''.join(pack('<H', x) for x in resp['ppdsaOrBindings']['aStringArray']) 

1512 strBindings = Oxids[:resp['ppdsaOrBindings']['wSecurityOffset']*2] 

1513 

1514 done = False 

1515 stringBindings = list() 

1516 while not done: 

1517 if strBindings[0:1] == b'\x00' and strBindings[1:2] == b'\x00': 

1518 done = True 

1519 else: 

1520 binding = STRINGBINDING(strBindings) 

1521 stringBindings.append(binding) 

1522 strBindings = strBindings[len(binding):] 

1523 

1524 return stringBindings 

1525 

1526# 3.1.2.5.2.1 IActivation Methods 

1527class IActivation: 

1528 def __init__(self, dce): 

1529 self.__portmap = dce 

1530 

1531 # 3.1.2.5.2.3.1 IActivation:: RemoteActivation (Opnum 0) 

1532 def RemoteActivation(self, clsId, iid): 

1533 # Only supports one interface at a time 

1534 self.__portmap.bind(IID_IActivation) 

1535 ORPCthis = ORPCTHIS() 

1536 ORPCthis['cid'] = generate() 

1537 ORPCthis['extensions'] = NULL 

1538 ORPCthis['flags'] = 1 

1539 

1540 request = RemoteActivation() 

1541 request['Clsid'] = clsId 

1542 request['pwszObjectName'] = NULL 

1543 request['pObjectStorage'] = NULL 

1544 request['ClientImpLevel'] = 2 

1545 request['Mode'] = 0 

1546 request['Interfaces'] = 1 

1547 

1548 _iid = IID() 

1549 _iid['Data'] = iid 

1550 

1551 request['pIIDs'].append(_iid) 

1552 request['cRequestedProtseqs'] = 1 

1553 request['aRequestedProtseqs'].append(7) 

1554 

1555 resp = self.__portmap.request(request) 

1556 

1557 # Now let's parse the answer and build an Interface instance 

1558 

1559 ipidRemUnknown = resp['pipidRemUnknown'] 

1560 

1561 Oxids = b''.join(pack('<H', x) for x in resp['ppdsaOxidBindings']['aStringArray']) 

1562 strBindings = Oxids[:resp['ppdsaOxidBindings']['wSecurityOffset']*2] 

1563 securityBindings = Oxids[resp['ppdsaOxidBindings']['wSecurityOffset']*2:] 

1564 

1565 done = False 

1566 stringBindings = list() 

1567 while not done: 

1568 if strBindings[0:1] == b'\x00' and strBindings[1:2] == b'\x00': 

1569 done = True 

1570 else: 

1571 binding = STRINGBINDING(strBindings) 

1572 stringBindings.append(binding) 

1573 strBindings = strBindings[len(binding):] 

1574 

1575 done = False 

1576 while not done: 

1577 if len(securityBindings) < 2: 1577 ↛ 1578line 1577 didn't jump to line 1578, because the condition on line 1577 was never true

1578 done = True 

1579 elif securityBindings[0:1] == b'\x00' and securityBindings[1:2 ]== b'\x00': 

1580 done = True 

1581 else: 

1582 secBinding = SECURITYBINDING(securityBindings) 

1583 securityBindings = securityBindings[len(secBinding):] 

1584 

1585 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings) 

1586 return IRemUnknown2(INTERFACE(classInstance, b''.join(resp['ppInterfaceData'][0]['abData']), ipidRemUnknown, 

1587 target=self.__portmap.get_rpc_transport().getRemoteHost())) 

1588 

1589 

1590# 3.1.2.5.2.2 IRemoteSCMActivator Methods 

1591class IRemoteSCMActivator: 

1592 def __init__(self, dce): 

1593 self.__portmap = dce 

1594 

1595 def RemoteGetClassObject(self, clsId, iid): 

1596 # iid should be IID_IClassFactory 

1597 self.__portmap.bind(IID_IRemoteSCMActivator) 

1598 ORPCthis = ORPCTHIS() 

1599 ORPCthis['cid'] = generate() 

1600 ORPCthis['extensions'] = NULL 

1601 ORPCthis['flags'] = 1 

1602 

1603 request = RemoteGetClassObject() 

1604 request['ORPCthis'] = ORPCthis 

1605 activationBLOB = ACTIVATION_BLOB() 

1606 activationBLOB['CustomHeader']['destCtx'] = 2 

1607 activationBLOB['CustomHeader']['pdwReserved'] = NULL 

1608 clsid = CLSID() 

1609 clsid['Data'] = CLSID_InstantiationInfo 

1610 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1611 clsid = CLSID() 

1612 clsid['Data'] = CLSID_ActivationContextInfo 

1613 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1614 clsid = CLSID() 

1615 clsid['Data'] = CLSID_ServerLocationInfo 

1616 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1617 clsid = CLSID() 

1618 clsid['Data'] = CLSID_ScmRequestInfo 

1619 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1620 

1621 properties = b'' 

1622 # InstantiationInfo 

1623 instantiationInfo = InstantiationInfoData() 

1624 instantiationInfo['classId'] = clsId 

1625 instantiationInfo['cIID'] = 1 

1626 

1627 _iid = IID() 

1628 _iid['Data'] = iid 

1629 

1630 instantiationInfo['pIID'].append(_iid) 

1631 

1632 dword = DWORD() 

1633 marshaled = instantiationInfo.getData()+instantiationInfo.getDataReferents() 

1634 pad = (8 - (len(marshaled) % 8)) % 8 

1635 dword['Data'] = len(marshaled) + pad 

1636 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1637 instantiationInfo['thisSize'] = dword['Data'] 

1638 

1639 properties += marshaled + b'\xFA'*pad 

1640 

1641 # ActivationContextInfoData 

1642 activationInfo = ActivationContextInfoData() 

1643 activationInfo['pIFDClientCtx'] = NULL 

1644 activationInfo['pIFDPrototypeCtx'] = NULL 

1645 

1646 dword = DWORD() 

1647 marshaled = activationInfo.getData()+activationInfo.getDataReferents() 

1648 pad = (8 - (len(marshaled) % 8)) % 8 

1649 dword['Data'] = len(marshaled) + pad 

1650 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1651 

1652 properties += marshaled + b'\xFA'*pad 

1653 

1654 # ServerLocation 

1655 locationInfo = LocationInfoData() 

1656 locationInfo['machineName'] = NULL 

1657 

1658 dword = DWORD() 

1659 dword['Data'] = len(locationInfo.getData()) 

1660 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1661 

1662 properties += locationInfo.getData()+locationInfo.getDataReferents() 

1663 

1664 # ScmRequestInfo 

1665 scmInfo = ScmRequestInfoData() 

1666 scmInfo['pdwReserved'] = NULL 

1667 #scmInfo['remoteRequest']['ClientImpLevel'] = 2 

1668 scmInfo['remoteRequest']['cRequestedProtseqs'] = 1 

1669 scmInfo['remoteRequest']['pRequestedProtseqs'].append(7) 

1670 

1671 dword = DWORD() 

1672 marshaled = scmInfo.getData()+scmInfo.getDataReferents() 

1673 pad = (8 - (len(marshaled) % 8)) % 8 

1674 dword['Data'] = len(marshaled) + pad 

1675 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1676 

1677 properties += marshaled + b'\xFA'*pad 

1678 

1679 activationBLOB['Property'] = properties 

1680 

1681 

1682 objrefcustom = OBJREF_CUSTOM() 

1683 objrefcustom['iid'] = IID_IActivationPropertiesIn[:-4] 

1684 objrefcustom['clsid'] = CLSID_ActivationPropertiesIn 

1685 

1686 objrefcustom['pObjectData'] = activationBLOB.getData() 

1687 objrefcustom['ObjectReferenceSize'] = len(objrefcustom['pObjectData'])+8 

1688 

1689 request['pActProperties']['ulCntData'] = len(objrefcustom.getData()) 

1690 request['pActProperties']['abData'] = list(objrefcustom.getData()) 

1691 resp = self.__portmap.request(request) 

1692 # Now let's parse the answer and build an Interface instance 

1693 

1694 objRefType = OBJREF(b''.join(resp['ppActProperties']['abData']))['flags'] 

1695 objRef = None 

1696 if objRefType == FLAGS_OBJREF_CUSTOM: 1696 ↛ 1698line 1696 didn't jump to line 1698, because the condition on line 1696 was never false

1697 objRef = OBJREF_CUSTOM(b''.join(resp['ppActProperties']['abData'])) 

1698 elif objRefType == FLAGS_OBJREF_HANDLER: 

1699 objRef = OBJREF_HANDLER(b''.join(resp['ppActProperties']['abData'])) 

1700 elif objRefType == FLAGS_OBJREF_STANDARD: 

1701 objRef = OBJREF_STANDARD(b''.join(resp['ppActProperties']['abData'])) 

1702 elif objRefType == FLAGS_OBJREF_EXTENDED: 

1703 objRef = OBJREF_EXTENDED(b''.join(resp['ppActProperties']['abData'])) 

1704 else: 

1705 LOG.error("Unknown OBJREF Type! 0x%x" % objRefType) 

1706 

1707 

1708 activationBlob = ACTIVATION_BLOB(objRef['pObjectData']) 

1709 

1710 propOutput = activationBlob['Property'][:activationBlob['CustomHeader']['pSizes'][0]['Data']] 

1711 scmReply = activationBlob['Property'][ 

1712 activationBlob['CustomHeader']['pSizes'][0]['Data']:activationBlob['CustomHeader']['pSizes'][0]['Data'] + 

1713 activationBlob['CustomHeader']['pSizes'][1]['Data']] 

1714 

1715 scmr = ScmReplyInfoData() 

1716 size = scmr.fromString(scmReply) 

1717 # Processing the scmReply 

1718 scmr.fromStringReferents(scmReply[size:]) 

1719 ipidRemUnknown = scmr['remoteReply']['ipidRemUnknown'] 

1720 Oxids = b''.join(pack('<H', x) for x in scmr['remoteReply']['pdsaOxidBindings']['aStringArray']) 

1721 strBindings = Oxids[:scmr['remoteReply']['pdsaOxidBindings']['wSecurityOffset']*2] 

1722 securityBindings = Oxids[scmr['remoteReply']['pdsaOxidBindings']['wSecurityOffset']*2:] 

1723 

1724 done = False 

1725 stringBindings = list() 

1726 while not done: 

1727 if strBindings[0:1] == b'\x00' and strBindings[1:2] == b'\x00': 

1728 done = True 

1729 else: 

1730 binding = STRINGBINDING(strBindings) 

1731 stringBindings.append(binding) 

1732 strBindings = strBindings[len(binding):] 

1733 

1734 done = False 

1735 while not done: 

1736 if len(securityBindings) < 2: 1736 ↛ 1737line 1736 didn't jump to line 1737, because the condition on line 1736 was never true

1737 done = True 

1738 elif securityBindings[0:1] == b'\x00' and securityBindings[1:2] == b'\x00': 

1739 done = True 

1740 else: 

1741 secBinding = SECURITYBINDING(securityBindings) 

1742 securityBindings = securityBindings[len(secBinding):] 

1743 

1744 # Processing the Properties Output 

1745 propsOut = PropsOutInfo() 

1746 size = propsOut.fromString(propOutput) 

1747 propsOut.fromStringReferents(propOutput[size:]) 

1748 

1749 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings) 

1750 classInstance.set_auth_level(scmr['remoteReply']['authnHint']) 

1751 classInstance.set_auth_type(self.__portmap.get_auth_type()) 

1752 return IRemUnknown2(INTERFACE(classInstance, b''.join(propsOut['ppIntfData'][0]['abData']), ipidRemUnknown, 

1753 target=self.__portmap.get_rpc_transport().getRemoteHost())) 

1754 

1755 def RemoteCreateInstance(self, clsId, iid): 

1756 # Only supports one interface at a time 

1757 self.__portmap.bind(IID_IRemoteSCMActivator) 

1758 

1759 ORPCthis = ORPCTHIS() 

1760 ORPCthis['cid'] = generate() 

1761 ORPCthis['extensions'] = NULL 

1762 ORPCthis['flags'] = 1 

1763 

1764 request = RemoteCreateInstance() 

1765 request['ORPCthis'] = ORPCthis 

1766 request['pUnkOuter'] = NULL 

1767 

1768 activationBLOB = ACTIVATION_BLOB() 

1769 activationBLOB['CustomHeader']['destCtx'] = 2 

1770 activationBLOB['CustomHeader']['pdwReserved'] = NULL 

1771 clsid = CLSID() 

1772 clsid['Data'] = CLSID_InstantiationInfo 

1773 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1774 clsid = CLSID() 

1775 clsid['Data'] = CLSID_ActivationContextInfo 

1776 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1777 clsid = CLSID() 

1778 clsid['Data'] = CLSID_ServerLocationInfo 

1779 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1780 clsid = CLSID() 

1781 clsid['Data'] = CLSID_ScmRequestInfo 

1782 activationBLOB['CustomHeader']['pclsid'].append(clsid) 

1783 

1784 properties = b'' 

1785 # InstantiationInfo 

1786 instantiationInfo = InstantiationInfoData() 

1787 instantiationInfo['classId'] = clsId 

1788 instantiationInfo['cIID'] = 1 

1789 

1790 _iid = IID() 

1791 _iid['Data'] = iid 

1792 

1793 instantiationInfo['pIID'].append(_iid) 

1794 

1795 dword = DWORD() 

1796 marshaled = instantiationInfo.getData()+instantiationInfo.getDataReferents() 

1797 pad = (8 - (len(marshaled) % 8)) % 8 

1798 dword['Data'] = len(marshaled) + pad 

1799 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1800 instantiationInfo['thisSize'] = dword['Data'] 

1801 

1802 properties += marshaled + b'\xFA'*pad 

1803 

1804 # ActivationContextInfoData 

1805 activationInfo = ActivationContextInfoData() 

1806 activationInfo['pIFDClientCtx'] = NULL 

1807 activationInfo['pIFDPrototypeCtx'] = NULL 

1808 

1809 dword = DWORD() 

1810 marshaled = activationInfo.getData()+activationInfo.getDataReferents() 

1811 pad = (8 - (len(marshaled) % 8)) % 8 

1812 dword['Data'] = len(marshaled) + pad 

1813 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1814 

1815 properties += marshaled + b'\xFA'*pad 

1816 

1817 # ServerLocation 

1818 locationInfo = LocationInfoData() 

1819 locationInfo['machineName'] = NULL 

1820 

1821 dword = DWORD() 

1822 dword['Data'] = len(locationInfo.getData()) 

1823 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1824 

1825 properties += locationInfo.getData()+locationInfo.getDataReferents() 

1826 

1827 # ScmRequestInfo 

1828 scmInfo = ScmRequestInfoData() 

1829 scmInfo['pdwReserved'] = NULL 

1830 #scmInfo['remoteRequest']['ClientImpLevel'] = 2 

1831 scmInfo['remoteRequest']['cRequestedProtseqs'] = 1 

1832 scmInfo['remoteRequest']['pRequestedProtseqs'].append(7) 

1833 

1834 dword = DWORD() 

1835 marshaled = scmInfo.getData()+scmInfo.getDataReferents() 

1836 pad = (8 - (len(marshaled) % 8)) % 8 

1837 dword['Data'] = len(marshaled) + pad 

1838 activationBLOB['CustomHeader']['pSizes'].append(dword) 

1839 

1840 properties += marshaled + b'\xFA'*pad 

1841 

1842 activationBLOB['Property'] = properties 

1843 

1844 

1845 objrefcustom = OBJREF_CUSTOM() 

1846 objrefcustom['iid'] = IID_IActivationPropertiesIn[:-4] 

1847 objrefcustom['clsid'] = CLSID_ActivationPropertiesIn 

1848 

1849 objrefcustom['pObjectData'] = activationBLOB.getData() 

1850 objrefcustom['ObjectReferenceSize'] = len(objrefcustom['pObjectData'])+8 

1851 

1852 request['pActProperties']['ulCntData'] = len(objrefcustom.getData()) 

1853 request['pActProperties']['abData'] = list(objrefcustom.getData()) 

1854 resp = self.__portmap.request(request) 

1855 

1856 # Now let's parse the answer and build an Interface instance 

1857 

1858 objRefType = OBJREF(b''.join(resp['ppActProperties']['abData']))['flags'] 

1859 objRef = None 

1860 if objRefType == FLAGS_OBJREF_CUSTOM: 1860 ↛ 1862line 1860 didn't jump to line 1862, because the condition on line 1860 was never false

1861 objRef = OBJREF_CUSTOM(b''.join(resp['ppActProperties']['abData'])) 

1862 elif objRefType == FLAGS_OBJREF_HANDLER: 

1863 objRef = OBJREF_HANDLER(b''.join(resp['ppActProperties']['abData'])) 

1864 elif objRefType == FLAGS_OBJREF_STANDARD: 

1865 objRef = OBJREF_STANDARD(b''.join(resp['ppActProperties']['abData'])) 

1866 elif objRefType == FLAGS_OBJREF_EXTENDED: 

1867 objRef = OBJREF_EXTENDED(b''.join(resp['ppActProperties']['abData'])) 

1868 else: 

1869 LOG.error("Unknown OBJREF Type! 0x%x" % objRefType) 

1870 

1871 

1872 activationBlob = ACTIVATION_BLOB(objRef['pObjectData']) 

1873 

1874 propOutput = activationBlob['Property'][:activationBlob['CustomHeader']['pSizes'][0]['Data']] 

1875 scmReply = activationBlob['Property'][ 

1876 activationBlob['CustomHeader']['pSizes'][0]['Data']:activationBlob['CustomHeader']['pSizes'][0]['Data'] + 

1877 activationBlob['CustomHeader']['pSizes'][1]['Data']] 

1878 

1879 scmr = ScmReplyInfoData() 

1880 size = scmr.fromString(scmReply) 

1881 # Processing the scmReply 

1882 scmr.fromStringReferents(scmReply[size:]) 

1883 ipidRemUnknown = scmr['remoteReply']['ipidRemUnknown'] 

1884 Oxids = b''.join(pack('<H', x) for x in scmr['remoteReply']['pdsaOxidBindings']['aStringArray']) 

1885 strBindings = Oxids[:scmr['remoteReply']['pdsaOxidBindings']['wSecurityOffset']*2] 

1886 securityBindings = Oxids[scmr['remoteReply']['pdsaOxidBindings']['wSecurityOffset']*2:] 

1887 

1888 done = False 

1889 stringBindings = list() 

1890 while not done: 

1891 if strBindings[0:1] == b'\x00' and strBindings[1:2] == b'\x00': 

1892 done = True 

1893 else: 

1894 binding = STRINGBINDING(strBindings) 

1895 stringBindings.append(binding) 

1896 strBindings = strBindings[len(binding):] 

1897 

1898 done = False 

1899 while not done: 

1900 if len(securityBindings) < 2: 1900 ↛ 1901line 1900 didn't jump to line 1901, because the condition on line 1900 was never true

1901 done = True 

1902 elif securityBindings[0:1] == b'\x00' and securityBindings[1:2] == b'\x00': 

1903 done = True 

1904 else: 

1905 secBinding = SECURITYBINDING(securityBindings) 

1906 securityBindings = securityBindings[len(secBinding):] 

1907 

1908 # Processing the Properties Output 

1909 propsOut = PropsOutInfo() 

1910 size = propsOut.fromString(propOutput) 

1911 propsOut.fromStringReferents(propOutput[size:]) 

1912 

1913 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings) 

1914 classInstance.set_auth_level(scmr['remoteReply']['authnHint']) 

1915 classInstance.set_auth_type(self.__portmap.get_auth_type()) 

1916 return IRemUnknown2(INTERFACE(classInstance, b''.join(propsOut['ppIntfData'][0]['abData']), ipidRemUnknown, 

1917 target=self.__portmap.get_rpc_transport().getRemoteHost()))