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# Impacket - Collection of Python classes for working with network protocols.

2#

3# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.

4#

5# This software is provided under a slightly modified version

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

7# for more information.

8#

9# Description:

10# [MS-DCOM] Interface implementation

11#

12# Best way to learn how to use these calls is to grab the protocol standard

13# so you understand what the call does, and then read the test case located

14# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC

15#

16# Some calls have helper functions, which makes it even easier to use.

17# They are located at the end of this file.

18# Helper functions start with "h"<name of the call>.

19# There are test cases for them too.

20#

21# Author:

22# Alberto Solino (@agsolino)

23#

24# ToDo:

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

26# for each call, making it slower.

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

28# not used, returning RPC_E_DISCONNECTED

29#

30

31 from __future__ import division

32 from __future__ import print_function

33 import socket

34 from struct import pack

35 from threading import Timer, current_thread

36

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

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

39 UUID, WIDESTR, NULL

40 from impacket import hresult_errors, LOG

41 from impacket.uuid import string_to_bin, uuidtup_to_bin, generate

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

43 RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_WINNT, DCERPCException

44 from impacket.dcerpc.v5 import transport

45

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

71

72 class DCERPCSessionError(DCERPCException):

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

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

75

76 def __str__( self ):

77 if self.error_code in hresult_errors.ERROR_MESSAGES:

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

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

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

81 else:

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

83

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

85# CONSTANTS

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

87# 2.2.1 OID

88 OID = ULONGLONG

89

90 class OID_ARRAY(NDRUniConformantArray):

91 item = OID

92

93 class POID_ARRAY(NDRPOINTER):

94 referent = (

95 ('Data', OID_ARRAY),

96 )

97

98# 2.2.2 SETID

99 SETID = ULONGLONG

100

101# 2.2.4 error_status_t

102 error_status_t = ULONG

103

104# 2.2.6 CID

105 CID = GUID

106

107# 2.2.7 CLSID

108 CLSID = GUID

109

110# 2.2.8 IID

111 IID = GUID

112 PIID = PGUID

113

114# 2.2.9 IPID

115 IPID = GUID

116

117# 2.2.10 OXID

118 OXID = ULONGLONG

119

120# 2.2.18 OBJREF

121 FLAGS_OBJREF_STANDARD = 0x00000001

122 FLAGS_OBJREF_HANDLER = 0x00000002

123 FLAGS_OBJREF_CUSTOM = 0x00000004

124 FLAGS_OBJREF_EXTENDED = 0x00000008

125

126# 2.2.18.1 STDOBJREF

127 SORF_NOPING = 0x00001000

128

129# 2.2.20 Context

130 CTXMSHLFLAGS_BYVAL = 0x00000002

131

132# 2.2.20.1 PROPMARSHALHEADER

133 CPFLAG_PROPAGATE = 0x00000001

134 CPFLAG_EXPOSE = 0x00000002

135 CPFLAG_ENVOY = 0x00000004

136

137# 2.2.22.2.1 InstantiationInfoData

138 ACTVFLAGS_DISABLE_AAA = 0x00000002

139 ACTVFLAGS_ACTIVATE_32_BIT_SERVER = 0x00000004

140 ACTVFLAGS_ACTIVATE_64_BIT_SERVER = 0x00000008

141 ACTVFLAGS_NO_FAILURE_LOG = 0x00000020

142

143# 2.2.22.2.2 SpecialPropertiesData

144 SPD_FLAG_USE_CONSOLE_SESSION = 0x00000001

145

146# 2.2.28.1 IDL Range Constants

147 MAX_REQUESTED_INTERFACES = 0x8000

148 MAX_REQUESTED_PROTSEQS = 0x8000

149 MIN_ACTPROP_LIMIT = 1

150 MAX_ACTPROP_LIMIT = 10

151

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

153# STRUCTURES

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

155 class handle_t(NDRSTRUCT):

156 structure = (

157 ('context_handle_attributes',ULONG),

158 ('context_handle_uuid',UUID),

159 )

160

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

162 NDRSTRUCT.__init__(self, data, isNDR64)

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

164

165 def isNull(self):

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

167

168# 2.2.11 COMVERSION

169 class COMVERSION(NDRSTRUCT):

170 default_major_version = 5

171 default_minor_version = 7

172

173 structure = (

174 ('MajorVersion',USHORT),

175 ('MinorVersion',USHORT),

176 )

177

178 @classmethod

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

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

181 if major_version is not None:

182 cls.default_major_version = major_version

183 if minor_version is not None:

184 cls.default_minor_version = minor_version

185

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

187 NDRSTRUCT.__init__(self, data, isNDR64)

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

189 self['MajorVersion'] = self.default_major_version

190 self['MinorVersion'] = self.default_minor_version

191

192 class PCOMVERSION(NDRPOINTER):

193 referent = (

194 ('Data', COMVERSION),

195 )

196

197# 2.2.13.1 ORPC_EXTENT

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

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

200 class BYTE_ARRAY(NDRUniConformantArray):

201 item = 'c'

202

203 class ORPC_EXTENT(NDRSTRUCT):

204 structure = (

205 ('id',GUID),

206 ('size',ULONG),

207 ('data',BYTE_ARRAY),

208 )

209

210# 2.2.13.2 ORPC_EXTENT_ARRAY

211# ThisMUSTbeanarrayofORPC_EXTENTs.ThearraysizeMUSTbeamultipleof2for alignment reasons.

212 class PORPC_EXTENT(NDRPOINTER):

213 referent = (

214 ('Data', ORPC_EXTENT),

215 )

216

217 class EXTENT_ARRAY(NDRUniConformantArray):

218 item = PORPC_EXTENT

219

220 class PEXTENT_ARRAY(NDRPOINTER):

221 referent = (

222 ('Data', EXTENT_ARRAY),

223 )

224

225 class ORPC_EXTENT_ARRAY(NDRSTRUCT):

226 structure = (

227 ('size',ULONG),

228 ('reserved',ULONG),

229 ('extent',PEXTENT_ARRAY),

230 )

231

232 class PORPC_EXTENT_ARRAY(NDRPOINTER):

233 referent = (

234 ('Data', ORPC_EXTENT_ARRAY),

235 )

236

237# 2.2.13.3 ORPCTHIS

238 class ORPCTHIS(NDRSTRUCT):

239 structure = (

240 ('version',COMVERSION),

241 ('flags',ULONG),

242 ('reserved1',ULONG),

243 ('cid',CID),

244 ('extensions',PORPC_EXTENT_ARRAY),

245 )

246

247# 2.2.13.4 ORPCTHAT

248 class ORPCTHAT(NDRSTRUCT):

249 structure = (

250 ('flags',ULONG),

251 ('extensions',PORPC_EXTENT_ARRAY),

252 )

253

254# 2.2.14 MInterfacePointer

255 class MInterfacePointer(NDRSTRUCT):

256 structure = (

257 ('ulCntData',ULONG),

258 ('abData',BYTE_ARRAY),

259 )

260

261# 2.2.15 PMInterfacePointerInternal

262 class PMInterfacePointerInternal(NDRPOINTER):

263 referent = (

264 ('Data', MInterfacePointer),

265 )

266

267# 2.2.16 PMInterfacePointer

268 class PMInterfacePointer(NDRPOINTER):

269 referent = (

270 ('Data', MInterfacePointer),

271 )

272

273 class PPMInterfacePointer(NDRPOINTER):

274 referent = (

275 ('Data', PMInterfacePointer),

276 )

277

278# 2.2.18 OBJREF

279 class OBJREF(NDRSTRUCT):

280 commonHdr = (

281 ('signature',ULONG),

282 ('flags',ULONG),

283 ('iid',GUID),

284 )

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

286 NDRSTRUCT.__init__(self, data, isNDR64)

287 if data is None:

288 self['signature'] = 0x574F454D

289

290# 2.2.18.1 STDOBJREF

291 class STDOBJREF(NDRSTRUCT):

292 structure = (

293 ('flags',ULONG),

294 ('cPublicRefs',ULONG),

295 ('oxid',OXID),

296 ('oid',OID),

297 ('ipid',IPID),

298 )

299

300# 2.2.18.4 OBJREF_STANDARD

301 class OBJREF_STANDARD(OBJREF):

302 structure = (

303 ('std',STDOBJREF),

304 ('saResAddr',':'),

305 )

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

307 OBJREF.__init__(self, data, isNDR64)

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

309 self['flags'] = FLAGS_OBJREF_STANDARD

310

311# 2.2.18.5 OBJREF_HANDLER

312 class OBJREF_HANDLER(OBJREF):

313 structure = (

314 ('std',STDOBJREF),

315 ('clsid',CLSID),

316 ('saResAddr',':'),

317 )

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

319 OBJREF.__init__(self, data, isNDR64)

320 if data is None:

321 self['flags'] = FLAGS_OBJREF_HANDLER

322

323# 2.2.18.6 OBJREF_CUSTOM

324 class OBJREF_CUSTOM(OBJREF):

325 structure = (

326 ('clsid',CLSID),

327 ('cbExtension',ULONG),

328 ('ObjectReferenceSize',ULONG),

329 ('pObjectData',':'),

330 )

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

332 OBJREF.__init__(self, data, isNDR64)

333 if data is None:

334 self['flags'] = FLAGS_OBJREF_CUSTOM

335

336# 2.2.18.8 DATAELEMENT

337 class DATAELEMENT(NDRSTRUCT):

338 structure = (

339 ('dataID',GUID),

340 ('cbSize',ULONG),

341 ('cbRounded',ULONG),

342 ('Data',':'),

343 )

344

345 class DUALSTRINGARRAYPACKED(NDRSTRUCT):

346 structure = (

347 ('wNumEntries',USHORT),

348 ('wSecurityOffset',USHORT),

349 ('aStringArray',':'),

350 )

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

352 return self['wNumEntries']*2

353

354# 2.2.18.7 OBJREF_EXTENDED

355 class OBJREF_EXTENDED(OBJREF):

356 structure = (

357 ('std',STDOBJREF),

358 ('Signature1',ULONG),

359 ('saResAddr',DUALSTRINGARRAYPACKED),

360 ('nElms',ULONG),

361 ('Signature2',ULONG),

362 ('ElmArray',DATAELEMENT),

363 )

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

365 OBJREF.__init__(self, data, isNDR64)

366 if data is None:

367 self['flags'] = FLAGS_OBJREF_EXTENDED

368 self['Signature1'] = 0x4E535956

369 self['Signature1'] = 0x4E535956

370 self['nElms'] = 0x4E535956

371

372# 2.2.19 DUALSTRINGARRAY

373 class USHORT_ARRAY(NDRUniConformantArray):

374 item = '<H'

375

376 class PUSHORT_ARRAY(NDRPOINTER):

377 referent = (

378 ('Data', USHORT_ARRAY),

379 )

380

381 class DUALSTRINGARRAY(NDRSTRUCT):

382 structure = (

383 ('wNumEntries',USHORT),

384 ('wSecurityOffset',USHORT),

385 ('aStringArray',USHORT_ARRAY),

386 )

387

388 class PDUALSTRINGARRAY(NDRPOINTER):

389 referent = (

390 ('Data',DUALSTRINGARRAY),

391 )

392

393# 2.2.19.3 STRINGBINDING

394 class STRINGBINDING(NDRSTRUCT):

395 structure = (

396 ('wTowerId',USHORT),

397 ('aNetworkAddr',WIDESTR),

398 )

399

400# 2.2.19.4 SECURITYBINDING

401 class SECURITYBINDING(NDRSTRUCT):

402 structure = (

403 ('wAuthnSvc',USHORT),

404 ('Reserved',USHORT),

405 ('aPrincName',WIDESTR),

406 )

407

408# 2.2.20.1 PROPMARSHALHEADER

409 class PROPMARSHALHEADER(NDRSTRUCT):

410 structure = (

411 ('clsid',CLSID),

412 ('policyId',GUID),

413 ('flags',ULONG),

414 ('cb',ULONG),

415 ('ctxProperty',':'),

416 )

417

418 class PROPMARSHALHEADER_ARRAY(NDRUniConformantArray):

419 item = PROPMARSHALHEADER

420

421# 2.2.20 Context

422 class Context(NDRSTRUCT):

423 structure = (

424 ('MajorVersion',USHORT),

425 ('MinVersion',USHORT),

426 ('ContextId',GUID),

427 ('Flags',ULONG),

428 ('Reserved',ULONG),

429 ('dwNumExtents',ULONG),

430 ('cbExtents',ULONG),

431 ('MshlFlags',ULONG),

432 ('Count',ULONG),

433 ('Frozen',ULONG),

434 ('PropMarshalHeader',PROPMARSHALHEADER_ARRAY),

435 )

436

437# 2.2.21.3 ErrorInfoString

438 class ErrorInfoString(NDRSTRUCT):

439 structure = (

440 ('dwMax',ULONG),

441 ('dwOffSet',ULONG),

442 ('dwActual',IID),

443 ('Name',WSTR),

444 )

445

446# 2.2.21.2 Custom-Marshaled Error Information Format

447 class ORPC_ERROR_INFORMATION(NDRSTRUCT):

448 structure = (

449 ('dwVersion',ULONG),

450 ('dwHelpContext',ULONG),

451 ('iid',IID),

452 ('dwSourceSignature',ULONG),

453 ('Source',ErrorInfoString),

454 ('dwDescriptionSignature',ULONG),

455 ('Description',ErrorInfoString),

456 ('dwHelpFileSignature',ULONG),

457 ('HelpFile',ErrorInfoString),

458 )

459

460# 2.2.21.5 EntryHeader

461 class EntryHeader(NDRSTRUCT):

462 structure = (

463 ('Signature',ULONG),

464 ('cbEHBuffer',ULONG),

465 ('cbSize',ULONG),

466 ('reserved',ULONG),

467 ('policyID',GUID),

468 )

469

470 class EntryHeader_ARRAY(NDRUniConformantArray):

471 item = EntryHeader

472

473# 2.2.21.4 Context ORPC Extension

474 class ORPC_CONTEXT(NDRSTRUCT):

475 structure = (

476 ('SignatureVersion',ULONG),

477 ('Version',ULONG),

478 ('cPolicies',ULONG),

479 ('cbBuffer',ULONG),

480 ('cbSize',ULONG),

481 ('hr',ULONG),

482 ('hrServer',ULONG),

483 ('reserved',ULONG),

484 ('EntryHeader',EntryHeader_ARRAY),

485 ('PolicyData',':'),

486 )

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

488 NDRSTRUCT.__init__(self, data, isNDR64)

489 if data is None:

490 self['SignatureVersion'] = 0x414E554B

491

492# 2.2.22.1 CustomHeader

493 class CLSID_ARRAY(NDRUniConformantArray):

494 item = CLSID

495

496 class PCLSID_ARRAY(NDRPOINTER):

497 referent = (

498 ('Data', CLSID_ARRAY),

499 )

500

501 class DWORD_ARRAY(NDRUniConformantArray):

502 item = DWORD

503

504 class PDWORD_ARRAY(NDRPOINTER):

505 referent = (

506 ('Data', DWORD_ARRAY),

507 )

508

509 class CustomHeader(TypeSerialization1):

510 structure = (

511 ('totalSize',DWORD),

512 ('headerSize',DWORD),

513 ('dwReserved',DWORD),

514 ('destCtx',DWORD),

515 ('cIfs',DWORD),

516 ('classInfoClsid',CLSID),

517 ('pclsid',PCLSID_ARRAY),

518 ('pSizes',PDWORD_ARRAY),

519 ('pdwReserved',LPLONG),

520 #('pdwReserved',LONG),

521 )

522 def getData(self, soFar = 0):

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

524 TypeSerialization1.getDataReferents(self, soFar))

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

526 return TypeSerialization1.getData(self, soFar)

527

528# 2.2.22 Activation Properties BLOB

529 class ACTIVATION_BLOB(NDRTLSTRUCT):

530 structure = (

531 ('dwSize',ULONG),

532 ('dwReserved',ULONG),

533 ('CustomHeader',CustomHeader),

534 ('Property',UNKNOWNDATA),

535 )

536 def getData(self, soFar = 0):

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

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

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

540 return NDRTLSTRUCT.getData(self)

541

542# 2.2.22.2.1 InstantiationInfoData

543 class IID_ARRAY(NDRUniConformantArray):

544 item = IID

545

546 class PIID_ARRAY(NDRPOINTER):

547 referent = (

548 ('Data', IID_ARRAY),

549 )

550

551 class InstantiationInfoData(TypeSerialization1):

552 structure = (

553 ('classId',CLSID),

554 ('classCtx',DWORD),

555 ('actvflags',DWORD),

556 ('fIsSurrogate',LONG),

557 ('cIID',DWORD),

558 ('instFlag',DWORD),

559 ('pIID',PIID_ARRAY),

560 ('thisSize',DWORD),

561 ('clientCOMVersion',COMVERSION),

562 )

563

564# 2.2.22.2.2 SpecialPropertiesData

565 class SpecialPropertiesData(TypeSerialization1):

566 structure = (

567 ('dwSessionId',ULONG),

568 ('fRemoteThisSessionId',LONG),

569 ('fClientImpersonating',LONG),

570 ('fPartitionIDPresent',LONG),

571 ('dwDefaultAuthnLvl',DWORD),

572 ('guidPartition',GUID),

573 ('dwPRTFlags',DWORD),

574 ('dwOrigClsctx',DWORD),

575 ('dwFlags',DWORD),

576 ('Reserved0',DWORD),

577 ('Reserved0',DWORD),

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

579 #('Reserved1',DWORD),

580 #('Reserved2',ULONGLONG),

581 #('Reserved3_1',DWORD),

582 #('Reserved3_2',DWORD),

583 #('Reserved3_3',DWORD),

584 #('Reserved3_4',DWORD),

585 #('Reserved3_5',DWORD),

586 )

587

588# 2.2.22.2.3 InstanceInfoData

589 class InstanceInfoData(TypeSerialization1):

590 structure = (

591 ('fileName',LPWSTR),

592 ('mode',DWORD),

593 ('ifdROT',PMInterfacePointer),

594 ('ifdStg',PMInterfacePointer),

595 )

596

597# 2.2.22.2.4.1 customREMOTE_REQUEST_SCM_INFO

598 class customREMOTE_REQUEST_SCM_INFO(NDRSTRUCT):

599 structure = (

600 ('ClientImpLevel',DWORD),

601 ('cRequestedProtseqs',USHORT),

602 ('pRequestedProtseqs',PUSHORT_ARRAY),

603 )

604

605 class PcustomREMOTE_REQUEST_SCM_INFO(NDRPOINTER):

606 referent = (

607 ('Data', customREMOTE_REQUEST_SCM_INFO),

608 )

609

610# 2.2.22.2.4 ScmRequestInfoData

611 class ScmRequestInfoData(TypeSerialization1):

612 structure = (

613 ('pdwReserved',LPLONG),

614 ('remoteRequest',PcustomREMOTE_REQUEST_SCM_INFO),

615 )

616

617# 2.2.22.2.5 ActivationContextInfoData

618 class ActivationContextInfoData(TypeSerialization1):

619 structure = (

620 ('clientOK',LONG),

621 ('bReserved1',LONG),

622 ('dwReserved1',DWORD),

623 ('dwReserved2',DWORD),

624 ('pIFDClientCtx',PMInterfacePointer),

625 ('pIFDPrototypeCtx',PMInterfacePointer),

626 )

627

628# 2.2.22.2.6 LocationInfoData

629 class LocationInfoData(TypeSerialization1):

630 structure = (

631 ('machineName',LPWSTR),

632 ('processId',DWORD),

633 ('apartmentId',DWORD),

634 ('contextId',DWORD),

635 )

636

637# 2.2.22.2.7.1 COSERVERINFO

638 class COSERVERINFO(NDRSTRUCT):

639 structure = (

640 ('dwReserved1',DWORD),

641 ('pwszName',LPWSTR),

642 ('pdwReserved',LPLONG),

643 ('dwReserved2',DWORD),

644 )

645

646 class PCOSERVERINFO(NDRPOINTER):

647 referent = (

648 ('Data', COSERVERINFO),

649 )

650

651# 2.2.22.2.7 SecurityInfoData

652 class SecurityInfoData(TypeSerialization1):

653 structure = (

654 ('dwAuthnFlags',DWORD),

655 ('pServerInfo',PCOSERVERINFO),

656 ('pdwReserved',LPLONG),

657 )

658

659# 2.2.22.2.8.1 customREMOTE_REPLY_SCM_INFO

660 class customREMOTE_REPLY_SCM_INFO(NDRSTRUCT):

661 structure = (

662 ('Oxid',OXID),

663 ('pdsaOxidBindings',PDUALSTRINGARRAY),

664 ('ipidRemUnknown',IPID),

665 ('authnHint',DWORD),

666 ('serverVersion',COMVERSION),

667 )

668

669 class PcustomREMOTE_REPLY_SCM_INFO(NDRPOINTER):

670 referent = (

671 ('Data', customREMOTE_REPLY_SCM_INFO),

672 )

673

674# 2.2.22.2.8 ScmReplyInfoData

675 class ScmReplyInfoData(TypeSerialization1):

676 structure = (

677 ('pdwReserved',DWORD),

678 ('remoteReply',PcustomREMOTE_REPLY_SCM_INFO),

679 )

680

681# 2.2.22.2.9 PropsOutInfo

682 class HRESULT_ARRAY(NDRUniConformantArray):

683 item = HRESULT

684

685 class PHRESULT_ARRAY(NDRPOINTER):

686 referent = (

687 ('Data', HRESULT_ARRAY),

688 )

689

690 class MInterfacePointer_ARRAY(NDRUniConformantArray):

691 item = MInterfacePointer

692

693 class PMInterfacePointer_ARRAY(NDRUniConformantArray):

694 item = PMInterfacePointer

695

696 class PPMInterfacePointer_ARRAY(NDRPOINTER):

697 referent = (

698 ('Data', PMInterfacePointer_ARRAY),

699 )

700

701 class PropsOutInfo(TypeSerialization1):

702 structure = (

703 ('cIfs',DWORD),

704 ('piid',PIID_ARRAY),

705 ('phresults',PHRESULT_ARRAY),

706 ('ppIntfData',PPMInterfacePointer_ARRAY),

707 )

708

709# 2.2.23 REMINTERFACEREF

710 class REMINTERFACEREF(NDRSTRUCT):

711 structure = (

712 ('ipid',IPID),

713 ('cPublicRefs',LONG),

714 ('cPrivateRefs',LONG),

715 )

716

717 class REMINTERFACEREF_ARRAY(NDRUniConformantArray):

718 item = REMINTERFACEREF

719

720# 2.2.24 REMQIRESULT

721 class REMQIRESULT(NDRSTRUCT):

722 structure = (

723 ('hResult',HRESULT),

724 ('std',STDOBJREF),

725 )

726

727# 2.2.25 PREMQIRESULT

728 class PREMQIRESULT(NDRPOINTER):

729 referent = (

730 ('Data', REMQIRESULT),

731 )

732

733# 2.2.26 REFIPID

734 REFIPID = GUID

735

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

737# RPC CALLS

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

739 class DCOMCALL(NDRCALL):

740 commonHdr = (

741 ('ORPCthis', ORPCTHIS),

742 )

743

744 class DCOMANSWER(NDRCALL):

745 commonHdr = (

746 ('ORPCthat', ORPCTHAT),

747 )

748

749# 3.1.2.5.1.1 IObjectExporter::ResolveOxid (Opnum 0)

750 class ResolveOxid(NDRCALL):

751 opnum = 0

752 structure = (

753 ('pOxid', OXID),

754 ('cRequestedProtseqs', USHORT),

755 ('arRequestedProtseqs', USHORT_ARRAY),

756 )

757

758 class ResolveOxidResponse(NDRCALL):

759 structure = (

760 ('ppdsaOxidBindings', PDUALSTRINGARRAY),

761 ('pipidRemUnknown', IPID),

762 ('pAuthnHint', DWORD),

763 ('ErrorCode', error_status_t),

764 )

765

766# 3.1.2.5.1.2 IObjectExporter::SimplePing (Opnum 1)

767 class SimplePing(NDRCALL):

768 opnum = 1

769 structure = (

770 ('pSetId', SETID),

771 )

772

773 class SimplePingResponse(NDRCALL):

774 structure = (

775 ('ErrorCode', error_status_t),

776 )

777

778# 3.1.2.5.1.3 IObjectExporter::ComplexPing (Opnum 2)

779 class ComplexPing(NDRCALL):

780 opnum = 2

781 structure = (

782 ('pSetId', SETID),

783 ('SequenceNum', USHORT),

784 ('cAddToSet', USHORT),

785 ('cDelFromSet', USHORT),

786 ('AddToSet', POID_ARRAY),

787 ('DelFromSet', POID_ARRAY),

788 )

789

790 class ComplexPingResponse(NDRCALL):

791 structure = (

792 ('pSetId', SETID),

793 ('pPingBackoffFactor', USHORT),

794 ('ErrorCode', error_status_t),

795 )

796

797# 3.1.2.5.1.4 IObjectExporter::ServerAlive (Opnum 3)

798 class ServerAlive(NDRCALL):

799 opnum = 3

800 structure = (

801 )

802

803 class ServerAliveResponse(NDRCALL):

804 structure = (

805 ('ErrorCode', error_status_t),

806 )

807

808# 3.1.2.5.1.5 IObjectExporter::ResolveOxid2 (Opnum 4)

809 class ResolveOxid2(NDRCALL):

810 opnum = 4

811 structure = (

812 ('pOxid', OXID),

813 ('cRequestedProtseqs', USHORT),

814 ('arRequestedProtseqs', USHORT_ARRAY),

815 )

816

817 class ResolveOxid2Response(NDRCALL):

818 structure = (

819 ('ppdsaOxidBindings', PDUALSTRINGARRAY),

820 ('pipidRemUnknown', IPID),

821 ('pAuthnHint', DWORD),

822 ('pComVersion', COMVERSION),

823 ('ErrorCode', error_status_t),

824 )

825

826# 3.1.2.5.1.6 IObjectExporter::ServerAlive2 (Opnum 5)

827 class ServerAlive2(NDRCALL):

828 opnum = 5

829 structure = (

830 )

831

832 class ServerAlive2Response(NDRCALL):

833 structure = (

834 ('pComVersion', COMVERSION),

835 ('ppdsaOrBindings', PDUALSTRINGARRAY),

836 ('pReserved', LPLONG),

837 ('ErrorCode', error_status_t),

838 )

839

840# 3.1.2.5.2.3.1 IActivation:: RemoteActivation (Opnum 0)

841 class RemoteActivation(NDRCALL):

842 opnum = 0

843 structure = (

844 ('ORPCthis', ORPCTHIS),

845 ('Clsid', GUID),

846 ('pwszObjectName', LPWSTR),

847 ('pObjectStorage', PMInterfacePointer),

848 ('ClientImpLevel', DWORD),

849 ('Mode', DWORD),

850 ('Interfaces', DWORD),

851 ('pIIDs', PIID_ARRAY),

852 ('cRequestedProtseqs', USHORT),

853 ('aRequestedProtseqs', USHORT_ARRAY),

854 )

855

856 class RemoteActivationResponse(NDRCALL):

857 structure = (

858 ('ORPCthat', ORPCTHAT),

859 ('pOxid', OXID),

860 ('ppdsaOxidBindings', PDUALSTRINGARRAY),

861 ('pipidRemUnknown', IPID),

862 ('pAuthnHint', DWORD),

863 ('pServerVersion', COMVERSION),

864 ('phr', HRESULT),

865 ('ppInterfaceData', PMInterfacePointer_ARRAY),

866 ('pResults', HRESULT_ARRAY),

867 ('ErrorCode', error_status_t),

868 )

869

870# 3.1.2.5.2.3.2 IRemoteSCMActivator:: RemoteGetClassObject (Opnum 3)

871 class RemoteGetClassObject(NDRCALL):

872 opnum = 3

873 structure = (

874 ('ORPCthis', ORPCTHIS),

875 ('pActProperties', PMInterfacePointer),

876 )

877

878 class RemoteGetClassObjectResponse(NDRCALL):

879 structure = (

880 ('ORPCthat', ORPCTHAT),

881 ('ppActProperties', PMInterfacePointer),

882 ('ErrorCode', error_status_t),

883 )

884

885# 3.1.2.5.2.3.3 IRemoteSCMActivator::RemoteCreateInstance (Opnum 4)

886 class RemoteCreateInstance(NDRCALL):

887 opnum = 4

888 structure = (

889 ('ORPCthis', ORPCTHIS),

890 ('pUnkOuter', PMInterfacePointer),

891 ('pActProperties', PMInterfacePointer),

892 )

893

894 class RemoteCreateInstanceResponse(NDRCALL):

895 structure = (

896 ('ORPCthat', ORPCTHAT),

897 ('ppActProperties', PMInterfacePointer),

898 ('ErrorCode', error_status_t),

899 )

900

901# 3.1.1.5.6.1.1 IRemUnknown::RemQueryInterface (Opnum 3)

902 class RemQueryInterface(DCOMCALL):

903 opnum = 3

904 structure = (

905 ('ripid', REFIPID),

906 ('cRefs', ULONG),

907 ('cIids', USHORT),

908 ('iids', IID_ARRAY),

909 )

910

911 class RemQueryInterfaceResponse(DCOMANSWER):

912 structure = (

913 ('ppQIResults', PREMQIRESULT),

914 ('ErrorCode', error_status_t),

915 )

916

917# 3.1.1.5.6.1.2 IRemUnknown::RemAddRef (Opnum 4 )

918 class RemAddRef(DCOMCALL):

919 opnum = 4

920 structure = (

921 ('cInterfaceRefs', USHORT),

922 ('InterfaceRefs', REMINTERFACEREF_ARRAY),

923 )

924

925 class RemAddRefResponse(DCOMANSWER):

926 structure = (

927 ('pResults', DWORD_ARRAY),

928 ('ErrorCode', error_status_t),

929 )

930

931# 3.1.1.5.6.1.3 IRemUnknown::RemRelease (Opnum 5)

932 class RemRelease(DCOMCALL):

933 opnum = 5

934 structure = (

935 ('cInterfaceRefs', USHORT),

936 ('InterfaceRefs', REMINTERFACEREF_ARRAY),

937 )

938

939 class RemReleaseResponse(DCOMANSWER):

940 structure = (

941 ('ErrorCode', error_status_t),

942 )

943

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

945# OPNUMs and their corresponding structures

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

947 OPNUMS = {

948}

949

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

951# HELPER FUNCTIONS

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

953 class DCOMConnection:

954 """

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

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

957 pinging the objects created against the target.

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

959 """

960 PINGTIMER = None

961 OID_ADD = {}

962 OID_DEL = {}

963 OID_SET = {}

964 PORTMAPS = {}

965

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

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

968 self.__target = target

969 self.__userName = username

970 self.__password = password

971 self.__domain = domain

972 self.__lmhash = lmhash

973 self.__nthash = nthash

974 self.__aesKey = aesKey

975 self.__TGT = TGT

976 self.__TGS = TGS

977 self.__authLevel = authLevel

978 self.__portmap = None

979 self.__oxidResolver = oxidResolver

980 self.__doKerberos = doKerberos

981 self.__kdcHost = kdcHost

982 self.initConnection()

983

984 @classmethod

985 def addOid(cls, target, oid):

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

987 DCOMConnection.OID_ADD[target] = set()

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

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

990 DCOMConnection.OID_SET[target] = {}

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

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

993

994 @classmethod

995 def delOid(cls, target, oid):

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

997 DCOMConnection.OID_DEL[target] = set()

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

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

1000 DCOMConnection.OID_SET[target] = {}

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

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

1003

1004 @classmethod

1005 def pingServer(cls):

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

1007 # ToDo: locking for avoiding race conditions

1008 #print DCOMConnection.PORTMAPS

1009 #print DCOMConnection.OID_SET

1010 try:

1011 for target in DCOMConnection.OID_SET:

1012 addedOids = set()

1013 deletedOids = set()

1014 if target in DCOMConnection.OID_ADD:

1015 addedOids = DCOMConnection.OID_ADD[target]

1016 del(DCOMConnection.OID_ADD[target])

1017

1018 if target in DCOMConnection.OID_DEL:

1019 deletedOids = DCOMConnection.OID_DEL[target]

1020 del(DCOMConnection.OID_DEL[target])

1021

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

1023

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

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

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

1027 else:

1028 setId = 0

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

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

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

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

1033 else:

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

1035 except Exception as e:

1036 # There might be exceptions when sending packets

1037 # We should try to continue tho.

1038 LOG.error(str(e))

1039 pass

1040

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

1042 try:

1043 DCOMConnection.PINGTIMER.start()

1044 except Exception as e:

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

1046 raise e

1047

1048 def initTimer(self):

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

1050 if DCOMConnection.PINGTIMER is None:

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

1052 try:

1053 DCOMConnection.PINGTIMER.start()

1054 except Exception as e:

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

1056 raise e

1057

1058 def initConnection(self):

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

1060 rpctransport = transport.DCERPCTransportFactory(stringBinding)

1061

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

1063 # This method exists only for selected protocol sequences.

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

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

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

1067 self.__portmap = rpctransport.get_dce_rpc()

1068 self.__portmap.set_auth_level(self.__authLevel)

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

1070 self.__portmap.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE)

1071 self.__portmap.connect()

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

1073

1074 def CoCreateInstanceEx(self, clsid, iid):

1075 scm = IRemoteSCMActivator(self.__portmap)

1076 iInterface = scm.RemoteCreateInstance(clsid, iid)

1077 self.initTimer()

1078 return iInterface

1079

1080 def get_dce_rpc(self):

1081 return DCOMConnection.PORTMAPS[self.__target]

1082

1083 def disconnect(self):

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

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

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

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

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

1089 DCOMConnection.PINGTIMER.cancel()

1090 DCOMConnection.PINGTIMER.join()

1091 DCOMConnection.PINGTIMER = None

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

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

1094 self.__portmap.disconnect()

1095 #print INTERFACE.CONNECTIONS

1096

1097 class CLASS_INSTANCE:

1098 def __init__(self, ORPCthis, stringBinding):

1099 self.__stringBindings = stringBinding

1100 self.__ORPCthis = ORPCthis

1101 self.__authType = RPC_C_AUTHN_WINNT

1102 self.__authLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY

1103 def get_ORPCthis(self):

1104 return self.__ORPCthis

1105 def get_string_bindings(self):

1106 return self.__stringBindings

1107 def get_auth_level(self):

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

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

1110 return RPC_C_AUTHN_LEVEL_PKT_INTEGRITY

1111 else:

1112 return RPC_C_AUTHN_LEVEL_PKT_PRIVACY

1113 return self.__authLevel

1114 def set_auth_level(self, level):

1115 self.__authLevel = level

1116 def get_auth_type(self):

1117 return self.__authType

1118 def set_auth_type(self, authType):

1119 self.__authType = authType

1120

1121

1122 class INTERFACE:

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

1124 CONNECTIONS = {}

1125

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

1127 interfaceInstance=None):

1128 if interfaceInstance is not None:

1129 self.__target = interfaceInstance.get_target()

1130 self.__iPid = interfaceInstance.get_iPid()

1131 self.__oid = interfaceInstance.get_oid()

1132 self.__oxid = interfaceInstance.get_oxid()

1133 self.__cinstance = interfaceInstance.get_cinstance()

1134 self.__objRef = interfaceInstance.get_objRef()

1135 self.__ipidRemUnknown = interfaceInstance.get_ipidRemUnknown()

1136 else:

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

1138 raise Exception('No target')

1139 self.__target = target

1140 self.__iPid = iPid

1141 self.__oid = oid

1142 self.__oxid = oxid

1143 self.__cinstance = cinstance

1144 self.__objRef = objRef

1145 self.__ipidRemUnknown = ipidRemUnknown

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

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

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

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

1150

1151 if objRef is not None:

1152 self.process_interface(objRef)

1153

1154 def process_interface(self, data):

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

1156 objRef = None

1157 if objRefType == FLAGS_OBJREF_CUSTOM:

1158 objRef = OBJREF_CUSTOM(data)

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

1160 objRef = OBJREF_HANDLER(data)

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

1162 objRef = OBJREF_STANDARD(data)

1163 elif objRefType == FLAGS_OBJREF_EXTENDED:

1164 objRef = OBJREF_EXTENDED(data)

1165 else:

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

1167

1168 if objRefType != FLAGS_OBJREF_CUSTOM:

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

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

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

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

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

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

1175 objRef.dump()

1176 raise Exception('OXID is None')

1177

1178 def get_oxid(self):

1179 return self.__oxid

1180

1181 def set_oxid(self, oxid):

1182 self.__oxid = oxid

1183

1184 def get_oid(self):

1185 return self.__oid

1186

1187 def set_oid(self, oid):

1188 self.__oid = oid

1189

1190 def get_target(self):

1191 return self.__target

1192

1193 def get_iPid(self):

1194 return self.__iPid

1195

1196 def set_iPid(self, iPid):

1197 self.__iPid = iPid

1198

1199 def get_objRef(self):

1200 return self.__objRef

1201

1202 def set_objRef(self, objRef):

1203 self.__objRef = objRef

1204

1205 def get_ipidRemUnknown(self):

1206 return self.__ipidRemUnknown

1207

1208 def get_dce_rpc(self):

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

1210

1211 def get_cinstance(self):

1212 return self.__cinstance

1213

1214 def set_cinstance(self, cinstance):

1215 self.__cinstance = cinstance

1216

1217 def is_fqdn(self):

1218 # I will assume the following

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

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

1221 # an FQDN with ':'

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

1223 try:

1224 socket.inet_aton(self.__target)

1225 except:

1226 # Not an IPv4

1227 try:

1228 self.__target.index(':')

1229 except:

1230 # Not an IPv6, it's a FQDN

1231 return True

1232 return False

1233

1234 def connect(self, iid = None):

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

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

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

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

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

1240 if currentBinding == iid:

1241 # We don't need to alter_ctx

1242 pass

1243 else:

1244 newDce = dce.alter_ctx(iid)

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

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

1247 else:

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

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

1250 stringBinding = None

1251 isTargetFQDN = self.is_fqdn()

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

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

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

1255 # 1) it's an IPv4 address

1256 # 2) it's an IPv6 address

1257 # 3) it's a NetBios Name

1258 # we should handle all this cases accordingly

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

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

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

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

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

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

1265 bindingPort = '[' + bindingPort

1266 else:

1267 binding = strBinding['aNetworkAddr']

1268 bindingPort = ''

1269

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

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

1272 break

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

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

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

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

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

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

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

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

1281 break

1282

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

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

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

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

1287

1288 dcomInterface = transport.DCERPCTransportFactory(stringBinding)

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

1290 # This method exists only for selected protocol sequences.

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

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

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

1294 dcomInterface.set_connect_timeout(300)

1295 dce = dcomInterface.get_dce_rpc()

1296

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

1298 raise Exception('IID is None')

1299 else:

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

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

1302

1303 dce.connect()

1304

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

1306 raise Exception('IID is None')

1307 else:

1308 dce.bind(iid)

1309

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

1311 #import traceback

1312 #traceback.print_stack()

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

1314

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

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

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

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

1319 else:

1320 # No connection created

1321 raise Exception('No connection created')

1322

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

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

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

1326 self.connect(iid)

1327 dce = self.get_dce_rpc()

1328 try:

1329 resp = dce.request(req, uuid)

1330 except Exception as e:

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

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

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

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

1335 raise DCERPCException(msg)

1336 else:

1337 raise

1338 return resp

1339

1340 def disconnect(self):

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

1342

1343

1344# 3.1.1.5.6.1 IRemUnknown Methods

1345 class IRemUnknown(INTERFACE):

1346 def __init__(self, interface):

1347 self._iid = IID_IRemUnknown

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

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

1350 INTERFACE.__init__(self, interfaceInstance=interface)

1351 self.set_oxid(interface.get_oxid())

1352

1353 def RemQueryInterface(self, cRefs, iids):

1354 # For now, it only supports a single IID

1355 request = RemQueryInterface()

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

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

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

1359 request['cRefs'] = cRefs

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

1361 for iid in iids:

1362 _iid = IID()

1363 _iid['Data'] = iid

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

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

1366 #resp.dump()

1367

1368 return IRemUnknown2(

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

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

1371 target=self.get_target()))

1372

1373 def RemAddRef(self):

1374 request = RemAddRef()

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

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

1377 request['cInterfaceRefs'] = 1

1378 element = REMINTERFACEREF()

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

1380 element['cPublicRefs'] = 1

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

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

1383 return resp

1384

1385 def RemRelease(self):

1386 request = RemRelease()

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

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

1389 request['cInterfaceRefs'] = 1

1390 element = REMINTERFACEREF()

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

1392 element['cPublicRefs'] = 1

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

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

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

1396 return resp

1397

1398# 3.1.1.5.7 IRemUnknown2 Interface

1399 class IRemUnknown2(IRemUnknown):

1400 def __init__(self, interface):

1401 IRemUnknown.__init__(self, interface)

1402 self._iid = IID_IRemUnknown2

1403

1404# 3.1.2.5.1 IObjectExporter Methods

1405 class IObjectExporter:

1406 def __init__(self, dce):

1407 self.__portmap = dce

1408

1409 # 3.1.2.5.1.1 IObjectExporter::ResolveOxid (Opnum 0)

1410 def ResolveOxid(self, pOxid, arRequestedProtseqs):

1411 self.__portmap.connect()

1412 self.__portmap.bind(IID_IObjectExporter)

1413 request = ResolveOxid()

1414 request['pOxid'] = pOxid

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

1416 for protSeq in arRequestedProtseqs:

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

1418 resp = self.__portmap.request(request)

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

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

1421

1422 done = False

1423 stringBindings = list()

1424 while not done:

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

1426 done = True

1427 else:

1428 binding = STRINGBINDING(strBindings)

1429 stringBindings.append(binding)

1430 strBindings = strBindings[len(binding):]

1431

1432 return stringBindings

1433

1434 # 3.1.2.5.1.2 IObjectExporter::SimplePing (Opnum 1)

1435 def SimplePing(self, setId):

1436 self.__portmap.connect()

1437 self.__portmap.bind(IID_IObjectExporter)

1438 request = SimplePing()

1439 request['pSetId'] = setId

1440 resp = self.__portmap.request(request)

1441 return resp

1442

1443 # 3.1.2.5.1.3 IObjectExporter::ComplexPing (Opnum 2)

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

1445 self.__portmap.connect()

1446 #self.__portmap.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)

1447 self.__portmap.bind(IID_IObjectExporter)

1448 request = ComplexPing()

1449 request['pSetId'] = setId

1450 request['SequenceNum'] = setId

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

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

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

1454 for oid in addToSet:

1455 oidn = OID()

1456 oidn['Data'] = oid

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

1458 else:

1459 request['AddToSet'] = NULL

1460

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

1462 for oid in delFromSet:

1463 oidn = OID()

1464 oidn['Data'] = oid

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

1466 else:

1467 request['DelFromSet'] = NULL

1468 resp = self.__portmap.request(request)

1469 return resp

1470

1471 # 3.1.2.5.1.4 IObjectExporter::ServerAlive (Opnum 3)

1472 def ServerAlive(self):

1473 self.__portmap.connect()

1474 self.__portmap.bind(IID_IObjectExporter)

1475 request = ServerAlive()

1476 resp = self.__portmap.request(request)

1477 return resp

1478

1479 # 3.1.2.5.1.5 IObjectExporter::ResolveOxid2 (Opnum 4)

1480 def ResolveOxid2(self,pOxid, arRequestedProtseqs):

1481 self.__portmap.connect()

1482 self.__portmap.bind(IID_IObjectExporter)

1483 request = ResolveOxid2()

1484 request['pOxid'] = pOxid

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

1486 for protSeq in arRequestedProtseqs:

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

1488 resp = self.__portmap.request(request)

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

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

1491

1492 done = False

1493 stringBindings = list()

1494 while not done:

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

1496 done = True

1497 else:

1498 binding = STRINGBINDING(strBindings)

1499 stringBindings.append(binding)

1500 strBindings = strBindings[len(binding):]

1501

1502 return stringBindings

1503

1504 # 3.1.2.5.1.6 IObjectExporter::ServerAlive2 (Opnum 5)

1505 def ServerAlive2(self):

1506 self.__portmap.connect()

1507 self.__portmap.bind(IID_IObjectExporter)

1508 request = ServerAlive2()

1509 resp = self.__portmap.request(request)

1510

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

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

1513

1514 done = False

1515 stringBindings = list()

1516 while not done:

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

1518 done = True

1519 else:

1520 binding = STRINGBINDING(strBindings)

1521 stringBindings.append(binding)

1522 strBindings = strBindings[len(binding):]

1523

1524 return stringBindings

1525

1526# 3.1.2.5.2.1 IActivation Methods

1527 class IActivation:

1528 def __init__(self, dce):

1529 self.__portmap = dce

1530

1531 # 3.1.2.5.2.3.1 IActivation:: RemoteActivation (Opnum 0)

1532 def RemoteActivation(self, clsId, iid):

1533 # Only supports one interface at a time

1534 self.__portmap.bind(IID_IActivation)

1535 ORPCthis = ORPCTHIS()

1536 ORPCthis['cid'] = generate()

1537 ORPCthis['extensions'] = NULL

1538 ORPCthis['flags'] = 1

1539

1540 request = RemoteActivation()

1541 request['Clsid'] = clsId

1542 request['pwszObjectName'] = NULL

1543 request['pObjectStorage'] = NULL

1544 request['ClientImpLevel'] = 2

1545 request['Mode'] = 0

1546 request['Interfaces'] = 1

1547

1548 _iid = IID()

1549 _iid['Data'] = iid

1550

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

1552 request['cRequestedProtseqs'] = 1

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

1554

1555 resp = self.__portmap.request(request)

1556

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

1558

1559 ipidRemUnknown = resp['pipidRemUnknown']

1560

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

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

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

1564

1565 done = False

1566 stringBindings = list()

1567 while not done:

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

1569 done = True

1570 else:

1571 binding = STRINGBINDING(strBindings)

1572 stringBindings.append(binding)

1573 strBindings = strBindings[len(binding):]

1574

1575 done = False

1576 while not done:

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

1578 done = True

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

1580 done = True

1581 else:

1582 secBinding = SECURITYBINDING(securityBindings)

1583 securityBindings = securityBindings[len(secBinding):]

1584

1585 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings)

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

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

1588

1589

1590# 3.1.2.5.2.2 IRemoteSCMActivator Methods

1591 class IRemoteSCMActivator:

1592 def __init__(self, dce):

1593 self.__portmap = dce

1594

1595 def RemoteGetClassObject(self, clsId, iid):

1596 # iid should be IID_IClassFactory

1597 self.__portmap.bind(IID_IRemoteSCMActivator)

1598 ORPCthis = ORPCTHIS()

1599 ORPCthis['cid'] = generate()

1600 ORPCthis['extensions'] = NULL

1601 ORPCthis['flags'] = 1

1602

1603 request = RemoteGetClassObject()

1604 request['ORPCthis'] = ORPCthis

1605 activationBLOB = ACTIVATION_BLOB()

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

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

1608 clsid = CLSID()

1609 clsid['Data'] = CLSID_InstantiationInfo

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

1611 clsid = CLSID()

1612 clsid['Data'] = CLSID_ActivationContextInfo

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

1614 clsid = CLSID()

1615 clsid['Data'] = CLSID_ServerLocationInfo

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

1617 clsid = CLSID()

1618 clsid['Data'] = CLSID_ScmRequestInfo

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

1620

1621 properties = b''

1622 # InstantiationInfo

1623 instantiationInfo = InstantiationInfoData()

1624 instantiationInfo['classId'] = clsId

1625 instantiationInfo['cIID'] = 1

1626

1627 _iid = IID()

1628 _iid['Data'] = iid

1629

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

1631

1632 dword = DWORD()

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

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

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

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

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

1638

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

1640

1641 # ActivationContextInfoData

1642 activationInfo = ActivationContextInfoData()

1643 activationInfo['pIFDClientCtx'] = NULL

1644 activationInfo['pIFDPrototypeCtx'] = NULL

1645

1646 dword = DWORD()

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

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

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

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

1651

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

1653

1654 # ServerLocation

1655 locationInfo = LocationInfoData()

1656 locationInfo['machineName'] = NULL

1657

1658 dword = DWORD()

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

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

1661

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

1663

1664 # ScmRequestInfo

1665 scmInfo = ScmRequestInfoData()

1666 scmInfo['pdwReserved'] = NULL

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

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

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

1670

1671 dword = DWORD()

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

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

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

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

1676

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

1678

1679 activationBLOB['Property'] = properties

1680

1681

1682 objrefcustom = OBJREF_CUSTOM()

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

1684 objrefcustom['clsid'] = CLSID_ActivationPropertiesIn

1685

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

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

1688

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

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

1691 resp = self.__portmap.request(request)

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

1693

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

1695 objRef = None

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

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

1698 elif objRefType == FLAGS_OBJREF_HANDLER:

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

1700 elif objRefType == FLAGS_OBJREF_STANDARD:

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

1702 elif objRefType == FLAGS_OBJREF_EXTENDED:

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

1704 else:

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

1706

1707

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

1709

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

1711 scmReply = activationBlob['Property'][

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

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

1714

1715 scmr = ScmReplyInfoData()

1716 size = scmr.fromString(scmReply)

1717 # Processing the scmReply

1718 scmr.fromStringReferents(scmReply[size:])

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

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

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

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

1723

1724 done = False

1725 stringBindings = list()

1726 while not done:

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

1728 done = True

1729 else:

1730 binding = STRINGBINDING(strBindings)

1731 stringBindings.append(binding)

1732 strBindings = strBindings[len(binding):]

1733

1734 done = False

1735 while not done:

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

1737 done = True

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

1739 done = True

1740 else:

1741 secBinding = SECURITYBINDING(securityBindings)

1742 securityBindings = securityBindings[len(secBinding):]

1743

1744 # Processing the Properties Output

1745 propsOut = PropsOutInfo()

1746 size = propsOut.fromString(propOutput)

1747 propsOut.fromStringReferents(propOutput[size:])

1748

1749 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings)

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

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

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

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

1754

1755 def RemoteCreateInstance(self, clsId, iid):

1756 # Only supports one interface at a time

1757 self.__portmap.bind(IID_IRemoteSCMActivator)

1758

1759 ORPCthis = ORPCTHIS()

1760 ORPCthis['cid'] = generate()

1761 ORPCthis['extensions'] = NULL

1762 ORPCthis['flags'] = 1

1763

1764 request = RemoteCreateInstance()

1765 request['ORPCthis'] = ORPCthis

1766 request['pUnkOuter'] = NULL

1767

1768 activationBLOB = ACTIVATION_BLOB()

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

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

1771 clsid = CLSID()

1772 clsid['Data'] = CLSID_InstantiationInfo

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

1774 clsid = CLSID()

1775 clsid['Data'] = CLSID_ActivationContextInfo

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

1777 clsid = CLSID()

1778 clsid['Data'] = CLSID_ServerLocationInfo

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

1780 clsid = CLSID()

1781 clsid['Data'] = CLSID_ScmRequestInfo

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

1783

1784 properties = b''

1785 # InstantiationInfo

1786 instantiationInfo = InstantiationInfoData()

1787 instantiationInfo['classId'] = clsId

1788 instantiationInfo['cIID'] = 1

1789

1790 _iid = IID()

1791 _iid['Data'] = iid

1792

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

1794

1795 dword = DWORD()

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

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

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

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

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

1801

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

1803

1804 # ActivationContextInfoData

1805 activationInfo = ActivationContextInfoData()

1806 activationInfo['pIFDClientCtx'] = NULL

1807 activationInfo['pIFDPrototypeCtx'] = NULL

1808

1809 dword = DWORD()

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

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

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

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

1814

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

1816

1817 # ServerLocation

1818 locationInfo = LocationInfoData()

1819 locationInfo['machineName'] = NULL

1820

1821 dword = DWORD()

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

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

1824

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

1826

1827 # ScmRequestInfo

1828 scmInfo = ScmRequestInfoData()

1829 scmInfo['pdwReserved'] = NULL

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

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

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

1833

1834 dword = DWORD()

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

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

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

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

1839

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

1841

1842 activationBLOB['Property'] = properties

1843

1844

1845 objrefcustom = OBJREF_CUSTOM()

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

1847 objrefcustom['clsid'] = CLSID_ActivationPropertiesIn

1848

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

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

1851

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

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

1854 resp = self.__portmap.request(request)

1855

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

1857

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

1859 objRef = None

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

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

1862 elif objRefType == FLAGS_OBJREF_HANDLER:

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

1864 elif objRefType == FLAGS_OBJREF_STANDARD:

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

1866 elif objRefType == FLAGS_OBJREF_EXTENDED:

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

1868 else:

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

1870

1871

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

1873

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

1875 scmReply = activationBlob['Property'][

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

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

1878

1879 scmr = ScmReplyInfoData()

1880 size = scmr.fromString(scmReply)

1881 # Processing the scmReply

1882 scmr.fromStringReferents(scmReply[size:])

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

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

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

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

1887

1888 done = False

1889 stringBindings = list()

1890 while not done:

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

1892 done = True

1893 else:

1894 binding = STRINGBINDING(strBindings)

1895 stringBindings.append(binding)

1896 strBindings = strBindings[len(binding):]

1897

1898 done = False

1899 while not done:

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

1901 done = True

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

1903 done = True

1904 else:

1905 secBinding = SECURITYBINDING(securityBindings)

1906 securityBindings = securityBindings[len(secBinding):]

1907

1908 # Processing the Properties Output

1909 propsOut = PropsOutInfo()

1910 size = propsOut.fromString(propOutput)

1911 propsOut.fromStringReferents(propOutput[size:])

1912

1913 classInstance = CLASS_INSTANCE(ORPCthis, stringBindings)

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

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

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

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