Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

2# 

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

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

5# for more information. 

6# 

7# Author: Alberto Solino (@agsolino) 

8# 

9# Description: 

10# [MS-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# 

21from __future__ import division 

22from __future__ import print_function 

23from builtins import bytes 

24import hashlib 

25from struct import pack 

26import six 

27from six import PY2 

28 

29from impacket import LOG 

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

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

32from impacket import hresult_errors, system_errors 

33from impacket.structure import Structure 

34from impacket.uuid import uuidtup_to_bin, string_to_bin 

35from impacket.dcerpc.v5.enum import Enum 

36from impacket.dcerpc.v5.rpcrt import DCERPCException 

37from impacket.krb5 import crypto 

38from pyasn1.type import univ 

39from pyasn1.codec.ber import decoder 

40from impacket.crypto import transformKey 

41 

42try: 

43 from Cryptodome.Cipher import ARC4, DES 

44except 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 

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

49 

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

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

107EXOP_FSMO_REQ_ROLE = 0x00000001 

108EXOP_FSMO_REQ_RID_ALLOC = 0x00000002 

109EXOP_FSMO_RID_REQ_ROLE = 0x00000003 

110EXOP_FSMO_REQ_PDC = 0x00000004 

111EXOP_FSMO_ABANDON_ROLE = 0x00000005 

112EXOP_REPL_OBJ = 0x00000006 

113EXOP_REPL_SECRETS = 0x00000007 

114 

115# 5.14 ATTRTYP 

116ATTRTYP = ULONG 

117 

118# 5.51 DSTIME 

119DSTIME = LONGLONG 

120 

121# 5.39 DRS_EXTENSIONS_INT 

122DRS_EXT_BASE = 0x00000001 

123DRS_EXT_ASYNCREPL = 0x00000002 

124DRS_EXT_REMOVEAPI = 0x00000004 

125DRS_EXT_MOVEREQ_V2 = 0x00000008 

126DRS_EXT_GETCHG_DEFLATE = 0x00000010 

127DRS_EXT_DCINFO_V1 = 0x00000020 

128DRS_EXT_RESTORE_USN_OPTIMIZATION = 0x00000040 

129DRS_EXT_ADDENTRY = 0x00000080 

130DRS_EXT_KCC_EXECUTE = 0x00000100 

131DRS_EXT_ADDENTRY_V2 = 0x00000200 

132DRS_EXT_LINKED_VALUE_REPLICATION = 0x00000400 

133DRS_EXT_DCINFO_V2 = 0x00000800 

134DRS_EXT_INSTANCE_TYPE_NOT_REQ_ON_MOD = 0x00001000 

135DRS_EXT_CRYPTO_BIND = 0x00002000 

136DRS_EXT_GET_REPL_INFO = 0x00004000 

137DRS_EXT_STRONG_ENCRYPTION = 0x00008000 

138DRS_EXT_DCINFO_VFFFFFFFF = 0x00010000 

139DRS_EXT_TRANSITIVE_MEMBERSHIP = 0x00020000 

140DRS_EXT_ADD_SID_HISTORY = 0x00040000 

141DRS_EXT_POST_BETA3 = 0x00080000 

142DRS_EXT_GETCHGREQ_V5 = 0x00100000 

143DRS_EXT_GETMEMBERSHIPS2 = 0x00200000 

144DRS_EXT_GETCHGREQ_V6 = 0x00400000 

145DRS_EXT_NONDOMAIN_NCS = 0x00800000 

146DRS_EXT_GETCHGREQ_V8 = 0x01000000 

147DRS_EXT_GETCHGREPLY_V5 = 0x02000000 

148DRS_EXT_GETCHGREPLY_V6 = 0x04000000 

149DRS_EXT_GETCHGREPLY_V9 = 0x00000100 

150DRS_EXT_WHISTLER_BETA3 = 0x08000000 

151DRS_EXT_W2K3_DEFLATE = 0x10000000 

152DRS_EXT_GETCHGREQ_V10 = 0x20000000 

153DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART2 = 0x40000000 

154DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART3 = 0x80000000 

155 

156# dwFlagsExt 

157DRS_EXT_ADAM = 0x00000001 

158DRS_EXT_LH_BETA2 = 0x00000002 

159DRS_EXT_RECYCLE_BIN = 0x00000004 

160 

161# 5.41 DRS_OPTIONS 

162DRS_ASYNC_OP = 0x00000001 

163DRS_GETCHG_CHECK = 0x00000002 

164DRS_UPDATE_NOTIFICATION = 0x00000002 

165DRS_ADD_REF = 0x00000004 

166DRS_SYNC_ALL = 0x00000008 

167DRS_DEL_REF = 0x00000008 

168DRS_WRIT_REP = 0x00000010 

169DRS_INIT_SYNC = 0x00000020 

170DRS_PER_SYNC = 0x00000040 

171DRS_MAIL_REP = 0x00000080 

172DRS_ASYNC_REP = 0x00000100 

173DRS_IGNORE_ERROR = 0x00000100 

174DRS_TWOWAY_SYNC = 0x00000200 

175DRS_CRITICAL_ONLY = 0x00000400 

176DRS_GET_ANC = 0x00000800 

177DRS_GET_NC_SIZE = 0x00001000 

178DRS_LOCAL_ONLY = 0x00001000 

179DRS_NONGC_RO_REP = 0x00002000 

180DRS_SYNC_BYNAME = 0x00004000 

181DRS_REF_OK = 0x00004000 

182DRS_FULL_SYNC_NOW = 0x00008000 

183DRS_NO_SOURCE = 0x00008000 

184DRS_FULL_SYNC_IN_PROGRESS = 0x00010000 

185DRS_FULL_SYNC_PACKET = 0x00020000 

186DRS_SYNC_REQUEUE = 0x00040000 

187DRS_SYNC_URGENT = 0x00080000 

188DRS_REF_GCSPN = 0x00100000 

189DRS_NO_DISCARD = 0x00100000 

190DRS_NEVER_SYNCED = 0x00200000 

191DRS_SPECIAL_SECRET_PROCESSING = 0x00400000 

192DRS_INIT_SYNC_NOW = 0x00800000 

193DRS_PREEMPTED = 0x01000000 

194DRS_SYNC_FORCED = 0x02000000 

195DRS_DISABLE_AUTO_SYNC = 0x04000000 

196DRS_DISABLE_PERIODIC_SYNC = 0x08000000 

197DRS_USE_COMPRESSION = 0x10000000 

198DRS_NEVER_NOTIFY = 0x20000000 

199DRS_SYNC_PAS = 0x40000000 

200DRS_GET_ALL_GROUP_MEMBERSHIP = 0x80000000 

201 

202 

203# 5.113 LDAP_CONN_PROPERTIES 

204BND = 0x00000001 

205SSL = 0x00000002 

206UDP = 0x00000004 

207GC = 0x00000008 

208GSS = 0x00000010 

209NGO = 0x00000020 

210SPL = 0x00000040 

211MD5 = 0x00000080 

212SGN = 0x00000100 

213SL = 0x00000200 

214 

215# 5.137 NTSAPI_CLIENT_GUID 

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

217 

218# 5.139 NULLGUID 

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

220 

221# 5.205 USN 

222USN = LONGLONG 

223 

224# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1 

225DS_NAME_FLAG_GCVERIFY = 0x00000004 

226DS_NAME_FLAG_TRUST_REFERRAL = 0x00000008 

227DS_NAME_FLAG_PRIVATE_RESOLVE_FPOS = 0x80000000 

228 

229DS_LIST_SITES = 0xFFFFFFFF 

230DS_LIST_SERVERS_IN_SITE = 0xFFFFFFFE 

231DS_LIST_DOMAINS_IN_SITE = 0xFFFFFFFD 

232DS_LIST_SERVERS_FOR_DOMAIN_IN_SITE = 0xFFFFFFFC 

233DS_LIST_INFO_FOR_SERVER = 0xFFFFFFFB 

234DS_LIST_ROLES = 0xFFFFFFFA 

235DS_NT4_ACCOUNT_NAME_SANS_DOMAIN = 0xFFFFFFF9 

236DS_MAP_SCHEMA_GUID = 0xFFFFFFF8 

237DS_LIST_DOMAINS = 0xFFFFFFF7 

238DS_LIST_NCS = 0xFFFFFFF6 

239DS_ALT_SECURITY_IDENTITIES_NAME = 0xFFFFFFF5 

240DS_STRING_SID_NAME = 0xFFFFFFF4 

241DS_LIST_SERVERS_WITH_DCS_IN_SITE = 0xFFFFFFF3 

242DS_LIST_GLOBAL_CATALOG_SERVERS = 0xFFFFFFF1 

243DS_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX = 0xFFFFFFF0 

244DS_USER_PRINCIPAL_NAME_AND_ALTSECID = 0xFFFFFFEF 

245 

246DS_USER_PRINCIPAL_NAME_FOR_LOGON = 0xFFFFFFF2 

247 

248# 5.53 ENTINF 

249ENTINF_FROM_MASTER = 0x00000001 

250ENTINF_DYNAMIC_OBJECT = 0x00000002 

251ENTINF_REMOTE_MODIFY = 0x00010000 

252 

253# 4.1.27.1.2 DRS_MSG_VERIFYREQ_V1 

254DRS_VERIFY_DSNAMES = 0x00000000 

255DRS_VERIFY_SIDS = 0x00000001 

256DRS_VERIFY_SAM_ACCOUNT_NAMES = 0x00000002 

257DRS_VERIFY_FPOS = 0x00000003 

258 

259# 4.1.11.1.2 DRS_MSG_NT4_CHGLOG_REQ_V1 

260DRS_NT4_CHGLOG_GET_CHANGE_LOG = 0x00000001 

261DRS_NT4_CHGLOG_GET_SERIAL_NUMBERS = 0x00000002 

262 

263# 4.1.10.2.15 DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER 

264DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER = 9 

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

266# STRUCTURES 

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

268# 4.1.10.2.16 ENCRYPTED_PAYLOAD 

269class ENCRYPTED_PAYLOAD(Structure): 

270 structure = ( 

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

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

273 ('EncryptedData',':'), 

274 ) 

275 

276# 5.136 NT4SID 

277class NT4SID(NDRSTRUCT): 

278 structure = ( 

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

280 ) 

281 def getAlignment(self): 

282 return 4 

283 

284# 5.40 DRS_HANDLE 

285class DRS_HANDLE(NDRSTRUCT): 

286 structure = ( 

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

288 ) 

289 def getAlignment(self): 

290 return 4 

291 

292class PDRS_HANDLE(NDRPOINTER): 

293 referent = ( 

294 ('Data',DRS_HANDLE), 

295 ) 

296 

297# 5.38 DRS_EXTENSIONS 

298class BYTE_ARRAY(NDRUniConformantArray): 

299 item = 'c' 

300 

301class PBYTE_ARRAY(NDRPOINTER): 

302 referent = ( 

303 ('Data',BYTE_ARRAY), 

304 ) 

305 

306class DRS_EXTENSIONS(NDRSTRUCT): 

307 structure = ( 

308 ('cb',DWORD), 

309 ('rgb',BYTE_ARRAY), 

310 ) 

311 

312class PDRS_EXTENSIONS(NDRPOINTER): 

313 referent = ( 

314 ('Data',DRS_EXTENSIONS), 

315 ) 

316 

317# 5.39 DRS_EXTENSIONS_INT 

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

330class DRS_MSG_DCINFOREQ_V1(NDRSTRUCT): 

331 structure = ( 

332 ('Domain',LPWSTR), 

333 ('InfoLevel',DWORD), 

334 ) 

335 

336# 4.1.5.1.1 DRS_MSG_DCINFOREQ 

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

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

357class DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRUniConformantArray): 

358 item = DS_DOMAIN_CONTROLLER_INFO_1W 

359 

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

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

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

391class DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRUniConformantArray): 

392 item = DS_DOMAIN_CONTROLLER_INFO_2W 

393 

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

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

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

426class DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRUniConformantArray): 

427 item = DS_DOMAIN_CONTROLLER_INFO_3W 

428 

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

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

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

453class DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRUniConformantArray): 

454 item = DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW 

455 

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

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

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

481class LPWSTR_ARRAY(NDRUniConformantArray): 

482 item = LPWSTR 

483 

484class PLPWSTR_ARRAY(NDRPOINTER): 

485 referent = ( 

486 ('Data',LPWSTR_ARRAY), 

487 ) 

488 

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

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

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

525class DS_NAME_RESULT_ITEMW(NDRSTRUCT): 

526 structure = ( 

527 ('status',DWORD), 

528 ('pDomain',LPWSTR), 

529 ('pName',LPWSTR), 

530 ) 

531 

532class DS_NAME_RESULT_ITEMW_ARRAY(NDRUniConformantArray): 

533 item = DS_NAME_RESULT_ITEMW 

534 

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

541class DS_NAME_RESULTW(NDRSTRUCT): 

542 structure = ( 

543 ('cItems',DWORD), 

544 ('rItems',PDS_NAME_RESULT_ITEMW_ARRAY), 

545 ) 

546 

547class PDS_NAME_RESULTW(NDRPOINTER): 

548 referent = ( 

549 ('Data',DS_NAME_RESULTW), 

550 ) 

551 

552# 4.1.4.1.7 DRS_MSG_CRACKREPLY_V1 

553class DRS_MSG_CRACKREPLY_V1(NDRSTRUCT): 

554 structure = ( 

555 ('pResult',PDS_NAME_RESULTW), 

556 ) 

557 

558# 4.1.4.1.6 DRS_MSG_CRACKREPLY 

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

568class UPTODATE_CURSOR_V1(NDRSTRUCT): 

569 structure = ( 

570 ('uuidDsa',UUID), 

571 ('usnHighPropUpdate',USN), 

572 ) 

573 

574class UPTODATE_CURSOR_V1_ARRAY(NDRUniConformantArray): 

575 item = UPTODATE_CURSOR_V1 

576 

577# 5.200 UPTODATE_VECTOR_V1_EXT 

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

587class PUPTODATE_VECTOR_V1_EXT(NDRPOINTER): 

588 referent = ( 

589 ('Data',UPTODATE_VECTOR_V1_EXT), 

590 ) 

591 

592# 5.206 USN_VECTOR 

593class USN_VECTOR(NDRSTRUCT): 

594 structure = ( 

595 ('usnHighObjUpdate',USN), 

596 ('usnReserved',USN), 

597 ('usnHighPropUpdate',USN), 

598 ) 

599 

600# 5.50 DSNAME 

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

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

633class PDSNAME(NDRPOINTER): 

634 referent = ( 

635 ('Data',DSNAME), 

636 ) 

637 

638class PDSNAME_ARRAY(NDRUniConformantArray): 

639 item = PDSNAME 

640 

641class PPDSNAME_ARRAY(NDRPOINTER): 

642 referent = ( 

643 ('Data',PDSNAME_ARRAY), 

644 ) 

645 

646class ATTRTYP_ARRAY(NDRUniConformantArray): 

647 item = ATTRTYP 

648 

649# 5.145 PARTIAL_ATTR_VECTOR_V1_EXT 

650class PARTIAL_ATTR_VECTOR_V1_EXT(NDRSTRUCT): 

651 structure = ( 

652 ('dwVersion',DWORD), 

653 ('dwReserved1',DWORD), 

654 ('cAttrs',DWORD), 

655 ('rgPartialAttr',ATTRTYP_ARRAY), 

656 ) 

657 

658class PPARTIAL_ATTR_VECTOR_V1_EXT(NDRPOINTER): 

659 referent = ( 

660 ('Data',PARTIAL_ATTR_VECTOR_V1_EXT), 

661 ) 

662 

663# 5.142 OID_t 

664class OID_t(NDRSTRUCT): 

665 structure = ( 

666 ('length',ULONG), 

667 ('elements',PBYTE_ARRAY), 

668 ) 

669 

670# 5.153 PrefixTableEntry 

671class PrefixTableEntry(NDRSTRUCT): 

672 structure = ( 

673 ('ndx',ULONG), 

674 ('prefix',OID_t), 

675 ) 

676 

677class PrefixTableEntry_ARRAY(NDRUniConformantArray): 

678 item = PrefixTableEntry 

679 

680class PPrefixTableEntry_ARRAY(NDRPOINTER): 

681 referent = ( 

682 ('Data',PrefixTableEntry_ARRAY), 

683 ) 

684 

685# 5.177 SCHEMA_PREFIX_TABLE 

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

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

709class MTX_ADDR(NDRSTRUCT): 

710 structure = ( 

711 ('mtx_namelen',ULONG), 

712 ('mtx_name',PBYTE_ARRAY), 

713 ) 

714 

715class PMTX_ADDR(NDRPOINTER): 

716 referent = ( 

717 ('Data',MTX_ADDR), 

718 ) 

719 

720# 4.1.10.2.3 DRS_MSG_GETCHGREQ_V4 

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

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

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

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

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

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

805class ATTRVAL(NDRSTRUCT): 

806 structure = ( 

807 ('valLen',ULONG), 

808 ('pVal',PBYTE_ARRAY), 

809 ) 

810 

811class ATTRVAL_ARRAY(NDRUniConformantArray): 

812 item = ATTRVAL 

813 

814class PATTRVAL_ARRAY(NDRPOINTER): 

815 referent = ( 

816 ('Data',ATTRVAL_ARRAY), 

817 ) 

818 

819# 5.17 ATTRVALBLOCK 

820class ATTRVALBLOCK(NDRSTRUCT): 

821 structure = ( 

822 ('valCount',ULONG), 

823 ('pAVal',PATTRVAL_ARRAY), 

824 ) 

825 

826# 5.9 ATTR 

827class ATTR(NDRSTRUCT): 

828 structure = ( 

829 ('attrTyp',ATTRTYP), 

830 ('AttrVal',ATTRVALBLOCK), 

831 ) 

832 

833class ATTR_ARRAY(NDRUniConformantArray): 

834 item = ATTR 

835 

836class PATTR_ARRAY(NDRPOINTER): 

837 referent = ( 

838 ('Data',ATTR_ARRAY), 

839 ) 

840 

841# 5.10 ATTRBLOCK 

842class ATTRBLOCK(NDRSTRUCT): 

843 structure = ( 

844 ('attrCount',ULONG), 

845 ('pAttr',PATTR_ARRAY), 

846 ) 

847 

848# 5.53 ENTINF 

849class ENTINF(NDRSTRUCT): 

850 structure = ( 

851 ('pName',PDSNAME), 

852 ('ulFlags',ULONG), 

853 ('AttrBlock',ATTRBLOCK), 

854 ) 

855 

856class ENTINF_ARRAY(NDRUniConformantArray): 

857 item = ENTINF 

858 

859class PENTINF_ARRAY(NDRPOINTER): 

860 referent = ( 

861 ('Data',ENTINF_ARRAY), 

862 ) 

863 

864# 5.154 PROPERTY_META_DATA_EXT 

865class PROPERTY_META_DATA_EXT(NDRSTRUCT): 

866 structure = ( 

867 ('dwVersion',DWORD), 

868 ('timeChanged',DSTIME), 

869 ('uuidDsaOriginating',UUID), 

870 ('usnOriginating',USN), 

871 ) 

872 

873class PROPERTY_META_DATA_EXT_ARRAY(NDRUniConformantArray): 

874 item = PROPERTY_META_DATA_EXT 

875 

876# 5.155 PROPERTY_META_DATA_EXT_VECTOR 

877class PROPERTY_META_DATA_EXT_VECTOR(NDRSTRUCT): 

878 structure = ( 

879 ('cNumProps',DWORD), 

880 ('rgMetaData',PROPERTY_META_DATA_EXT_ARRAY), 

881 ) 

882 

883class PPROPERTY_META_DATA_EXT_VECTOR(NDRPOINTER): 

884 referent = ( 

885 ('Data',PROPERTY_META_DATA_EXT_VECTOR), 

886 ) 

887 

888# 5.161 REPLENTINFLIST 

889 

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

905class PREPLENTINFLIST(NDRPOINTER): 

906 referent = ( 

907 ('Data',REPLENTINFLIST), 

908 ) 

909 

910# 4.1.10.2.9 DRS_MSG_GETCHGREPLY_V1 

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

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

936class DRS_MSG_GETCHGREPLY_V2(NDRSTRUCT): 

937 structure = ( 

938 ('CompressedV1',DRS_COMPRESSED_BLOB), 

939 ) 

940 

941# 5.199 UPTODATE_CURSOR_V2 

942class UPTODATE_CURSOR_V2(NDRSTRUCT): 

943 structure = ( 

944 ('uuidDsa',UUID), 

945 ('usnHighPropUpdate',USN), 

946 ('timeLastSyncSuccess',DSTIME), 

947 ) 

948 

949class UPTODATE_CURSOR_V2_ARRAY(NDRUniConformantArray): 

950 item = UPTODATE_CURSOR_V2 

951 

952# 5.201 UPTODATE_VECTOR_V2_EXT 

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

962class PUPTODATE_VECTOR_V2_EXT(NDRPOINTER): 

963 referent = ( 

964 ('Data',UPTODATE_VECTOR_V2_EXT), 

965 ) 

966 

967# 5.211 VALUE_META_DATA_EXT_V1 

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

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

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

1000class REPLVALINF_V1_ARRAY(NDRUniConformantArray): 

1001 item = REPLVALINF_V1 

1002 

1003class PREPLVALINF_V1_ARRAY(NDRPOINTER): 

1004 referent = ( 

1005 ('Data', REPLVALINF_V1_ARRAY), 

1006 ) 

1007 

1008# 5.168 REPLVALINF_V3 

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

1023class REPLVALINF_V3_ARRAY(NDRUniConformantArray): 

1024 item = REPLVALINF_V3 

1025 

1026class PREPLVALINF_V3_ARRAY(NDRPOINTER): 

1027 referent = ( 

1028 ('Data', REPLVALINF_V3_ARRAY), 

1029 ) 

1030 

1031# 5.169 REPLVALINF_NATIVE 

1032REPLVALINF_NATIVE = REPLVALINF_V3 

1033 

1034# 4.1.10.2.11 DRS_MSG_GETCHGREPLY_V6 

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

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

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

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

1101DRS_MSG_GETCHGREPLY_NATIVE = DRS_MSG_GETCHGREPLY_V9 

1102 

1103# 4.1.10.2.8 DRS_MSG_GETCHGREPLY 

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

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

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

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

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

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

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

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

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

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

1206class DRSBind(NDRCALL): 

1207 opnum = 0 

1208 structure = ( 

1209 ('puuidClientDsa', PUUID), 

1210 ('pextClient', PDRS_EXTENSIONS), 

1211 ) 

1212 

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

1221class DRSUnbind(NDRCALL): 

1222 opnum = 1 

1223 structure = ( 

1224 ('phDrs', DRS_HANDLE), 

1225 ) 

1226 

1227class DRSUnbindResponse(NDRCALL): 

1228 structure = ( 

1229 ('phDrs', DRS_HANDLE), 

1230 ('ErrorCode',DWORD), 

1231 ) 

1232 

1233# 4.1.10 IDL_DRSGetNCChanges (Opnum 3) 

1234class DRSGetNCChanges(NDRCALL): 

1235 opnum = 3 

1236 structure = ( 

1237 ('hDrs', DRS_HANDLE), 

1238 ('dwInVersion', DWORD), 

1239 ('pmsgIn', DRS_MSG_GETCHGREQ), 

1240 ) 

1241 

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

1250class DRSVerifyNames(NDRCALL): 

1251 opnum = 8 

1252 structure = ( 

1253 ('hDrs', DRS_HANDLE), 

1254 ('dwInVersion', DWORD), 

1255 ('pmsgIn', DRS_MSG_VERIFYREQ), 

1256 ) 

1257 

1258class DRSVerifyNamesResponse(NDRCALL): 

1259 structure = ( 

1260 ('pdwOutVersion', DWORD), 

1261 ('pmsgOut', DRS_MSG_VERIFYREPLY), 

1262 ('ErrorCode',DWORD), 

1263 ) 

1264# 4.1.11 IDL_DRSGetNT4ChangeLog (Opnum 11) 

1265class DRSGetNT4ChangeLog(NDRCALL): 

1266 opnum = 11 

1267 structure = ( 

1268 ('hDrs', DRS_HANDLE), 

1269 ('dwInVersion', DWORD), 

1270 ('pmsgIn', DRS_MSG_NT4_CHGLOG_REQ), 

1271 ) 

1272 

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

1281class DRSCrackNames(NDRCALL): 

1282 opnum = 12 

1283 structure = ( 

1284 ('hDrs', DRS_HANDLE), 

1285 ('dwInVersion', DWORD), 

1286 ('pmsgIn', DRS_MSG_CRACKREQ), 

1287 ) 

1288 

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

1297class DRSDomainControllerInfo(NDRCALL): 

1298 opnum = 16 

1299 structure = ( 

1300 ('hDrs', DRS_HANDLE), 

1301 ('dwInVersion', DWORD), 

1302 ('pmsgIn', DRS_MSG_DCINFOREQ), 

1303 ) 

1304 

1305class 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################################################################################ 

1315OPNUMS = { 

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

1326def 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 

1335def hDRSUnbind(dce, hDrs): 

1336 request = DRSUnbind() 

1337 request['phDrs'] = hDrs 

1338 return dce.request(request) 

1339 

1340def 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 

1350def 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 

1369def 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 

1384def 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 

1394def 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 

1419def 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 

1464def 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 

1490if __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)