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

2#

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

4#

5# This software is provided under a slightly modified version

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

7# for more information.

8#

9# Description:

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

22# Alberto Solino (@agsolino)

23#

24

25 from __future__ import division

26 from __future__ import print_function

27 from builtins import bytes

28 import hashlib

29 from struct import pack

30 import six

31 from six import PY2

32

33 from impacket import LOG

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

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

36 from impacket import hresult_errors, system_errors

37 from impacket.structure import Structure

38 from impacket.uuid import uuidtup_to_bin, string_to_bin

39 from impacket.dcerpc.v5.enum import Enum

40 from impacket.dcerpc.v5.rpcrt import DCERPCException

41 from impacket.krb5 import crypto

42 from pyasn1.type import univ

43 from pyasn1.codec.ber import decoder

44 from impacket.crypto import transformKey

45

46 try:

47 from Cryptodome.Cipher import ARC4, DES

48 except Exception:

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

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

51

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

53

54 class DCERPCSessionError(DCERPCException):

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

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

57

58 def __str__( self ):

59 key = self.error_code

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

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

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

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

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

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

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

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

68 else:

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

70

71################################################################################

72# CONSTANTS

73################################################################################

74# 4.1.10.2.17 EXOP_ERR Codes

75 class EXOP_ERR(NDRENUM):

76 align = 4

77 align64 = 4

78 structure = (

79 ('Data', '<L'),

80 )

81 class enumItems(Enum):

82 EXOP_ERR_SUCCESS = 0x00000001

83 EXOP_ERR_UNKNOWN_OP = 0x00000002

84 EXOP_ERR_FSMO_NOT_OWNER = 0x00000003

85 EXOP_ERR_UPDATE_ERR = 0x00000004

86 EXOP_ERR_EXCEPTION = 0x00000005

87 EXOP_ERR_UNKNOWN_CALLER = 0x00000006

88 EXOP_ERR_RID_ALLOC = 0x00000007

89 EXOP_ERR_FSMO_OWNER_DELETED = 0x00000008

90 EXOP_ERR_FSMO_PENDING_OP = 0x00000009

91 EXOP_ERR_MISMATCH = 0x0000000A

92 EXOP_ERR_COULDNT_CONTACT = 0x0000000B

93 EXOP_ERR_FSMO_REFUSING_ROLES = 0x0000000C

94 EXOP_ERR_DIR_ERROR = 0x0000000D

95 EXOP_ERR_FSMO_MISSING_SETTINGS = 0x0000000E

96 EXOP_ERR_ACCESS_DENIED = 0x0000000F

97 EXOP_ERR_PARAM_ERROR = 0x00000010

98

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

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

101 msg = self.__class__.__name__

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

103 print(msg, end=' ')

104

105 try:

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

107 except ValueError:

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

109

110# 4.1.10.2.18 EXOP_REQ Codes

111 EXOP_FSMO_REQ_ROLE = 0x00000001

112 EXOP_FSMO_REQ_RID_ALLOC = 0x00000002

113 EXOP_FSMO_RID_REQ_ROLE = 0x00000003

114 EXOP_FSMO_REQ_PDC = 0x00000004

115 EXOP_FSMO_ABANDON_ROLE = 0x00000005

116 EXOP_REPL_OBJ = 0x00000006

117 EXOP_REPL_SECRETS = 0x00000007

118

119# 5.14 ATTRTYP

120 ATTRTYP = ULONG

121

122# 5.51 DSTIME

123 DSTIME = LONGLONG

124

125# 5.39 DRS_EXTENSIONS_INT

126 DRS_EXT_BASE = 0x00000001

127 DRS_EXT_ASYNCREPL = 0x00000002

128 DRS_EXT_REMOVEAPI = 0x00000004

129 DRS_EXT_MOVEREQ_V2 = 0x00000008

130 DRS_EXT_GETCHG_DEFLATE = 0x00000010

131 DRS_EXT_DCINFO_V1 = 0x00000020

132 DRS_EXT_RESTORE_USN_OPTIMIZATION = 0x00000040

133 DRS_EXT_ADDENTRY = 0x00000080

134 DRS_EXT_KCC_EXECUTE = 0x00000100

135 DRS_EXT_ADDENTRY_V2 = 0x00000200

136 DRS_EXT_LINKED_VALUE_REPLICATION = 0x00000400

137 DRS_EXT_DCINFO_V2 = 0x00000800

138 DRS_EXT_INSTANCE_TYPE_NOT_REQ_ON_MOD = 0x00001000

139 DRS_EXT_CRYPTO_BIND = 0x00002000

140 DRS_EXT_GET_REPL_INFO = 0x00004000

141 DRS_EXT_STRONG_ENCRYPTION = 0x00008000

142 DRS_EXT_DCINFO_VFFFFFFFF = 0x00010000

143 DRS_EXT_TRANSITIVE_MEMBERSHIP = 0x00020000

144 DRS_EXT_ADD_SID_HISTORY = 0x00040000

145 DRS_EXT_POST_BETA3 = 0x00080000

146 DRS_EXT_GETCHGREQ_V5 = 0x00100000

147 DRS_EXT_GETMEMBERSHIPS2 = 0x00200000

148 DRS_EXT_GETCHGREQ_V6 = 0x00400000

149 DRS_EXT_NONDOMAIN_NCS = 0x00800000

150 DRS_EXT_GETCHGREQ_V8 = 0x01000000

151 DRS_EXT_GETCHGREPLY_V5 = 0x02000000

152 DRS_EXT_GETCHGREPLY_V6 = 0x04000000

153 DRS_EXT_GETCHGREPLY_V9 = 0x00000100

154 DRS_EXT_WHISTLER_BETA3 = 0x08000000

155 DRS_EXT_W2K3_DEFLATE = 0x10000000

156 DRS_EXT_GETCHGREQ_V10 = 0x20000000

157 DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART2 = 0x40000000

158 DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART3 = 0x80000000

159

160# dwFlagsExt

161 DRS_EXT_ADAM = 0x00000001

162 DRS_EXT_LH_BETA2 = 0x00000002

163 DRS_EXT_RECYCLE_BIN = 0x00000004

164

165# 5.41 DRS_OPTIONS

166 DRS_ASYNC_OP = 0x00000001

167 DRS_GETCHG_CHECK = 0x00000002

168 DRS_UPDATE_NOTIFICATION = 0x00000002

169 DRS_ADD_REF = 0x00000004

170 DRS_SYNC_ALL = 0x00000008

171 DRS_DEL_REF = 0x00000008

172 DRS_WRIT_REP = 0x00000010

173 DRS_INIT_SYNC = 0x00000020

174 DRS_PER_SYNC = 0x00000040

175 DRS_MAIL_REP = 0x00000080

176 DRS_ASYNC_REP = 0x00000100

177 DRS_IGNORE_ERROR = 0x00000100

178 DRS_TWOWAY_SYNC = 0x00000200

179 DRS_CRITICAL_ONLY = 0x00000400

180 DRS_GET_ANC = 0x00000800

181 DRS_GET_NC_SIZE = 0x00001000

182 DRS_LOCAL_ONLY = 0x00001000

183 DRS_NONGC_RO_REP = 0x00002000

184 DRS_SYNC_BYNAME = 0x00004000

185 DRS_REF_OK = 0x00004000

186 DRS_FULL_SYNC_NOW = 0x00008000

187 DRS_NO_SOURCE = 0x00008000

188 DRS_FULL_SYNC_IN_PROGRESS = 0x00010000

189 DRS_FULL_SYNC_PACKET = 0x00020000

190 DRS_SYNC_REQUEUE = 0x00040000

191 DRS_SYNC_URGENT = 0x00080000

192 DRS_REF_GCSPN = 0x00100000

193 DRS_NO_DISCARD = 0x00100000

194 DRS_NEVER_SYNCED = 0x00200000

195 DRS_SPECIAL_SECRET_PROCESSING = 0x00400000

196 DRS_INIT_SYNC_NOW = 0x00800000

197 DRS_PREEMPTED = 0x01000000

198 DRS_SYNC_FORCED = 0x02000000

199 DRS_DISABLE_AUTO_SYNC = 0x04000000

200 DRS_DISABLE_PERIODIC_SYNC = 0x08000000

201 DRS_USE_COMPRESSION = 0x10000000

202 DRS_NEVER_NOTIFY = 0x20000000

203 DRS_SYNC_PAS = 0x40000000

204 DRS_GET_ALL_GROUP_MEMBERSHIP = 0x80000000

205

206

207# 5.113 LDAP_CONN_PROPERTIES

208 BND = 0x00000001

209 SSL = 0x00000002

210 UDP = 0x00000004

211 GC = 0x00000008

212 GSS = 0x00000010

213 NGO = 0x00000020

214 SPL = 0x00000040

215 MD5 = 0x00000080

216 SGN = 0x00000100

217 SL = 0x00000200

218

219# 5.137 NTSAPI_CLIENT_GUID

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

221

222# 5.139 NULLGUID

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

224

225# 5.205 USN

226 USN = LONGLONG

227

228# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1

229 DS_NAME_FLAG_GCVERIFY = 0x00000004

230 DS_NAME_FLAG_TRUST_REFERRAL = 0x00000008

231 DS_NAME_FLAG_PRIVATE_RESOLVE_FPOS = 0x80000000

232

233 DS_LIST_SITES = 0xFFFFFFFF

234 DS_LIST_SERVERS_IN_SITE = 0xFFFFFFFE

235 DS_LIST_DOMAINS_IN_SITE = 0xFFFFFFFD

236 DS_LIST_SERVERS_FOR_DOMAIN_IN_SITE = 0xFFFFFFFC

237 DS_LIST_INFO_FOR_SERVER = 0xFFFFFFFB

238 DS_LIST_ROLES = 0xFFFFFFFA

239 DS_NT4_ACCOUNT_NAME_SANS_DOMAIN = 0xFFFFFFF9

240 DS_MAP_SCHEMA_GUID = 0xFFFFFFF8

241 DS_LIST_DOMAINS = 0xFFFFFFF7

242 DS_LIST_NCS = 0xFFFFFFF6

243 DS_ALT_SECURITY_IDENTITIES_NAME = 0xFFFFFFF5

244 DS_STRING_SID_NAME = 0xFFFFFFF4

245 DS_LIST_SERVERS_WITH_DCS_IN_SITE = 0xFFFFFFF3

246 DS_LIST_GLOBAL_CATALOG_SERVERS = 0xFFFFFFF1

247 DS_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX = 0xFFFFFFF0

248 DS_USER_PRINCIPAL_NAME_AND_ALTSECID = 0xFFFFFFEF

249

250 DS_USER_PRINCIPAL_NAME_FOR_LOGON = 0xFFFFFFF2

251

252# 5.53 ENTINF

253 ENTINF_FROM_MASTER = 0x00000001

254 ENTINF_DYNAMIC_OBJECT = 0x00000002

255 ENTINF_REMOTE_MODIFY = 0x00010000

256

257# 4.1.27.1.2 DRS_MSG_VERIFYREQ_V1

258 DRS_VERIFY_DSNAMES = 0x00000000

259 DRS_VERIFY_SIDS = 0x00000001

260 DRS_VERIFY_SAM_ACCOUNT_NAMES = 0x00000002

261 DRS_VERIFY_FPOS = 0x00000003

262

263# 4.1.11.1.2 DRS_MSG_NT4_CHGLOG_REQ_V1

264 DRS_NT4_CHGLOG_GET_CHANGE_LOG = 0x00000001

265 DRS_NT4_CHGLOG_GET_SERIAL_NUMBERS = 0x00000002

266

267# 4.1.10.2.15 DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER

268 DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER = 9

269################################################################################

270# STRUCTURES

271################################################################################

272# 4.1.10.2.16 ENCRYPTED_PAYLOAD

273 class ENCRYPTED_PAYLOAD(Structure):

274 structure = (

275 ('Salt','16s'),

276 ('CheckSum','<L'),

277 ('EncryptedData',':'),

278 )

279

280# 5.136 NT4SID

281 class NT4SID(NDRSTRUCT):

282 structure = (

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

284 )

285 def getAlignment(self):

286 return 4

287

288# 5.40 DRS_HANDLE

289 class DRS_HANDLE(NDRSTRUCT):

290 structure = (

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

292 )

293 def getAlignment(self):

294 return 4

295

296 class PDRS_HANDLE(NDRPOINTER):

297 referent = (

298 ('Data',DRS_HANDLE),

299 )

300

301# 5.38 DRS_EXTENSIONS

302 class BYTE_ARRAY(NDRUniConformantArray):

303 item = 'c'

304

305 class PBYTE_ARRAY(NDRPOINTER):

306 referent = (

307 ('Data',BYTE_ARRAY),

308 )

309

310 class DRS_EXTENSIONS(NDRSTRUCT):

311 structure = (

312 ('cb',DWORD),

313 ('rgb',BYTE_ARRAY),

314 )

315

316 class PDRS_EXTENSIONS(NDRPOINTER):

317 referent = (

318 ('Data',DRS_EXTENSIONS),

319 )

320

321# 5.39 DRS_EXTENSIONS_INT

322 class DRS_EXTENSIONS_INT(Structure):

323 structure = (

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

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

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

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

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

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

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

331 )

332

333# 4.1.5.1.2 DRS_MSG_DCINFOREQ_V1

334 class DRS_MSG_DCINFOREQ_V1(NDRSTRUCT):

335 structure = (

336 ('Domain',LPWSTR),

337 ('InfoLevel',DWORD),

338 )

339

340# 4.1.5.1.1 DRS_MSG_DCINFOREQ

341 class DRS_MSG_DCINFOREQ(NDRUNION):

342 commonHdr = (

343 ('tag', DWORD),

344 )

345 union = {

346 1 : ('V1', DRS_MSG_DCINFOREQ_V1),

347 }

348

349# 4.1.5.1.8 DS_DOMAIN_CONTROLLER_INFO_1W

350 class DS_DOMAIN_CONTROLLER_INFO_1W(NDRSTRUCT):

351 structure = (

352 ('NetbiosName',LPWSTR),

353 ('DnsHostName',LPWSTR),

354 ('SiteName',LPWSTR),

355 ('ComputerObjectName',LPWSTR),

356 ('ServerObjectName',LPWSTR),

357 ('fIsPdc',BOOL),

358 ('fDsEnabled',BOOL),

359 )

360

361 class DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRUniConformantArray):

362 item = DS_DOMAIN_CONTROLLER_INFO_1W

363

364 class PDS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRPOINTER):

365 referent = (

366 ('Data',DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY),

367 )

368

369# 4.1.5.1.4 DRS_MSG_DCINFOREPLY_V1

370 class DRS_MSG_DCINFOREPLY_V1(NDRSTRUCT):

371 structure = (

372 ('cItems',DWORD),

373 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_1W_ARRAY),

374 )

375

376# 4.1.5.1.9 DS_DOMAIN_CONTROLLER_INFO_2W

377 class DS_DOMAIN_CONTROLLER_INFO_2W(NDRSTRUCT):

378 structure = (

379 ('NetbiosName',LPWSTR),

380 ('DnsHostName',LPWSTR),

381 ('SiteName',LPWSTR),

382 ('SiteObjectName',LPWSTR),

383 ('ComputerObjectName',LPWSTR),

384 ('ServerObjectName',LPWSTR),

385 ('NtdsDsaObjectName',LPWSTR),

386 ('fIsPdc',BOOL),

387 ('fDsEnabled',BOOL),

388 ('fIsGc',BOOL),

389 ('SiteObjectGuid',GUID),

390 ('ComputerObjectGuid',GUID),

391 ('ServerObjectGuid',GUID),

392 ('NtdsDsaObjectGuid',GUID),

393 )

394

395 class DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRUniConformantArray):

396 item = DS_DOMAIN_CONTROLLER_INFO_2W

397

398 class PDS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRPOINTER):

399 referent = (

400 ('Data',DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY),

401 )

402

403# 4.1.5.1.5 DRS_MSG_DCINFOREPLY_V2

404 class DRS_MSG_DCINFOREPLY_V2(NDRSTRUCT):

405 structure = (

406 ('cItems',DWORD),

407 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_2W_ARRAY),

408 )

409

410# 4.1.5.1.10 DS_DOMAIN_CONTROLLER_INFO_3W

411 class DS_DOMAIN_CONTROLLER_INFO_3W(NDRSTRUCT):

412 structure = (

413 ('NetbiosName',LPWSTR),

414 ('DnsHostName',LPWSTR),

415 ('SiteName',LPWSTR),

416 ('SiteObjectName',LPWSTR),

417 ('ComputerObjectName',LPWSTR),

418 ('ServerObjectName',LPWSTR),

419 ('NtdsDsaObjectName',LPWSTR),

420 ('fIsPdc',BOOL),

421 ('fDsEnabled',BOOL),

422 ('fIsGc',BOOL),

423 ('fIsRodc',BOOL),

424 ('SiteObjectGuid',GUID),

425 ('ComputerObjectGuid',GUID),

426 ('ServerObjectGuid',GUID),

427 ('NtdsDsaObjectGuid',GUID),

428 )

429

430 class DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRUniConformantArray):

431 item = DS_DOMAIN_CONTROLLER_INFO_3W

432

433 class PDS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRPOINTER):

434 referent = (

435 ('Data',DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY),

436 )

437

438# 4.1.5.1.6 DRS_MSG_DCINFOREPLY_V3

439 class DRS_MSG_DCINFOREPLY_V3(NDRSTRUCT):

440 structure = (

441 ('cItems',DWORD),

442 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_3W_ARRAY),

443 )

444

445# 4.1.5.1.11 DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW

446 class DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW(NDRSTRUCT):

447 structure = (

448 ('IPAddress',DWORD),

449 ('NotificationCount',DWORD),

450 ('secTimeConnected',DWORD),

451 ('Flags',DWORD),

452 ('TotalRequests',DWORD),

453 ('Reserved1',DWORD),

454 ('UserName',LPWSTR),

455 )

456

457 class DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRUniConformantArray):

458 item = DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW

459

460 class PDS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRPOINTER):

461 referent = (

462 ('Data',DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY),

463 )

464

465# 4.1.5.1.7 DRS_MSG_DCINFOREPLY_VFFFFFFFF

466 class DRS_MSG_DCINFOREPLY_VFFFFFFFF(NDRSTRUCT):

467 structure = (

468 ('cItems',DWORD),

469 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY),

470 )

471

472# 4.1.5.1.3 DRS_MSG_DCINFOREPLY

473 class DRS_MSG_DCINFOREPLY(NDRUNION):

474 commonHdr = (

475 ('tag', DWORD),

476 )

477 union = {

478 1 : ('V1', DRS_MSG_DCINFOREPLY_V1),

479 2 : ('V2', DRS_MSG_DCINFOREPLY_V2),

480 3 : ('V3', DRS_MSG_DCINFOREPLY_V3),

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

482 }

483

484# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1

485 class LPWSTR_ARRAY(NDRUniConformantArray):

486 item = LPWSTR

487

488 class PLPWSTR_ARRAY(NDRPOINTER):

489 referent = (

490 ('Data',LPWSTR_ARRAY),

491 )

492

493 class DRS_MSG_CRACKREQ_V1(NDRSTRUCT):

494 structure = (

495 ('CodePage',ULONG),

496 ('LocaleId',ULONG),

497 ('dwFlags',DWORD),

498 ('formatOffered',DWORD),

499 ('formatDesired',DWORD),

500 ('cNames',DWORD),

501 ('rpNames',PLPWSTR_ARRAY),

502 )

503

504# 4.1.4.1.1 DRS_MSG_CRACKREQ

505 class DRS_MSG_CRACKREQ(NDRUNION):

506 commonHdr = (

507 ('tag', DWORD),

508 )

509 union = {

510 1 : ('V1', DRS_MSG_CRACKREQ_V1),

511 }

512

513# 4.1.4.1.3 DS_NAME_FORMAT

514 class DS_NAME_FORMAT(NDRENUM):

515 class enumItems(Enum):

516 DS_UNKNOWN_NAME = 0

517 DS_FQDN_1779_NAME = 1

518 DS_NT4_ACCOUNT_NAME = 2

519 DS_DISPLAY_NAME = 3

520 DS_UNIQUE_ID_NAME = 6

521 DS_CANONICAL_NAME = 7

522 DS_USER_PRINCIPAL_NAME = 8

523 DS_CANONICAL_NAME_EX = 9

524 DS_SERVICE_PRINCIPAL_NAME = 10

525 DS_SID_OR_SID_HISTORY_NAME = 11

526 DS_DNS_DOMAIN_NAME = 12

527

528# 4.1.4.1.4 DS_NAME_RESULT_ITEMW

529 class DS_NAME_RESULT_ITEMW(NDRSTRUCT):

530 structure = (

531 ('status',DWORD),

532 ('pDomain',LPWSTR),

533 ('pName',LPWSTR),

534 )

535

536 class DS_NAME_RESULT_ITEMW_ARRAY(NDRUniConformantArray):

537 item = DS_NAME_RESULT_ITEMW

538

539 class PDS_NAME_RESULT_ITEMW_ARRAY(NDRPOINTER):

540 referent = (

541 ('Data',DS_NAME_RESULT_ITEMW_ARRAY),

542 )

543

544# 4.1.4.1.5 DS_NAME_RESULTW

545 class DS_NAME_RESULTW(NDRSTRUCT):

546 structure = (

547 ('cItems',DWORD),

548 ('rItems',PDS_NAME_RESULT_ITEMW_ARRAY),

549 )

550

551 class PDS_NAME_RESULTW(NDRPOINTER):

552 referent = (

553 ('Data',DS_NAME_RESULTW),

554 )

555

556# 4.1.4.1.7 DRS_MSG_CRACKREPLY_V1

557 class DRS_MSG_CRACKREPLY_V1(NDRSTRUCT):

558 structure = (

559 ('pResult',PDS_NAME_RESULTW),

560 )

561

562# 4.1.4.1.6 DRS_MSG_CRACKREPLY

563 class DRS_MSG_CRACKREPLY(NDRUNION):

564 commonHdr = (

565 ('tag', DWORD),

566 )

567 union = {

568 1 : ('V1', DRS_MSG_CRACKREPLY_V1),

569 }

570

571# 5.198 UPTODATE_CURSOR_V1

572 class UPTODATE_CURSOR_V1(NDRSTRUCT):

573 structure = (

574 ('uuidDsa',UUID),

575 ('usnHighPropUpdate',USN),

576 )

577

578 class UPTODATE_CURSOR_V1_ARRAY(NDRUniConformantArray):

579 item = UPTODATE_CURSOR_V1

580

581# 5.200 UPTODATE_VECTOR_V1_EXT

582 class UPTODATE_VECTOR_V1_EXT(NDRSTRUCT):

583 structure = (

584 ('dwVersion',DWORD),

585 ('dwReserved1',DWORD),

586 ('cNumCursors',DWORD),

587 ('dwReserved2',DWORD),

588 ('rgCursors',UPTODATE_CURSOR_V1_ARRAY),

589 )

590

591 class PUPTODATE_VECTOR_V1_EXT(NDRPOINTER):

592 referent = (

593 ('Data',UPTODATE_VECTOR_V1_EXT),

594 )

595

596# 5.206 USN_VECTOR

597 class USN_VECTOR(NDRSTRUCT):

598 structure = (

599 ('usnHighObjUpdate',USN),

600 ('usnReserved',USN),

601 ('usnHighPropUpdate',USN),

602 )

603

604# 5.50 DSNAME

605 class WCHAR_ARRAY(NDRUniConformantArray):

606 item = 'H'

607

608 def __setitem__(self, key, value):

609 self.fields['MaximumCount'] = None

610 self.data = None # force recompute

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

612

613 def __getitem__(self, key):

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

615 try:

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

617 except ValueError as e:

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

619 LOG.error(str(e))

620 else:

621 return NDR.__getitem__(self,key)

622

623 class DSNAME(NDRSTRUCT):

624 structure = (

625 ('structLen',ULONG),

626 ('SidLen',ULONG),

627 ('Guid',GUID),

628 ('Sid',NT4SID),

629 ('NameLen',ULONG),

630 ('StringName', WCHAR_ARRAY),

631 )

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

633 return self['NameLen']

634 def getData(self, soFar = 0):

635 return NDRSTRUCT.getData(self, soFar)

636

637 class PDSNAME(NDRPOINTER):

638 referent = (

639 ('Data',DSNAME),

640 )

641

642 class PDSNAME_ARRAY(NDRUniConformantArray):

643 item = PDSNAME

644

645 class PPDSNAME_ARRAY(NDRPOINTER):

646 referent = (

647 ('Data',PDSNAME_ARRAY),

648 )

649

650 class ATTRTYP_ARRAY(NDRUniConformantArray):

651 item = ATTRTYP

652

653# 5.145 PARTIAL_ATTR_VECTOR_V1_EXT

654 class PARTIAL_ATTR_VECTOR_V1_EXT(NDRSTRUCT):

655 structure = (

656 ('dwVersion',DWORD),

657 ('dwReserved1',DWORD),

658 ('cAttrs',DWORD),

659 ('rgPartialAttr',ATTRTYP_ARRAY),

660 )

661

662 class PPARTIAL_ATTR_VECTOR_V1_EXT(NDRPOINTER):

663 referent = (

664 ('Data',PARTIAL_ATTR_VECTOR_V1_EXT),

665 )

666

667# 5.142 OID_t

668 class OID_t(NDRSTRUCT):

669 structure = (

670 ('length',ULONG),

671 ('elements',PBYTE_ARRAY),

672 )

673

674# 5.153 PrefixTableEntry

675 class PrefixTableEntry(NDRSTRUCT):

676 structure = (

677 ('ndx',ULONG),

678 ('prefix',OID_t),

679 )

680

681 class PrefixTableEntry_ARRAY(NDRUniConformantArray):

682 item = PrefixTableEntry

683

684 class PPrefixTableEntry_ARRAY(NDRPOINTER):

685 referent = (

686 ('Data',PrefixTableEntry_ARRAY),

687 )

688

689# 5.177 SCHEMA_PREFIX_TABLE

690 class SCHEMA_PREFIX_TABLE(NDRSTRUCT):

691 structure = (

692 ('PrefixCount',DWORD),

693 ('pPrefixEntry',PPrefixTableEntry_ARRAY),

694 )

695

696# 4.1.10.2.2 DRS_MSG_GETCHGREQ_V3

697 class DRS_MSG_GETCHGREQ_V3(NDRSTRUCT):

698 structure = (

699 ('uuidDsaObjDest',UUID),

700 ('uuidInvocIdSrc',UUID),

701 ('pNC',PDSNAME),

702 ('usnvecFrom',USN_VECTOR),

703 ('pUpToDateVecDestV1',PUPTODATE_VECTOR_V1_EXT),

704 ('pPartialAttrVecDestV1',PPARTIAL_ATTR_VECTOR_V1_EXT),

705 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

706 ('ulFlags',ULONG),

707 ('cMaxObjects',ULONG),

708 ('cMaxBytes',ULONG),

709 ('ulExtendedOp',ULONG),

710 )

711

712# 5.131 MTX_ADDR

713 class MTX_ADDR(NDRSTRUCT):

714 structure = (

715 ('mtx_namelen',ULONG),

716 ('mtx_name',PBYTE_ARRAY),

717 )

718

719 class PMTX_ADDR(NDRPOINTER):

720 referent = (

721 ('Data',MTX_ADDR),

722 )

723

724# 4.1.10.2.3 DRS_MSG_GETCHGREQ_V4

725 class DRS_MSG_GETCHGREQ_V4(NDRSTRUCT):

726 structure = (

727 ('uuidTransportObj',UUID),

728 ('pmtxReturnAddress',PMTX_ADDR),

729 ('V3',DRS_MSG_GETCHGREQ_V3),

730 )

731

732# 4.1.10.2.4 DRS_MSG_GETCHGREQ_V5

733 class DRS_MSG_GETCHGREQ_V5(NDRSTRUCT):

734 structure = (

735 ('uuidDsaObjDest',UUID),

736 ('uuidInvocIdSrc',UUID),

737 ('pNC',PDSNAME),

738 ('usnvecFrom',USN_VECTOR),

739 ('pUpToDateVecDestV1',PUPTODATE_VECTOR_V1_EXT),

740 ('ulFlags',ULONG),

741 ('cMaxObjects',ULONG),

742 ('cMaxBytes',ULONG),

743 ('ulExtendedOp',ULONG),

744 ('liFsmoInfo',ULARGE_INTEGER),

745 )

746

747# 4.1.10.2.5 DRS_MSG_GETCHGREQ_V7

748 class DRS_MSG_GETCHGREQ_V7(NDRSTRUCT):

749 structure = (

750 ('uuidTransportObj',UUID),

751 ('pmtxReturnAddress',PMTX_ADDR),

752 ('V3',DRS_MSG_GETCHGREQ_V3),

753 ('pPartialAttrSet',PPARTIAL_ATTR_VECTOR_V1_EXT),

754 ('pPartialAttrSetEx1',PPARTIAL_ATTR_VECTOR_V1_EXT),

755 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

756 )

757

758# 4.1.10.2.6 DRS_MSG_GETCHGREQ_V8

759 class DRS_MSG_GETCHGREQ_V8(NDRSTRUCT):

760 structure = (

761 ('uuidDsaObjDest',UUID),

762 ('uuidInvocIdSrc',UUID),

763 ('pNC',PDSNAME),

764 ('usnvecFrom',USN_VECTOR),

765 ('pUpToDateVecDest',PUPTODATE_VECTOR_V1_EXT),

766 ('ulFlags',ULONG),

767 ('cMaxObjects',ULONG),

768 ('cMaxBytes',ULONG),

769 ('ulExtendedOp',ULONG),

770 ('liFsmoInfo',ULARGE_INTEGER),

771 ('pPartialAttrSet',PPARTIAL_ATTR_VECTOR_V1_EXT),

772 ('pPartialAttrSetEx1',PPARTIAL_ATTR_VECTOR_V1_EXT),

773 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

774 )

775

776# 4.1.10.2.7 DRS_MSG_GETCHGREQ_V10

777 class DRS_MSG_GETCHGREQ_V10(NDRSTRUCT):

778 structure = (

779 ('uuidDsaObjDest',UUID),

780 ('uuidInvocIdSrc',UUID),

781 ('pNC',PDSNAME),

782 ('usnvecFrom',USN_VECTOR),

783 ('pUpToDateVecDest',PUPTODATE_VECTOR_V1_EXT),

784 ('ulFlags',ULONG),

785 ('cMaxObjects',ULONG),

786 ('cMaxBytes',ULONG),

787 ('ulExtendedOp',ULONG),

788 ('liFsmoInfo',ULARGE_INTEGER),

789 ('pPartialAttrSet',PPARTIAL_ATTR_VECTOR_V1_EXT),

790 ('pPartialAttrSetEx1',PPARTIAL_ATTR_VECTOR_V1_EXT),

791 ('PrefixTableDest',SCHEMA_PREFIX_TABLE),

792 ('ulMoreFlags',ULONG),

793 )

794

795# 4.1.10.2.1 DRS_MSG_GETCHGREQ

796 class DRS_MSG_GETCHGREQ(NDRUNION):

797 commonHdr = (

798 ('tag', DWORD),

799 )

800 union = {

801 4 : ('V4', DRS_MSG_GETCHGREQ_V4),

802 5 : ('V5', DRS_MSG_GETCHGREQ_V5),

803 7 : ('V7', DRS_MSG_GETCHGREQ_V7),

804 8 : ('V8', DRS_MSG_GETCHGREQ_V8),

805 10 : ('V10', DRS_MSG_GETCHGREQ_V10),

806 }

807

808# 5.16 ATTRVAL

809 class ATTRVAL(NDRSTRUCT):

810 structure = (

811 ('valLen',ULONG),

812 ('pVal',PBYTE_ARRAY),

813 )

814

815 class ATTRVAL_ARRAY(NDRUniConformantArray):

816 item = ATTRVAL

817

818 class PATTRVAL_ARRAY(NDRPOINTER):

819 referent = (

820 ('Data',ATTRVAL_ARRAY),

821 )

822

823# 5.17 ATTRVALBLOCK

824 class ATTRVALBLOCK(NDRSTRUCT):

825 structure = (

826 ('valCount',ULONG),

827 ('pAVal',PATTRVAL_ARRAY),

828 )

829

830# 5.9 ATTR

831 class ATTR(NDRSTRUCT):

832 structure = (

833 ('attrTyp',ATTRTYP),

834 ('AttrVal',ATTRVALBLOCK),

835 )

836

837 class ATTR_ARRAY(NDRUniConformantArray):

838 item = ATTR

839

840 class PATTR_ARRAY(NDRPOINTER):

841 referent = (

842 ('Data',ATTR_ARRAY),

843 )

844

845# 5.10 ATTRBLOCK

846 class ATTRBLOCK(NDRSTRUCT):

847 structure = (

848 ('attrCount',ULONG),

849 ('pAttr',PATTR_ARRAY),

850 )

851

852# 5.53 ENTINF

853 class ENTINF(NDRSTRUCT):

854 structure = (

855 ('pName',PDSNAME),

856 ('ulFlags',ULONG),

857 ('AttrBlock',ATTRBLOCK),

858 )

859

860 class ENTINF_ARRAY(NDRUniConformantArray):

861 item = ENTINF

862

863 class PENTINF_ARRAY(NDRPOINTER):

864 referent = (

865 ('Data',ENTINF_ARRAY),

866 )

867

868# 5.154 PROPERTY_META_DATA_EXT

869 class PROPERTY_META_DATA_EXT(NDRSTRUCT):

870 structure = (

871 ('dwVersion',DWORD),

872 ('timeChanged',DSTIME),

873 ('uuidDsaOriginating',UUID),

874 ('usnOriginating',USN),

875 )

876

877 class PROPERTY_META_DATA_EXT_ARRAY(NDRUniConformantArray):

878 item = PROPERTY_META_DATA_EXT

879

880# 5.155 PROPERTY_META_DATA_EXT_VECTOR

881 class PROPERTY_META_DATA_EXT_VECTOR(NDRSTRUCT):

882 structure = (

883 ('cNumProps',DWORD),

884 ('rgMetaData',PROPERTY_META_DATA_EXT_ARRAY),

885 )

886

887 class PPROPERTY_META_DATA_EXT_VECTOR(NDRPOINTER):

888 referent = (

889 ('Data',PROPERTY_META_DATA_EXT_VECTOR),

890 )

891

892# 5.161 REPLENTINFLIST

893

894 class REPLENTINFLIST(NDRSTRUCT):

895 structure = (

896 ('pNextEntInf',NDRPOINTER),

897 ('Entinf',ENTINF),

898 ('fIsNCPrefix',BOOL),

899 ('pParentGuidm',PUUID),

900 ('pMetaDataExt',PPROPERTY_META_DATA_EXT_VECTOR),

901 )

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

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

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

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

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

907 return retVal

908

909 class PREPLENTINFLIST(NDRPOINTER):

910 referent = (

911 ('Data',REPLENTINFLIST),

912 )

913

914# 4.1.10.2.9 DRS_MSG_GETCHGREPLY_V1

915 class DRS_MSG_GETCHGREPLY_V1(NDRSTRUCT):

916 structure = (

917 ('uuidDsaObjSrc',UUID),

918 ('uuidInvocIdSrc',UUID),

919 ('pNC',PDSNAME),

920 ('usnvecFrom',USN_VECTOR),

921 ('usnvecTo',USN_VECTOR),

922 ('pUpToDateVecSrcV1',PUPTODATE_VECTOR_V1_EXT),

923 ('PrefixTableSrc',SCHEMA_PREFIX_TABLE),

924 ('ulExtendedRet',EXOP_ERR),

925 ('cNumObjects',ULONG),

926 ('cNumBytes',ULONG),

927 ('pObjects',PREPLENTINFLIST),

928 ('fMoreData',BOOL),

929 )

930

931# 4.1.10.2.15 DRS_COMPRESSED_BLOB

932 class DRS_COMPRESSED_BLOB(NDRSTRUCT):

933 structure = (

934 ('cbUncompressedSize',DWORD),

935 ('cbCompressedSize',DWORD),

936 ('pbCompressedData',BYTE_ARRAY),

937 )

938

939# 4.1.10.2.10 DRS_MSG_GETCHGREPLY_V2

940 class DRS_MSG_GETCHGREPLY_V2(NDRSTRUCT):

941 structure = (

942 ('CompressedV1',DRS_COMPRESSED_BLOB),

943 )

944

945# 5.199 UPTODATE_CURSOR_V2

946 class UPTODATE_CURSOR_V2(NDRSTRUCT):

947 structure = (

948 ('uuidDsa',UUID),

949 ('usnHighPropUpdate',USN),

950 ('timeLastSyncSuccess',DSTIME),

951 )

952

953 class UPTODATE_CURSOR_V2_ARRAY(NDRUniConformantArray):

954 item = UPTODATE_CURSOR_V2

955

956# 5.201 UPTODATE_VECTOR_V2_EXT

957 class UPTODATE_VECTOR_V2_EXT(NDRSTRUCT):

958 structure = (

959 ('dwVersion',DWORD),

960 ('dwReserved1',DWORD),

961 ('cNumCursors',DWORD),

962 ('dwReserved2',DWORD),

963 ('rgCursors',UPTODATE_CURSOR_V2_ARRAY),

964 )

965

966 class PUPTODATE_VECTOR_V2_EXT(NDRPOINTER):

967 referent = (

968 ('Data',UPTODATE_VECTOR_V2_EXT),

969 )

970

971# 5.211 VALUE_META_DATA_EXT_V1

972 class VALUE_META_DATA_EXT_V1(NDRSTRUCT):

973 structure = (

974 ('timeCreated',DSTIME),

975 ('MetaData',PROPERTY_META_DATA_EXT),

976 )

977

978# 5.215 VALUE_META_DATA_EXT_V3

979 class VALUE_META_DATA_EXT_V3(NDRSTRUCT):

980 structure = (

981 ('timeCreated',DSTIME),

982 ('MetaData',PROPERTY_META_DATA_EXT),

983 ('unused1',DWORD),

984 ('unused1',DWORD),

985 ('unused1',DWORD),

986 ('timeExpired',DSTIME),

987 )

988

989# 5.167 REPLVALINF_V1

990 class REPLVALINF_V1(NDRSTRUCT):

991 structure = (

992 ('pObject',PDSNAME),

993 ('attrTyp',ATTRTYP),

994 ('Aval',ATTRVAL),

995 ('fIsPresent',BOOL),

996 ('MetaData',VALUE_META_DATA_EXT_V1),

997 )

998

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

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

1001 #self.dumpRaw()

1002 return retVal

1003

1004 class REPLVALINF_V1_ARRAY(NDRUniConformantArray):

1005 item = REPLVALINF_V1

1006

1007 class PREPLVALINF_V1_ARRAY(NDRPOINTER):

1008 referent = (

1009 ('Data', REPLVALINF_V1_ARRAY),

1010 )

1011

1012# 5.168 REPLVALINF_V3

1013 class REPLVALINF_V3(NDRSTRUCT):

1014 structure = (

1015 ('pObject', PDSNAME),

1016 ('attrTyp', ATTRTYP),

1017 ('Aval', ATTRVAL),

1018 ('fIsPresent', BOOL),

1019 ('MetaData', VALUE_META_DATA_EXT_V3),

1020 )

1021

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

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

1024 # self.dumpRaw()

1025 return retVal

1026

1027 class REPLVALINF_V3_ARRAY(NDRUniConformantArray):

1028 item = REPLVALINF_V3

1029

1030 class PREPLVALINF_V3_ARRAY(NDRPOINTER):

1031 referent = (

1032 ('Data', REPLVALINF_V3_ARRAY),

1033 )

1034

1035# 5.169 REPLVALINF_NATIVE

1036 REPLVALINF_NATIVE = REPLVALINF_V3

1037

1038# 4.1.10.2.11 DRS_MSG_GETCHGREPLY_V6

1039 class DRS_MSG_GETCHGREPLY_V6(NDRSTRUCT):

1040 structure = (

1041 ('uuidDsaObjSrc',UUID),

1042 ('uuidInvocIdSrc',UUID),

1043 ('pNC',PDSNAME),

1044 ('usnvecFrom',USN_VECTOR),

1045 ('usnvecTo',USN_VECTOR),

1046 ('pUpToDateVecSrc',PUPTODATE_VECTOR_V2_EXT),

1047 ('PrefixTableSrc',SCHEMA_PREFIX_TABLE),

1048 ('ulExtendedRet',EXOP_ERR),

1049 ('cNumObjects',ULONG),

1050 ('cNumBytes',ULONG),

1051 ('pObjects',PREPLENTINFLIST),

1052 ('fMoreData',BOOL),

1053 ('cNumNcSizeObjectsc',ULONG),

1054 ('cNumNcSizeValues',ULONG),

1055 ('cNumValues',DWORD),

1056 #('rgValues',PREPLVALINF_V1_ARRAY),

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

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

1059 ('rgValues',DWORD),

1060 ('dwDRSError',DWORD),

1061 )

1062

1063# 4.1.10.2.14 DRS_COMP_ALG_TYPE

1064 class DRS_COMP_ALG_TYPE(NDRENUM):

1065 class enumItems(Enum):

1066 DRS_COMP_ALG_NONE = 0

1067 DRS_COMP_ALG_UNUSED = 1

1068 DRS_COMP_ALG_MSZIP = 2

1069 DRS_COMP_ALG_WIN2K3 = 3

1070

1071# 4.1.10.2.12 DRS_MSG_GETCHGREPLY_V7

1072 class DRS_MSG_GETCHGREPLY_V7(NDRSTRUCT):

1073 structure = (

1074 ('dwCompressedVersion',DWORD),

1075 ('CompressionAlg',DRS_COMP_ALG_TYPE),

1076 ('CompressedAny',DRS_COMPRESSED_BLOB),

1077 )

1078

1079# 4.1.10.2.13 DRS_MSG_GETCHGREPLY_V9

1080 class DRS_MSG_GETCHGREPLY_V9(NDRSTRUCT):

1081 structure = (

1082 ('uuidDsaObjSrc',UUID),

1083 ('uuidInvocIdSrc',UUID),

1084 ('pNC',PDSNAME),

1085 ('usnvecFrom',USN_VECTOR),

1086 ('usnvecTo',USN_VECTOR),

1087 ('pUpToDateVecSrc',PUPTODATE_VECTOR_V2_EXT),

1088 ('PrefixTableSrc',SCHEMA_PREFIX_TABLE),

1089 ('ulExtendedRet',EXOP_ERR),

1090 ('cNumObjects',ULONG),

1091 ('cNumBytes',ULONG),

1092 ('pObjects',PREPLENTINFLIST),

1093 ('fMoreData',BOOL),

1094 ('cNumNcSizeObjectsc',ULONG),

1095 ('cNumNcSizeValues',ULONG),

1096 ('cNumValues',DWORD),

1097 #('rgValues',PREPLVALINF_V3_ARRAY),

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

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

1100 ('rgValues',DWORD),

1101 ('dwDRSError',DWORD),

1102 )

1103

1104# 4.1.10.2.14 DRS_MSG_GETCHGREPLY_NATIVE

1105 DRS_MSG_GETCHGREPLY_NATIVE = DRS_MSG_GETCHGREPLY_V9

1106

1107# 4.1.10.2.8 DRS_MSG_GETCHGREPLY

1108 class DRS_MSG_GETCHGREPLY(NDRUNION):

1109 commonHdr = (

1110 ('tag', DWORD),

1111 )

1112 union = {

1113 1 : ('V1', DRS_MSG_GETCHGREPLY_V1),

1114 2 : ('V2', DRS_MSG_GETCHGREPLY_V2),

1115 6 : ('V6', DRS_MSG_GETCHGREPLY_V6),

1116 7 : ('V7', DRS_MSG_GETCHGREPLY_V7),

1117 9 : ('V9', DRS_MSG_GETCHGREPLY_V9),

1118 }

1119

1120# 4.1.27.1.2 DRS_MSG_VERIFYREQ_V1

1121 class DRS_MSG_VERIFYREQ_V1(NDRSTRUCT):

1122 structure = (

1123 ('dwFlags',DWORD),

1124 ('cNames',DWORD),

1125 ('rpNames',PPDSNAME_ARRAY),

1126 ('RequiredAttrs',ATTRBLOCK),

1127 ('PrefixTable',SCHEMA_PREFIX_TABLE),

1128 )

1129

1130# 4.1.27.1.1 DRS_MSG_VERIFYREQ

1131 class DRS_MSG_VERIFYREQ(NDRUNION):

1132 commonHdr = (

1133 ('tag', DWORD),

1134 )

1135 union = {

1136 1 : ('V1', DRS_MSG_VERIFYREQ_V1),

1137 }

1138

1139# 4.1.27.1.4 DRS_MSG_VERIFYREPLY_V1

1140 class DRS_MSG_VERIFYREPLY_V1(NDRSTRUCT):

1141 structure = (

1142 ('error',DWORD),

1143 ('cNames',DWORD),

1144 ('rpEntInf',PENTINF_ARRAY),

1145 ('PrefixTable',SCHEMA_PREFIX_TABLE),

1146 )

1147

1148# 4.1.27.1.3 DRS_MSG_VERIFYREPLY

1149 class DRS_MSG_VERIFYREPLY(NDRUNION):

1150 commonHdr = (

1151 ('tag', DWORD),

1152 )

1153 union = {

1154 1 : ('V1', DRS_MSG_VERIFYREPLY_V1),

1155 }

1156

1157# 4.1.11.1.2 DRS_MSG_NT4_CHGLOG_REQ_V1

1158 class DRS_MSG_NT4_CHGLOG_REQ_V1(NDRSTRUCT):

1159 structure = (

1160 ('dwFlags',DWORD),

1161 ('PreferredMaximumLength',DWORD),

1162 ('cbRestart',DWORD),

1163 ('pRestart',PBYTE_ARRAY),

1164 )

1165

1166# 4.1.11.1.1 DRS_MSG_NT4_CHGLOG_REQ

1167 class DRS_MSG_NT4_CHGLOG_REQ(NDRUNION):

1168 commonHdr = (

1169 ('tag', DWORD),

1170 )

1171 union = {

1172 1 : ('V1', DRS_MSG_NT4_CHGLOG_REQ_V1),

1173 }

1174

1175# 4.1.11.1.5 NT4_REPLICATION_STATE

1176 class NT4_REPLICATION_STATE(NDRSTRUCT):

1177 structure = (

1178 ('SamSerialNumber',LARGE_INTEGER),

1179 ('SamCreationTime',LARGE_INTEGER),

1180 ('BuiltinSerialNumber',LARGE_INTEGER),

1181 ('BuiltinCreationTime',LARGE_INTEGER),

1182 ('LsaSerialNumber',LARGE_INTEGER),

1183 ('LsaCreationTime',LARGE_INTEGER),

1184 )

1185

1186# 4.1.11.1.4 DRS_MSG_NT4_CHGLOG_REPLY_V1

1187 class DRS_MSG_NT4_CHGLOG_REPLY_V1(NDRSTRUCT):

1188 structure = (

1189 ('cbRestart',DWORD),

1190 ('cbLog',DWORD),

1191 ('ReplicationState',NT4_REPLICATION_STATE),

1192 ('ActualNtStatus',DWORD),

1193 ('pRestart',PBYTE_ARRAY),

1194 ('pLog',PBYTE_ARRAY),

1195 )

1196

1197# 4.1.11.1.3 DRS_MSG_NT4_CHGLOG_REPLY

1198 class DRS_MSG_NT4_CHGLOG_REPLY(NDRUNION):

1199 commonHdr = (

1200 ('tag', DWORD),

1201 )

1202 union = {

1203 1 : ('V1', DRS_MSG_NT4_CHGLOG_REPLY_V1),

1204 }

1205

1206################################################################################

1207# RPC CALLS

1208################################################################################

1209# 4.1.3 IDL_DRSBind (Opnum 0)

1210 class DRSBind(NDRCALL):

1211 opnum = 0

1212 structure = (

1213 ('puuidClientDsa', PUUID),

1214 ('pextClient', PDRS_EXTENSIONS),

1215 )

1216

1217 class DRSBindResponse(NDRCALL):

1218 structure = (

1219 ('ppextServer', PDRS_EXTENSIONS),

1220 ('phDrs', DRS_HANDLE),

1221 ('ErrorCode',DWORD),

1222 )

1223

1224# 4.1.25 IDL_DRSUnbind (Opnum 1)

1225 class DRSUnbind(NDRCALL):

1226 opnum = 1

1227 structure = (

1228 ('phDrs', DRS_HANDLE),

1229 )

1230

1231 class DRSUnbindResponse(NDRCALL):

1232 structure = (

1233 ('phDrs', DRS_HANDLE),

1234 ('ErrorCode',DWORD),

1235 )

1236

1237# 4.1.10 IDL_DRSGetNCChanges (Opnum 3)

1238 class DRSGetNCChanges(NDRCALL):

1239 opnum = 3

1240 structure = (

1241 ('hDrs', DRS_HANDLE),

1242 ('dwInVersion', DWORD),

1243 ('pmsgIn', DRS_MSG_GETCHGREQ),

1244 )

1245

1246 class DRSGetNCChangesResponse(NDRCALL):

1247 structure = (

1248 ('pdwOutVersion', DWORD),

1249 ('pmsgOut', DRS_MSG_GETCHGREPLY),

1250 ('ErrorCode',DWORD),

1251 )

1252

1253# 4.1.27 IDL_DRSVerifyNames (Opnum 8)

1254 class DRSVerifyNames(NDRCALL):

1255 opnum = 8

1256 structure = (

1257 ('hDrs', DRS_HANDLE),

1258 ('dwInVersion', DWORD),

1259 ('pmsgIn', DRS_MSG_VERIFYREQ),

1260 )

1261

1262 class DRSVerifyNamesResponse(NDRCALL):

1263 structure = (

1264 ('pdwOutVersion', DWORD),

1265 ('pmsgOut', DRS_MSG_VERIFYREPLY),

1266 ('ErrorCode',DWORD),

1267 )

1268# 4.1.11 IDL_DRSGetNT4ChangeLog (Opnum 11)

1269 class DRSGetNT4ChangeLog(NDRCALL):

1270 opnum = 11

1271 structure = (

1272 ('hDrs', DRS_HANDLE),

1273 ('dwInVersion', DWORD),

1274 ('pmsgIn', DRS_MSG_NT4_CHGLOG_REQ),

1275 )

1276

1277 class DRSGetNT4ChangeLogResponse(NDRCALL):

1278 structure = (

1279 ('pdwOutVersion', DWORD),

1280 ('pmsgOut', DRS_MSG_NT4_CHGLOG_REPLY),

1281 ('ErrorCode',DWORD),

1282 )

1283

1284# 4.1.4 IDL_DRSCrackNames (Opnum 12)

1285 class DRSCrackNames(NDRCALL):

1286 opnum = 12

1287 structure = (

1288 ('hDrs', DRS_HANDLE),

1289 ('dwInVersion', DWORD),

1290 ('pmsgIn', DRS_MSG_CRACKREQ),

1291 )

1292

1293 class DRSCrackNamesResponse(NDRCALL):

1294 structure = (

1295 ('pdwOutVersion', DWORD),

1296 ('pmsgOut', DRS_MSG_CRACKREPLY),

1297 ('ErrorCode',DWORD),

1298 )

1299

1300# 4.1.5 IDL_DRSDomainControllerInfo (Opnum 16)

1301 class DRSDomainControllerInfo(NDRCALL):

1302 opnum = 16

1303 structure = (

1304 ('hDrs', DRS_HANDLE),

1305 ('dwInVersion', DWORD),

1306 ('pmsgIn', DRS_MSG_DCINFOREQ),

1307 )

1308

1309 class DRSDomainControllerInfoResponse(NDRCALL):

1310 structure = (

1311 ('pdwOutVersion', DWORD),

1312 ('pmsgOut', DRS_MSG_DCINFOREPLY),

1313 ('ErrorCode',DWORD),

1314 )

1315

1316################################################################################

1317# OPNUMs and their corresponding structures

1318################################################################################

1319 OPNUMS = {

1320 0 : (DRSBind,DRSBindResponse ),

1321 1 : (DRSUnbind,DRSUnbindResponse ),

1322 3 : (DRSGetNCChanges,DRSGetNCChangesResponse ),

1323 12: (DRSCrackNames,DRSCrackNamesResponse ),

1324 16: (DRSDomainControllerInfo,DRSDomainControllerInfoResponse ),

1325}

1326

1327################################################################################

1328# HELPER FUNCTIONS

1329################################################################################

1330 def checkNullString(string):

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

1332 return string

1333

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

1335 return string + '\x00'

1336 else:

1337 return string

1338

1339 def hDRSUnbind(dce, hDrs):

1340 request = DRSUnbind()

1341 request['phDrs'] = hDrs

1342 return dce.request(request)

1343

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

1345 request = DRSDomainControllerInfo()

1346 request['hDrs'] = hDrs

1347 request['dwInVersion'] = 1

1348

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

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

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

1352 return dce.request(request)

1353

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

1355 request = DRSCrackNames()

1356 request['hDrs'] = hDrs

1357 request['dwInVersion'] = 1

1358

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

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

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

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

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

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

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

1366 for name in rpNames:

1367 record = LPWSTR()

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

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

1370

1371 return dce.request(request)

1372

1373 def deriveKey(baseKey):

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

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

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

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

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

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

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

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

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

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

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

1385 else:

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

1387

1388 def removeDESLayer(cryptedHash, rid):

1389 Key1,Key2 = deriveKey(rid)

1390

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

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

1393

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

1395

1396 return decryptedHash

1397

1398 def DecryptAttributeValue(dce, attribute):

1399 sessionKey = dce.get_session_key()

1400 # Is it a Kerberos Session Key?

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

1402 # Extract its contents and move on

1403 sessionKey = sessionKey.contents

1404

1405 encryptedPayload = ENCRYPTED_PAYLOAD(attribute)

1406

1407 md5 = hashlib.new('md5')

1408 md5.update(sessionKey)

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

1410 finalMD5 = md5.digest()

1411

1412 cipher = ARC4.new(finalMD5)

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

1414

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

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

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

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

1419

1420 return plainText[4:]

1421

1422# 5.16.4 ATTRTYP-to-OID Conversion

1423 def MakeAttid(prefixTable, oid):

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

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

1426

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

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

1429 from pyasn1.type import univ

1430 from pyasn1.codec.ber import encoder

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

1432

1433 # get the prefix of the OID

1434 if lastValue < 128:

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

1436 else:

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

1438

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

1440 # one entry for the new prefix.

1441 fToAdd = True

1442 pos = len(prefixTable)

1443 for j, item in enumerate(prefixTable):

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

1445 fToAdd = False

1446 pos = j

1447 break

1448

1449 if fToAdd is True:

1450 entry = PrefixTableEntry()

1451 entry['ndx'] = pos

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

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

1454 prefixTable.append(entry)

1455

1456 # compose the attid

1457 lowerWord = lastValue % 16384

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

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

1460 lowerWord += 32768

1461

1462 upperWord = pos

1463

1464 attrTyp = ATTRTYP()

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

1466 return attrTyp

1467

1468 def OidFromAttid(prefixTable, attr):

1469 # separate the ATTRTYP into two parts

1470 upperWord = attr // 65536

1471 lowerWord = attr % 65536

1472

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

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

1475 # found prefix.

1476

1477 binaryOID = None

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

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

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

1481 if lowerWord < 128:

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

1483 else:

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

1485 lowerWord -= 32768

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

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

1488 break

1489

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

1491 return None

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

1493

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

1495 prefixTable = []

1496 oid0 = '1.2.840.113556.1.4.94'

1497 oid1 = '2.5.6.2'

1498 oid2 = '1.2.840.113556.1.2.1'

1499 oid3 = '1.2.840.113556.1.3.223'

1500 oid4 = '1.2.840.113556.1.5.7000.53'

1501

1502 o0 = MakeAttid(prefixTable, oid0)

1503 print(hex(o0))

1504 o1 = MakeAttid(prefixTable, oid1)

1505 print(hex(o1))

1506 o2 = MakeAttid(prefixTable, oid2)

1507 print(hex(o2))

1508 o3 = MakeAttid(prefixTable, oid3)

1509 print(hex(o3))

1510 o4 = MakeAttid(prefixTable, oid4)

1511 print(hex(o4))

1512 jj = OidFromAttid(prefixTable, o0)

1513 print(jj)

1514 jj = OidFromAttid(prefixTable, o1)

1515 print(jj)

1516 jj = OidFromAttid(prefixTable, o2)

1517 print(jj)

1518 jj = OidFromAttid(prefixTable, o3)

1519 print(jj)

1520 jj = OidFromAttid(prefixTable, o4)

1521 print(jj)