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# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under under a slightly modified version 

4# of the Apache Software License. See the accompanying LICENSE file 

5# for more information. 

6# 

7# Author: Alberto Solino (@agsolino) 

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# ToDo: 

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

23# for each call, making it slower. 

24# 

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

26# not used, returning RPC_E_DISCONNECTED 

27# 

28from __future__ import division 

29from __future__ import print_function 

30import socket 

31from struct import pack 

32from threading import Timer, currentThread 

33 

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

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

36 UUID, WIDESTR, NULL 

37from impacket import hresult_errors, LOG 

38from impacket.uuid import string_to_bin, uuidtup_to_bin, generate 

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

40 RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_WINNT, DCERPCException 

41from impacket.dcerpc.v5 import transport 

42 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

68 

69class DCERPCSessionError(DCERPCException): 

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

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

72 

73 def __str__( self ): 

74 if self.error_code in hresult_errors.ERROR_MESSAGES: 

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

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

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

78 else: 

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

80 

81################################################################################ 

82# CONSTANTS 

83################################################################################ 

84# 2.2.1 OID 

85OID = ULONGLONG 

86 

87class OID_ARRAY(NDRUniConformantArray): 

88 item = OID 

89 

90class POID_ARRAY(NDRPOINTER): 

91 referent = ( 

92 ('Data', OID_ARRAY), 

93 ) 

94 

95# 2.2.2 SETID 

96SETID = ULONGLONG 

97 

98# 2.2.4 error_status_t 

99error_status_t = ULONG 

100 

101# 2.2.6 CID 

102CID = GUID 

103 

104# 2.2.7 CLSID 

105CLSID = GUID 

106 

107# 2.2.8 IID 

108IID = GUID 

109PIID = PGUID 

110 

111# 2.2.9 IPID 

112IPID = GUID 

113 

114# 2.2.10 OXID 

115OXID = ULONGLONG 

116 

117# 2.2.18 OBJREF 

118FLAGS_OBJREF_STANDARD = 0x00000001 

119FLAGS_OBJREF_HANDLER = 0x00000002 

120FLAGS_OBJREF_CUSTOM = 0x00000004 

121FLAGS_OBJREF_EXTENDED = 0x00000008 

122 

123# 2.2.18.1 STDOBJREF 

124SORF_NOPING = 0x00001000 

125 

126# 2.2.20 Context 

127CTXMSHLFLAGS_BYVAL = 0x00000002 

128 

129# 2.2.20.1 PROPMARSHALHEADER 

130CPFLAG_PROPAGATE = 0x00000001 

131CPFLAG_EXPOSE = 0x00000002 

132CPFLAG_ENVOY = 0x00000004 

133 

134# 2.2.22.2.1 InstantiationInfoData 

135ACTVFLAGS_DISABLE_AAA = 0x00000002 

136ACTVFLAGS_ACTIVATE_32_BIT_SERVER = 0x00000004 

137ACTVFLAGS_ACTIVATE_64_BIT_SERVER = 0x00000008 

138ACTVFLAGS_NO_FAILURE_LOG = 0x00000020 

139 

140# 2.2.22.2.2 SpecialPropertiesData 

141SPD_FLAG_USE_CONSOLE_SESSION = 0x00000001 

142 

143# 2.2.28.1 IDL Range Constants 

144MAX_REQUESTED_INTERFACES = 0x8000 

145MAX_REQUESTED_PROTSEQS = 0x8000 

146MIN_ACTPROP_LIMIT = 1 

147MAX_ACTPROP_LIMIT = 10 

148 

149################################################################################ 

150# STRUCTURES 

151################################################################################ 

152class handle_t(NDRSTRUCT): 

153 structure = ( 

154 ('context_handle_attributes',ULONG), 

155 ('context_handle_uuid',UUID), 

156 ) 

157 

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

159 NDRSTRUCT.__init__(self, data, isNDR64) 

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

161 

162 def isNull(self): 

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

164 

165# 2.2.11 COMVERSION 

166class COMVERSION(NDRSTRUCT): 

167 default_major_version = 5 

168 default_minor_version = 7 

169 

170 structure = ( 

171 ('MajorVersion',USHORT), 

172 ('MinorVersion',USHORT), 

173 ) 

174 

175 @classmethod 

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

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

178 if major_version is not None: 

179 cls.default_major_version = major_version 

180 if minor_version is not None: 

181 cls.default_minor_version = minor_version 

182 

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

184 NDRSTRUCT.__init__(self, data, isNDR64) 

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

186 self['MajorVersion'] = self.default_major_version 

187 self['MinorVersion'] = self.default_minor_version 

188 

189class PCOMVERSION(NDRPOINTER): 

190 referent = ( 

191 ('Data', COMVERSION), 

192 ) 

193 

194# 2.2.13.1 ORPC_EXTENT 

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

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

197class BYTE_ARRAY(NDRUniConformantArray): 

198 item = 'c' 

199 

200class ORPC_EXTENT(NDRSTRUCT): 

201 structure = ( 

202 ('id',GUID), 

203 ('size',ULONG), 

204 ('data',BYTE_ARRAY), 

205 ) 

206 

207# 2.2.13.2 ORPC_EXTENT_ARRAY 

208# ThisMUSTbeanarrayofORPC_EXTENTs.ThearraysizeMUSTbeamultipleof2for alignment reasons. 

209class PORPC_EXTENT(NDRPOINTER): 

210 referent = ( 

211 ('Data', ORPC_EXTENT), 

212 ) 

213 

214class EXTENT_ARRAY(NDRUniConformantArray): 

215 item = PORPC_EXTENT 

216 

217class PEXTENT_ARRAY(NDRPOINTER): 

218 referent = ( 

219 ('Data', EXTENT_ARRAY), 

220 ) 

221 

222class ORPC_EXTENT_ARRAY(NDRSTRUCT): 

223 structure = ( 

224 ('size',ULONG), 

225 ('reserved',ULONG), 

226 ('extent',PEXTENT_ARRAY), 

227 ) 

228 

229class PORPC_EXTENT_ARRAY(NDRPOINTER): 

230 referent = ( 

231 ('Data', ORPC_EXTENT_ARRAY), 

232 ) 

233 

234# 2.2.13.3 ORPCTHIS 

235class ORPCTHIS(NDRSTRUCT): 

236 structure = ( 

237 ('version',COMVERSION), 

238 ('flags',ULONG), 

239 ('reserved1',ULONG), 

240 ('cid',CID), 

241 ('extensions',PORPC_EXTENT_ARRAY), 

242 ) 

243 

244# 2.2.13.4 ORPCTHAT 

245class ORPCTHAT(NDRSTRUCT): 

246 structure = ( 

247 ('flags',ULONG), 

248 ('extensions',PORPC_EXTENT_ARRAY), 

249 ) 

250 

251# 2.2.14 MInterfacePointer 

252class MInterfacePointer(NDRSTRUCT): 

253 structure = ( 

254 ('ulCntData',ULONG), 

255 ('abData',BYTE_ARRAY), 

256 ) 

257 

258# 2.2.15 PMInterfacePointerInternal 

259class PMInterfacePointerInternal(NDRPOINTER): 

260 referent = ( 

261 ('Data', MInterfacePointer), 

262 ) 

263 

264# 2.2.16 PMInterfacePointer 

265class PMInterfacePointer(NDRPOINTER): 

266 referent = ( 

267 ('Data', MInterfacePointer), 

268 ) 

269 

270class PPMInterfacePointer(NDRPOINTER): 

271 referent = ( 

272 ('Data', PMInterfacePointer), 

273 ) 

274 

275# 2.2.18 OBJREF 

276class OBJREF(NDRSTRUCT): 

277 commonHdr = ( 

278 ('signature',ULONG), 

279 ('flags',ULONG), 

280 ('iid',GUID), 

281 ) 

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

283 NDRSTRUCT.__init__(self, data, isNDR64) 

284 if data is None: 

285 self['signature'] = 0x574F454D 

286 

287# 2.2.18.1 STDOBJREF 

288class STDOBJREF(NDRSTRUCT): 

289 structure = ( 

290 ('flags',ULONG), 

291 ('cPublicRefs',ULONG), 

292 ('oxid',OXID), 

293 ('oid',OID), 

294 ('ipid',IPID), 

295 ) 

296 

297# 2.2.18.4 OBJREF_STANDARD 

298class OBJREF_STANDARD(OBJREF): 

299 structure = ( 

300 ('std',STDOBJREF), 

301 ('saResAddr',':'), 

302 ) 

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

304 OBJREF.__init__(self, data, isNDR64) 

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

306 self['flags'] = FLAGS_OBJREF_STANDARD 

307 

308# 2.2.18.5 OBJREF_HANDLER 

309class OBJREF_HANDLER(OBJREF): 

310 structure = ( 

311 ('std',STDOBJREF), 

312 ('clsid',CLSID), 

313 ('saResAddr',':'), 

314 ) 

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

316 OBJREF.__init__(self, data, isNDR64) 

317 if data is None: 

318 self['flags'] = FLAGS_OBJREF_HANDLER 

319 

320# 2.2.18.6 OBJREF_CUSTOM 

321class OBJREF_CUSTOM(OBJREF): 

322 structure = ( 

323 ('clsid',CLSID), 

324 ('cbExtension',ULONG), 

325 ('ObjectReferenceSize',ULONG), 

326 ('pObjectData',':'), 

327 ) 

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

329 OBJREF.__init__(self, data, isNDR64) 

330 if data is None: 

331 self['flags'] = FLAGS_OBJREF_CUSTOM 

332 

333# 2.2.18.8 DATAELEMENT 

334class DATAELEMENT(NDRSTRUCT): 

335 structure = ( 

336 ('dataID',GUID), 

337 ('cbSize',ULONG), 

338 ('cbRounded',ULONG), 

339 ('Data',':'), 

340 ) 

341 

342class DUALSTRINGARRAYPACKED(NDRSTRUCT): 

343 structure = ( 

344 ('wNumEntries',USHORT), 

345 ('wSecurityOffset',USHORT), 

346 ('aStringArray',':'), 

347 ) 

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

349 return self['wNumEntries']*2 

350 

351# 2.2.18.7 OBJREF_EXTENDED 

352class OBJREF_EXTENDED(OBJREF): 

353 structure = ( 

354 ('std',STDOBJREF), 

355 ('Signature1',ULONG), 

356 ('saResAddr',DUALSTRINGARRAYPACKED), 

357 ('nElms',ULONG), 

358 ('Signature2',ULONG), 

359 ('ElmArray',DATAELEMENT), 

360 ) 

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

362 OBJREF.__init__(self, data, isNDR64) 

363 if data is None: 

364 self['flags'] = FLAGS_OBJREF_EXTENDED 

365 self['Signature1'] = 0x4E535956 

366 self['Signature1'] = 0x4E535956 

367 self['nElms'] = 0x4E535956 

368 

369# 2.2.19 DUALSTRINGARRAY 

370class USHORT_ARRAY(NDRUniConformantArray): 

371 item = '<H' 

372 

373class PUSHORT_ARRAY(NDRPOINTER): 

374 referent = ( 

375 ('Data', USHORT_ARRAY), 

376 ) 

377 

378class DUALSTRINGARRAY(NDRSTRUCT): 

379 structure = ( 

380 ('wNumEntries',USHORT), 

381 ('wSecurityOffset',USHORT), 

382 ('aStringArray',USHORT_ARRAY), 

383 ) 

384 

385class PDUALSTRINGARRAY(NDRPOINTER): 

386 referent = ( 

387 ('Data',DUALSTRINGARRAY), 

388 ) 

389 

390# 2.2.19.3 STRINGBINDING 

391class STRINGBINDING(NDRSTRUCT): 

392 structure = ( 

393 ('wTowerId',USHORT), 

394 ('aNetworkAddr',WIDESTR), 

395 ) 

396 

397# 2.2.19.4 SECURITYBINDING 

398class SECURITYBINDING(NDRSTRUCT): 

399 structure = ( 

400 ('wAuthnSvc',USHORT), 

401 ('Reserved',USHORT), 

402 ('aPrincName',WIDESTR), 

403 ) 

404 

405# 2.2.20.1 PROPMARSHALHEADER 

406class PROPMARSHALHEADER(NDRSTRUCT): 

407 structure = ( 

408 ('clsid',CLSID), 

409 ('policyId',GUID), 

410 ('flags',ULONG), 

411 ('cb',ULONG), 

412 ('ctxProperty',':'), 

413 ) 

414 

415class PROPMARSHALHEADER_ARRAY(NDRUniConformantArray): 

416 item = PROPMARSHALHEADER 

417 

418# 2.2.20 Context 

419class Context(NDRSTRUCT): 

420 structure = ( 

421 ('MajorVersion',USHORT), 

422 ('MinVersion',USHORT), 

423 ('ContextId',GUID), 

424 ('Flags',ULONG), 

425 ('Reserved',ULONG), 

426 ('dwNumExtents',ULONG), 

427 ('cbExtents',ULONG), 

428 ('MshlFlags',ULONG), 

429 ('Count',ULONG), 

430 ('Frozen',ULONG), 

431 ('PropMarshalHeader',PROPMARSHALHEADER_ARRAY), 

432 ) 

433 

434# 2.2.21.3 ErrorInfoString 

435class ErrorInfoString(NDRSTRUCT): 

436 structure = ( 

437 ('dwMax',ULONG), 

438 ('dwOffSet',ULONG), 

439 ('dwActual',IID), 

440 ('Name',WSTR), 

441 ) 

442 

443# 2.2.21.2 Custom-Marshaled Error Information Format 

444class ORPC_ERROR_INFORMATION(NDRSTRUCT): 

445 structure = ( 

446 ('dwVersion',ULONG), 

447 ('dwHelpContext',ULONG), 

448 ('iid',IID), 

449 ('dwSourceSignature',ULONG), 

450 ('Source',ErrorInfoString), 

451 ('dwDescriptionSignature',ULONG), 

452 ('Description',ErrorInfoString), 

453 ('dwHelpFileSignature',ULONG), 

454 ('HelpFile',ErrorInfoString), 

455 ) 

456 

457# 2.2.21.5 EntryHeader 

458class EntryHeader(NDRSTRUCT): 

459 structure = ( 

460 ('Signature',ULONG), 

461 ('cbEHBuffer',ULONG), 

462 ('cbSize',ULONG), 

463 ('reserved',ULONG), 

464 ('policyID',GUID), 

465 ) 

466 

467class EntryHeader_ARRAY(NDRUniConformantArray): 

468 item = EntryHeader 

469 

470# 2.2.21.4 Context ORPC Extension 

471class ORPC_CONTEXT(NDRSTRUCT): 

472 structure = ( 

473 ('SignatureVersion',ULONG), 

474 ('Version',ULONG), 

475 ('cPolicies',ULONG), 

476 ('cbBuffer',ULONG), 

477 ('cbSize',ULONG), 

478 ('hr',ULONG), 

479 ('hrServer',ULONG), 

480 ('reserved',ULONG), 

481 ('EntryHeader',EntryHeader_ARRAY), 

482 ('PolicyData',':'), 

483 ) 

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

485 NDRSTRUCT.__init__(self, data, isNDR64) 

486 if data is None: 

487 self['SignatureVersion'] = 0x414E554B 

488 

489# 2.2.22.1 CustomHeader 

490class CLSID_ARRAY(NDRUniConformantArray): 

491 item = CLSID 

492 

493class PCLSID_ARRAY(NDRPOINTER): 

494 referent = ( 

495 ('Data', CLSID_ARRAY), 

496 ) 

497 

498class DWORD_ARRAY(NDRUniConformantArray): 

499 item = DWORD 

500 

501class PDWORD_ARRAY(NDRPOINTER): 

502 referent = ( 

503 ('Data', DWORD_ARRAY), 

504 ) 

505 

506class CustomHeader(TypeSerialization1): 

507 structure = ( 

508 ('totalSize',DWORD), 

509 ('headerSize',DWORD), 

510 ('dwReserved',DWORD), 

511 ('destCtx',DWORD), 

512 ('cIfs',DWORD), 

513 ('classInfoClsid',CLSID), 

514 ('pclsid',PCLSID_ARRAY), 

515 ('pSizes',PDWORD_ARRAY), 

516 ('pdwReserved',LPLONG), 

517 #('pdwReserved',LONG), 

518 ) 

519 def getData(self, soFar = 0): 

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

521 TypeSerialization1.getDataReferents(self, soFar)) 

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

523 return TypeSerialization1.getData(self, soFar) 

524 

525# 2.2.22 Activation Properties BLOB 

526class ACTIVATION_BLOB(NDRTLSTRUCT): 

527 structure = ( 

528 ('dwSize',ULONG), 

529 ('dwReserved',ULONG), 

530 ('CustomHeader',CustomHeader), 

531 ('Property',UNKNOWNDATA), 

532 ) 

533 def getData(self, soFar = 0): 

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

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

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

537 return NDRTLSTRUCT.getData(self) 

538 

539# 2.2.22.2.1 InstantiationInfoData 

540class IID_ARRAY(NDRUniConformantArray): 

541 item = IID 

542 

543class PIID_ARRAY(NDRPOINTER): 

544 referent = ( 

545 ('Data', IID_ARRAY), 

546 ) 

547 

548class InstantiationInfoData(TypeSerialization1): 

549 structure = ( 

550 ('classId',CLSID), 

551 ('classCtx',DWORD), 

552 ('actvflags',DWORD), 

553 ('fIsSurrogate',LONG), 

554 ('cIID',DWORD), 

555 ('instFlag',DWORD), 

556 ('pIID',PIID_ARRAY), 

557 ('thisSize',DWORD), 

558 ('clientCOMVersion',COMVERSION), 

559 ) 

560 

561# 2.2.22.2.2 SpecialPropertiesData 

562class SpecialPropertiesData(TypeSerialization1): 

563 structure = ( 

564 ('dwSessionId',ULONG), 

565 ('fRemoteThisSessionId',LONG), 

566 ('fClientImpersonating',LONG), 

567 ('fPartitionIDPresent',LONG), 

568 ('dwDefaultAuthnLvl',DWORD), 

569 ('guidPartition',GUID), 

570 ('dwPRTFlags',DWORD), 

571 ('dwOrigClsctx',DWORD), 

572 ('dwFlags',DWORD), 

573 ('Reserved0',DWORD), 

574 ('Reserved0',DWORD), 

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

576 #('Reserved1',DWORD), 

577 #('Reserved2',ULONGLONG), 

578 #('Reserved3_1',DWORD), 

579 #('Reserved3_2',DWORD), 

580 #('Reserved3_3',DWORD), 

581 #('Reserved3_4',DWORD), 

582 #('Reserved3_5',DWORD), 

583 ) 

584 

585# 2.2.22.2.3 InstanceInfoData 

586class InstanceInfoData(TypeSerialization1): 

587 structure = ( 

588 ('fileName',LPWSTR), 

589 ('mode',DWORD), 

590 ('ifdROT',PMInterfacePointer), 

591 ('ifdStg',PMInterfacePointer), 

592 ) 

593 

594# 2.2.22.2.4.1 customREMOTE_REQUEST_SCM_INFO 

595class customREMOTE_REQUEST_SCM_INFO(NDRSTRUCT): 

596 structure = ( 

597 ('ClientImpLevel',DWORD), 

598 ('cRequestedProtseqs',USHORT), 

599 ('pRequestedProtseqs',PUSHORT_ARRAY), 

600 ) 

601 

602class PcustomREMOTE_REQUEST_SCM_INFO(NDRPOINTER): 

603 referent = ( 

604 ('Data', customREMOTE_REQUEST_SCM_INFO), 

605 ) 

606 

607# 2.2.22.2.4 ScmRequestInfoData 

608class ScmRequestInfoData(TypeSerialization1): 

609 structure = ( 

610 ('pdwReserved',LPLONG), 

611 ('remoteRequest',PcustomREMOTE_REQUEST_SCM_INFO), 

612 ) 

613 

614# 2.2.22.2.5 ActivationContextInfoData 

615class ActivationContextInfoData(TypeSerialization1): 

616 structure = ( 

617 ('clientOK',LONG), 

618 ('bReserved1',LONG), 

619 ('dwReserved1',DWORD), 

620 ('dwReserved2',DWORD), 

621 ('pIFDClientCtx',PMInterfacePointer), 

622 ('pIFDPrototypeCtx',PMInterfacePointer), 

623 ) 

624 

625# 2.2.22.2.6 LocationInfoData 

626class LocationInfoData(TypeSerialization1): 

627 structure = ( 

628 ('machineName',LPWSTR), 

629 ('processId',DWORD), 

630 ('apartmentId',DWORD), 

631 ('contextId',DWORD), 

632 ) 

633 

634# 2.2.22.2.7.1 COSERVERINFO 

635class COSERVERINFO(NDRSTRUCT): 

636 structure = ( 

637 ('dwReserved1',DWORD), 

638 ('pwszName',LPWSTR), 

639 ('pdwReserved',LPLONG), 

640 ('dwReserved2',DWORD), 

641 ) 

642 

643class PCOSERVERINFO(NDRPOINTER): 

644 referent = ( 

645 ('Data', COSERVERINFO), 

646 ) 

647 

648# 2.2.22.2.7 SecurityInfoData 

649class SecurityInfoData(TypeSerialization1): 

650 structure = ( 

651 ('dwAuthnFlags',DWORD), 

652 ('pServerInfo',PCOSERVERINFO), 

653 ('pdwReserved',LPLONG), 

654 ) 

655 

656# 2.2.22.2.8.1 customREMOTE_REPLY_SCM_INFO 

657class customREMOTE_REPLY_SCM_INFO(NDRSTRUCT): 

658 structure = ( 

659 ('Oxid',OXID), 

660 ('pdsaOxidBindings',PDUALSTRINGARRAY), 

661 ('ipidRemUnknown',IPID), 

662 ('authnHint',DWORD), 

663 ('serverVersion',COMVERSION), 

664 ) 

665 

666class PcustomREMOTE_REPLY_SCM_INFO(NDRPOINTER): 

667 referent = ( 

668 ('Data', customREMOTE_REPLY_SCM_INFO), 

669 ) 

670 

671# 2.2.22.2.8 ScmReplyInfoData 

672class ScmReplyInfoData(TypeSerialization1): 

673 structure = ( 

674 ('pdwReserved',DWORD), 

675 ('remoteReply',PcustomREMOTE_REPLY_SCM_INFO), 

676 ) 

677 

678# 2.2.22.2.9 PropsOutInfo 

679class HRESULT_ARRAY(NDRUniConformantArray): 

680 item = HRESULT 

681 

682class PHRESULT_ARRAY(NDRPOINTER): 

683 referent = ( 

684 ('Data', HRESULT_ARRAY), 

685 ) 

686 

687class MInterfacePointer_ARRAY(NDRUniConformantArray): 

688 item = MInterfacePointer 

689 

690class PMInterfacePointer_ARRAY(NDRUniConformantArray): 

691 item = PMInterfacePointer 

692 

693class PPMInterfacePointer_ARRAY(NDRPOINTER): 

694 referent = ( 

695 ('Data', PMInterfacePointer_ARRAY), 

696 ) 

697 

698class PropsOutInfo(TypeSerialization1): 

699 structure = ( 

700 ('cIfs',DWORD), 

701 ('piid',PIID_ARRAY), 

702 ('phresults',PHRESULT_ARRAY), 

703 ('ppIntfData',PPMInterfacePointer_ARRAY), 

704 ) 

705 

706# 2.2.23 REMINTERFACEREF 

707class REMINTERFACEREF(NDRSTRUCT): 

708 structure = ( 

709 ('ipid',IPID), 

710 ('cPublicRefs',LONG), 

711 ('cPrivateRefs',LONG), 

712 ) 

713 

714class REMINTERFACEREF_ARRAY(NDRUniConformantArray): 

715 item = REMINTERFACEREF 

716 

717# 2.2.24 REMQIRESULT 

718class REMQIRESULT(NDRSTRUCT): 

719 structure = ( 

720 ('hResult',HRESULT), 

721 ('std',STDOBJREF), 

722 ) 

723 

724# 2.2.25 PREMQIRESULT 

725class PREMQIRESULT(NDRPOINTER): 

726 referent = ( 

727 ('Data', REMQIRESULT), 

728 ) 

729 

730# 2.2.26 REFIPID 

731REFIPID = GUID 

732 

733################################################################################ 

734# RPC CALLS 

735################################################################################ 

736class DCOMCALL(NDRCALL): 

737 commonHdr = ( 

738 ('ORPCthis', ORPCTHIS), 

739 ) 

740 

741class DCOMANSWER(NDRCALL): 

742 commonHdr = ( 

743 ('ORPCthat', ORPCTHAT), 

744 ) 

745 

746# 3.1.2.5.1.1 IObjectExporter::ResolveOxid (Opnum 0) 

747class ResolveOxid(NDRCALL): 

748 opnum = 0 

749 structure = ( 

750 ('pOxid', OXID), 

751 ('cRequestedProtseqs', USHORT), 

752 ('arRequestedProtseqs', USHORT_ARRAY), 

753 ) 

754 

755class ResolveOxidResponse(NDRCALL): 

756 structure = ( 

757 ('ppdsaOxidBindings', PDUALSTRINGARRAY), 

758 ('pipidRemUnknown', IPID), 

759 ('pAuthnHint', DWORD), 

760 ('ErrorCode', error_status_t), 

761 ) 

762 

763# 3.1.2.5.1.2 IObjectExporter::SimplePing (Opnum 1) 

764class SimplePing(NDRCALL): 

765 opnum = 1 

766 structure = ( 

767 ('pSetId', SETID), 

768 ) 

769 

770class SimplePingResponse(NDRCALL): 

771 structure = ( 

772 ('ErrorCode', error_status_t), 

773 ) 

774 

775# 3.1.2.5.1.3 IObjectExporter::ComplexPing (Opnum 2) 

776class ComplexPing(NDRCALL): 

777 opnum = 2 

778 structure = ( 

779 ('pSetId', SETID), 

780 ('SequenceNum', USHORT), 

781 ('cAddToSet', USHORT), 

782 ('cDelFromSet', USHORT), 

783 ('AddToSet', POID_ARRAY), 

784 ('DelFromSet', POID_ARRAY), 

785 ) 

786 

787class ComplexPingResponse(NDRCALL): 

788 structure = ( 

789 ('pSetId', SETID), 

790 ('pPingBackoffFactor', USHORT), 

791 ('ErrorCode', error_status_t), 

792 ) 

793 

794# 3.1.2.5.1.4 IObjectExporter::ServerAlive (Opnum 3) 

795class ServerAlive(NDRCALL): 

796 opnum = 3 

797 structure = ( 

798 ) 

799 

800class ServerAliveResponse(NDRCALL): 

801 structure = ( 

802 ('ErrorCode', error_status_t), 

803 ) 

804 

805# 3.1.2.5.1.5 IObjectExporter::ResolveOxid2 (Opnum 4) 

806class ResolveOxid2(NDRCALL): 

807 opnum = 4 

808 structure = ( 

809 ('pOxid', OXID), 

810 ('cRequestedProtseqs', USHORT), 

811 ('arRequestedProtseqs', USHORT_ARRAY), 

812 ) 

813 

814class ResolveOxid2Response(NDRCALL): 

815 structure = ( 

816 ('ppdsaOxidBindings', PDUALSTRINGARRAY), 

817 ('pipidRemUnknown', IPID), 

818 ('pAuthnHint', DWORD), 

819 ('pComVersion', COMVERSION), 

820 ('ErrorCode', error_status_t), 

821 ) 

822 

823# 3.1.2.5.1.6 IObjectExporter::ServerAlive2 (Opnum 5) 

824class ServerAlive2(NDRCALL): 

825 opnum = 5 

826 structure = ( 

827 ) 

828 

829class ServerAlive2Response(NDRCALL): 

830 structure = ( 

831 ('pComVersion', COMVERSION), 

832 ('ppdsaOrBindings', PDUALSTRINGARRAY), 

833 ('pReserved', LPLONG), 

834 ('ErrorCode', error_status_t), 

835 ) 

836 

837# 3.1.2.5.2.3.1 IActivation:: RemoteActivation (Opnum 0) 

838class RemoteActivation(NDRCALL): 

839 opnum = 0 

840 structure = ( 

841 ('ORPCthis', ORPCTHIS), 

842 ('Clsid', GUID), 

843 ('pwszObjectName', LPWSTR), 

844 ('pObjectStorage', PMInterfacePointer), 

845 ('ClientImpLevel', DWORD), 

846 ('Mode', DWORD), 

847 ('Interfaces', DWORD), 

848 ('pIIDs', PIID_ARRAY), 

849 ('cRequestedProtseqs', USHORT), 

850 ('aRequestedProtseqs', USHORT_ARRAY), 

851 ) 

852 

853class RemoteActivationResponse(NDRCALL): 

854 structure = ( 

855 ('ORPCthat', ORPCTHAT), 

856 ('pOxid', OXID), 

857 ('ppdsaOxidBindings', PDUALSTRINGARRAY), 

858 ('pipidRemUnknown', IPID), 

859 ('pAuthnHint', DWORD), 

860 ('pServerVersion', COMVERSION), 

861 ('phr', HRESULT), 

862 ('ppInterfaceData', PMInterfacePointer_ARRAY), 

863 ('pResults', HRESULT_ARRAY), 

864 ('ErrorCode', error_status_t), 

865 ) 

866 

867# 3.1.2.5.2.3.2 IRemoteSCMActivator:: RemoteGetClassObject (Opnum 3) 

868class RemoteGetClassObject(NDRCALL): 

869 opnum = 3 

870 structure = ( 

871 ('ORPCthis', ORPCTHIS), 

872 ('pActProperties', PMInterfacePointer), 

873 ) 

874 

875class RemoteGetClassObjectResponse(NDRCALL): 

876 structure = ( 

877 ('ORPCthat', ORPCTHAT), 

878 ('ppActProperties', PMInterfacePointer), 

879 ('ErrorCode', error_status_t), 

880 ) 

881 

882# 3.1.2.5.2.3.3 IRemoteSCMActivator::RemoteCreateInstance (Opnum 4) 

883class RemoteCreateInstance(NDRCALL): 

884 opnum = 4 

885 structure = ( 

886 ('ORPCthis', ORPCTHIS), 

887 ('pUnkOuter', PMInterfacePointer), 

888 ('pActProperties', PMInterfacePointer), 

889 ) 

890 

891class RemoteCreateInstanceResponse(NDRCALL): 

892 structure = ( 

893 ('ORPCthat', ORPCTHAT), 

894 ('ppActProperties', PMInterfacePointer), 

895 ('ErrorCode', error_status_t), 

896 ) 

897 

898# 3.1.1.5.6.1.1 IRemUnknown::RemQueryInterface (Opnum 3) 

899class RemQueryInterface(DCOMCALL): 

900 opnum = 3 

901 structure = ( 

902 ('ripid', REFIPID), 

903 ('cRefs', ULONG), 

904 ('cIids', USHORT), 

905 ('iids', IID_ARRAY), 

906 ) 

907 

908class RemQueryInterfaceResponse(DCOMANSWER): 

909 structure = ( 

910 ('ppQIResults', PREMQIRESULT), 

911 ('ErrorCode', error_status_t), 

912 ) 

913 

914# 3.1.1.5.6.1.2 IRemUnknown::RemAddRef (Opnum 4 ) 

915class RemAddRef(DCOMCALL): 

916 opnum = 4 

917 structure = ( 

918 ('cInterfaceRefs', USHORT), 

919 ('InterfaceRefs', REMINTERFACEREF_ARRAY), 

920 ) 

921 

922class RemAddRefResponse(DCOMANSWER): 

923 structure = ( 

924 ('pResults', DWORD_ARRAY), 

925 ('ErrorCode', error_status_t), 

926 ) 

927 

928# 3.1.1.5.6.1.3 IRemUnknown::RemRelease (Opnum 5) 

929class RemRelease(DCOMCALL): 

930 opnum = 5 

931 structure = ( 

932 ('cInterfaceRefs', USHORT), 

933 ('InterfaceRefs', REMINTERFACEREF_ARRAY), 

934 ) 

935 

936class RemReleaseResponse(DCOMANSWER): 

937 structure = ( 

938 ('ErrorCode', error_status_t), 

939 ) 

940 

941################################################################################ 

942# OPNUMs and their corresponding structures 

943################################################################################ 

944OPNUMS = { 

945} 

946 

947################################################################################ 

948# HELPER FUNCTIONS 

949################################################################################ 

950class DCOMConnection: 

951 """ 

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

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

954 pinging the objects created against the target. 

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

956 """ 

957 PINGTIMER = None 

958 OID_ADD = {} 

959 OID_DEL = {} 

960 OID_SET = {} 

961 PORTMAPS = {} 

962 

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

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

965 self.__target = target 

966 self.__userName = username 

967 self.__password = password 

968 self.__domain = domain 

969 self.__lmhash = lmhash 

970 self.__nthash = nthash 

971 self.__aesKey = aesKey 

972 self.__TGT = TGT 

973 self.__TGS = TGS 

974 self.__authLevel = authLevel 

975 self.__portmap = None 

976 self.__oxidResolver = oxidResolver 

977 self.__doKerberos = doKerberos 

978 self.__kdcHost = kdcHost 

979 self.initConnection() 

980 

981 @classmethod 

982 def addOid(cls, target, oid): 

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

984 DCOMConnection.OID_ADD[target] = set() 

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

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

987 DCOMConnection.OID_SET[target] = {} 

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

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

990 

991 @classmethod 

992 def delOid(cls, target, oid): 

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

994 DCOMConnection.OID_DEL[target] = set() 

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

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

997 DCOMConnection.OID_SET[target] = {} 

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

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

1000 

1001 @classmethod 

1002 def pingServer(cls): 

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

1004 # ToDo: locking for avoiding race conditions 

1005 #print DCOMConnection.PORTMAPS 

1006 #print DCOMConnection.OID_SET 

1007 try: 

1008 for target in DCOMConnection.OID_SET: 

1009 addedOids = set() 

1010 deletedOids = set() 

1011 if target in DCOMConnection.OID_ADD: 

1012 addedOids = DCOMConnection.OID_ADD[target] 

1013 del(DCOMConnection.OID_ADD[target]) 

1014 

1015 if target in DCOMConnection.OID_DEL: 

1016 deletedOids = DCOMConnection.OID_DEL[target] 

1017 del(DCOMConnection.OID_DEL[target]) 

1018 

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

1020 

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

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

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

1024 else: 

1025 setId = 0 

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

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

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

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

1030 else: 

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

1032 except Exception as e: 

1033 # There might be exceptions when sending packets  

1034 # We should try to continue tho. 

1035 LOG.error(str(e)) 

1036 pass 

1037 

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

1039 try: 

1040 DCOMConnection.PINGTIMER.start() 

1041 except Exception as e: 

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

1043 raise e 

1044 

1045 def initTimer(self): 

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

1047 if DCOMConnection.PINGTIMER is None: 

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

1049 try: 

1050 DCOMConnection.PINGTIMER.start() 

1051 except Exception as e: 

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

1053 raise e 

1054 

1055 def initConnection(self): 

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

1057 rpctransport = transport.DCERPCTransportFactory(stringBinding) 

1058 

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

1060 # This method exists only for selected protocol sequences. 

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

1062 self.__aesKey, self.__TGT, self.__TGS) 

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

1064 self.__portmap = rpctransport.get_dce_rpc() 

1065 self.__portmap.set_auth_level(self.__authLevel) 

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

1067 self.__portmap.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) 

1068 self.__portmap.connect() 

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

1070 

1071 def CoCreateInstanceEx(self, clsid, iid): 

1072 scm = IRemoteSCMActivator(self.__portmap) 

1073 iInterface = scm.RemoteCreateInstance(clsid, iid) 

1074 self.initTimer() 

1075 return iInterface 

1076 

1077 def get_dce_rpc(self): 

1078 return DCOMConnection.PORTMAPS[self.__target] 

1079 

1080 def disconnect(self): 

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

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

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

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

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

1086 DCOMConnection.PINGTIMER.cancel() 

1087 DCOMConnection.PINGTIMER.join() 

1088 DCOMConnection.PINGTIMER = None 

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

1090 del(INTERFACE.CONNECTIONS[self.__target][currentThread().getName()]) 

1091 self.__portmap.disconnect() 

1092 #print INTERFACE.CONNECTIONS 

1093 

1094class CLASS_INSTANCE: 

1095 def __init__(self, ORPCthis, stringBinding): 

1096 self.__stringBindings = stringBinding 

1097 self.__ORPCthis = ORPCthis 

1098 self.__authType = RPC_C_AUTHN_WINNT 

1099 self.__authLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY 

1100 def get_ORPCthis(self): 

1101 return self.__ORPCthis 

1102 def get_string_bindings(self): 

1103 return self.__stringBindings 

1104 def get_auth_level(self): 

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

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

1107 return RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 

1108 else: 

1109 return RPC_C_AUTHN_LEVEL_PKT_PRIVACY 

1110 return self.__authLevel 

1111 def set_auth_level(self, level): 

1112 self.__authLevel = level 

1113 def get_auth_type(self): 

1114 return self.__authType 

1115 def set_auth_type(self, authType): 

1116 self.__authType = authType 

1117 

1118 

1119class INTERFACE: 

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

1121 CONNECTIONS = {} 

1122 

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

1124 interfaceInstance=None): 

1125 if interfaceInstance is not None: 

1126 self.__target = interfaceInstance.get_target() 

1127 self.__iPid = interfaceInstance.get_iPid() 

1128 self.__oid = interfaceInstance.get_oid() 

1129 self.__oxid = interfaceInstance.get_oxid() 

1130 self.__cinstance = interfaceInstance.get_cinstance() 

1131 self.__objRef = interfaceInstance.get_objRef() 

1132 self.__ipidRemUnknown = interfaceInstance.get_ipidRemUnknown() 

1133 else: 

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

1135 raise Exception('No target') 

1136 self.__target = target 

1137 self.__iPid = iPid 

1138 self.__oid = oid 

1139 self.__oxid = oxid 

1140 self.__cinstance = cinstance 

1141 self.__objRef = objRef 

1142 self.__ipidRemUnknown = ipidRemUnknown 

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

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

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

1146 INTERFACE.CONNECTIONS[self.__target][currentThread().getName()] = {} 

1147 

1148 if objRef is not None: 

1149 self.process_interface(objRef) 

1150 

1151 def process_interface(self, data): 

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

1153 objRef = None 

1154 if objRefType == FLAGS_OBJREF_CUSTOM: 

1155 objRef = OBJREF_CUSTOM(data) 

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

1157 objRef = OBJREF_HANDLER(data) 

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

1159 objRef = OBJREF_STANDARD(data) 

1160 elif objRefType == FLAGS_OBJREF_EXTENDED: 

1161 objRef = OBJREF_EXTENDED(data) 

1162 else: 

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

1164 

1165 if objRefType != FLAGS_OBJREF_CUSTOM: 

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

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

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

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

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

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

1172 objRef.dump() 

1173 raise Exception('OXID is None') 

1174 

1175 def get_oxid(self): 

1176 return self.__oxid 

1177 

1178 def set_oxid(self, oxid): 

1179 self.__oxid = oxid 

1180 

1181 def get_oid(self): 

1182 return self.__oid 

1183 

1184 def set_oid(self, oid): 

1185 self.__oid = oid 

1186 

1187 def get_target(self): 

1188 return self.__target 

1189 

1190 def get_iPid(self): 

1191 return self.__iPid 

1192 

1193 def set_iPid(self, iPid): 

1194 self.__iPid = iPid 

1195 

1196 def get_objRef(self): 

1197 return self.__objRef 

1198 

1199 def set_objRef(self, objRef): 

1200 self.__objRef = objRef 

1201 

1202 def get_ipidRemUnknown(self): 

1203 return self.__ipidRemUnknown 

1204 

1205 def get_dce_rpc(self): 

1206 return INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['dce'] 

1207 

1208 def get_cinstance(self): 

1209 return self.__cinstance 

1210 

1211 def set_cinstance(self, cinstance): 

1212 self.__cinstance = cinstance 

1213 

1214 def is_fdqn(self): 

1215 # I will assume the following 

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

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

1218 # an FQDN with ':' 

1219 # Is it isn't both, then it is a FDQN 

1220 try: 

1221 socket.inet_aton(self.__target) 

1222 except: 

1223 # Not an IPv4 

1224 try: 

1225 self.__target.index(':') 

1226 except: 

1227 # Not an IPv6, it's a FDQN 

1228 return True 

1229 return False 

1230 

1231 

1232 def connect(self, iid = None): 

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

1234 if currentThread().getName() in INTERFACE.CONNECTIONS[self.__target] and \ 

1235 (self.__oxid in INTERFACE.CONNECTIONS[self.__target][currentThread().getName()]) is True: 

1236 dce = INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['dce'] 

1237 currentBinding = INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['currentBinding'] 

1238 if currentBinding == iid: 

1239 # We don't need to alter_ctx 

1240 pass 

1241 else: 

1242 newDce = dce.alter_ctx(iid) 

1243 INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['dce'] = newDce 

1244 INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['currentBinding'] = iid 

1245 else: 

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

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

1248 stringBinding = None 

1249 isTargetFDQN = self.is_fdqn() 

1250 LOG.debug('Target system is %s and isFDQN is %s' % (self.get_target(), isTargetFDQN)) 

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

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

1253 # 1) it's an IPv4 address 

1254 # 2) it's an IPv6 address 

1255 # 3) it's a NetBios Name 

1256 # we should handle all this cases accordingly 

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

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

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

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

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

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

1263 bindingPort = '[' + bindingPort 

1264 else: 

1265 binding = strBinding['aNetworkAddr'] 

1266 bindingPort = '' 

1267 

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

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

1270 break 

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

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

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

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

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

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

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

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

1279 break 

1280 

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

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

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

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

1285 

1286 dcomInterface = transport.DCERPCTransportFactory(stringBinding) 

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

1288 # This method exists only for selected protocol sequences. 

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

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

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

1292 dcomInterface.set_connect_timeout(300) 

1293 dce = dcomInterface.get_dce_rpc() 

1294 

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

1296 raise Exception('IID is None') 

1297 else: 

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

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

1300 

1301 dce.connect() 

1302 

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

1304 raise Exception('IID is None') 

1305 else: 

1306 dce.bind(iid) 

1307 

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

1309 #import traceback 

1310 #traceback.print_stack() 

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

1312 

1313 INTERFACE.CONNECTIONS[self.__target][currentThread().getName()] = {} 

1314 INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid] = {} 

1315 INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['dce'] = dce 

1316 INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['currentBinding'] = iid 

1317 else: 

1318 # No connection created 

1319 raise Exception('No connection created') 

1320 

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

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

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

1324 self.connect(iid) 

1325 dce = self.get_dce_rpc() 

1326 try: 

1327 resp = dce.request(req, uuid) 

1328 except Exception as e: 

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

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

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

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

1333 raise DCERPCException(msg) 

1334 else: 

1335 raise 

1336 return resp 

1337 

1338 def disconnect(self): 

1339 return INTERFACE.CONNECTIONS[self.__target][currentThread().getName()][self.__oxid]['dce'].disconnect() 

1340 

1341 

1342# 3.1.1.5.6.1 IRemUnknown Methods 

1343class IRemUnknown(INTERFACE): 

1344 def __init__(self, interface): 

1345 self._iid = IID_IRemUnknown 

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

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

1348 INTERFACE.__init__(self, interfaceInstance=interface) 

1349 self.set_oxid(interface.get_oxid()) 

1350 

1351 def RemQueryInterface(self, cRefs, iids): 

1352 # For now, it only supports a single IID 

1353 request = RemQueryInterface() 

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

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

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

1357 request['cRefs'] = cRefs 

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

1359 for iid in iids: 

1360 _iid = IID() 

1361 _iid['Data'] = iid 

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

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

1364 #resp.dump() 

1365 

1366 return IRemUnknown2( 

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

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

1369 target=self.get_target())) 

1370 

1371 def RemAddRef(self): 

1372 request = RemAddRef() 

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

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

1375 request['cInterfaceRefs'] = 1 

1376 element = REMINTERFACEREF() 

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

1378 element['cPublicRefs'] = 1 

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

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

1381 return resp 

1382 

1383 def RemRelease(self): 

1384 request = RemRelease() 

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

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

1387 request['cInterfaceRefs'] = 1 

1388 element = REMINTERFACEREF() 

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

1390 element['cPublicRefs'] = 1 

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

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

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

1394 return resp 

1395 

1396# 3.1.1.5.7 IRemUnknown2 Interface 

1397class IRemUnknown2(IRemUnknown): 

1398 def __init__(self, interface): 

1399 IRemUnknown.__init__(self, interface) 

1400 self._iid = IID_IRemUnknown2 

1401 

1402# 3.1.2.5.1 IObjectExporter Methods 

1403class IObjectExporter: 

1404 def __init__(self, dce): 

1405 self.__portmap = dce 

1406 

1407 # 3.1.2.5.1.1 IObjectExporter::ResolveOxid (Opnum 0) 

1408 def ResolveOxid(self, pOxid, arRequestedProtseqs): 

1409 self.__portmap.connect() 

1410 self.__portmap.bind(IID_IObjectExporter) 

1411 request = ResolveOxid() 

1412 request['pOxid'] = pOxid 

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

1414 for protSeq in arRequestedProtseqs: 

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

1416 resp = self.__portmap.request(request) 

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

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

1419 

1420 done = False 

1421 stringBindings = list() 

1422 while not done: 

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

1424 done = True 

1425 else: 

1426 binding = STRINGBINDING(strBindings) 

1427 stringBindings.append(binding) 

1428 strBindings = strBindings[len(binding):] 

1429 

1430 return stringBindings 

1431 

1432 # 3.1.2.5.1.2 IObjectExporter::SimplePing (Opnum 1) 

1433 def SimplePing(self, setId): 

1434 self.__portmap.connect() 

1435 self.__portmap.bind(IID_IObjectExporter) 

1436 request = SimplePing() 

1437 request['pSetId'] = setId 

1438 resp = self.__portmap.request(request) 

1439 return resp 

1440 

1441 # 3.1.2.5.1.3 IObjectExporter::ComplexPing (Opnum 2) 

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

1443 self.__portmap.connect() 

1444 #self.__portmap.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) 

1445 self.__portmap.bind(IID_IObjectExporter) 

1446 request = ComplexPing() 

1447 request['pSetId'] = setId 

1448 request['SequenceNum'] = setId 

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

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

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

1452 for oid in addToSet: 

1453 oidn = OID() 

1454 oidn['Data'] = oid 

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

1456 else: 

1457 request['AddToSet'] = NULL 

1458 

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

1460 for oid in delFromSet: 

1461 oidn = OID() 

1462 oidn['Data'] = oid 

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

1464 else: 

1465 request['DelFromSet'] = NULL 

1466 resp = self.__portmap.request(request) 

1467 return resp 

1468 

1469 # 3.1.2.5.1.4 IObjectExporter::ServerAlive (Opnum 3) 

1470 def ServerAlive(self): 

1471 self.__portmap.connect() 

1472 self.__portmap.bind(IID_IObjectExporter) 

1473 request = ServerAlive() 

1474 resp = self.__portmap.request(request) 

1475 return resp 

1476 

1477 # 3.1.2.5.1.5 IObjectExporter::ResolveOxid2 (Opnum 4) 

1478 def ResolveOxid2(self,pOxid, arRequestedProtseqs): 

1479 self.__portmap.connect() 

1480 self.__portmap.bind(IID_IObjectExporter) 

1481 request = ResolveOxid2() 

1482 request['pOxid'] = pOxid 

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

1484 for protSeq in arRequestedProtseqs: 

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

1486 resp = self.__portmap.request(request) 

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

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

1489 

1490 done = False 

1491 stringBindings = list() 

1492 while not done: 

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

1494 done = True 

1495 else: 

1496 binding = STRINGBINDING(strBindings) 

1497 stringBindings.append(binding) 

1498 strBindings = strBindings[len(binding):] 

1499 

1500 return stringBindings 

1501 

1502 # 3.1.2.5.1.6 IObjectExporter::ServerAlive2 (Opnum 5) 

1503 def ServerAlive2(self): 

1504 self.__portmap.connect() 

1505 self.__portmap.bind(IID_IObjectExporter) 

1506 request = ServerAlive2() 

1507 resp = self.__portmap.request(request) 

1508 

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

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

1511 

1512 done = False 

1513 stringBindings = list() 

1514 while not done: 

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

1516 done = True 

1517 else: 

1518 binding = STRINGBINDING(strBindings) 

1519 stringBindings.append(binding) 

1520 strBindings = strBindings[len(binding):] 

1521 

1522 return stringBindings 

1523 

1524# 3.1.2.5.2.1 IActivation Methods 

1525class IActivation: 

1526 def __init__(self, dce): 

1527 self.__portmap = dce 

1528 

1529 # 3.1.2.5.2.3.1 IActivation:: RemoteActivation (Opnum 0) 

1530 def RemoteActivation(self, clsId, iid): 

1531 # Only supports one interface at a time 

1532 self.__portmap.bind(IID_IActivation) 

1533 ORPCthis = ORPCTHIS() 

1534 ORPCthis['cid'] = generate() 

1535 ORPCthis['extensions'] = NULL 

1536 ORPCthis['flags'] = 1 

1537 

1538 request = RemoteActivation() 

1539 request['Clsid'] = clsId 

1540 request['pwszObjectName'] = NULL 

1541 request['pObjectStorage'] = NULL 

1542 request['ClientImpLevel'] = 2 

1543 request['Mode'] = 0 

1544 request['Interfaces'] = 1 

1545 

1546 _iid = IID() 

1547 _iid['Data'] = iid 

1548 

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

1550 request['cRequestedProtseqs'] = 1 

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

1552 

1553 resp = self.__portmap.request(request) 

1554 

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

1556 

1557 ipidRemUnknown = resp['pipidRemUnknown'] 

1558 

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

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

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

1562 

1563 done = False 

1564 stringBindings = list() 

1565 while not done: 

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

1567 done = True 

1568 else: 

1569 binding = STRINGBINDING(strBindings) 

1570 stringBindings.append(binding) 

1571 strBindings = strBindings[len(binding):] 

1572 

1573 done = False 

1574 while not done: 

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

1576 done = True 

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

1578 done = True 

1579 else: 

1580 secBinding = SECURITYBINDING(securityBindings) 

1581 securityBindings = securityBindings[len(secBinding):] 

1582 

1583 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings) 

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

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

1586 

1587 

1588# 3.1.2.5.2.2 IRemoteSCMActivator Methods 

1589class IRemoteSCMActivator: 

1590 def __init__(self, dce): 

1591 self.__portmap = dce 

1592 

1593 def RemoteGetClassObject(self, clsId, iid): 

1594 # iid should be IID_IClassFactory 

1595 self.__portmap.bind(IID_IRemoteSCMActivator) 

1596 ORPCthis = ORPCTHIS() 

1597 ORPCthis['cid'] = generate() 

1598 ORPCthis['extensions'] = NULL 

1599 ORPCthis['flags'] = 1 

1600 

1601 request = RemoteGetClassObject() 

1602 request['ORPCthis'] = ORPCthis 

1603 activationBLOB = ACTIVATION_BLOB() 

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

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

1606 clsid = CLSID() 

1607 clsid['Data'] = CLSID_InstantiationInfo 

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

1609 clsid = CLSID() 

1610 clsid['Data'] = CLSID_ActivationContextInfo 

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

1612 clsid = CLSID() 

1613 clsid['Data'] = CLSID_ServerLocationInfo 

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

1615 clsid = CLSID() 

1616 clsid['Data'] = CLSID_ScmRequestInfo 

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

1618 

1619 properties = b'' 

1620 # InstantiationInfo 

1621 instantiationInfo = InstantiationInfoData() 

1622 instantiationInfo['classId'] = clsId 

1623 instantiationInfo['cIID'] = 1 

1624 

1625 _iid = IID() 

1626 _iid['Data'] = iid 

1627 

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

1629 

1630 dword = DWORD() 

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

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

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

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

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

1636 

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

1638 

1639 # ActivationContextInfoData 

1640 activationInfo = ActivationContextInfoData() 

1641 activationInfo['pIFDClientCtx'] = NULL 

1642 activationInfo['pIFDPrototypeCtx'] = NULL 

1643 

1644 dword = DWORD() 

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

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

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

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

1649 

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

1651 

1652 # ServerLocation 

1653 locationInfo = LocationInfoData() 

1654 locationInfo['machineName'] = NULL 

1655 

1656 dword = DWORD() 

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

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

1659 

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

1661 

1662 # ScmRequestInfo 

1663 scmInfo = ScmRequestInfoData() 

1664 scmInfo['pdwReserved'] = NULL 

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

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

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

1668 

1669 dword = DWORD() 

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

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

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

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

1674 

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

1676 

1677 activationBLOB['Property'] = properties 

1678 

1679 

1680 objrefcustom = OBJREF_CUSTOM() 

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

1682 objrefcustom['clsid'] = CLSID_ActivationPropertiesIn 

1683 

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

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

1686 

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

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

1689 resp = self.__portmap.request(request) 

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

1691 

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

1693 objRef = None 

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

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

1696 elif objRefType == FLAGS_OBJREF_HANDLER: 

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

1698 elif objRefType == FLAGS_OBJREF_STANDARD: 

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

1700 elif objRefType == FLAGS_OBJREF_EXTENDED: 

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

1702 else: 

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

1704 

1705 

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

1707 

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

1709 scmReply = activationBlob['Property'][ 

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

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

1712 

1713 scmr = ScmReplyInfoData() 

1714 size = scmr.fromString(scmReply) 

1715 # Processing the scmReply 

1716 scmr.fromStringReferents(scmReply[size:]) 

1717 ipidRemUnknown = scmr['remoteReply']['ipidRemUnknown'] 

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

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

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

1721 

1722 done = False 

1723 stringBindings = list() 

1724 while not done: 

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

1726 done = True 

1727 else: 

1728 binding = STRINGBINDING(strBindings) 

1729 stringBindings.append(binding) 

1730 strBindings = strBindings[len(binding):] 

1731 

1732 done = False 

1733 while not done: 

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

1735 done = True 

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

1737 done = True 

1738 else: 

1739 secBinding = SECURITYBINDING(securityBindings) 

1740 securityBindings = securityBindings[len(secBinding):] 

1741 

1742 # Processing the Properties Output 

1743 propsOut = PropsOutInfo() 

1744 size = propsOut.fromString(propOutput) 

1745 propsOut.fromStringReferents(propOutput[size:]) 

1746 

1747 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings) 

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

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

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

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

1752 

1753 def RemoteCreateInstance(self, clsId, iid): 

1754 # Only supports one interface at a time 

1755 self.__portmap.bind(IID_IRemoteSCMActivator) 

1756 

1757 ORPCthis = ORPCTHIS() 

1758 ORPCthis['cid'] = generate() 

1759 ORPCthis['extensions'] = NULL 

1760 ORPCthis['flags'] = 1 

1761 

1762 request = RemoteCreateInstance() 

1763 request['ORPCthis'] = ORPCthis 

1764 request['pUnkOuter'] = NULL 

1765 

1766 activationBLOB = ACTIVATION_BLOB() 

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

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

1769 clsid = CLSID() 

1770 clsid['Data'] = CLSID_InstantiationInfo 

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

1772 clsid = CLSID() 

1773 clsid['Data'] = CLSID_ActivationContextInfo 

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

1775 clsid = CLSID() 

1776 clsid['Data'] = CLSID_ServerLocationInfo 

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

1778 clsid = CLSID() 

1779 clsid['Data'] = CLSID_ScmRequestInfo 

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

1781 

1782 properties = b'' 

1783 # InstantiationInfo 

1784 instantiationInfo = InstantiationInfoData() 

1785 instantiationInfo['classId'] = clsId 

1786 instantiationInfo['cIID'] = 1 

1787 

1788 _iid = IID() 

1789 _iid['Data'] = iid 

1790 

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

1792 

1793 dword = DWORD() 

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

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

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

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

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

1799 

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

1801 

1802 # ActivationContextInfoData 

1803 activationInfo = ActivationContextInfoData() 

1804 activationInfo['pIFDClientCtx'] = NULL 

1805 activationInfo['pIFDPrototypeCtx'] = NULL 

1806 

1807 dword = DWORD() 

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

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

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

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

1812 

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

1814 

1815 # ServerLocation 

1816 locationInfo = LocationInfoData() 

1817 locationInfo['machineName'] = NULL 

1818 

1819 dword = DWORD() 

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

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

1822 

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

1824 

1825 # ScmRequestInfo 

1826 scmInfo = ScmRequestInfoData() 

1827 scmInfo['pdwReserved'] = NULL 

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

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

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

1831 

1832 dword = DWORD() 

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

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

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

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

1837 

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

1839 

1840 activationBLOB['Property'] = properties 

1841 

1842 

1843 objrefcustom = OBJREF_CUSTOM() 

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

1845 objrefcustom['clsid'] = CLSID_ActivationPropertiesIn 

1846 

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

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

1849 

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

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

1852 resp = self.__portmap.request(request) 

1853 

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

1855 

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

1857 objRef = None 

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

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

1860 elif objRefType == FLAGS_OBJREF_HANDLER: 

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

1862 elif objRefType == FLAGS_OBJREF_STANDARD: 

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

1864 elif objRefType == FLAGS_OBJREF_EXTENDED: 

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

1866 else: 

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

1868 

1869 

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

1871 

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

1873 scmReply = activationBlob['Property'][ 

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

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

1876 

1877 scmr = ScmReplyInfoData() 

1878 size = scmr.fromString(scmReply) 

1879 # Processing the scmReply 

1880 scmr.fromStringReferents(scmReply[size:]) 

1881 ipidRemUnknown = scmr['remoteReply']['ipidRemUnknown'] 

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

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

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

1885 

1886 done = False 

1887 stringBindings = list() 

1888 while not done: 

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

1890 done = True 

1891 else: 

1892 binding = STRINGBINDING(strBindings) 

1893 stringBindings.append(binding) 

1894 strBindings = strBindings[len(binding):] 

1895 

1896 done = False 

1897 while not done: 

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

1899 done = True 

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

1901 done = True 

1902 else: 

1903 secBinding = SECURITYBINDING(securityBindings) 

1904 securityBindings = securityBindings[len(secBinding):] 

1905 

1906 # Processing the Properties Output 

1907 propsOut = PropsOutInfo() 

1908 size = propsOut.fromString(propOutput) 

1909 propsOut.fromStringReferents(propOutput[size:]) 

1910 

1911 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings) 

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

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

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

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