Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/drsuapi.py: 90%

# Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/drsuapi.py : 90%

## 646 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-DRSR] Directory Replication Service (DRS) DRSUAPI 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 from __future__ import division

22 from __future__ import print_function

23 from builtins import bytes

24 import hashlib

25 from struct import pack

26 import six

27 from six import PY2

28

29 from impacket import LOG

30 from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRUNION, NDR, NDRENUM

31 from impacket.dcerpc.v5.dtypes import PUUID, DWORD, NULL, GUID, LPWSTR, BOOL, ULONG, UUID, LONGLONG, ULARGE_INTEGER, LARGE_INTEGER

32 from impacket import hresult_errors, system_errors

33 from impacket.structure import Structure

34 from impacket.uuid import uuidtup_to_bin, string_to_bin

35 from impacket.dcerpc.v5.enum import Enum

36 from impacket.dcerpc.v5.rpcrt import DCERPCException

37 from impacket.krb5 import crypto

38 from pyasn1.type import univ

39 from pyasn1.codec.ber import decoder

40 from impacket.crypto import transformKey

41

42 try:

43 from Cryptodome.Cipher import ARC4, DES

44 except Exception:

45 LOG.critical("Warning: You don't have any crypto installed. You need pycryptodomex")

46 LOG.critical("See https://pypi.org/project/pycryptodomex/")

47

48 MSRPC_UUID_DRSUAPI = uuidtup_to_bin(('E3514235-4B06-11D1-AB04-00C04FC2DCD2','4.0'))

49

50 class DCERPCSessionError(DCERPCException):

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

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

53

54 def __str__( self ):

55 key = self.error_code

56 if key in hresult_errors.ERROR_MESSAGES: 56 ↛ 57line 56 didn't jump to line 57, because the condition on line 56 was never true

57 error_msg_short = hresult_errors.ERROR_MESSAGES[key][0]

58 error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1]

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

60 elif key & 0xffff in system_errors.ERROR_MESSAGES: 60 ↛ 65line 60 didn't jump to line 65, because the condition on line 60 was never false

61 error_msg_short = system_errors.ERROR_MESSAGES[key & 0xffff][0]

62 error_msg_verbose = system_errors.ERROR_MESSAGES[key & 0xffff][1]

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

64 else:

65 return 'DRSR SessionError: unknown error code: 0x%x' % self.error_code

66

67################################################################################

68# CONSTANTS

69################################################################################

70# 4.1.10.2.17 EXOP_ERR Codes

71 class EXOP_ERR(NDRENUM):

72 align = 4

73 align64 = 4

74 structure = (

75 ('Data', '<L'),

76 )

77 class enumItems(Enum):

78 EXOP_ERR_SUCCESS = 0x00000001

79 EXOP_ERR_UNKNOWN_OP = 0x00000002

80 EXOP_ERR_FSMO_NOT_OWNER = 0x00000003

81 EXOP_ERR_UPDATE_ERR = 0x00000004

82 EXOP_ERR_EXCEPTION = 0x00000005

83 EXOP_ERR_UNKNOWN_CALLER = 0x00000006

84 EXOP_ERR_RID_ALLOC = 0x00000007

85 EXOP_ERR_FSMO_OWNER_DELETED = 0x00000008

86 EXOP_ERR_FSMO_PENDING_OP = 0x00000009

87 EXOP_ERR_MISMATCH = 0x0000000A

88 EXOP_ERR_COULDNT_CONTACT = 0x0000000B

89 EXOP_ERR_FSMO_REFUSING_ROLES = 0x0000000C

90 EXOP_ERR_DIR_ERROR = 0x0000000D

91 EXOP_ERR_FSMO_MISSING_SETTINGS = 0x0000000E

92 EXOP_ERR_ACCESS_DENIED = 0x0000000F

93 EXOP_ERR_PARAM_ERROR = 0x00000010

94

95 def dump(self, msg = None, indent = 0):

96 if msg is None: 96 ↛ 97line 96 didn't jump to line 97, because the condition on line 96 was never true

97 msg = self.__class__.__name__

98 if msg != '': 98 ↛ 101line 98 didn't jump to line 101, because the condition on line 98 was never false

99 print(msg, end=' ')

100

101 try:

102 print(" %s" % self.enumItems(self.fields['Data']).name, end=' ')

103 except ValueError:

104 print(" %d" % self.fields['Data'])

105

106# 4.1.10.2.18 EXOP_REQ Codes

107 EXOP_FSMO_REQ_ROLE = 0x00000001

108 EXOP_FSMO_REQ_RID_ALLOC = 0x00000002

109 EXOP_FSMO_RID_REQ_ROLE = 0x00000003

110 EXOP_FSMO_REQ_PDC = 0x00000004

111 EXOP_FSMO_ABANDON_ROLE = 0x00000005

112 EXOP_REPL_OBJ = 0x00000006

113 EXOP_REPL_SECRETS = 0x00000007

114

115# 5.14 ATTRTYP

116 ATTRTYP = ULONG

117

118# 5.51 DSTIME

119 DSTIME = LONGLONG

120

121# 5.39 DRS_EXTENSIONS_INT

122 DRS_EXT_BASE = 0x00000001

123 DRS_EXT_ASYNCREPL = 0x00000002

124 DRS_EXT_REMOVEAPI = 0x00000004

125 DRS_EXT_MOVEREQ_V2 = 0x00000008

126 DRS_EXT_GETCHG_DEFLATE = 0x00000010

127 DRS_EXT_DCINFO_V1 = 0x00000020

128 DRS_EXT_RESTORE_USN_OPTIMIZATION = 0x00000040

129 DRS_EXT_ADDENTRY = 0x00000080

130 DRS_EXT_KCC_EXECUTE = 0x00000100

131 DRS_EXT_ADDENTRY_V2 = 0x00000200

132 DRS_EXT_LINKED_VALUE_REPLICATION = 0x00000400

133 DRS_EXT_DCINFO_V2 = 0x00000800

134 DRS_EXT_INSTANCE_TYPE_NOT_REQ_ON_MOD = 0x00001000

135 DRS_EXT_CRYPTO_BIND = 0x00002000

136 DRS_EXT_GET_REPL_INFO = 0x00004000

137 DRS_EXT_STRONG_ENCRYPTION = 0x00008000

138 DRS_EXT_DCINFO_VFFFFFFFF = 0x00010000

139 DRS_EXT_TRANSITIVE_MEMBERSHIP = 0x00020000

140 DRS_EXT_ADD_SID_HISTORY = 0x00040000

141 DRS_EXT_POST_BETA3 = 0x00080000

142 DRS_EXT_GETCHGREQ_V5 = 0x00100000

143 DRS_EXT_GETMEMBERSHIPS2 = 0x00200000

144 DRS_EXT_GETCHGREQ_V6 = 0x00400000

145 DRS_EXT_NONDOMAIN_NCS = 0x00800000

146 DRS_EXT_GETCHGREQ_V8 = 0x01000000

147 DRS_EXT_GETCHGREPLY_V5 = 0x02000000

148 DRS_EXT_GETCHGREPLY_V6 = 0x04000000

149 DRS_EXT_GETCHGREPLY_V9 = 0x00000100

150 DRS_EXT_WHISTLER_BETA3 = 0x08000000

151 DRS_EXT_W2K3_DEFLATE = 0x10000000

152 DRS_EXT_GETCHGREQ_V10 = 0x20000000

153 DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART2 = 0x40000000

154 DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART3 = 0x80000000

155

156# dwFlagsExt

157 DRS_EXT_ADAM = 0x00000001

158 DRS_EXT_LH_BETA2 = 0x00000002

159 DRS_EXT_RECYCLE_BIN = 0x00000004

160

161# 5.41 DRS_OPTIONS

162 DRS_ASYNC_OP = 0x00000001

163 DRS_GETCHG_CHECK = 0x00000002

164 DRS_UPDATE_NOTIFICATION = 0x00000002

165 DRS_ADD_REF = 0x00000004

166 DRS_SYNC_ALL = 0x00000008

167 DRS_DEL_REF = 0x00000008

168 DRS_WRIT_REP = 0x00000010

169 DRS_INIT_SYNC = 0x00000020

170 DRS_PER_SYNC = 0x00000040

171 DRS_MAIL_REP = 0x00000080

172 DRS_ASYNC_REP = 0x00000100

173 DRS_IGNORE_ERROR = 0x00000100

174 DRS_TWOWAY_SYNC = 0x00000200

175 DRS_CRITICAL_ONLY = 0x00000400

176 DRS_GET_ANC = 0x00000800

177 DRS_GET_NC_SIZE = 0x00001000

178 DRS_LOCAL_ONLY = 0x00001000

179 DRS_NONGC_RO_REP = 0x00002000

180 DRS_SYNC_BYNAME = 0x00004000

181 DRS_REF_OK = 0x00004000

182 DRS_FULL_SYNC_NOW = 0x00008000

183 DRS_NO_SOURCE = 0x00008000

184 DRS_FULL_SYNC_IN_PROGRESS = 0x00010000

185 DRS_FULL_SYNC_PACKET = 0x00020000

186 DRS_SYNC_REQUEUE = 0x00040000

187 DRS_SYNC_URGENT = 0x00080000

188 DRS_REF_GCSPN = 0x00100000

189 DRS_NO_DISCARD = 0x00100000

190 DRS_NEVER_SYNCED = 0x00200000

191 DRS_SPECIAL_SECRET_PROCESSING = 0x00400000

192 DRS_INIT_SYNC_NOW = 0x00800000

193 DRS_PREEMPTED = 0x01000000

194 DRS_SYNC_FORCED = 0x02000000

195 DRS_DISABLE_AUTO_SYNC = 0x04000000

196 DRS_DISABLE_PERIODIC_SYNC = 0x08000000

197 DRS_USE_COMPRESSION = 0x10000000

198 DRS_NEVER_NOTIFY = 0x20000000

199 DRS_SYNC_PAS = 0x40000000

200 DRS_GET_ALL_GROUP_MEMBERSHIP = 0x80000000

201

202

203# 5.113 LDAP_CONN_PROPERTIES

204 BND = 0x00000001

205 SSL = 0x00000002

206 UDP = 0x00000004

207 GC = 0x00000008

208 GSS = 0x00000010

209 NGO = 0x00000020

210 SPL = 0x00000040

211 MD5 = 0x00000080

212 SGN = 0x00000100

213 SL = 0x00000200

214

215# 5.137 NTSAPI_CLIENT_GUID

216 NTDSAPI_CLIENT_GUID = string_to_bin('e24d201a-4fd6-11d1-a3da-0000f875ae0d')

217

218# 5.139 NULLGUID

219 NULLGUID = string_to_bin('00000000-0000-0000-0000-000000000000')

220

221# 5.205 USN

222 USN = LONGLONG

223

224# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1

225 DS_NAME_FLAG_GCVERIFY = 0x00000004

226 DS_NAME_FLAG_TRUST_REFERRAL = 0x00000008

227 DS_NAME_FLAG_PRIVATE_RESOLVE_FPOS = 0x80000000

228

229 DS_LIST_SITES = 0xFFFFFFFF

230 DS_LIST_SERVERS_IN_SITE = 0xFFFFFFFE

231 DS_LIST_DOMAINS_IN_SITE = 0xFFFFFFFD

232 DS_LIST_SERVERS_FOR_DOMAIN_IN_SITE = 0xFFFFFFFC

233 DS_LIST_INFO_FOR_SERVER = 0xFFFFFFFB

234 DS_LIST_ROLES = 0xFFFFFFFA

235 DS_NT4_ACCOUNT_NAME_SANS_DOMAIN = 0xFFFFFFF9

236 DS_MAP_SCHEMA_GUID = 0xFFFFFFF8

237 DS_LIST_DOMAINS = 0xFFFFFFF7

238 DS_LIST_NCS = 0xFFFFFFF6

239 DS_ALT_SECURITY_IDENTITIES_NAME = 0xFFFFFFF5

240 DS_STRING_SID_NAME = 0xFFFFFFF4

241 DS_LIST_SERVERS_WITH_DCS_IN_SITE = 0xFFFFFFF3

242 DS_LIST_GLOBAL_CATALOG_SERVERS = 0xFFFFFFF1

243 DS_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX = 0xFFFFFFF0

244 DS_USER_PRINCIPAL_NAME_AND_ALTSECID = 0xFFFFFFEF

245

246 DS_USER_PRINCIPAL_NAME_FOR_LOGON = 0xFFFFFFF2

247

248# 5.53 ENTINF

249 ENTINF_FROM_MASTER = 0x00000001

250 ENTINF_DYNAMIC_OBJECT = 0x00000002

251 ENTINF_REMOTE_MODIFY = 0x00010000

252

253# 4.1.27.1.2 DRS_MSG_VERIFYREQ_V1

254 DRS_VERIFY_DSNAMES = 0x00000000

255 DRS_VERIFY_SIDS = 0x00000001

256 DRS_VERIFY_SAM_ACCOUNT_NAMES = 0x00000002

257 DRS_VERIFY_FPOS = 0x00000003

258

259# 4.1.11.1.2 DRS_MSG_NT4_CHGLOG_REQ_V1

260 DRS_NT4_CHGLOG_GET_CHANGE_LOG = 0x00000001

261 DRS_NT4_CHGLOG_GET_SERIAL_NUMBERS = 0x00000002

262

263# 4.1.10.2.15 DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER

264 DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER = 9

265################################################################################

266# STRUCTURES

267################################################################################

268# 4.1.10.2.16 ENCRYPTED_PAYLOAD

269 class ENCRYPTED_PAYLOAD(Structure):

270 structure = (

271 ('Salt','16s'),

272 ('CheckSum','<L'),

273 ('EncryptedData',':'),

274 )

275

276# 5.136 NT4SID

277 class NT4SID(NDRSTRUCT):

278 structure = (

279 ('Data','28s=b""'),

280 )

281 def getAlignment(self):

282 return 4

283

284# 5.40 DRS_HANDLE

285 class DRS_HANDLE(NDRSTRUCT):

286 structure = (

287 ('Data','20s=b""'),

288 )

289 def getAlignment(self):

290 return 4

291

292 class PDRS_HANDLE(NDRPOINTER):

293 referent = (

294 ('Data',DRS_HANDLE),

295 )

296

297# 5.38 DRS_EXTENSIONS

298 class BYTE_ARRAY(NDRUniConformantArray):

299 item = 'c'

300

301 class PBYTE_ARRAY(NDRPOINTER):

302 referent = (

303 ('Data',BYTE_ARRAY),

304 )

305

306 class DRS_EXTENSIONS(NDRSTRUCT):

307 structure = (

308 ('cb',DWORD),

309 ('rgb',BYTE_ARRAY),

310 )

311

312 class PDRS_EXTENSIONS(NDRPOINTER):

313 referent = (

314 ('Data',DRS_EXTENSIONS),

315 )

316

317# 5.39 DRS_EXTENSIONS_INT

318 class DRS_EXTENSIONS_INT(Structure):

319 structure = (

320 ('dwFlags','<L=0'),

321 ('SiteObjGuid','16s=b""'),

322 ('Pid','<L=0'),

323 ('dwReplEpoch','<L=0'),

324 ('dwFlagsExt','<L=0'),

325 ('ConfigObjGUID','16s=b""'),

326 ('dwExtCaps','<L=0'),

327 )

328

329# 4.1.5.1.2 DRS_MSG_DCINFOREQ_V1

330 class DRS_MSG_DCINFOREQ_V1(NDRSTRUCT):

331 structure = (

332 ('Domain',LPWSTR),

333 ('InfoLevel',DWORD),

334 )

335

336# 4.1.5.1.1 DRS_MSG_DCINFOREQ

337 class DRS_MSG_DCINFOREQ(NDRUNION):

338 commonHdr = (

339 ('tag', DWORD),

340 )

341 union = {

342 1 : ('V1', DRS_MSG_DCINFOREQ_V1),

343 }

344

345# 4.1.5.1.8 DS_DOMAIN_CONTROLLER_INFO_1W

346 class DS_DOMAIN_CONTROLLER_INFO_1W(NDRSTRUCT):

347 structure = (

348 ('NetbiosName',LPWSTR),

349 ('DnsHostName',LPWSTR),

350 ('SiteName',LPWSTR),

351 ('ComputerObjectName',LPWSTR),

352 ('ServerObjectName',LPWSTR),

353 ('fIsPdc',BOOL),

354 ('fDsEnabled',BOOL),

355 )

356

357 class DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRUniConformantArray):

358 item = DS_DOMAIN_CONTROLLER_INFO_1W

359

360 class PDS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRPOINTER):

361 referent = (

362 ('Data',DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY),

363 )

364

365# 4.1.5.1.4 DRS_MSG_DCINFOREPLY_V1

366 class DRS_MSG_DCINFOREPLY_V1(NDRSTRUCT):

367 structure = (

368 ('cItems',DWORD),

369 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_1W_ARRAY),

370 )

371

372# 4.1.5.1.9 DS_DOMAIN_CONTROLLER_INFO_2W

373 class DS_DOMAIN_CONTROLLER_INFO_2W(NDRSTRUCT):

374 structure = (

375 ('NetbiosName',LPWSTR),

376 ('DnsHostName',LPWSTR),

377 ('SiteName',LPWSTR),

378 ('SiteObjectName',LPWSTR),

379 ('ComputerObjectName',LPWSTR),

380 ('ServerObjectName',LPWSTR),

381 ('NtdsDsaObjectName',LPWSTR),

382 ('fIsPdc',BOOL),

383 ('fDsEnabled',BOOL),

384 ('fIsGc',BOOL),

385 ('SiteObjectGuid',GUID),

386 ('ComputerObjectGuid',GUID),

387 ('ServerObjectGuid',GUID),

388 ('NtdsDsaObjectGuid',GUID),

389 )

390

391 class DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRUniConformantArray):

392 item = DS_DOMAIN_CONTROLLER_INFO_2W

393

394 class PDS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRPOINTER):

395 referent = (

396 ('Data',DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY),

397 )

398

399# 4.1.5.1.5 DRS_MSG_DCINFOREPLY_V2

400 class DRS_MSG_DCINFOREPLY_V2(NDRSTRUCT):

401 structure = (

402 ('cItems',DWORD),

403 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_2W_ARRAY),

404 )

405

406# 4.1.5.1.10 DS_DOMAIN_CONTROLLER_INFO_3W

407 class DS_DOMAIN_CONTROLLER_INFO_3W(NDRSTRUCT):

408 structure = (

409 ('NetbiosName',LPWSTR),

410 ('DnsHostName',LPWSTR),

411 ('SiteName',LPWSTR),

412 ('SiteObjectName',LPWSTR),

413 ('ComputerObjectName',LPWSTR),

414 ('ServerObjectName',LPWSTR),

415 ('NtdsDsaObjectName',LPWSTR),

416 ('fIsPdc',BOOL),

417 ('fDsEnabled',BOOL),

418 ('fIsGc',BOOL),

419 ('fIsRodc',BOOL),

420 ('SiteObjectGuid',GUID),

421 ('ComputerObjectGuid',GUID),

422 ('ServerObjectGuid',GUID),

423 ('NtdsDsaObjectGuid',GUID),

424 )

425

426 class DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRUniConformantArray):

427 item = DS_DOMAIN_CONTROLLER_INFO_3W

428

429 class PDS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRPOINTER):

430 referent = (

431 ('Data',DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY),

432 )

433

434# 4.1.5.1.6 DRS_MSG_DCINFOREPLY_V3

435 class DRS_MSG_DCINFOREPLY_V3(NDRSTRUCT):

436 structure = (

437 ('cItems',DWORD),

438 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_3W_ARRAY),

439 )

440

441# 4.1.5.1.11 DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW

442 class DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW(NDRSTRUCT):

443 structure = (

444 ('IPAddress',DWORD),

445 ('NotificationCount',DWORD),

446 ('secTimeConnected',DWORD),

447 ('Flags',DWORD),

448 ('TotalRequests',DWORD),

449 ('Reserved1',DWORD),

450 ('UserName',LPWSTR),

451 )

452

453 class DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRUniConformantArray):

454 item = DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW

455

456 class PDS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRPOINTER):

457 referent = (

458 ('Data',DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY),

459 )

460

461# 4.1.5.1.7 DRS_MSG_DCINFOREPLY_VFFFFFFFF

462 class DRS_MSG_DCINFOREPLY_VFFFFFFFF(NDRSTRUCT):

463 structure = (

464 ('cItems',DWORD),

465 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY),

466 )

467

468# 4.1.5.1.3 DRS_MSG_DCINFOREPLY

469 class DRS_MSG_DCINFOREPLY(NDRUNION):

470 commonHdr = (

471 ('tag', DWORD),

472 )

473 union = {

474 1 : ('V1', DRS_MSG_DCINFOREPLY_V1),

475 2 : ('V2', DRS_MSG_DCINFOREPLY_V2),

476 3 : ('V3', DRS_MSG_DCINFOREPLY_V3),

477 0xffffffff : ('V1', DRS_MSG_DCINFOREPLY_VFFFFFFFF),

478 }

479

480# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1

481 class LPWSTR_ARRAY(NDRUniConformantArray):

482 item = LPWSTR

483

484 class PLPWSTR_ARRAY(NDRPOINTER):

485 referent = (

486 ('Data',LPWSTR_ARRAY),

487 )

488

489 class DRS_MSG_CRACKREQ_V1(NDRSTRUCT):

490 structure = (

491 ('CodePage',ULONG),

492 ('LocaleId',ULONG),

493 ('dwFlags',DWORD),

494 ('formatOffered',DWORD),

495 ('formatDesired',DWORD),

496 ('cNames',DWORD),

497 ('rpNames',PLPWSTR_ARRAY),

498 )

499

500# 4.1.4.1.1 DRS_MSG_CRACKREQ

501 class DRS_MSG_CRACKREQ(NDRUNION):

502 commonHdr = (

503 ('tag', DWORD),

504 )

505 union = {

506 1 : ('V1', DRS_MSG_CRACKREQ_V1),

507 }

508

509# 4.1.4.1.3 DS_NAME_FORMAT

510 class DS_NAME_FORMAT(NDRENUM):

511 class enumItems(Enum):

512 DS_UNKNOWN_NAME = 0

513 DS_FQDN_1779_NAME = 1

514 DS_NT4_ACCOUNT_NAME = 2

515 DS_DISPLAY_NAME = 3

516 DS_UNIQUE_ID_NAME = 6

517 DS_CANONICAL_NAME = 7

518 DS_USER_PRINCIPAL_NAME = 8

519 DS_CANONICAL_NAME_EX = 9

520 DS_SERVICE_PRINCIPAL_NAME = 10

521 DS_SID_OR_SID_HISTORY_NAME = 11

522 DS_DNS_DOMAIN_NAME = 12

523

524# 4.1.4.1.4 DS_NAME_RESULT_ITEMW

525 class DS_NAME_RESULT_ITEMW(NDRSTRUCT):

526 structure = (

527 ('status',DWORD),

528 ('pDomain',LPWSTR),

529 ('pName',LPWSTR),

530 )

531

532 class DS_NAME_RESULT_ITEMW_ARRAY(NDRUniConformantArray):

533 item = DS_NAME_RESULT_ITEMW

534

535 class PDS_NAME_RESULT_ITEMW_ARRAY(NDRPOINTER):

536 referent = (

537 ('Data',DS_NAME_RESULT_ITEMW_ARRAY),

538 )

539

540# 4.1.4.1.5 DS_NAME_RESULTW

541 class DS_NAME_RESULTW(NDRSTRUCT):

542 structure = (

543 ('cItems',DWORD),

544 ('rItems',PDS_NAME_RESULT_ITEMW_ARRAY),

545 )

546

547 class PDS_NAME_RESULTW(NDRPOINTER):

548 referent = (

549 ('Data',DS_NAME_RESULTW),

550 )

551

552# 4.1.4.1.7 DRS_MSG_CRACKREPLY_V1

553 class DRS_MSG_CRACKREPLY_V1(NDRSTRUCT):

554 structure = (

555 ('pResult',PDS_NAME_RESULTW),

556 )

557

558# 4.1.4.1.6 DRS_MSG_CRACKREPLY

559 class DRS_MSG_CRACKREPLY(NDRUNION):

560 commonHdr = (

561 ('tag', DWORD),

562 )

563 union = {

564 1 : ('V1', DRS_MSG_CRACKREPLY_V1),

565 }

566

567# 5.198 UPTODATE_CURSOR_V1

568 class UPTODATE_CURSOR_V1(NDRSTRUCT):

569 structure = (

570 ('uuidDsa',UUID),

571 ('usnHighPropUpdate',USN),

572 )

573

574 class UPTODATE_CURSOR_V1_ARRAY(NDRUniConformantArray):

575 item = UPTODATE_CURSOR_V1

576

577# 5.200 UPTODATE_VECTOR_V1_EXT

578 class UPTODATE_VECTOR_V1_EXT(NDRSTRUCT):

579 structure = (

580 ('dwVersion',DWORD),

581 ('dwReserved1',DWORD),

582 ('cNumCursors',DWORD),

583 ('dwReserved2',DWORD),

584 ('rgCursors',UPTODATE_CURSOR_V1_ARRAY),

585 )

586

587 class PUPTODATE_VECTOR_V1_EXT(NDRPOINTER):

588 referent = (

589 ('Data',UPTODATE_VECTOR_V1_EXT),

590 )

591

592# 5.206 USN_VECTOR

593 class USN_VECTOR(NDRSTRUCT):

594 structure = (

595 ('usnHighObjUpdate',USN),

596 ('usnReserved',USN),

597 ('usnHighPropUpdate',USN),

598 )

599

600# 5.50 DSNAME

601 class WCHAR_ARRAY(NDRUniConformantArray):

602 item = 'H'

603

604 def __setitem__(self, key, value):

605 self.fields['MaximumCount'] = None

606 self.data = None # force recompute

607 return NDRUniConformantArray.__setitem__(self, key, [ord(c) for c in value])

608

609 def __getitem__(self, key):

610 if key == 'Data': 610 ↛ 617line 610 didn't jump to line 617, because the condition on line 610 was never false

611 try:

612 return ''.join([six.unichr(i) for i in self.fields[key]])

613 except ValueError as e:

614 LOG.debug("ValueError Exception", exc_info=True)

615 LOG.error(str(e))

616 else:

617 return NDR.__getitem__(self,key)

618

619 class DSNAME(NDRSTRUCT):

620 structure = (

621 ('structLen',ULONG),

622 ('SidLen',ULONG),

623 ('Guid',GUID),

624 ('Sid',NT4SID),

625 ('NameLen',ULONG),

626 ('StringName', WCHAR_ARRAY),

627 )

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

629 return self['NameLen']

630 def getData(self, soFar = 0):

631 return NDRSTRUCT.getData(self, soFar)

632

633 class PDSNAME(NDRPOINTER):

634 referent = (

635 ('Data',DSNAME),

636 )

637

638 class PDSNAME_ARRAY(NDRUniConformantArray):

639 item = PDSNAME

640

641 class PPDSNAME_ARRAY(NDRPOINTER):

642 referent = (

643 ('Data',PDSNAME_ARRAY),

644 )

645

646 class ATTRTYP_ARRAY(NDRUniConformantArray):

647 item = ATTRTYP

648

649# 5.145 PARTIAL_ATTR_VECTOR_V1_EXT

650 class PARTIAL_ATTR_VECTOR_V1_EXT(NDRSTRUCT):

651 structure = (

652 ('dwVersion',DWORD),

653 ('dwReserved1',DWORD),

654 ('cAttrs',DWORD),

655 ('rgPartialAttr',ATTRTYP_ARRAY),

656 )

657

658 class PPARTIAL_ATTR_VECTOR_V1_EXT(NDRPOINTER):

659 referent = (

660 ('Data',PARTIAL_ATTR_VECTOR_V1_EXT),

661 )

662

663# 5.142 OID_t

664 class OID_t(NDRSTRUCT):

665 structure = (

666 ('length',ULONG),

667 ('elements',PBYTE_ARRAY),

668 )

669

670# 5.153 PrefixTableEntry

671 class PrefixTableEntry(NDRSTRUCT):

672 structure = (

673 ('ndx',ULONG),

674 ('prefix',OID_t),

675 )

676

677 class PrefixTableEntry_ARRAY(NDRUniConformantArray):

678 item = PrefixTableEntry

679

680 class PPrefixTableEntry_ARRAY(NDRPOINTER):

681 referent = (

682 ('Data',PrefixTableEntry_ARRAY),

683 )

684

685# 5.177 SCHEMA_PREFIX_TABLE

686 class SCHEMA_PREFIX_TABLE(NDRSTRUCT):

687 structure = (

688 ('PrefixCount',DWORD),

689 ('pPrefixEntry',PPrefixTableEntry_ARRAY),

690 )

691

692# 4.1.10.2.2 DRS_MSG_GETCHGREQ_V3

693 class DRS_MSG_GETCHGREQ_V3(NDRSTRUCT):

694 structure = (

695 ('uuidDsaObjDest',UUID),

696 ('uuidInvocIdSrc',UUID),

697 ('pNC',PDSNAME),

698 ('usnvecFrom',USN_VECTOR),

699 ('pUpToDateVecDestV1',PUPTODATE_VECTOR_V1_EXT),

700 ('pPartialAttrVecDestV1',PPARTIAL_ATTR_VECTOR_V1_EXT),

701 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

702 ('ulFlags',ULONG),

703 ('cMaxObjects',ULONG),

704 ('cMaxBytes',ULONG),

705 ('ulExtendedOp',ULONG),

706 )

707

708# 5.131 MTX_ADDR

709 class MTX_ADDR(NDRSTRUCT):

710 structure = (

711 ('mtx_namelen',ULONG),

712 ('mtx_name',PBYTE_ARRAY),

713 )

714

715 class PMTX_ADDR(NDRPOINTER):

716 referent = (

717 ('Data',MTX_ADDR),

718 )

719

720# 4.1.10.2.3 DRS_MSG_GETCHGREQ_V4

721 class DRS_MSG_GETCHGREQ_V4(NDRSTRUCT):

722 structure = (

723 ('uuidTransportObj',UUID),

724 ('pmtxReturnAddress',PMTX_ADDR),

725 ('V3',DRS_MSG_GETCHGREQ_V3),

726 )

727

728# 4.1.10.2.4 DRS_MSG_GETCHGREQ_V5

729 class DRS_MSG_GETCHGREQ_V5(NDRSTRUCT):

730 structure = (

731 ('uuidDsaObjDest',UUID),

732 ('uuidInvocIdSrc',UUID),

733 ('pNC',PDSNAME),

734 ('usnvecFrom',USN_VECTOR),

735 ('pUpToDateVecDestV1',PUPTODATE_VECTOR_V1_EXT),

736 ('ulFlags',ULONG),

737 ('cMaxObjects',ULONG),

738 ('cMaxBytes',ULONG),

739 ('ulExtendedOp',ULONG),

740 ('liFsmoInfo',ULARGE_INTEGER),

741 )

742

743# 4.1.10.2.5 DRS_MSG_GETCHGREQ_V7

744 class DRS_MSG_GETCHGREQ_V7(NDRSTRUCT):

745 structure = (

746 ('uuidTransportObj',UUID),

747 ('pmtxReturnAddress',PMTX_ADDR),

748 ('V3',DRS_MSG_GETCHGREQ_V3),

749 ('pPartialAttrSet',PPARTIAL_ATTR_VECTOR_V1_EXT),

750 ('pPartialAttrSetEx1',PPARTIAL_ATTR_VECTOR_V1_EXT),

751 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

752 )

753

754# 4.1.10.2.6 DRS_MSG_GETCHGREQ_V8

755 class DRS_MSG_GETCHGREQ_V8(NDRSTRUCT):

756 structure = (

757 ('uuidDsaObjDest',UUID),

758 ('uuidInvocIdSrc',UUID),

759 ('pNC',PDSNAME),

760 ('usnvecFrom',USN_VECTOR),

761 ('pUpToDateVecDest',PUPTODATE_VECTOR_V1_EXT),

762 ('ulFlags',ULONG),

763 ('cMaxObjects',ULONG),

764 ('cMaxBytes',ULONG),

765 ('ulExtendedOp',ULONG),

766 ('liFsmoInfo',ULARGE_INTEGER),

767 ('pPartialAttrSet',PPARTIAL_ATTR_VECTOR_V1_EXT),

768 ('pPartialAttrSetEx1',PPARTIAL_ATTR_VECTOR_V1_EXT),

769 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

770 )

771

772# 4.1.10.2.7 DRS_MSG_GETCHGREQ_V10

773 class DRS_MSG_GETCHGREQ_V10(NDRSTRUCT):

774 structure = (

775 ('uuidDsaObjDest',UUID),

776 ('uuidInvocIdSrc',UUID),

777 ('pNC',PDSNAME),

778 ('usnvecFrom',USN_VECTOR),

779 ('pUpToDateVecDest',PUPTODATE_VECTOR_V1_EXT),

780 ('ulFlags',ULONG),

781 ('cMaxObjects',ULONG),

782 ('cMaxBytes',ULONG),

783 ('ulExtendedOp',ULONG),

784 ('liFsmoInfo',ULARGE_INTEGER),

785 ('pPartialAttrSet',PPARTIAL_ATTR_VECTOR_V1_EXT),

786 ('pPartialAttrSetEx1',PPARTIAL_ATTR_VECTOR_V1_EXT),

787 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

788 ('ulMoreFlags',ULONG),

789 )

790

791# 4.1.10.2.1 DRS_MSG_GETCHGREQ

792 class DRS_MSG_GETCHGREQ(NDRUNION):

793 commonHdr = (

794 ('tag', DWORD),

795 )

796 union = {

797 4 : ('V4', DRS_MSG_GETCHGREQ_V4),

798 5 : ('V5', DRS_MSG_GETCHGREQ_V5),

799 7 : ('V7', DRS_MSG_GETCHGREQ_V7),

800 8 : ('V8', DRS_MSG_GETCHGREQ_V8),

801 10 : ('V10', DRS_MSG_GETCHGREQ_V10),

802 }

803

804# 5.16 ATTRVAL

805 class ATTRVAL(NDRSTRUCT):

806 structure = (

807 ('valLen',ULONG),

808 ('pVal',PBYTE_ARRAY),

809 )

810

811 class ATTRVAL_ARRAY(NDRUniConformantArray):

812 item = ATTRVAL

813

814 class PATTRVAL_ARRAY(NDRPOINTER):

815 referent = (

816 ('Data',ATTRVAL_ARRAY),

817 )

818

819# 5.17 ATTRVALBLOCK

820 class ATTRVALBLOCK(NDRSTRUCT):

821 structure = (

822 ('valCount',ULONG),

823 ('pAVal',PATTRVAL_ARRAY),

824 )

825

826# 5.9 ATTR

827 class ATTR(NDRSTRUCT):

828 structure = (

829 ('attrTyp',ATTRTYP),

830 ('AttrVal',ATTRVALBLOCK),

831 )

832

833 class ATTR_ARRAY(NDRUniConformantArray):

834 item = ATTR

835

836 class PATTR_ARRAY(NDRPOINTER):

837 referent = (

838 ('Data',ATTR_ARRAY),

839 )

840

841# 5.10 ATTRBLOCK

842 class ATTRBLOCK(NDRSTRUCT):

843 structure = (

844 ('attrCount',ULONG),

845 ('pAttr',PATTR_ARRAY),

846 )

847

848# 5.53 ENTINF

849 class ENTINF(NDRSTRUCT):

850 structure = (

851 ('pName',PDSNAME),

852 ('ulFlags',ULONG),

853 ('AttrBlock',ATTRBLOCK),

854 )

855

856 class ENTINF_ARRAY(NDRUniConformantArray):

857 item = ENTINF

858

859 class PENTINF_ARRAY(NDRPOINTER):

860 referent = (

861 ('Data',ENTINF_ARRAY),

862 )

863

864# 5.154 PROPERTY_META_DATA_EXT

865 class PROPERTY_META_DATA_EXT(NDRSTRUCT):

866 structure = (

867 ('dwVersion',DWORD),

868 ('timeChanged',DSTIME),

869 ('uuidDsaOriginating',UUID),

870 ('usnOriginating',USN),

871 )

872

873 class PROPERTY_META_DATA_EXT_ARRAY(NDRUniConformantArray):

874 item = PROPERTY_META_DATA_EXT

875

876# 5.155 PROPERTY_META_DATA_EXT_VECTOR

877 class PROPERTY_META_DATA_EXT_VECTOR(NDRSTRUCT):

878 structure = (

879 ('cNumProps',DWORD),

880 ('rgMetaData',PROPERTY_META_DATA_EXT_ARRAY),

881 )

882

883 class PPROPERTY_META_DATA_EXT_VECTOR(NDRPOINTER):

884 referent = (

885 ('Data',PROPERTY_META_DATA_EXT_VECTOR),

886 )

887

888# 5.161 REPLENTINFLIST

889

890 class REPLENTINFLIST(NDRSTRUCT):

891 structure = (

892 ('pNextEntInf',NDRPOINTER),

893 ('Entinf',ENTINF),

894 ('fIsNCPrefix',BOOL),

895 ('pParentGuidm',PUUID),

896 ('pMetaDataExt',PPROPERTY_META_DATA_EXT_VECTOR),

897 )

898 # ToDo: Here we should work with getData and fromString because we're cheating with pNextEntInf

899 def fromString(self, data, soFar = 0 ):

900 # Here we're changing the struct so we can represent a linked list with NDR

901 self.fields['pNextEntInf'] = PREPLENTINFLIST(isNDR64 = self._isNDR64)

902 retVal = NDRSTRUCT.fromString(self, data, soFar)

903 return retVal

904

905 class PREPLENTINFLIST(NDRPOINTER):

906 referent = (

907 ('Data',REPLENTINFLIST),

908 )

909

910# 4.1.10.2.9 DRS_MSG_GETCHGREPLY_V1

911 class DRS_MSG_GETCHGREPLY_V1(NDRSTRUCT):

912 structure = (

913 ('uuidDsaObjSrc',UUID),

914 ('uuidInvocIdSrc',UUID),

915 ('pNC',PDSNAME),

916 ('usnvecFrom',USN_VECTOR),

917 ('usnvecTo',USN_VECTOR),

918 ('pUpToDateVecSrcV1',PUPTODATE_VECTOR_V1_EXT),

919 ('PrefixTableSrc',SCHEMA_PREFIX_TABLE),

920 ('ulExtendedRet',EXOP_ERR),

921 ('cNumObjects',ULONG),

922 ('cNumBytes',ULONG),

923 ('pObjects',PREPLENTINFLIST),

924 ('fMoreData',BOOL),

925 )

926

927# 4.1.10.2.15 DRS_COMPRESSED_BLOB

928 class DRS_COMPRESSED_BLOB(NDRSTRUCT):

929 structure = (

930 ('cbUncompressedSize',DWORD),

931 ('cbCompressedSize',DWORD),

932 ('pbCompressedData',BYTE_ARRAY),

933 )

934

935# 4.1.10.2.10 DRS_MSG_GETCHGREPLY_V2

936 class DRS_MSG_GETCHGREPLY_V2(NDRSTRUCT):

937 structure = (

938 ('CompressedV1',DRS_COMPRESSED_BLOB),

939 )

940

941# 5.199 UPTODATE_CURSOR_V2

942 class UPTODATE_CURSOR_V2(NDRSTRUCT):

943 structure = (

944 ('uuidDsa',UUID),

945 ('usnHighPropUpdate',USN),

946 ('timeLastSyncSuccess',DSTIME),

947 )

948

949 class UPTODATE_CURSOR_V2_ARRAY(NDRUniConformantArray):

950 item = UPTODATE_CURSOR_V2

951

952# 5.201 UPTODATE_VECTOR_V2_EXT

953 class UPTODATE_VECTOR_V2_EXT(NDRSTRUCT):

954 structure = (

955 ('dwVersion',DWORD),

956 ('dwReserved1',DWORD),

957 ('cNumCursors',DWORD),

958 ('dwReserved2',DWORD),

959 ('rgCursors',UPTODATE_CURSOR_V2_ARRAY),

960 )

961

962 class PUPTODATE_VECTOR_V2_EXT(NDRPOINTER):

963 referent = (

964 ('Data',UPTODATE_VECTOR_V2_EXT),

965 )

966

967# 5.211 VALUE_META_DATA_EXT_V1

968 class VALUE_META_DATA_EXT_V1(NDRSTRUCT):

969 structure = (

970 ('timeCreated',DSTIME),

971 ('MetaData',PROPERTY_META_DATA_EXT),

972 )

973

974# 5.215 VALUE_META_DATA_EXT_V3

975 class VALUE_META_DATA_EXT_V3(NDRSTRUCT):

976 structure = (

977 ('timeCreated',DSTIME),

978 ('MetaData',PROPERTY_META_DATA_EXT),

979 ('unused1',DWORD),

980 ('unused1',DWORD),

981 ('unused1',DWORD),

982 ('timeExpired',DSTIME),

983 )

984

985# 5.167 REPLVALINF_V1

986 class REPLVALINF_V1(NDRSTRUCT):

987 structure = (

988 ('pObject',PDSNAME),

989 ('attrTyp',ATTRTYP),

990 ('Aval',ATTRVAL),

991 ('fIsPresent',BOOL),

992 ('MetaData',VALUE_META_DATA_EXT_V1),

993 )

994

995 def fromString(self, data, soFar = 0):

996 retVal = NDRSTRUCT.fromString(self, data, soFar)

997 #self.dumpRaw()

998 return retVal

999

1000 class REPLVALINF_V1_ARRAY(NDRUniConformantArray):

1001 item = REPLVALINF_V1

1002

1003 class PREPLVALINF_V1_ARRAY(NDRPOINTER):

1004 referent = (

1005 ('Data', REPLVALINF_V1_ARRAY),

1006 )

1007

1008# 5.168 REPLVALINF_V3

1009 class REPLVALINF_V3(NDRSTRUCT):

1010 structure = (

1011 ('pObject', PDSNAME),

1012 ('attrTyp', ATTRTYP),

1013 ('Aval', ATTRVAL),

1014 ('fIsPresent', BOOL),

1015 ('MetaData', VALUE_META_DATA_EXT_V3),

1016 )

1017

1018 def fromString(self, data, soFar=0):

1019 retVal = NDRSTRUCT.fromString(self, data, soFar)

1020 # self.dumpRaw()

1021 return retVal

1022

1023 class REPLVALINF_V3_ARRAY(NDRUniConformantArray):

1024 item = REPLVALINF_V3

1025

1026 class PREPLVALINF_V3_ARRAY(NDRPOINTER):

1027 referent = (

1028 ('Data', REPLVALINF_V3_ARRAY),

1029 )

1030

1031# 5.169 REPLVALINF_NATIVE

1032 REPLVALINF_NATIVE = REPLVALINF_V3

1033

1034# 4.1.10.2.11 DRS_MSG_GETCHGREPLY_V6

1035 class DRS_MSG_GETCHGREPLY_V6(NDRSTRUCT):

1036 structure = (

1037 ('uuidDsaObjSrc',UUID),

1038 ('uuidInvocIdSrc',UUID),

1039 ('pNC',PDSNAME),

1040 ('usnvecFrom',USN_VECTOR),

1041 ('usnvecTo',USN_VECTOR),

1042 ('pUpToDateVecSrc',PUPTODATE_VECTOR_V2_EXT),

1043 ('PrefixTableSrc',SCHEMA_PREFIX_TABLE),

1044 ('ulExtendedRet',EXOP_ERR),

1045 ('cNumObjects',ULONG),

1046 ('cNumBytes',ULONG),

1047 ('pObjects',PREPLENTINFLIST),

1048 ('fMoreData',BOOL),

1049 ('cNumNcSizeObjectsc',ULONG),

1050 ('cNumNcSizeValues',ULONG),

1051 ('cNumValues',DWORD),

1052 #('rgValues',PREPLVALINF_V1_ARRAY),

1053 # ToDo: Once we find out what's going on with PREPLVALINF_ARRAY get it back

1054 # Seems there's something in there that is not being parsed correctly

1055 ('rgValues',DWORD),

1056 ('dwDRSError',DWORD),

1057 )

1058

1059# 4.1.10.2.14 DRS_COMP_ALG_TYPE

1060 class DRS_COMP_ALG_TYPE(NDRENUM):

1061 class enumItems(Enum):

1062 DRS_COMP_ALG_NONE = 0

1063 DRS_COMP_ALG_UNUSED = 1

1064 DRS_COMP_ALG_MSZIP = 2

1065 DRS_COMP_ALG_WIN2K3 = 3

1066

1067# 4.1.10.2.12 DRS_MSG_GETCHGREPLY_V7

1068 class DRS_MSG_GETCHGREPLY_V7(NDRSTRUCT):

1069 structure = (

1070 ('dwCompressedVersion',DWORD),

1071 ('CompressionAlg',DRS_COMP_ALG_TYPE),

1072 ('CompressedAny',DRS_COMPRESSED_BLOB),

1073 )

1074

1075# 4.1.10.2.13 DRS_MSG_GETCHGREPLY_V9

1076 class DRS_MSG_GETCHGREPLY_V9(NDRSTRUCT):

1077 structure = (

1078 ('uuidDsaObjSrc',UUID),

1079 ('uuidInvocIdSrc',UUID),

1080 ('pNC',PDSNAME),

1081 ('usnvecFrom',USN_VECTOR),

1082 ('usnvecTo',USN_VECTOR),

1083 ('pUpToDateVecSrc',PUPTODATE_VECTOR_V2_EXT),

1084 ('PrefixTableSrc',SCHEMA_PREFIX_TABLE),

1085 ('ulExtendedRet',EXOP_ERR),

1086 ('cNumObjects',ULONG),

1087 ('cNumBytes',ULONG),

1088 ('pObjects',PREPLENTINFLIST),

1089 ('fMoreData',BOOL),

1090 ('cNumNcSizeObjectsc',ULONG),

1091 ('cNumNcSizeValues',ULONG),

1092 ('cNumValues',DWORD),

1093 #('rgValues',PREPLVALINF_V3_ARRAY),

1094 # ToDo: Once we find out what's going on with PREPLVALINF_ARRAY get it back

1095 # Seems there's something in there that is not being parsed correctly

1096 ('rgValues',DWORD),

1097 ('dwDRSError',DWORD),

1098 )

1099

1100# 4.1.10.2.14 DRS_MSG_GETCHGREPLY_NATIVE

1101 DRS_MSG_GETCHGREPLY_NATIVE = DRS_MSG_GETCHGREPLY_V9

1102

1103# 4.1.10.2.8 DRS_MSG_GETCHGREPLY

1104 class DRS_MSG_GETCHGREPLY(NDRUNION):

1105 commonHdr = (

1106 ('tag', DWORD),

1107 )

1108 union = {

1109 1 : ('V1', DRS_MSG_GETCHGREPLY_V1),

1110 2 : ('V2', DRS_MSG_GETCHGREPLY_V2),

1111 6 : ('V6', DRS_MSG_GETCHGREPLY_V6),

1112 7 : ('V7', DRS_MSG_GETCHGREPLY_V7),

1113 9 : ('V9', DRS_MSG_GETCHGREPLY_V9),

1114 }

1115

1116# 4.1.27.1.2 DRS_MSG_VERIFYREQ_V1

1117 class DRS_MSG_VERIFYREQ_V1(NDRSTRUCT):

1118 structure = (

1119 ('dwFlags',DWORD),

1120 ('cNames',DWORD),

1121 ('rpNames',PPDSNAME_ARRAY),

1122 ('RequiredAttrs',ATTRBLOCK),

1123 ('PrefixTable',SCHEMA_PREFIX_TABLE),

1124 )

1125

1126# 4.1.27.1.1 DRS_MSG_VERIFYREQ

1127 class DRS_MSG_VERIFYREQ(NDRUNION):

1128 commonHdr = (

1129 ('tag', DWORD),

1130 )

1131 union = {

1132 1 : ('V1', DRS_MSG_VERIFYREQ_V1),

1133 }

1134

1135# 4.1.27.1.4 DRS_MSG_VERIFYREPLY_V1

1136 class DRS_MSG_VERIFYREPLY_V1(NDRSTRUCT):

1137 structure = (

1138 ('error',DWORD),

1139 ('cNames',DWORD),

1140 ('rpEntInf',PENTINF_ARRAY),

1141 ('PrefixTable',SCHEMA_PREFIX_TABLE),

1142 )

1143

1144# 4.1.27.1.3 DRS_MSG_VERIFYREPLY

1145 class DRS_MSG_VERIFYREPLY(NDRUNION):

1146 commonHdr = (

1147 ('tag', DWORD),

1148 )

1149 union = {

1150 1 : ('V1', DRS_MSG_VERIFYREPLY_V1),

1151 }

1152

1153# 4.1.11.1.2 DRS_MSG_NT4_CHGLOG_REQ_V1

1154 class DRS_MSG_NT4_CHGLOG_REQ_V1(NDRSTRUCT):

1155 structure = (

1156 ('dwFlags',DWORD),

1157 ('PreferredMaximumLength',DWORD),

1158 ('cbRestart',DWORD),

1159 ('pRestart',PBYTE_ARRAY),

1160 )

1161

1162# 4.1.11.1.1 DRS_MSG_NT4_CHGLOG_REQ

1163 class DRS_MSG_NT4_CHGLOG_REQ(NDRUNION):

1164 commonHdr = (

1165 ('tag', DWORD),

1166 )

1167 union = {

1168 1 : ('V1', DRS_MSG_NT4_CHGLOG_REQ_V1),

1169 }

1170

1171# 4.1.11.1.5 NT4_REPLICATION_STATE

1172 class NT4_REPLICATION_STATE(NDRSTRUCT):

1173 structure = (

1174 ('SamSerialNumber',LARGE_INTEGER),

1175 ('SamCreationTime',LARGE_INTEGER),

1176 ('BuiltinSerialNumber',LARGE_INTEGER),

1177 ('BuiltinCreationTime',LARGE_INTEGER),

1178 ('LsaSerialNumber',LARGE_INTEGER),

1179 ('LsaCreationTime',LARGE_INTEGER),

1180 )

1181

1182# 4.1.11.1.4 DRS_MSG_NT4_CHGLOG_REPLY_V1

1183 class DRS_MSG_NT4_CHGLOG_REPLY_V1(NDRSTRUCT):

1184 structure = (

1185 ('cbRestart',DWORD),

1186 ('cbLog',DWORD),

1187 ('ReplicationState',NT4_REPLICATION_STATE),

1188 ('ActualNtStatus',DWORD),

1189 ('pRestart',PBYTE_ARRAY),

1190 ('pLog',PBYTE_ARRAY),

1191 )

1192

1193# 4.1.11.1.3 DRS_MSG_NT4_CHGLOG_REPLY

1194 class DRS_MSG_NT4_CHGLOG_REPLY(NDRUNION):

1195 commonHdr = (

1196 ('tag', DWORD),

1197 )

1198 union = {

1199 1 : ('V1', DRS_MSG_NT4_CHGLOG_REPLY_V1),

1200 }

1201

1202################################################################################

1203# RPC CALLS

1204################################################################################

1205# 4.1.3 IDL_DRSBind (Opnum 0)

1206 class DRSBind(NDRCALL):

1207 opnum = 0

1208 structure = (

1209 ('puuidClientDsa', PUUID),

1210 ('pextClient', PDRS_EXTENSIONS),

1211 )

1212

1213 class DRSBindResponse(NDRCALL):

1214 structure = (

1215 ('ppextServer', PDRS_EXTENSIONS),

1216 ('phDrs', DRS_HANDLE),

1217 ('ErrorCode',DWORD),

1218 )

1219

1220# 4.1.25 IDL_DRSUnbind (Opnum 1)

1221 class DRSUnbind(NDRCALL):

1222 opnum = 1

1223 structure = (

1224 ('phDrs', DRS_HANDLE),

1225 )

1226

1227 class DRSUnbindResponse(NDRCALL):

1228 structure = (

1229 ('phDrs', DRS_HANDLE),

1230 ('ErrorCode',DWORD),

1231 )

1232

1233# 4.1.10 IDL_DRSGetNCChanges (Opnum 3)

1234 class DRSGetNCChanges(NDRCALL):

1235 opnum = 3

1236 structure = (

1237 ('hDrs', DRS_HANDLE),

1238 ('dwInVersion', DWORD),

1239 ('pmsgIn', DRS_MSG_GETCHGREQ),

1240 )

1241

1242 class DRSGetNCChangesResponse(NDRCALL):

1243 structure = (

1244 ('pdwOutVersion', DWORD),

1245 ('pmsgOut', DRS_MSG_GETCHGREPLY),

1246 ('ErrorCode',DWORD),

1247 )

1248

1249# 4.1.27 IDL_DRSVerifyNames (Opnum 8)

1250 class DRSVerifyNames(NDRCALL):

1251 opnum = 8

1252 structure = (

1253 ('hDrs', DRS_HANDLE),

1254 ('dwInVersion', DWORD),

1255 ('pmsgIn', DRS_MSG_VERIFYREQ),

1256 )

1257

1258 class DRSVerifyNamesResponse(NDRCALL):

1259 structure = (

1260 ('pdwOutVersion', DWORD),

1261 ('pmsgOut', DRS_MSG_VERIFYREPLY),

1262 ('ErrorCode',DWORD),

1263 )

1264# 4.1.11 IDL_DRSGetNT4ChangeLog (Opnum 11)

1265 class DRSGetNT4ChangeLog(NDRCALL):

1266 opnum = 11

1267 structure = (

1268 ('hDrs', DRS_HANDLE),

1269 ('dwInVersion', DWORD),

1270 ('pmsgIn', DRS_MSG_NT4_CHGLOG_REQ),

1271 )

1272

1273 class DRSGetNT4ChangeLogResponse(NDRCALL):

1274 structure = (

1275 ('pdwOutVersion', DWORD),

1276 ('pmsgOut', DRS_MSG_NT4_CHGLOG_REPLY),

1277 ('ErrorCode',DWORD),

1278 )

1279

1280# 4.1.4 IDL_DRSCrackNames (Opnum 12)

1281 class DRSCrackNames(NDRCALL):

1282 opnum = 12

1283 structure = (

1284 ('hDrs', DRS_HANDLE),

1285 ('dwInVersion', DWORD),

1286 ('pmsgIn', DRS_MSG_CRACKREQ),

1287 )

1288

1289 class DRSCrackNamesResponse(NDRCALL):

1290 structure = (

1291 ('pdwOutVersion', DWORD),

1292 ('pmsgOut', DRS_MSG_CRACKREPLY),

1293 ('ErrorCode',DWORD),

1294 )

1295

1296# 4.1.5 IDL_DRSDomainControllerInfo (Opnum 16)

1297 class DRSDomainControllerInfo(NDRCALL):

1298 opnum = 16

1299 structure = (

1300 ('hDrs', DRS_HANDLE),

1301 ('dwInVersion', DWORD),

1302 ('pmsgIn', DRS_MSG_DCINFOREQ),

1303 )

1304

1305 class DRSDomainControllerInfoResponse(NDRCALL):

1306 structure = (

1307 ('pdwOutVersion', DWORD),

1308 ('pmsgOut', DRS_MSG_DCINFOREPLY),

1309 ('ErrorCode',DWORD),

1310 )

1311

1312################################################################################

1313# OPNUMs and their corresponding structures

1314################################################################################

1315 OPNUMS = {

1316 0 : (DRSBind,DRSBindResponse ),

1317 1 : (DRSUnbind,DRSUnbindResponse ),

1318 3 : (DRSGetNCChanges,DRSGetNCChangesResponse ),

1319 12: (DRSCrackNames,DRSCrackNamesResponse ),

1320 16: (DRSDomainControllerInfo,DRSDomainControllerInfoResponse ),

1321}

1322

1323################################################################################

1324# HELPER FUNCTIONS

1325################################################################################

1326 def checkNullString(string):

1327 if string == NULL: 1327 ↛ 1328line 1327 didn't jump to line 1328, because the condition on line 1327 was never true

1328 return string

1329

1330 if string[-1:] != '\x00': 1330 ↛ 1333line 1330 didn't jump to line 1333, because the condition on line 1330 was never false

1331 return string + '\x00'

1332 else:

1333 return string

1334

1335 def hDRSUnbind(dce, hDrs):

1336 request = DRSUnbind()

1337 request['phDrs'] = hDrs

1338 return dce.request(request)

1339

1340 def hDRSDomainControllerInfo(dce, hDrs, domain, infoLevel):

1341 request = DRSDomainControllerInfo()

1342 request['hDrs'] = hDrs

1343 request['dwInVersion'] = 1

1344

1345 request['pmsgIn']['tag'] = 1

1346 request['pmsgIn']['V1']['Domain'] = checkNullString(domain)

1347 request['pmsgIn']['V1']['InfoLevel'] = infoLevel

1348 return dce.request(request)

1349

1350 def hDRSCrackNames(dce, hDrs, flags, formatOffered, formatDesired, rpNames = ()):

1351 request = DRSCrackNames()

1352 request['hDrs'] = hDrs

1353 request['dwInVersion'] = 1

1354

1355 request['pmsgIn']['tag'] = 1

1356 request['pmsgIn']['V1']['CodePage'] = 0

1357 request['pmsgIn']['V1']['LocaleId'] = 0

1358 request['pmsgIn']['V1']['dwFlags'] = flags

1359 request['pmsgIn']['V1']['formatOffered'] = formatOffered

1360 request['pmsgIn']['V1']['formatDesired'] = formatDesired

1361 request['pmsgIn']['V1']['cNames'] = len(rpNames)

1362 for name in rpNames:

1363 record = LPWSTR()

1364 record['Data'] = checkNullString(name)

1365 request['pmsgIn']['V1']['rpNames'].append(record)

1366

1367 return dce.request(request)

1368

1369 def deriveKey(baseKey):

1370 # 2.2.11.1.3 Deriving Key1 and Key2 from a Little-Endian, Unsigned Integer Key

1371 # Let I be the little-endian, unsigned integer.

1372 # Let I[X] be the Xth byte of I, where I is interpreted as a zero-base-index array of bytes.

1373 # Note that because I is in little-endian byte order, I[0] is the least significant byte.

1374 # Key1 is a concatenation of the following values: I[0], I[1], I[2], I[3], I[0], I[1], I[2].

1375 # Key2 is a concatenation of the following values: I[3], I[0], I[1], I[2], I[3], I[0], I[1]

1376 key = pack('<L',baseKey)

1377 key1 = [key[0] , key[1] , key[2] , key[3] , key[0] , key[1] , key[2]]

1378 key2 = [key[3] , key[0] , key[1] , key[2] , key[3] , key[0] , key[1]]

1379 if PY2: 1379 ↛ 1380line 1379 didn't jump to line 1380, because the condition on line 1379 was never true

1380 return transformKey(b''.join(key1)),transformKey(b''.join(key2))

1381 else:

1382 return transformKey(bytes(key1)),transformKey(bytes(key2))

1383

1384 def removeDESLayer(cryptedHash, rid):

1385 Key1,Key2 = deriveKey(rid)

1386

1387 Crypt1 = DES.new(Key1, DES.MODE_ECB)

1388 Crypt2 = DES.new(Key2, DES.MODE_ECB)

1389

1390 decryptedHash = Crypt1.decrypt(cryptedHash[:8]) + Crypt2.decrypt(cryptedHash[8:])

1391

1392 return decryptedHash

1393

1394 def DecryptAttributeValue(dce, attribute):

1395 sessionKey = dce.get_session_key()

1396 # Is it a Kerberos Session Key?

1397 if isinstance(sessionKey, crypto.Key): 1397 ↛ 1399line 1397 didn't jump to line 1399, because the condition on line 1397 was never true

1398 # Extract its contents and move on

1399 sessionKey = sessionKey.contents

1400

1401 encryptedPayload = ENCRYPTED_PAYLOAD(attribute)

1402

1403 md5 = hashlib.new('md5')

1404 md5.update(sessionKey)

1405 md5.update(encryptedPayload['Salt'])

1406 finalMD5 = md5.digest()

1407

1408 cipher = ARC4.new(finalMD5)

1409 plainText = cipher.decrypt(attribute[16:])

1410

1411 #chkSum = (binascii.crc32(plainText[4:])) & 0xffffffff

1412 #if unpack('<L',plainText[:4])[0] != chkSum:

1413 # print "RECEIVED 0x%x" % unpack('<L',plainText[:4])[0]

1414 # print "CALCULATED 0x%x" % chkSum

1415

1416 return plainText[4:]

1417

1418# 5.16.4 ATTRTYP-to-OID Conversion

1419 def MakeAttid(prefixTable, oid):

1420 # get the last value in the original OID: the value * after the last '.'

1421 lastValue = int(oid.split('.')[-1])

1422

1423 # convert the dotted form of OID into a BER encoded binary * format.

1424 # The BER encoding of OID is described in section * 8.19 of [ITUX690]

1425 from pyasn1.type import univ

1426 from pyasn1.codec.ber import encoder

1427 binaryOID = encoder.encode(univ.ObjectIdentifier(oid))[2:]

1428

1429 # get the prefix of the OID

1430 if lastValue < 128:

1431 oidPrefix = list(binaryOID[:-1])

1432 else:

1433 oidPrefix = list(binaryOID[:-2])

1434

1435 # search the prefix in the prefix table, if none found, add

1436 # one entry for the new prefix.

1437 fToAdd = True

1438 pos = len(prefixTable)

1439 for j, item in enumerate(prefixTable):

1440 if item['prefix']['elements'] == oidPrefix: 1440 ↛ 1439line 1440 didn't jump to line 1439, because the condition on line 1440 was never false

1441 fToAdd = False

1442 pos = j

1443 break

1444

1445 if fToAdd is True:

1446 entry = PrefixTableEntry()

1447 entry['ndx'] = pos

1448 entry['prefix']['length'] = len(oidPrefix)

1449 entry['prefix']['elements'] = oidPrefix

1450 prefixTable.append(entry)

1451

1452 # compose the attid

1453 lowerWord = lastValue % 16384

1454 if lastValue >= 16384: 1454 ↛ 1456line 1454 didn't jump to line 1456, because the condition on line 1454 was never true

1455 # mark it so that it is known to not be the whole lastValue

1456 lowerWord += 32768

1457

1458 upperWord = pos

1459

1460 attrTyp = ATTRTYP()

1461 attrTyp['Data'] = (upperWord << 16) + lowerWord

1462 return attrTyp

1463

1464 def OidFromAttid(prefixTable, attr):

1465 # separate the ATTRTYP into two parts

1466 upperWord = attr // 65536

1467 lowerWord = attr % 65536

1468

1469 # search in the prefix table to find the upperWord, if found,

1470 # construct the binary OID by appending lowerWord to the end of

1471 # found prefix.

1472

1473 binaryOID = None

1474 for j, item in enumerate(prefixTable): 1474 ↛ 1486line 1474 didn't jump to line 1486, because the loop on line 1474 didn't complete

1475 if item['ndx'] == upperWord:

1476 binaryOID = item['prefix']['elements'][:item['prefix']['length']]

1477 if lowerWord < 128:

1478 binaryOID.append(pack('B',lowerWord))

1479 else:

1480 if lowerWord >= 32768: 1480 ↛ 1481line 1480 didn't jump to line 1481, because the condition on line 1480 was never true

1481 lowerWord -= 32768

1482 binaryOID.append(pack('B',(((lowerWord//128) % 128)+128)))

1483 binaryOID.append(pack('B',(lowerWord%128)))

1484 break

1485

1486 if binaryOID is None: 1486 ↛ 1487line 1486 didn't jump to line 1487, because the condition on line 1486 was never true

1487 return None

1488 return str(decoder.decode(b'\x06' + pack('B',(len(binaryOID))) + b''.join(binaryOID), asn1Spec = univ.ObjectIdentifier())[0])

1489

1490 if __name__ == '__main__': 1490 ↛ 1491line 1490 didn't jump to line 1491, because the condition on line 1490 was never true

1491 prefixTable = []

1492 oid0 = '1.2.840.113556.1.4.94'

1493 oid1 = '2.5.6.2'

1494 oid2 = '1.2.840.113556.1.2.1'

1495 oid3 = '1.2.840.113556.1.3.223'

1496 oid4 = '1.2.840.113556.1.5.7000.53'

1497

1498 o0 = MakeAttid(prefixTable, oid0)

1499 print(hex(o0))

1500 o1 = MakeAttid(prefixTable, oid1)

1501 print(hex(o1))

1502 o2 = MakeAttid(prefixTable, oid2)

1503 print(hex(o2))

1504 o3 = MakeAttid(prefixTable, oid3)

1505 print(hex(o3))

1506 o4 = MakeAttid(prefixTable, oid4)

1507 print(hex(o4))

1508 jj = OidFromAttid(prefixTable, o0)

1509 print(jj)

1510 jj = OidFromAttid(prefixTable, o1)

1511 print(jj)

1512 jj = OidFromAttid(prefixTable, o2)

1513 print(jj)

1514 jj = OidFromAttid(prefixTable, o3)

1515 print(jj)

1516 jj = OidFromAttid(prefixTable, o4)

1517 print(jj)