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# 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
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
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/")
48MSRPC_UUID_DRSUAPI = uuidtup_to_bin(('E3514235-4B06-11D1-AB04-00C04FC2DCD2','4.0'))
50class DCERPCSessionError(DCERPCException):
51 def __init__(self, error_string=None, error_code=None, packet=None):
52 DCERPCException.__init__(self, error_string, error_code, packet)
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
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
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=' ')
101 try:
102 print(" %s" % self.enumItems(self.fields['Data']).name, end=' ')
103 except ValueError:
104 print(" %d" % self.fields['Data'])
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
115# 5.14 ATTRTYP
116ATTRTYP = ULONG
118# 5.51 DSTIME
119DSTIME = LONGLONG
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
156# dwFlagsExt
157DRS_EXT_ADAM = 0x00000001
158DRS_EXT_LH_BETA2 = 0x00000002
159DRS_EXT_RECYCLE_BIN = 0x00000004
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
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
215# 5.137 NTSAPI_CLIENT_GUID
216NTDSAPI_CLIENT_GUID = string_to_bin('e24d201a-4fd6-11d1-a3da-0000f875ae0d')
218# 5.139 NULLGUID
219NULLGUID = string_to_bin('00000000-0000-0000-0000-000000000000')
221# 5.205 USN
222USN = LONGLONG
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
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
246DS_USER_PRINCIPAL_NAME_FOR_LOGON = 0xFFFFFFF2
248# 5.53 ENTINF
249ENTINF_FROM_MASTER = 0x00000001
250ENTINF_DYNAMIC_OBJECT = 0x00000002
251ENTINF_REMOTE_MODIFY = 0x00010000
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
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
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 )
276# 5.136 NT4SID
277class NT4SID(NDRSTRUCT):
278 structure = (
279 ('Data','28s=b""'),
280 )
281 def getAlignment(self):
282 return 4
284# 5.40 DRS_HANDLE
285class DRS_HANDLE(NDRSTRUCT):
286 structure = (
287 ('Data','20s=b""'),
288 )
289 def getAlignment(self):
290 return 4
292class PDRS_HANDLE(NDRPOINTER):
293 referent = (
294 ('Data',DRS_HANDLE),
295 )
297# 5.38 DRS_EXTENSIONS
298class BYTE_ARRAY(NDRUniConformantArray):
299 item = 'c'
301class PBYTE_ARRAY(NDRPOINTER):
302 referent = (
303 ('Data',BYTE_ARRAY),
304 )
306class DRS_EXTENSIONS(NDRSTRUCT):
307 structure = (
308 ('cb',DWORD),
309 ('rgb',BYTE_ARRAY),
310 )
312class PDRS_EXTENSIONS(NDRPOINTER):
313 referent = (
314 ('Data',DRS_EXTENSIONS),
315 )
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 )
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 )
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 }
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 )
357class DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRUniConformantArray):
358 item = DS_DOMAIN_CONTROLLER_INFO_1W
360class PDS_DOMAIN_CONTROLLER_INFO_1W_ARRAY(NDRPOINTER):
361 referent = (
362 ('Data',DS_DOMAIN_CONTROLLER_INFO_1W_ARRAY),
363 )
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 )
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 )
391class DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRUniConformantArray):
392 item = DS_DOMAIN_CONTROLLER_INFO_2W
394class PDS_DOMAIN_CONTROLLER_INFO_2W_ARRAY(NDRPOINTER):
395 referent = (
396 ('Data',DS_DOMAIN_CONTROLLER_INFO_2W_ARRAY),
397 )
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 )
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 )
426class DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRUniConformantArray):
427 item = DS_DOMAIN_CONTROLLER_INFO_3W
429class PDS_DOMAIN_CONTROLLER_INFO_3W_ARRAY(NDRPOINTER):
430 referent = (
431 ('Data',DS_DOMAIN_CONTROLLER_INFO_3W_ARRAY),
432 )
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 )
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 )
453class DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRUniConformantArray):
454 item = DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW
456class PDS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY(NDRPOINTER):
457 referent = (
458 ('Data',DS_DOMAIN_CONTROLLER_INFO_FFFFFFFFW_ARRAY),
459 )
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 )
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 }
480# 4.1.4.1.2 DRS_MSG_CRACKREQ_V1
481class LPWSTR_ARRAY(NDRUniConformantArray):
482 item = LPWSTR
484class PLPWSTR_ARRAY(NDRPOINTER):
485 referent = (
486 ('Data',LPWSTR_ARRAY),
487 )
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 )
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 }
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
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 )
532class DS_NAME_RESULT_ITEMW_ARRAY(NDRUniConformantArray):
533 item = DS_NAME_RESULT_ITEMW
535class PDS_NAME_RESULT_ITEMW_ARRAY(NDRPOINTER):
536 referent = (
537 ('Data',DS_NAME_RESULT_ITEMW_ARRAY),
538 )
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 )
547class PDS_NAME_RESULTW(NDRPOINTER):
548 referent = (
549 ('Data',DS_NAME_RESULTW),
550 )
552# 4.1.4.1.7 DRS_MSG_CRACKREPLY_V1
553class DRS_MSG_CRACKREPLY_V1(NDRSTRUCT):
554 structure = (
555 ('pResult',PDS_NAME_RESULTW),
556 )
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 }
567# 5.198 UPTODATE_CURSOR_V1
568class UPTODATE_CURSOR_V1(NDRSTRUCT):
569 structure = (
570 ('uuidDsa',UUID),
571 ('usnHighPropUpdate',USN),
572 )
574class UPTODATE_CURSOR_V1_ARRAY(NDRUniConformantArray):
575 item = UPTODATE_CURSOR_V1
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 )
587class PUPTODATE_VECTOR_V1_EXT(NDRPOINTER):
588 referent = (
589 ('Data',UPTODATE_VECTOR_V1_EXT),
590 )
592# 5.206 USN_VECTOR
593class USN_VECTOR(NDRSTRUCT):
594 structure = (
595 ('usnHighObjUpdate',USN),
596 ('usnReserved',USN),
597 ('usnHighPropUpdate',USN),
598 )
600# 5.50 DSNAME
601class WCHAR_ARRAY(NDRUniConformantArray):
602 item = 'H'
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])
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)
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)
633class PDSNAME(NDRPOINTER):
634 referent = (
635 ('Data',DSNAME),
636 )
638class PDSNAME_ARRAY(NDRUniConformantArray):
639 item = PDSNAME
641class PPDSNAME_ARRAY(NDRPOINTER):
642 referent = (
643 ('Data',PDSNAME_ARRAY),
644 )
646class ATTRTYP_ARRAY(NDRUniConformantArray):
647 item = ATTRTYP
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 )
658class PPARTIAL_ATTR_VECTOR_V1_EXT(NDRPOINTER):
659 referent = (
660 ('Data',PARTIAL_ATTR_VECTOR_V1_EXT),
661 )
663# 5.142 OID_t
664class OID_t(NDRSTRUCT):
665 structure = (
666 ('length',ULONG),
667 ('elements',PBYTE_ARRAY),
668 )
670# 5.153 PrefixTableEntry
671class PrefixTableEntry(NDRSTRUCT):
672 structure = (
673 ('ndx',ULONG),
674 ('prefix',OID_t),
675 )
677class PrefixTableEntry_ARRAY(NDRUniConformantArray):
678 item = PrefixTableEntry
680class PPrefixTableEntry_ARRAY(NDRPOINTER):
681 referent = (
682 ('Data',PrefixTableEntry_ARRAY),
683 )
685# 5.177 SCHEMA_PREFIX_TABLE
686class SCHEMA_PREFIX_TABLE(NDRSTRUCT):
687 structure = (
688 ('PrefixCount',DWORD),
689 ('pPrefixEntry',PPrefixTableEntry_ARRAY),
690 )
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 )
708# 5.131 MTX_ADDR
709class MTX_ADDR(NDRSTRUCT):
710 structure = (
711 ('mtx_namelen',ULONG),
712 ('mtx_name',PBYTE_ARRAY),
713 )
715class PMTX_ADDR(NDRPOINTER):
716 referent = (
717 ('Data',MTX_ADDR),
718 )
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 )
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 )
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 )
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 )
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 )
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 }
804# 5.16 ATTRVAL
805class ATTRVAL(NDRSTRUCT):
806 structure = (
807 ('valLen',ULONG),
808 ('pVal',PBYTE_ARRAY),
809 )
811class ATTRVAL_ARRAY(NDRUniConformantArray):
812 item = ATTRVAL
814class PATTRVAL_ARRAY(NDRPOINTER):
815 referent = (
816 ('Data',ATTRVAL_ARRAY),
817 )
819# 5.17 ATTRVALBLOCK
820class ATTRVALBLOCK(NDRSTRUCT):
821 structure = (
822 ('valCount',ULONG),
823 ('pAVal',PATTRVAL_ARRAY),
824 )
826# 5.9 ATTR
827class ATTR(NDRSTRUCT):
828 structure = (
829 ('attrTyp',ATTRTYP),
830 ('AttrVal',ATTRVALBLOCK),
831 )
833class ATTR_ARRAY(NDRUniConformantArray):
834 item = ATTR
836class PATTR_ARRAY(NDRPOINTER):
837 referent = (
838 ('Data',ATTR_ARRAY),
839 )
841# 5.10 ATTRBLOCK
842class ATTRBLOCK(NDRSTRUCT):
843 structure = (
844 ('attrCount',ULONG),
845 ('pAttr',PATTR_ARRAY),
846 )
848# 5.53 ENTINF
849class ENTINF(NDRSTRUCT):
850 structure = (
851 ('pName',PDSNAME),
852 ('ulFlags',ULONG),
853 ('AttrBlock',ATTRBLOCK),
854 )
856class ENTINF_ARRAY(NDRUniConformantArray):
857 item = ENTINF
859class PENTINF_ARRAY(NDRPOINTER):
860 referent = (
861 ('Data',ENTINF_ARRAY),
862 )
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 )
873class PROPERTY_META_DATA_EXT_ARRAY(NDRUniConformantArray):
874 item = PROPERTY_META_DATA_EXT
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 )
883class PPROPERTY_META_DATA_EXT_VECTOR(NDRPOINTER):
884 referent = (
885 ('Data',PROPERTY_META_DATA_EXT_VECTOR),
886 )
888# 5.161 REPLENTINFLIST
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
905class PREPLENTINFLIST(NDRPOINTER):
906 referent = (
907 ('Data',REPLENTINFLIST),
908 )
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 )
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 )
935# 4.1.10.2.10 DRS_MSG_GETCHGREPLY_V2
936class DRS_MSG_GETCHGREPLY_V2(NDRSTRUCT):
937 structure = (
938 ('CompressedV1',DRS_COMPRESSED_BLOB),
939 )
941# 5.199 UPTODATE_CURSOR_V2
942class UPTODATE_CURSOR_V2(NDRSTRUCT):
943 structure = (
944 ('uuidDsa',UUID),
945 ('usnHighPropUpdate',USN),
946 ('timeLastSyncSuccess',DSTIME),
947 )
949class UPTODATE_CURSOR_V2_ARRAY(NDRUniConformantArray):
950 item = UPTODATE_CURSOR_V2
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 )
962class PUPTODATE_VECTOR_V2_EXT(NDRPOINTER):
963 referent = (
964 ('Data',UPTODATE_VECTOR_V2_EXT),
965 )
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 )
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 )
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 )
995 def fromString(self, data, soFar = 0):
996 retVal = NDRSTRUCT.fromString(self, data, soFar)
997 #self.dumpRaw()
998 return retVal
1000class REPLVALINF_V1_ARRAY(NDRUniConformantArray):
1001 item = REPLVALINF_V1
1003class PREPLVALINF_V1_ARRAY(NDRPOINTER):
1004 referent = (
1005 ('Data', REPLVALINF_V1_ARRAY),
1006 )
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 )
1018 def fromString(self, data, soFar=0):
1019 retVal = NDRSTRUCT.fromString(self, data, soFar)
1020 # self.dumpRaw()
1021 return retVal
1023class REPLVALINF_V3_ARRAY(NDRUniConformantArray):
1024 item = REPLVALINF_V3
1026class PREPLVALINF_V3_ARRAY(NDRPOINTER):
1027 referent = (
1028 ('Data', REPLVALINF_V3_ARRAY),
1029 )
1031# 5.169 REPLVALINF_NATIVE
1032REPLVALINF_NATIVE = REPLVALINF_V3
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 )
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
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 )
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 )
1100# 4.1.10.2.14 DRS_MSG_GETCHGREPLY_NATIVE
1101DRS_MSG_GETCHGREPLY_NATIVE = DRS_MSG_GETCHGREPLY_V9
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 }
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 )
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 }
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 )
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 }
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 )
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 }
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 )
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 )
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 }
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 )
1213class DRSBindResponse(NDRCALL):
1214 structure = (
1215 ('ppextServer', PDRS_EXTENSIONS),
1216 ('phDrs', DRS_HANDLE),
1217 ('ErrorCode',DWORD),
1218 )
1220# 4.1.25 IDL_DRSUnbind (Opnum 1)
1221class DRSUnbind(NDRCALL):
1222 opnum = 1
1223 structure = (
1224 ('phDrs', DRS_HANDLE),
1225 )
1227class DRSUnbindResponse(NDRCALL):
1228 structure = (
1229 ('phDrs', DRS_HANDLE),
1230 ('ErrorCode',DWORD),
1231 )
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 )
1242class DRSGetNCChangesResponse(NDRCALL):
1243 structure = (
1244 ('pdwOutVersion', DWORD),
1245 ('pmsgOut', DRS_MSG_GETCHGREPLY),
1246 ('ErrorCode',DWORD),
1247 )
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 )
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 )
1273class DRSGetNT4ChangeLogResponse(NDRCALL):
1274 structure = (
1275 ('pdwOutVersion', DWORD),
1276 ('pmsgOut', DRS_MSG_NT4_CHGLOG_REPLY),
1277 ('ErrorCode',DWORD),
1278 )
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 )
1289class DRSCrackNamesResponse(NDRCALL):
1290 structure = (
1291 ('pdwOutVersion', DWORD),
1292 ('pmsgOut', DRS_MSG_CRACKREPLY),
1293 ('ErrorCode',DWORD),
1294 )
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 )
1305class DRSDomainControllerInfoResponse(NDRCALL):
1306 structure = (
1307 ('pdwOutVersion', DWORD),
1308 ('pmsgOut', DRS_MSG_DCINFOREPLY),
1309 ('ErrorCode',DWORD),
1310 )
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}
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
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
1335def hDRSUnbind(dce, hDrs):
1336 request = DRSUnbind()
1337 request['phDrs'] = hDrs
1338 return dce.request(request)
1340def hDRSDomainControllerInfo(dce, hDrs, domain, infoLevel):
1341 request = DRSDomainControllerInfo()
1342 request['hDrs'] = hDrs
1343 request['dwInVersion'] = 1
1345 request['pmsgIn']['tag'] = 1
1346 request['pmsgIn']['V1']['Domain'] = checkNullString(domain)
1347 request['pmsgIn']['V1']['InfoLevel'] = infoLevel
1348 return dce.request(request)
1350def hDRSCrackNames(dce, hDrs, flags, formatOffered, formatDesired, rpNames = ()):
1351 request = DRSCrackNames()
1352 request['hDrs'] = hDrs
1353 request['dwInVersion'] = 1
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)
1367 return dce.request(request)
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))
1384def removeDESLayer(cryptedHash, rid):
1385 Key1,Key2 = deriveKey(rid)
1387 Crypt1 = DES.new(Key1, DES.MODE_ECB)
1388 Crypt2 = DES.new(Key2, DES.MODE_ECB)
1390 decryptedHash = Crypt1.decrypt(cryptedHash[:8]) + Crypt2.decrypt(cryptedHash[8:])
1392 return decryptedHash
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
1401 encryptedPayload = ENCRYPTED_PAYLOAD(attribute)
1403 md5 = hashlib.new('md5')
1404 md5.update(sessionKey)
1405 md5.update(encryptedPayload['Salt'])
1406 finalMD5 = md5.digest()
1408 cipher = ARC4.new(finalMD5)
1409 plainText = cipher.decrypt(attribute[16:])
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
1416 return plainText[4:]
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])
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:]
1429 # get the prefix of the OID
1430 if lastValue < 128:
1431 oidPrefix = list(binaryOID[:-1])
1432 else:
1433 oidPrefix = list(binaryOID[:-2])
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
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)
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
1458 upperWord = pos
1460 attrTyp = ATTRTYP()
1461 attrTyp['Data'] = (upperWord << 16) + lowerWord
1462 return attrTyp
1464def OidFromAttid(prefixTable, attr):
1465 # separate the ATTRTYP into two parts
1466 upperWord = attr // 65536
1467 lowerWord = attr % 65536
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.
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
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])
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'
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)