Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/dcomrt.py: 82%

# Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/dcomrt.py : 82%

## 1036 statements

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#

28 from __future__ import division

29 from __future__ import print_function

30 import socket

31 from struct import pack

32 from threading import Timer, currentThread

33

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

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

36 UUID, WIDESTR, NULL

37 from impacket import hresult_errors, LOG

38 from impacket.uuid import string_to_bin, uuidtup_to_bin, generate

39 from 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

41 from impacket.dcerpc.v5 import transport

42

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

68

69 class 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

85 OID = ULONGLONG

86

87 class OID_ARRAY(NDRUniConformantArray):

88 item = OID

89

90 class POID_ARRAY(NDRPOINTER):

91 referent = (

92 ('Data', OID_ARRAY),

93 )

94

95# 2.2.2 SETID

96 SETID = ULONGLONG

97

98# 2.2.4 error_status_t

99 error_status_t = ULONG

100

101# 2.2.6 CID

102 CID = GUID

103

104# 2.2.7 CLSID

105 CLSID = GUID

106

107# 2.2.8 IID

108 IID = GUID

109 PIID = PGUID

110

111# 2.2.9 IPID

112 IPID = GUID

113

114# 2.2.10 OXID

115 OXID = ULONGLONG

116

117# 2.2.18 OBJREF

118 FLAGS_OBJREF_STANDARD = 0x00000001

119 FLAGS_OBJREF_HANDLER = 0x00000002

120 FLAGS_OBJREF_CUSTOM = 0x00000004

121 FLAGS_OBJREF_EXTENDED = 0x00000008

122

123# 2.2.18.1 STDOBJREF

124 SORF_NOPING = 0x00001000

125

126# 2.2.20 Context

127 CTXMSHLFLAGS_BYVAL = 0x00000002

128

129# 2.2.20.1 PROPMARSHALHEADER

130 CPFLAG_PROPAGATE = 0x00000001

131 CPFLAG_EXPOSE = 0x00000002

132 CPFLAG_ENVOY = 0x00000004

133

134# 2.2.22.2.1 InstantiationInfoData

135 ACTVFLAGS_DISABLE_AAA = 0x00000002

136 ACTVFLAGS_ACTIVATE_32_BIT_SERVER = 0x00000004

137 ACTVFLAGS_ACTIVATE_64_BIT_SERVER = 0x00000008

138 ACTVFLAGS_NO_FAILURE_LOG = 0x00000020

139

140# 2.2.22.2.2 SpecialPropertiesData

141 SPD_FLAG_USE_CONSOLE_SESSION = 0x00000001

142

143# 2.2.28.1 IDL Range Constants

144 MAX_REQUESTED_INTERFACES = 0x8000

145 MAX_REQUESTED_PROTSEQS = 0x8000

146 MIN_ACTPROP_LIMIT = 1

147 MAX_ACTPROP_LIMIT = 10

148

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

150# STRUCTURES

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

152 class 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

166 class 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

189 class 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.

197 class BYTE_ARRAY(NDRUniConformantArray):

198 item = 'c'

199

200 class 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.

209 class PORPC_EXTENT(NDRPOINTER):

210 referent = (

211 ('Data', ORPC_EXTENT),

212 )

213

214 class EXTENT_ARRAY(NDRUniConformantArray):

215 item = PORPC_EXTENT

216

217 class PEXTENT_ARRAY(NDRPOINTER):

218 referent = (

219 ('Data', EXTENT_ARRAY),

220 )

221

222 class ORPC_EXTENT_ARRAY(NDRSTRUCT):

223 structure = (

224 ('size',ULONG),

225 ('reserved',ULONG),

226 ('extent',PEXTENT_ARRAY),

227 )

228

229 class PORPC_EXTENT_ARRAY(NDRPOINTER):

230 referent = (

231 ('Data', ORPC_EXTENT_ARRAY),

232 )

233

234# 2.2.13.3 ORPCTHIS

235 class 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

245 class ORPCTHAT(NDRSTRUCT):

246 structure = (

247 ('flags',ULONG),

248 ('extensions',PORPC_EXTENT_ARRAY),

249 )

250

251# 2.2.14 MInterfacePointer

252 class MInterfacePointer(NDRSTRUCT):

253 structure = (

254 ('ulCntData',ULONG),

255 ('abData',BYTE_ARRAY),

256 )

257

258# 2.2.15 PMInterfacePointerInternal

259 class PMInterfacePointerInternal(NDRPOINTER):

260 referent = (

261 ('Data', MInterfacePointer),

262 )

263

264# 2.2.16 PMInterfacePointer

265 class PMInterfacePointer(NDRPOINTER):

266 referent = (

267 ('Data', MInterfacePointer),

268 )

269

270 class PPMInterfacePointer(NDRPOINTER):

271 referent = (

272 ('Data', PMInterfacePointer),

273 )

274

275# 2.2.18 OBJREF

276 class 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

288 class 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

298 class 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

309 class 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

321 class 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

334 class DATAELEMENT(NDRSTRUCT):

335 structure = (

336 ('dataID',GUID),

337 ('cbSize',ULONG),

338 ('cbRounded',ULONG),

339 ('Data',':'),

340 )

341

342 class 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

352 class 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

370 class USHORT_ARRAY(NDRUniConformantArray):

371 item = '<H'

372

373 class PUSHORT_ARRAY(NDRPOINTER):

374 referent = (

375 ('Data', USHORT_ARRAY),

376 )

377

378 class DUALSTRINGARRAY(NDRSTRUCT):

379 structure = (

380 ('wNumEntries',USHORT),

381 ('wSecurityOffset',USHORT),

382 ('aStringArray',USHORT_ARRAY),

383 )

384

385 class PDUALSTRINGARRAY(NDRPOINTER):

386 referent = (

387 ('Data',DUALSTRINGARRAY),

388 )

389

390# 2.2.19.3 STRINGBINDING

391 class STRINGBINDING(NDRSTRUCT):

392 structure = (

393 ('wTowerId',USHORT),

394 ('aNetworkAddr',WIDESTR),

395 )

396

397# 2.2.19.4 SECURITYBINDING

398 class SECURITYBINDING(NDRSTRUCT):

399 structure = (

400 ('wAuthnSvc',USHORT),

401 ('Reserved',USHORT),

402 ('aPrincName',WIDESTR),

403 )

404

405# 2.2.20.1 PROPMARSHALHEADER

406 class PROPMARSHALHEADER(NDRSTRUCT):

407 structure = (

408 ('clsid',CLSID),

409 ('policyId',GUID),

410 ('flags',ULONG),

411 ('cb',ULONG),

412 ('ctxProperty',':'),

413 )

414

415 class PROPMARSHALHEADER_ARRAY(NDRUniConformantArray):

416 item = PROPMARSHALHEADER

417

418# 2.2.20 Context

419 class 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

435 class 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

444 class 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

458 class EntryHeader(NDRSTRUCT):

459 structure = (

460 ('Signature',ULONG),

461 ('cbEHBuffer',ULONG),

462 ('cbSize',ULONG),

463 ('reserved',ULONG),

464 ('policyID',GUID),

465 )

466

467 class EntryHeader_ARRAY(NDRUniConformantArray):

468 item = EntryHeader

469

470# 2.2.21.4 Context ORPC Extension

471 class 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

490 class CLSID_ARRAY(NDRUniConformantArray):

491 item = CLSID

492

493 class PCLSID_ARRAY(NDRPOINTER):

494 referent = (

495 ('Data', CLSID_ARRAY),

496 )

497

498 class DWORD_ARRAY(NDRUniConformantArray):

499 item = DWORD

500

501 class PDWORD_ARRAY(NDRPOINTER):

502 referent = (

503 ('Data', DWORD_ARRAY),

504 )

505

506 class 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

526 class 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

540 class IID_ARRAY(NDRUniConformantArray):

541 item = IID

542

543 class PIID_ARRAY(NDRPOINTER):

544 referent = (

545 ('Data', IID_ARRAY),

546 )

547

548 class 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

562 class 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

586 class 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

595 class customREMOTE_REQUEST_SCM_INFO(NDRSTRUCT):

596 structure = (

597 ('ClientImpLevel',DWORD),

598 ('cRequestedProtseqs',USHORT),

599 ('pRequestedProtseqs',PUSHORT_ARRAY),

600 )

601

602 class PcustomREMOTE_REQUEST_SCM_INFO(NDRPOINTER):

603 referent = (

604 ('Data', customREMOTE_REQUEST_SCM_INFO),

605 )

606

607# 2.2.22.2.4 ScmRequestInfoData

608 class ScmRequestInfoData(TypeSerialization1):

609 structure = (

610 ('pdwReserved',LPLONG),

611 ('remoteRequest',PcustomREMOTE_REQUEST_SCM_INFO),

612 )

613

614# 2.2.22.2.5 ActivationContextInfoData

615 class 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

626 class 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

635 class COSERVERINFO(NDRSTRUCT):

636 structure = (

637 ('dwReserved1',DWORD),

638 ('pwszName',LPWSTR),

639 ('pdwReserved',LPLONG),

640 ('dwReserved2',DWORD),

641 )

642

643 class PCOSERVERINFO(NDRPOINTER):

644 referent = (

645 ('Data', COSERVERINFO),

646 )

647

648# 2.2.22.2.7 SecurityInfoData

649 class 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

657 class customREMOTE_REPLY_SCM_INFO(NDRSTRUCT):

658 structure = (

659 ('Oxid',OXID),

660 ('pdsaOxidBindings',PDUALSTRINGARRAY),

661 ('ipidRemUnknown',IPID),

662 ('authnHint',DWORD),

663 ('serverVersion',COMVERSION),

664 )

665

666 class PcustomREMOTE_REPLY_SCM_INFO(NDRPOINTER):

667 referent = (

668 ('Data', customREMOTE_REPLY_SCM_INFO),

669 )

670

671# 2.2.22.2.8 ScmReplyInfoData

672 class ScmReplyInfoData(TypeSerialization1):

673 structure = (

674 ('pdwReserved',DWORD),

675 ('remoteReply',PcustomREMOTE_REPLY_SCM_INFO),

676 )

677

678# 2.2.22.2.9 PropsOutInfo

679 class HRESULT_ARRAY(NDRUniConformantArray):

680 item = HRESULT

681

682 class PHRESULT_ARRAY(NDRPOINTER):

683 referent = (

684 ('Data', HRESULT_ARRAY),

685 )

686

687 class MInterfacePointer_ARRAY(NDRUniConformantArray):

688 item = MInterfacePointer

689

690 class PMInterfacePointer_ARRAY(NDRUniConformantArray):

691 item = PMInterfacePointer

692

693 class PPMInterfacePointer_ARRAY(NDRPOINTER):

694 referent = (

695 ('Data', PMInterfacePointer_ARRAY),

696 )

697

698 class 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

707 class REMINTERFACEREF(NDRSTRUCT):

708 structure = (

709 ('ipid',IPID),

710 ('cPublicRefs',LONG),

711 ('cPrivateRefs',LONG),

712 )

713

714 class REMINTERFACEREF_ARRAY(NDRUniConformantArray):

715 item = REMINTERFACEREF

716

717# 2.2.24 REMQIRESULT

718 class REMQIRESULT(NDRSTRUCT):

719 structure = (

720 ('hResult',HRESULT),

721 ('std',STDOBJREF),

722 )

723

724# 2.2.25 PREMQIRESULT

725 class PREMQIRESULT(NDRPOINTER):

726 referent = (

727 ('Data', REMQIRESULT),

728 )

729

730# 2.2.26 REFIPID

731 REFIPID = GUID

732

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

734# RPC CALLS

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

736 class DCOMCALL(NDRCALL):

737 commonHdr = (

738 ('ORPCthis', ORPCTHIS),

739 )

740

741 class DCOMANSWER(NDRCALL):

742 commonHdr = (

743 ('ORPCthat', ORPCTHAT),

744 )

745

746# 3.1.2.5.1.1 IObjectExporter::ResolveOxid (Opnum 0)

747 class ResolveOxid(NDRCALL):

748 opnum = 0

749 structure = (

750 ('pOxid', OXID),

751 ('cRequestedProtseqs', USHORT),

752 ('arRequestedProtseqs', USHORT_ARRAY),

753 )

754

755 class 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)

764 class SimplePing(NDRCALL):

765 opnum = 1

766 structure = (

767 ('pSetId', SETID),

768 )

769

770 class SimplePingResponse(NDRCALL):

771 structure = (

772 ('ErrorCode', error_status_t),

773 )

774

775# 3.1.2.5.1.3 IObjectExporter::ComplexPing (Opnum 2)

776 class 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

787 class 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)

795 class ServerAlive(NDRCALL):

796 opnum = 3

797 structure = (

798 )

799

800 class ServerAliveResponse(NDRCALL):

801 structure = (

802 ('ErrorCode', error_status_t),

803 )

804

805# 3.1.2.5.1.5 IObjectExporter::ResolveOxid2 (Opnum 4)

806 class ResolveOxid2(NDRCALL):

807 opnum = 4

808 structure = (

809 ('pOxid', OXID),

810 ('cRequestedProtseqs', USHORT),

811 ('arRequestedProtseqs', USHORT_ARRAY),

812 )

813

814 class 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)

824 class ServerAlive2(NDRCALL):

825 opnum = 5

826 structure = (

827 )

828

829 class 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)

838 class 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

853 class 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)

868 class RemoteGetClassObject(NDRCALL):

869 opnum = 3

870 structure = (

871 ('ORPCthis', ORPCTHIS),

872 ('pActProperties', PMInterfacePointer),

873 )

874

875 class 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)

883 class RemoteCreateInstance(NDRCALL):

884 opnum = 4

885 structure = (

886 ('ORPCthis', ORPCTHIS),

887 ('pUnkOuter', PMInterfacePointer),

888 ('pActProperties', PMInterfacePointer),

889 )

890

891 class 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)

899 class RemQueryInterface(DCOMCALL):

900 opnum = 3

901 structure = (

902 ('ripid', REFIPID),

903 ('cRefs', ULONG),

904 ('cIids', USHORT),

905 ('iids', IID_ARRAY),

906 )

907

908 class 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 )

915 class RemAddRef(DCOMCALL):

916 opnum = 4

917 structure = (

918 ('cInterfaceRefs', USHORT),

919 ('InterfaceRefs', REMINTERFACEREF_ARRAY),

920 )

921

922 class 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)

929 class RemRelease(DCOMCALL):

930 opnum = 5

931 structure = (

932 ('cInterfaceRefs', USHORT),

933 ('InterfaceRefs', REMINTERFACEREF_ARRAY),

934 )

935

936 class RemReleaseResponse(DCOMANSWER):

937 structure = (

938 ('ErrorCode', error_status_t),

939 )

940

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

942# OPNUMs and their corresponding structures

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

944 OPNUMS = {

945}

946

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

948# HELPER FUNCTIONS

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

950 class 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

1094 class 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

1119 class 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

1343 class 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

1397 class 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

1403 class 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

1525 class 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

1589 class 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()))