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

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#
25from __future__ import division
26from __future__ import print_function
27from builtins import bytes
28import hashlib
29from struct import pack
30import six
31from six import PY2
33from impacket import LOG
34from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRUNION, NDR, NDRENUM
35from impacket.dcerpc.v5.dtypes import PUUID, DWORD, NULL, GUID, LPWSTR, BOOL, ULONG, UUID, LONGLONG, ULARGE_INTEGER, LARGE_INTEGER
36from impacket import hresult_errors, system_errors
37from impacket.structure import Structure
38from impacket.uuid import uuidtup_to_bin, string_to_bin
39from impacket.dcerpc.v5.enum import Enum
40from impacket.dcerpc.v5.rpcrt import DCERPCException
41from impacket.krb5 import crypto
42from pyasn1.type import univ
43from pyasn1.codec.ber import decoder
44from impacket.crypto import transformKey
46try:
47 from Cryptodome.Cipher import ARC4, DES
48except Exception:
49 LOG.critical("Warning: You don't have any crypto installed. You need pycryptodomex")
50 LOG.critical("See https://pypi.org/project/pycryptodomex/")
52MSRPC_UUID_DRSUAPI = uuidtup_to_bin(('E3514235-4B06-11D1-AB04-00C04FC2DCD2','4.0'))
54class DCERPCSessionError(DCERPCException):
55 def __init__(self, error_string=None, error_code=None, packet=None):
56 DCERPCException.__init__(self, error_string, error_code, packet)
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
71################################################################################
72# CONSTANTS
73################################################################################
74# 4.1.10.2.17 EXOP_ERR Codes
75class 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
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=' ')
105 try:
106 print(" %s" % self.enumItems(self.fields['Data']).name, end=' ')
107 except ValueError:
108 print(" %d" % self.fields['Data'])
110# 4.1.10.2.18 EXOP_REQ Codes
111EXOP_FSMO_REQ_ROLE = 0x00000001
112EXOP_FSMO_REQ_RID_ALLOC = 0x00000002
113EXOP_FSMO_RID_REQ_ROLE = 0x00000003
114EXOP_FSMO_REQ_PDC = 0x00000004
115EXOP_FSMO_ABANDON_ROLE = 0x00000005
116EXOP_REPL_OBJ = 0x00000006
117EXOP_REPL_SECRETS = 0x00000007
119# 5.14 ATTRTYP
120ATTRTYP = ULONG
122# 5.51 DSTIME
123DSTIME = LONGLONG
125# 5.39 DRS_EXTENSIONS_INT
126DRS_EXT_BASE = 0x00000001
127DRS_EXT_ASYNCREPL = 0x00000002
128DRS_EXT_REMOVEAPI = 0x00000004
129DRS_EXT_MOVEREQ_V2 = 0x00000008
130DRS_EXT_GETCHG_DEFLATE = 0x00000010
131DRS_EXT_DCINFO_V1 = 0x00000020
132DRS_EXT_RESTORE_USN_OPTIMIZATION = 0x00000040
133DRS_EXT_ADDENTRY = 0x00000080
134DRS_EXT_KCC_EXECUTE = 0x00000100
135DRS_EXT_ADDENTRY_V2 = 0x00000200
136DRS_EXT_LINKED_VALUE_REPLICATION = 0x00000400
137DRS_EXT_DCINFO_V2 = 0x00000800
138DRS_EXT_INSTANCE_TYPE_NOT_REQ_ON_MOD = 0x00001000
139DRS_EXT_CRYPTO_BIND = 0x00002000
140DRS_EXT_GET_REPL_INFO = 0x00004000
141DRS_EXT_STRONG_ENCRYPTION = 0x00008000
142DRS_EXT_DCINFO_VFFFFFFFF = 0x00010000
143DRS_EXT_TRANSITIVE_MEMBERSHIP = 0x00020000
144DRS_EXT_ADD_SID_HISTORY = 0x00040000
145DRS_EXT_POST_BETA3 = 0x00080000
146DRS_EXT_GETCHGREQ_V5 = 0x00100000
147DRS_EXT_GETMEMBERSHIPS2 = 0x00200000
148DRS_EXT_GETCHGREQ_V6 = 0x00400000
149DRS_EXT_NONDOMAIN_NCS = 0x00800000
150DRS_EXT_GETCHGREQ_V8 = 0x01000000
151DRS_EXT_GETCHGREPLY_V5 = 0x02000000
152DRS_EXT_GETCHGREPLY_V6 = 0x04000000
153DRS_EXT_GETCHGREPLY_V9 = 0x00000100
154DRS_EXT_WHISTLER_BETA3 = 0x08000000
155DRS_EXT_W2K3_DEFLATE = 0x10000000
156DRS_EXT_GETCHGREQ_V10 = 0x20000000
157DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART2 = 0x40000000
158DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART3 = 0x80000000
160# dwFlagsExt
161DRS_EXT_ADAM = 0x00000001
162DRS_EXT_LH_BETA2 = 0x00000002
163DRS_EXT_RECYCLE_BIN = 0x00000004
165# 5.41 DRS_OPTIONS
166DRS_ASYNC_OP = 0x00000001
167DRS_GETCHG_CHECK = 0x00000002
168DRS_UPDATE_NOTIFICATION = 0x00000002
169DRS_ADD_REF = 0x00000004
170DRS_SYNC_ALL = 0x00000008
171DRS_DEL_REF = 0x00000008
172DRS_WRIT_REP = 0x00000010
173DRS_INIT_SYNC = 0x00000020
174DRS_PER_SYNC = 0x00000040
175DRS_MAIL_REP = 0x00000080
176DRS_ASYNC_REP = 0x00000100
177DRS_IGNORE_ERROR = 0x00000100
178DRS_TWOWAY_SYNC = 0x00000200
179DRS_CRITICAL_ONLY = 0x00000400
180DRS_GET_ANC = 0x00000800
181DRS_GET_NC_SIZE = 0x00001000
182DRS_LOCAL_ONLY = 0x00001000
183DRS_NONGC_RO_REP = 0x00002000
184DRS_SYNC_BYNAME = 0x00004000
185DRS_REF_OK = 0x00004000
186DRS_FULL_SYNC_NOW = 0x00008000
187DRS_NO_SOURCE = 0x00008000
188DRS_FULL_SYNC_IN_PROGRESS = 0x00010000
189DRS_FULL_SYNC_PACKET = 0x00020000
190DRS_SYNC_REQUEUE = 0x00040000
191DRS_SYNC_URGENT = 0x00080000
192DRS_REF_GCSPN = 0x00100000
193DRS_NO_DISCARD = 0x00100000
194DRS_NEVER_SYNCED = 0x00200000
195DRS_SPECIAL_SECRET_PROCESSING = 0x00400000
196DRS_INIT_SYNC_NOW = 0x00800000
197DRS_PREEMPTED = 0x01000000
198DRS_SYNC_FORCED = 0x02000000
199DRS_DISABLE_AUTO_SYNC = 0x04000000
200DRS_DISABLE_PERIODIC_SYNC = 0x08000000
201DRS_USE_COMPRESSION = 0x10000000
202DRS_NEVER_NOTIFY = 0x20000000
203DRS_SYNC_PAS = 0x40000000
204DRS_GET_ALL_GROUP_MEMBERSHIP = 0x80000000
207# 5.113 LDAP_CONN_PROPERTIES
208BND = 0x00000001
209SSL = 0x00000002
210UDP = 0x00000004
211GC = 0x00000008
212GSS = 0x00000010
213NGO = 0x00000020
214SPL = 0x00000040
215MD5 = 0x00000080
216SGN = 0x00000100
217SL = 0x00000200
219# 5.137 NTSAPI_CLIENT_GUID
220NTDSAPI_CLIENT_GUID = string_to_bin('e24d201a-4fd6-11d1-a3da-0000f875ae0d')
222# 5.139 NULLGUID
223NULLGUID = string_to_bin('00000000-0000-0000-0000-000000000000')
225# 5.205 USN
226USN = LONGLONG
228# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1
229DS_NAME_FLAG_GCVERIFY = 0x00000004
230DS_NAME_FLAG_TRUST_REFERRAL = 0x00000008
231DS_NAME_FLAG_PRIVATE_RESOLVE_FPOS = 0x80000000
233DS_LIST_SITES = 0xFFFFFFFF
234DS_LIST_SERVERS_IN_SITE = 0xFFFFFFFE
235DS_LIST_DOMAINS_IN_SITE = 0xFFFFFFFD
236DS_LIST_SERVERS_FOR_DOMAIN_IN_SITE = 0xFFFFFFFC
237DS_LIST_INFO_FOR_SERVER = 0xFFFFFFFB
238DS_LIST_ROLES = 0xFFFFFFFA
239DS_NT4_ACCOUNT_NAME_SANS_DOMAIN = 0xFFFFFFF9
240DS_MAP_SCHEMA_GUID = 0xFFFFFFF8
241DS_LIST_DOMAINS = 0xFFFFFFF7
242DS_LIST_NCS = 0xFFFFFFF6
243DS_ALT_SECURITY_IDENTITIES_NAME = 0xFFFFFFF5
244DS_STRING_SID_NAME = 0xFFFFFFF4
245DS_LIST_SERVERS_WITH_DCS_IN_SITE = 0xFFFFFFF3
246DS_LIST_GLOBAL_CATALOG_SERVERS = 0xFFFFFFF1
247DS_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX = 0xFFFFFFF0
248DS_USER_PRINCIPAL_NAME_AND_ALTSECID = 0xFFFFFFEF
250DS_USER_PRINCIPAL_NAME_FOR_LOGON = 0xFFFFFFF2
252# 5.53 ENTINF
253ENTINF_FROM_MASTER = 0x00000001
254ENTINF_DYNAMIC_OBJECT = 0x00000002
255ENTINF_REMOTE_MODIFY = 0x00010000
257# 4.1.27.1.2 DRS_MSG_VERIFYREQ_V1
258DRS_VERIFY_DSNAMES = 0x00000000
259DRS_VERIFY_SIDS = 0x00000001
260DRS_VERIFY_SAM_ACCOUNT_NAMES = 0x00000002
261DRS_VERIFY_FPOS = 0x00000003
263# 4.1.11.1.2 DRS_MSG_NT4_CHGLOG_REQ_V1
264DRS_NT4_CHGLOG_GET_CHANGE_LOG = 0x00000001
265DRS_NT4_CHGLOG_GET_SERIAL_NUMBERS = 0x00000002
267# 4.1.10.2.15 DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER
268DRS_MSG_GETCHGREPLY_NATIVE_VERSION_NUMBER = 9
269################################################################################
270# STRUCTURES
271################################################################################
272# 4.1.10.2.16 ENCRYPTED_PAYLOAD
273class ENCRYPTED_PAYLOAD(Structure):
274 structure = (
275 ('Salt','16s'),
276 ('CheckSum','<L'),
277 ('EncryptedData',':'),
278 )
280# 5.136 NT4SID
281class NT4SID(NDRSTRUCT):
282 structure = (
283 ('Data','28s=b""'),
284 )
285 def getAlignment(self):
286 return 4
288# 5.40 DRS_HANDLE
289class DRS_HANDLE(NDRSTRUCT):
290 structure = (
291 ('Data','20s=b""'),
292 )
293 def getAlignment(self):
294 return 4
296class PDRS_HANDLE(NDRPOINTER):
297 referent = (
298 ('Data',DRS_HANDLE),
299 )
301# 5.38 DRS_EXTENSIONS
302class BYTE_ARRAY(NDRUniConformantArray):
303 item = 'c'
305class PBYTE_ARRAY(NDRPOINTER):
306 referent = (
307 ('Data',BYTE_ARRAY),
308 )
310class DRS_EXTENSIONS(NDRSTRUCT):
311 structure = (
312 ('cb',DWORD),
313 ('rgb',BYTE_ARRAY),
314 )
316class PDRS_EXTENSIONS(NDRPOINTER):
317 referent = (
318 ('Data',DRS_EXTENSIONS),
319 )
321# 5.39 DRS_EXTENSIONS_INT
322class 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 )
333# 4.1.5.1.2 DRS_MSG_DCINFOREQ_V1
334class DRS_MSG_DCINFOREQ_V1(NDRSTRUCT):
335 structure = (
336 ('Domain',LPWSTR),
337 ('InfoLevel',DWORD),
338 )
340# 4.1.5.1.1 DRS_MSG_DCINFOREQ
341class DRS_MSG_DCINFOREQ(NDRUNION):
342 commonHdr = (
343 ('tag', DWORD),
344 )
345 union = {
346 1 : ('V1', DRS_MSG_DCINFOREQ_V1),
347 }
349# 4.1.5.1.8 DS_DOMAIN_CONTROLLER_INFO_1W
350class 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 )
361class DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRUniConformantArray):
362 item = DS_DOMAIN_CONTROLLER_INFO_1W
364class PDS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRPOINTER):
365 referent = (
366 ('Data',DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY),
367 )
369# 4.1.5.1.4 DRS_MSG_DCINFOREPLY_V1
370class DRS_MSG_DCINFOREPLY_V1(NDRSTRUCT):
371 structure = (
372 ('cItems',DWORD),
373 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_1W_ARRAY),
374 )
376# 4.1.5.1.9 DS_DOMAIN_CONTROLLER_INFO_2W
377class 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 )
395class DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRUniConformantArray):
396 item = DS_DOMAIN_CONTROLLER_INFO_2W
398class PDS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRPOINTER):
399 referent = (
400 ('Data',DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY),
401 )
403# 4.1.5.1.5 DRS_MSG_DCINFOREPLY_V2
404class DRS_MSG_DCINFOREPLY_V2(NDRSTRUCT):
405 structure = (
406 ('cItems',DWORD),
407 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_2W_ARRAY),
408 )
410# 4.1.5.1.10 DS_DOMAIN_CONTROLLER_INFO_3W
411class 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 )
430class DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRUniConformantArray):
431 item = DS_DOMAIN_CONTROLLER_INFO_3W
433class PDS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRPOINTER):
434 referent = (
435 ('Data',DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY),
436 )
438# 4.1.5.1.6 DRS_MSG_DCINFOREPLY_V3
439class DRS_MSG_DCINFOREPLY_V3(NDRSTRUCT):
440 structure = (
441 ('cItems',DWORD),
442 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_3W_ARRAY),
443 )
445# 4.1.5.1.11 DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW
446class 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 )
457class DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRUniConformantArray):
458 item = DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW
460class PDS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRPOINTER):
461 referent = (
462 ('Data',DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY),
463 )
465# 4.1.5.1.7 DRS_MSG_DCINFOREPLY_VFFFFFFFF
466class DRS_MSG_DCINFOREPLY_VFFFFFFFF(NDRSTRUCT):
467 structure = (
468 ('cItems',DWORD),
469 ('rItems',PDS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY),
470 )
472# 4.1.5.1.3 DRS_MSG_DCINFOREPLY
473class 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 }
484# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1
485class LPWSTR_ARRAY(NDRUniConformantArray):
486 item = LPWSTR
488class PLPWSTR_ARRAY(NDRPOINTER):
489 referent = (
490 ('Data',LPWSTR_ARRAY),
491 )
493class 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 )
504# 4.1.4.1.1 DRS_MSG_CRACKREQ
505class DRS_MSG_CRACKREQ(NDRUNION):
506 commonHdr = (
507 ('tag', DWORD),
508 )
509 union = {
510 1 : ('V1', DRS_MSG_CRACKREQ_V1),
511 }
513# 4.1.4.1.3 DS_NAME_FORMAT
514class 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
528# 4.1.4.1.4 DS_NAME_RESULT_ITEMW
529class DS_NAME_RESULT_ITEMW(NDRSTRUCT):
530 structure = (
531 ('status',DWORD),
532 ('pDomain',LPWSTR),
533 ('pName',LPWSTR),
534 )
536class DS_NAME_RESULT_ITEMW_ARRAY(NDRUniConformantArray):
537 item = DS_NAME_RESULT_ITEMW
539class PDS_NAME_RESULT_ITEMW_ARRAY(NDRPOINTER):
540 referent = (
541 ('Data',DS_NAME_RESULT_ITEMW_ARRAY),
542 )
544# 4.1.4.1.5 DS_NAME_RESULTW
545class DS_NAME_RESULTW(NDRSTRUCT):
546 structure = (
547 ('cItems',DWORD),
548 ('rItems',PDS_NAME_RESULT_ITEMW_ARRAY),
549 )
551class PDS_NAME_RESULTW(NDRPOINTER):
552 referent = (
553 ('Data',DS_NAME_RESULTW),
554 )
556# 4.1.4.1.7 DRS_MSG_CRACKREPLY_V1
557class DRS_MSG_CRACKREPLY_V1(NDRSTRUCT):
558 structure = (
559 ('pResult',PDS_NAME_RESULTW),
560 )
562# 4.1.4.1.6 DRS_MSG_CRACKREPLY
563class DRS_MSG_CRACKREPLY(NDRUNION):
564 commonHdr = (
565 ('tag', DWORD),
566 )
567 union = {
568 1 : ('V1', DRS_MSG_CRACKREPLY_V1),
569 }
571# 5.198 UPTODATE_CURSOR_V1
572class UPTODATE_CURSOR_V1(NDRSTRUCT):
573 structure = (
574 ('uuidDsa',UUID),
575 ('usnHighPropUpdate',USN),
576 )
578class UPTODATE_CURSOR_V1_ARRAY(NDRUniConformantArray):
579 item = UPTODATE_CURSOR_V1
581# 5.200 UPTODATE_VECTOR_V1_EXT
582class 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 )
591class PUPTODATE_VECTOR_V1_EXT(NDRPOINTER):
592 referent = (
593 ('Data',UPTODATE_VECTOR_V1_EXT),
594 )
596# 5.206 USN_VECTOR
597class USN_VECTOR(NDRSTRUCT):
598 structure = (
599 ('usnHighObjUpdate',USN),
600 ('usnReserved',USN),
601 ('usnHighPropUpdate',USN),
602 )
604# 5.50 DSNAME
605class WCHAR_ARRAY(NDRUniConformantArray):
606 item = 'H'
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])
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)
623class 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)
637class PDSNAME(NDRPOINTER):
638 referent = (
639 ('Data',DSNAME),
640 )
642class PDSNAME_ARRAY(NDRUniConformantArray):
643 item = PDSNAME
645class PPDSNAME_ARRAY(NDRPOINTER):
646 referent = (
647 ('Data',PDSNAME_ARRAY),
648 )
650class ATTRTYP_ARRAY(NDRUniConformantArray):
651 item = ATTRTYP
653# 5.145 PARTIAL_ATTR_VECTOR_V1_EXT
654class PARTIAL_ATTR_VECTOR_V1_EXT(NDRSTRUCT):
655 structure = (
656 ('dwVersion',DWORD),
657 ('dwReserved1',DWORD),
658 ('cAttrs',DWORD),
659 ('rgPartialAttr',ATTRTYP_ARRAY),
660 )
662class PPARTIAL_ATTR_VECTOR_V1_EXT(NDRPOINTER):
663 referent = (
664 ('Data',PARTIAL_ATTR_VECTOR_V1_EXT),
665 )
667# 5.142 OID_t
668class OID_t(NDRSTRUCT):
669 structure = (
670 ('length',ULONG),
671 ('elements',PBYTE_ARRAY),
672 )
674# 5.153 PrefixTableEntry
675class PrefixTableEntry(NDRSTRUCT):
676 structure = (
677 ('ndx',ULONG),
678 ('prefix',OID_t),
679 )
681class PrefixTableEntry_ARRAY(NDRUniConformantArray):
682 item = PrefixTableEntry
684class PPrefixTableEntry_ARRAY(NDRPOINTER):
685 referent = (
686 ('Data',PrefixTableEntry_ARRAY),
687 )
689# 5.177 SCHEMA_PREFIX_TABLE
690class SCHEMA_PREFIX_TABLE(NDRSTRUCT):
691 structure = (
692 ('PrefixCount',DWORD),
693 ('pPrefixEntry',PPrefixTableEntry_ARRAY),
694 )
696# 4.1.10.2.2 DRS_MSG_GETCHGREQ_V3
697class 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 )
712# 5.131 MTX_ADDR
713class MTX_ADDR(NDRSTRUCT):
714 structure = (
715 ('mtx_namelen',ULONG),
716 ('mtx_name',PBYTE_ARRAY),
717 )
719class PMTX_ADDR(NDRPOINTER):
720 referent = (
721 ('Data',MTX_ADDR),
722 )
724# 4.1.10.2.3 DRS_MSG_GETCHGREQ_V4
725class DRS_MSG_GETCHGREQ_V4(NDRSTRUCT):
726 structure = (
727 ('uuidTransportObj',UUID),
728 ('pmtxReturnAddress',PMTX_ADDR),
729 ('V3',DRS_MSG_GETCHGREQ_V3),
730 )
732# 4.1.10.2.4 DRS_MSG_GETCHGREQ_V5
733class 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 )
747# 4.1.10.2.5 DRS_MSG_GETCHGREQ_V7
748class 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 )
758# 4.1.10.2.6 DRS_MSG_GETCHGREQ_V8
759class 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 )
776# 4.1.10.2.7 DRS_MSG_GETCHGREQ_V10
777class 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 )
795# 4.1.10.2.1 DRS_MSG_GETCHGREQ
796class 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 }
808# 5.16 ATTRVAL
809class ATTRVAL(NDRSTRUCT):
810 structure = (
811 ('valLen',ULONG),
812 ('pVal',PBYTE_ARRAY),
813 )
815class ATTRVAL_ARRAY(NDRUniConformantArray):
816 item = ATTRVAL
818class PATTRVAL_ARRAY(NDRPOINTER):
819 referent = (
820 ('Data',ATTRVAL_ARRAY),
821 )
823# 5.17 ATTRVALBLOCK
824class ATTRVALBLOCK(NDRSTRUCT):
825 structure = (
826 ('valCount',ULONG),
827 ('pAVal',PATTRVAL_ARRAY),
828 )
830# 5.9 ATTR
831class ATTR(NDRSTRUCT):
832 structure = (
833 ('attrTyp',ATTRTYP),
834 ('AttrVal',ATTRVALBLOCK),
835 )
837class ATTR_ARRAY(NDRUniConformantArray):
838 item = ATTR
840class PATTR_ARRAY(NDRPOINTER):
841 referent = (
842 ('Data',ATTR_ARRAY),
843 )
845# 5.10 ATTRBLOCK
846class ATTRBLOCK(NDRSTRUCT):
847 structure = (
848 ('attrCount',ULONG),
849 ('pAttr',PATTR_ARRAY),
850 )
852# 5.53 ENTINF
853class ENTINF(NDRSTRUCT):
854 structure = (
855 ('pName',PDSNAME),
856 ('ulFlags',ULONG),
857 ('AttrBlock',ATTRBLOCK),
858 )
860class ENTINF_ARRAY(NDRUniConformantArray):
861 item = ENTINF
863class PENTINF_ARRAY(NDRPOINTER):
864 referent = (
865 ('Data',ENTINF_ARRAY),
866 )
868# 5.154 PROPERTY_META_DATA_EXT
869class PROPERTY_META_DATA_EXT(NDRSTRUCT):
870 structure = (
871 ('dwVersion',DWORD),
872 ('timeChanged',DSTIME),
873 ('uuidDsaOriginating',UUID),
874 ('usnOriginating',USN),
875 )
877class PROPERTY_META_DATA_EXT_ARRAY(NDRUniConformantArray):
878 item = PROPERTY_META_DATA_EXT
880# 5.155 PROPERTY_META_DATA_EXT_VECTOR
881class PROPERTY_META_DATA_EXT_VECTOR(NDRSTRUCT):
882 structure = (
883 ('cNumProps',DWORD),
884 ('rgMetaData',PROPERTY_META_DATA_EXT_ARRAY),
885 )
887class PPROPERTY_META_DATA_EXT_VECTOR(NDRPOINTER):
888 referent = (
889 ('Data',PROPERTY_META_DATA_EXT_VECTOR),
890 )
892# 5.161 REPLENTINFLIST
894class 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
909class PREPLENTINFLIST(NDRPOINTER):
910 referent = (
911 ('Data',REPLENTINFLIST),
912 )
914# 4.1.10.2.9 DRS_MSG_GETCHGREPLY_V1
915class 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 )
931# 4.1.10.2.15 DRS_COMPRESSED_BLOB
932class DRS_COMPRESSED_BLOB(NDRSTRUCT):
933 structure = (
934 ('cbUncompressedSize',DWORD),
935 ('cbCompressedSize',DWORD),
936 ('pbCompressedData',BYTE_ARRAY),
937 )
939# 4.1.10.2.10 DRS_MSG_GETCHGREPLY_V2
940class DRS_MSG_GETCHGREPLY_V2(NDRSTRUCT):
941 structure = (
942 ('CompressedV1',DRS_COMPRESSED_BLOB),
943 )
945# 5.199 UPTODATE_CURSOR_V2
946class UPTODATE_CURSOR_V2(NDRSTRUCT):
947 structure = (
948 ('uuidDsa',UUID),
949 ('usnHighPropUpdate',USN),
950 ('timeLastSyncSuccess',DSTIME),
951 )
953class UPTODATE_CURSOR_V2_ARRAY(NDRUniConformantArray):
954 item = UPTODATE_CURSOR_V2
956# 5.201 UPTODATE_VECTOR_V2_EXT
957class 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 )
966class PUPTODATE_VECTOR_V2_EXT(NDRPOINTER):
967 referent = (
968 ('Data',UPTODATE_VECTOR_V2_EXT),
969 )
971# 5.211 VALUE_META_DATA_EXT_V1
972class VALUE_META_DATA_EXT_V1(NDRSTRUCT):
973 structure = (
974 ('timeCreated',DSTIME),
975 ('MetaData',PROPERTY_META_DATA_EXT),
976 )
978# 5.215 VALUE_META_DATA_EXT_V3
979class 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 )
989# 5.167 REPLVALINF_V1
990class 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 )
999 def fromString(self, data, soFar = 0):
1000 retVal = NDRSTRUCT.fromString(self, data, soFar)
1001 #self.dumpRaw()
1002 return retVal
1004class REPLVALINF_V1_ARRAY(NDRUniConformantArray):
1005 item = REPLVALINF_V1
1007class PREPLVALINF_V1_ARRAY(NDRPOINTER):
1008 referent = (
1009 ('Data', REPLVALINF_V1_ARRAY),
1010 )
1012# 5.168 REPLVALINF_V3
1013class 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 )
1022 def fromString(self, data, soFar=0):
1023 retVal = NDRSTRUCT.fromString(self, data, soFar)
1024 # self.dumpRaw()
1025 return retVal
1027class REPLVALINF_V3_ARRAY(NDRUniConformantArray):
1028 item = REPLVALINF_V3
1030class PREPLVALINF_V3_ARRAY(NDRPOINTER):
1031 referent = (
1032 ('Data', REPLVALINF_V3_ARRAY),
1033 )
1035# 5.169 REPLVALINF_NATIVE
1036REPLVALINF_NATIVE = REPLVALINF_V3
1038# 4.1.10.2.11 DRS_MSG_GETCHGREPLY_V6
1039class 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 )
1063# 4.1.10.2.14 DRS_COMP_ALG_TYPE
1064class 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
1071# 4.1.10.2.12 DRS_MSG_GETCHGREPLY_V7
1072class DRS_MSG_GETCHGREPLY_V7(NDRSTRUCT):
1073 structure = (
1074 ('dwCompressedVersion',DWORD),
1075 ('CompressionAlg',DRS_COMP_ALG_TYPE),
1076 ('CompressedAny',DRS_COMPRESSED_BLOB),
1077 )
1079# 4.1.10.2.13 DRS_MSG_GETCHGREPLY_V9
1080class 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 )
1104# 4.1.10.2.14 DRS_MSG_GETCHGREPLY_NATIVE
1105DRS_MSG_GETCHGREPLY_NATIVE = DRS_MSG_GETCHGREPLY_V9
1107# 4.1.10.2.8 DRS_MSG_GETCHGREPLY
1108class 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 }
1120# 4.1.27.1.2 DRS_MSG_VERIFYREQ_V1
1121class 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 )
1130# 4.1.27.1.1 DRS_MSG_VERIFYREQ
1131class DRS_MSG_VERIFYREQ(NDRUNION):
1132 commonHdr = (
1133 ('tag', DWORD),
1134 )
1135 union = {
1136 1 : ('V1', DRS_MSG_VERIFYREQ_V1),
1137 }
1139# 4.1.27.1.4 DRS_MSG_VERIFYREPLY_V1
1140class DRS_MSG_VERIFYREPLY_V1(NDRSTRUCT):
1141 structure = (
1142 ('error',DWORD),
1143 ('cNames',DWORD),
1144 ('rpEntInf',PENTINF_ARRAY),
1145 ('PrefixTable',SCHEMA_PREFIX_TABLE),
1146 )
1148# 4.1.27.1.3 DRS_MSG_VERIFYREPLY
1149class DRS_MSG_VERIFYREPLY(NDRUNION):
1150 commonHdr = (
1151 ('tag', DWORD),
1152 )
1153 union = {
1154 1 : ('V1', DRS_MSG_VERIFYREPLY_V1),
1155 }
1157# 4.1.11.1.2 DRS_MSG_NT4_CHGLOG_REQ_V1
1158class DRS_MSG_NT4_CHGLOG_REQ_V1(NDRSTRUCT):
1159 structure = (
1160 ('dwFlags',DWORD),
1161 ('PreferredMaximumLength',DWORD),
1162 ('cbRestart',DWORD),
1163 ('pRestart',PBYTE_ARRAY),
1164 )
1166# 4.1.11.1.1 DRS_MSG_NT4_CHGLOG_REQ
1167class DRS_MSG_NT4_CHGLOG_REQ(NDRUNION):
1168 commonHdr = (
1169 ('tag', DWORD),
1170 )
1171 union = {
1172 1 : ('V1', DRS_MSG_NT4_CHGLOG_REQ_V1),
1173 }
1175# 4.1.11.1.5 NT4_REPLICATION_STATE
1176class 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 )
1186# 4.1.11.1.4 DRS_MSG_NT4_CHGLOG_REPLY_V1
1187class 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 )
1197# 4.1.11.1.3 DRS_MSG_NT4_CHGLOG_REPLY
1198class DRS_MSG_NT4_CHGLOG_REPLY(NDRUNION):
1199 commonHdr = (
1200 ('tag', DWORD),
1201 )
1202 union = {
1203 1 : ('V1', DRS_MSG_NT4_CHGLOG_REPLY_V1),
1204 }
1206################################################################################
1207# RPC CALLS
1208################################################################################
1209# 4.1.3 IDL_DRSBind (Opnum 0)
1210class DRSBind(NDRCALL):
1211 opnum = 0
1212 structure = (
1213 ('puuidClientDsa', PUUID),
1214 ('pextClient', PDRS_EXTENSIONS),
1215 )
1217class DRSBindResponse(NDRCALL):
1218 structure = (
1219 ('ppextServer', PDRS_EXTENSIONS),
1220 ('phDrs', DRS_HANDLE),
1221 ('ErrorCode',DWORD),
1222 )
1224# 4.1.25 IDL_DRSUnbind (Opnum 1)
1225class DRSUnbind(NDRCALL):
1226 opnum = 1
1227 structure = (
1228 ('phDrs', DRS_HANDLE),
1229 )
1231class DRSUnbindResponse(NDRCALL):
1232 structure = (
1233 ('phDrs', DRS_HANDLE),
1234 ('ErrorCode',DWORD),
1235 )
1237# 4.1.10 IDL_DRSGetNCChanges (Opnum 3)
1238class DRSGetNCChanges(NDRCALL):
1239 opnum = 3
1240 structure = (
1241 ('hDrs', DRS_HANDLE),
1242 ('dwInVersion', DWORD),
1243 ('pmsgIn', DRS_MSG_GETCHGREQ),
1244 )
1246class DRSGetNCChangesResponse(NDRCALL):
1247 structure = (
1248 ('pdwOutVersion', DWORD),
1249 ('pmsgOut', DRS_MSG_GETCHGREPLY),
1250 ('ErrorCode',DWORD),
1251 )
1253# 4.1.27 IDL_DRSVerifyNames (Opnum 8)
1254class DRSVerifyNames(NDRCALL):
1255 opnum = 8
1256 structure = (
1257 ('hDrs', DRS_HANDLE),
1258 ('dwInVersion', DWORD),
1259 ('pmsgIn', DRS_MSG_VERIFYREQ),
1260 )
1262class DRSVerifyNamesResponse(NDRCALL):
1263 structure = (
1264 ('pdwOutVersion', DWORD),
1265 ('pmsgOut', DRS_MSG_VERIFYREPLY),
1266 ('ErrorCode',DWORD),
1267 )
1268# 4.1.11 IDL_DRSGetNT4ChangeLog (Opnum 11)
1269class DRSGetNT4ChangeLog(NDRCALL):
1270 opnum = 11
1271 structure = (
1272 ('hDrs', DRS_HANDLE),
1273 ('dwInVersion', DWORD),
1274 ('pmsgIn', DRS_MSG_NT4_CHGLOG_REQ),
1275 )
1277class DRSGetNT4ChangeLogResponse(NDRCALL):
1278 structure = (
1279 ('pdwOutVersion', DWORD),
1280 ('pmsgOut', DRS_MSG_NT4_CHGLOG_REPLY),
1281 ('ErrorCode',DWORD),
1282 )
1284# 4.1.4 IDL_DRSCrackNames (Opnum 12)
1285class DRSCrackNames(NDRCALL):
1286 opnum = 12
1287 structure = (
1288 ('hDrs', DRS_HANDLE),
1289 ('dwInVersion', DWORD),
1290 ('pmsgIn', DRS_MSG_CRACKREQ),
1291 )
1293class DRSCrackNamesResponse(NDRCALL):
1294 structure = (
1295 ('pdwOutVersion', DWORD),
1296 ('pmsgOut', DRS_MSG_CRACKREPLY),
1297 ('ErrorCode',DWORD),
1298 )
1300# 4.1.5 IDL_DRSDomainControllerInfo (Opnum 16)
1301class DRSDomainControllerInfo(NDRCALL):
1302 opnum = 16
1303 structure = (
1304 ('hDrs', DRS_HANDLE),
1305 ('dwInVersion', DWORD),
1306 ('pmsgIn', DRS_MSG_DCINFOREQ),
1307 )
1309class DRSDomainControllerInfoResponse(NDRCALL):
1310 structure = (
1311 ('pdwOutVersion', DWORD),
1312 ('pmsgOut', DRS_MSG_DCINFOREPLY),
1313 ('ErrorCode',DWORD),
1314 )
1316################################################################################
1317# OPNUMs and their corresponding structures
1318################################################################################
1319OPNUMS = {
1320 0 : (DRSBind,DRSBindResponse ),
1321 1 : (DRSUnbind,DRSUnbindResponse ),
1322 3 : (DRSGetNCChanges,DRSGetNCChangesResponse ),
1323 12: (DRSCrackNames,DRSCrackNamesResponse ),
1324 16: (DRSDomainControllerInfo,DRSDomainControllerInfoResponse ),
1325}
1327################################################################################
1328# HELPER FUNCTIONS
1329################################################################################
1330def 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
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
1339def hDRSUnbind(dce, hDrs):
1340 request = DRSUnbind()
1341 request['phDrs'] = hDrs
1342 return dce.request(request)
1344def hDRSDomainControllerInfo(dce, hDrs, domain, infoLevel):
1345 request = DRSDomainControllerInfo()
1346 request['hDrs'] = hDrs
1347 request['dwInVersion'] = 1
1349 request['pmsgIn']['tag'] = 1
1350 request['pmsgIn']['V1']['Domain'] = checkNullString(domain)
1351 request['pmsgIn']['V1']['InfoLevel'] = infoLevel
1352 return dce.request(request)
1354def hDRSCrackNames(dce, hDrs, flags, formatOffered, formatDesired, rpNames = ()):
1355 request = DRSCrackNames()
1356 request['hDrs'] = hDrs
1357 request['dwInVersion'] = 1
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)
1371 return dce.request(request)
1373def 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))
1388def removeDESLayer(cryptedHash, rid):
1389 Key1,Key2 = deriveKey(rid)
1391 Crypt1 = DES.new(Key1, DES.MODE_ECB)
1392 Crypt2 = DES.new(Key2, DES.MODE_ECB)
1394 decryptedHash = Crypt1.decrypt(cryptedHash[:8]) + Crypt2.decrypt(cryptedHash[8:])
1396 return decryptedHash
1398def 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
1405 encryptedPayload = ENCRYPTED_PAYLOAD(attribute)
1407 md5 = hashlib.new('md5')
1408 md5.update(sessionKey)
1409 md5.update(encryptedPayload['Salt'])
1410 finalMD5 = md5.digest()
1412 cipher = ARC4.new(finalMD5)
1413 plainText = cipher.decrypt(attribute[16:])
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
1420 return plainText[4:]
1422# 5.16.4 ATTRTYP-to-OID Conversion
1423def MakeAttid(prefixTable, oid):
1424 # get the last value in the original OID: the value * after the last '.'
1425 lastValue = int(oid.split('.')[-1])
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:]
1433 # get the prefix of the OID
1434 if lastValue < 128:
1435 oidPrefix = list(binaryOID[:-1])
1436 else:
1437 oidPrefix = list(binaryOID[:-2])
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
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)
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
1462 upperWord = pos
1464 attrTyp = ATTRTYP()
1465 attrTyp['Data'] = (upperWord << 16) + lowerWord
1466 return attrTyp
1468def OidFromAttid(prefixTable, attr):
1469 # separate the ATTRTYP into two parts
1470 upperWord = attr // 65536
1471 lowerWord = attr % 65536
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.
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
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])
1494if __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'
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)