async def do_changeowner(self, new_owner_sid, target_dn, target_attribute=None): """Changes the owner in a Security Descriptor to the new_owner_sid on an LDAP object or on an LDAP object's attribute identified by target_dn and target_attribute. target_attribute can be omitted to change the target_dn's SD's owner""" try: await self.do_ldapinfo(False) await self.do_adinfo(False) try: new_owner_sid = SID.from_string(new_owner_sid) except: print('Incorrect SID!') return False, Exception('Incorrect SID') target_sd = None if target_attribute is None or target_attribute == '': target_attribute = 'nTSecurityDescriptor' res, err = await self.connection.get_objectacl_by_dn(target_dn) if err is not None: raise err target_sd = SECURITY_DESCRIPTOR.from_bytes(res) else: query = '(distinguishedName=%s)' % target_dn async for entry, err in self.connection.pagedsearch( query, [target_attribute]): if err is not None: raise err print(entry['attributes'][target_attribute]) target_sd = SECURITY_DESCRIPTOR.from_bytes( entry['attributes'][target_attribute]) break else: print('Target DN not found!') return False, Exception('Target DN not found!') new_sd = copy.deepcopy(target_sd) new_sd.Owner = new_owner_sid changes = {target_attribute: [('replace', [new_sd.to_bytes()])]} _, err = await self.connection.modify(target_dn, changes) if err is not None: raise err print('Change OK!') except: traceback.print_exc()
async def get_all_machines(self): try: async for machine_data, err in self.ldap.get_all_machines(): if err is not None: raise err machine = Machine.from_adcomp(machine_data) delegations = [] allowedtoact = [] if machine_data.allowedtoactonbehalfofotheridentity is not None: try: sd = SECURITY_DESCRIPTOR.from_bytes(machine_data.allowedtoactonbehalfofotheridentity) if sd.Dacl is not None: for ace in sd.Dacl.aces: aa = MachineAllowedToAct() aa.machine_sid = machine.objectSid aa.target_sid = str(ace.Sid) allowedtoact.append(aa) except Exception as e: logger.debug('Error parsing allowedtoact SD! %s Reason: %s' % (machine.sAMAccountName, e)) if machine_data.allowedtodelegateto is not None: for delegate_data in machine_data.allowedtodelegateto: delegations.append(MachineConstrainedDelegation.from_spn_str(delegate_data)) await self.agent_out_q.put((LDAPAgentCommand.MACHINE, {'machine' : machine, 'delegations' : delegations, 'allowedtoact' : allowedtoact})) except: await self.agent_out_q.put((LDAPAgentCommand.EXCEPTION, str(traceback.format_exc()))) finally: await self.agent_out_q.put((LDAPAgentCommand.MACHINES_FINISHED, None))
async def do_acl(self, dn): """Feteches security info for a given DN""" try: await self.do_ldapinfo(False) await self.do_adinfo(False) async for sec_info in self.connection.get_objectacl_by_dn(dn): print(str(SECURITY_DESCRIPTOR.from_bytes(sec_info.nTSecurityDescriptor))) except: traceback.print_exc()
def main(): import sys sql = sys.argv[1] ad_id = sys.argv[2] session = get_session(sql) for res in session.query(JackDawSD).filter_by(ad_id=ad_id).all(): sd = SECURITY_DESCRIPTOR.from_bytes(base64.b64decode(res.sd)) #print(sd) store_sd(session, ad_id, res.object_type, res.guid, res.sid, sd)
def from_buffer(buff): sk = NTRegistrySK() sk.magic = buff.read(2) sk.unknown = int.from_bytes(buff.read(2), 'little', signed = False) sk.offset_prev = int.from_bytes(buff.read(4), 'little', signed = False) sk.offset_next = int.from_bytes(buff.read(4), 'little', signed = False) sk.reference_cnt = int.from_bytes(buff.read(4), 'little', signed = False) sk.sd_size = int.from_bytes(buff.read(4), 'little', signed = False) if sk.sd_size > 15: sk.sd = SECURITY_DESCRIPTOR.from_bytes(buff.read(sk.sd_size)) return sk
async def do_acl(self, dn): """Feteches security info for a given DN""" try: await self.do_ldapinfo(False) await self.do_adinfo(False) sec_info, err = await self.connection.get_objectacl_by_dn(dn) if err is not None: raise err print(str(SECURITY_DESCRIPTOR.from_bytes(sec_info))) except: traceback.print_exc()
async def do_getsd(self, dn): """Feteches security info for a given DN""" try: await self.do_ldapinfo(False) await self.do_adinfo(False) sec_info, err = await self.connection.get_objectacl_by_dn(dn) if err is not None: raise err sd = SECURITY_DESCRIPTOR.from_bytes(sec_info) print(sd.to_sddl()) return True except: traceback.print_exc() return False
async def add_priv_dcsync(self, user_dn, forest_dn=None): """Adds DCSync rights to the given user by modifying the forest's Security Descriptor to add GetChanges and GetChangesAll ACE""" try: #getting SID of target dn user_sid, err = await self.get_objectsid_for_dn(user_dn) if err is not None: raise err if forest_dn is None: forest_dn = self._ldapinfo.distinguishedName res, err = await self.get_objectacl_by_dn(forest_dn) if err is not None: raise err if res is None: raise Exception('Failed to get forest\'s SD') forest_sd = SECURITY_DESCRIPTOR.from_bytes(res) new_sd = copy.deepcopy(forest_sd) ace_1 = ACCESS_ALLOWED_OBJECT_ACE() ace_1.Sid = SID.from_string(user_sid) ace_1.ObjectType = GUID.from_string( '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2') ace_1.Mask = ADS_ACCESS_MASK.CONTROL_ACCESS ace_1.AceFlags = 0 new_sd.Dacl.aces.append(ace_1) ace_2 = ACCESS_ALLOWED_OBJECT_ACE() ace_2.Sid = SID.from_string(user_sid) ace_2.ObjectType = GUID.from_string( '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2') ace_2.Mask = ADS_ACCESS_MASK.CONTROL_ACCESS ace_2.AceFlags = 0 new_sd.Dacl.aces.append(ace_2) changes = { 'nTSecurityDescriptor': [('replace', [new_sd.to_bytes()])] } _, err = await self.modify(forest_dn, changes) if err is not None: raise err return True, None except Exception as e: return False, e
async def do_machine(self, samaccountname): """Feteches a machine object based on the sAMAccountName of the machine""" try: await self.do_ldapinfo(False) await self.do_adinfo(False) machine, err = await self.connection.get_machine(samaccountname) if err is not None: raise err if machine is None: print('machine not found!') else: print(machine) ####TEST x = SECURITY_DESCRIPTOR.from_bytes(machine.allowedtoactonbehalfofotheridentity) print(x) except: traceback.print_exc()
async def GetKeySecurity(self, key, securityInformation=SECURITY_INFORMATION.OWNER): try: key = await self.__get_rawhandle(key) res, err = await rrp.hBaseRegGetKeySecurity( self.dce, key, securityInformation=securityInformation) if err is not None: raise err return SECURITY_DESCRIPTOR.from_bytes(res), None except Exception as e: if isinstance(e, rrp.DCERPCSessionError): return None, OSError( e.get_error_code(), system_errors.ERROR_MESSAGES[e.get_error_code()][1]) return None, e
async def do_setsd(self, target_dn, sddl): """Updates the security descriptor of an object""" try: await self.do_ldapinfo(False) await self.do_adinfo(False) try: new_sd = SECURITY_DESCRIPTOR.from_sddl(sddl) except: print('Incorrect SDDL input!') return False, Exception('Incorrect SDDL input!') _, err = await self.connection.set_objectacl_by_dn(target_dn, new_sd.to_bytes()) if err is not None: raise err print('Change OK!') except: print('Erro while updating security descriptor!') traceback.print_exc()
def from_ldap(entry): adi = MSADCertificateTemplate() adi.sn = entry['attributes'].get('sn') adi.cn = entry['attributes'].get('cn') adi.distinguishedName = entry['attributes'].get('distinguishedName') adi.name = entry['attributes'].get('name') adi.RA_Application_Policies = entry['attributes'].get('msPKI-RA-Application-Policies') adi.Certificate_Application_Policy = entry['attributes'].get('msPKI-Certificate-Application-Policy') adi.Template_Schema_Version = entry['attributes'].get('msPKI-Template-Schema-Version') adi.Certificate_Name_Flag = entry['attributes'].get('msPKI-Certificate-Name-Flag') adi.Enrollment_Flag = entry['attributes'].get('msPKI-Enrollment-Flag') adi.RA_Signature = entry['attributes'].get('msPKI-RA-Signature') adi.Private_Key_Flag = entry['attributes'].get('msPKI-Private-Key-Flag') adi.pKIExtendedKeyUsage = entry['attributes'].get('pKIExtendedKeyUsage', []) adi.nTSecurityDescriptor = entry['attributes'].get('nTSecurityDescriptor') if adi.nTSecurityDescriptor is not None: adi.nTSecurityDescriptor = SECURITY_DESCRIPTOR.from_bytes(adi.nTSecurityDescriptor) adi.calc_aces() return adi
def GetSecurityInfo(handle_obj, obj_type, info_req): _GetSecurityInfo = windll.advapi32.GetSecurityInfo _GetSecurityInfo.argtypes = [ HANDLE, DWORD, DWORD, PVOID, PVOID, PVOID, PVOID, PVOID ] #[HANDLE, SE_OBJECT_TYPE, DWORD, PSID, PSID, PACL, PACL, PSECURITY_DESCRIPTOR] _GetSecurityInfo.restype = DWORD _GetSecurityInfo.errcheck = win_succ_check ppsidOwner = None ppsidGroup = None ppDacl = None ppSacl = None ppSecurityDescriptor = ctypes.pointer(ctypes.c_uint(0)) ret = _GetSecurityInfo(handle_obj, obj_type, info_req, ppsidOwner, ppsidGroup, ppDacl, ppSacl, ctypes.byref(ppSecurityDescriptor)) pSecurityDescriptor = ppSecurityDescriptor.contents buff = MemoryBuffer(ctypes.addressof(ppSecurityDescriptor.contents)) sd = SECURITY_DESCRIPTOR.from_buffer(buff, obj_type) LocalFree(ppSecurityDescriptor) return sd
def QueryServiceObjectSecurity(hService, dwSecurityInformation=OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, sd_object_type=None): _QueryServiceObjectSecurity = windll.advapi32.QueryServiceObjectSecurity _QueryServiceObjectSecurity.argtypes = [ SC_HANDLE, DWORD, PVOID, DWORD, LPDWORD ] _QueryServiceObjectSecurity.restype = DWORD #_QueryServiceObjectSecurity.errcheck = RaiseIfZero #first we get the size lpSecurityDescriptor = None cbBufSize = DWORD(0) pcbBytesNeeded = DWORD(0) correct_length = 0 res = _QueryServiceObjectSecurity(hService, dwSecurityInformation, lpSecurityDescriptor, cbBufSize, pcbBytesNeeded) if res == 0: #getting the correct length correct_length = pcbBytesNeeded.value lpSecurityDescriptor = ctypes.create_string_buffer(correct_length) cbBufSize = DWORD(correct_length) pcbBytesNeeded = DWORD(0) res = _QueryServiceObjectSecurity(hService, dwSecurityInformation, lpSecurityDescriptor, cbBufSize, pcbBytesNeeded) if res == 0: raise ctypes.WinError(result) buff = ctypes.string_at(lpSecurityDescriptor, pcbBytesNeeded.value) sd = SECURITY_DESCRIPTOR.from_bytes(buff, sd_object_type) return sd
async def add_priv_addmember(self, user_dn, group_dn): """Adds AddMember rights to the user on the group specified by group_dn""" try: #getting SID of target dn user_sid, err = await self.get_objectsid_for_dn(user_dn) if err is not None: raise err res, err = await self.get_objectacl_by_dn(group_dn) if err is not None: raise err if res is None: raise Exception('Failed to get forest\'s SD') group_sd = SECURITY_DESCRIPTOR.from_bytes(res) new_sd = copy.deepcopy(group_sd) ace_1 = ACCESS_ALLOWED_OBJECT_ACE() ace_1.Sid = SID.from_string(user_sid) ace_1.ObjectType = GUID.from_string( 'bf9679c0-0de6-11d0-a285-00aa003049e2') ace_1.Mask = ADS_ACCESS_MASK.WRITE_PROP ace_1.AceFlags = 0 new_sd.Dacl.aces.append(ace_1) changes = { 'nTSecurityDescriptor': [('replace', [new_sd.to_bytes()])] } _, err = await self.modify(group_dn, changes) if err is not None: raise err return True, None except Exception as e: return False, e
def acl_calc_gen(session, adid, inqueue, procno): total = session.query(func.count(JackDawSD.id)).filter_by(ad_id = adid).scalar() q = session.query(JackDawSD).filter_by(ad_id = adid) for adsd in tqdm(windowed_query(q, JackDawSD.id, 1000), total=total): sd = SECURITY_DESCRIPTOR.from_bytes(base64.b64decode(adsd.sd)) order_ctr = 0 for ace in sd.Dacl.aces: acl = JackDawADDACL() acl.ad_id = adsd.ad_id acl.object_type = adsd.object_type acl.object_type_guid = OBJECTTYPE_GUID_MAP.get(adsd.object_type) acl.owner_sid = str(sd.Owner) acl.group_sid = str(sd.Group) acl.ace_order = order_ctr order_ctr += 1 acl.guid = str(adsd.guid) if adsd.sid: acl.sid = str(adsd.sid) #if sd.cn: # acl.cn = sd.cn #if sd.distinguishedName: # acl.dn = str(sd.distinguishedName) acl.sd_control = sd.Control acl.ace_type = ace.AceType.name acl.ace_mask = ace.Mask t = getattr(ace,'ObjectType', None) if t: acl.ace_objecttype = str(t) t = getattr(ace,'InheritedObjectType', None) if t: acl.ace_inheritedobjecttype = str(t) true_attr, false_attr = JackDawADDACL.mask2attr(ace.Mask) for attr in true_attr: setattr(acl, attr, True) for attr in false_attr: setattr(acl, attr, False) true_attr, false_attr = JackDawADDACL.hdrflag2attr(ace.AceFlags) for attr in true_attr: setattr(acl, attr, True) for attr in false_attr: setattr(acl, attr, False) acl.ace_sid = str(ace.Sid) inqueue.put(acl) #adinfo = session.query(JackDawADInfo).get(adid) #for acl in adinfo.objectacls: # inqueue.put(acl) for _ in range(procno): inqueue.put(None)
def acl_calc_mp(inqueue, outqueue, construct): while True: adsd = inqueue.get() if adsd is None: outqueue.put(None) return sd = SECURITY_DESCRIPTOR.from_bytes(base64.b64decode(adsd.sd)) order_ctr = 0 for ace in sd.Dacl.aces: acl = JackDawADDACL() acl.ad_id = adsd.ad_id acl.object_type = adsd.object_type acl.object_type_guid = OBJECTTYPE_GUID_MAP.get(adsd.object_type) acl.owner_sid = str(sd.Owner) acl.group_sid = str(sd.Group) acl.ace_order = order_ctr order_ctr += 1 acl.guid = str(adsd.guid) if adsd.sid: acl.sid = str(adsd.sid) #if sd.cn: # acl.cn = sd.cn #if sd.distinguishedName: # acl.dn = str(sd.distinguishedName) acl.sd_control = sd.Control acl.ace_type = ace.AceType.name acl.ace_mask = ace.Mask t = getattr(ace, 'ObjectType', None) if t: acl.ace_objecttype = str(t) t = getattr(ace, 'InheritedObjectType', None) if t: acl.ace_inheritedobjecttype = str(t) true_attr, false_attr = JackDawADDACL.mask2attr(ace.Mask) for attr in true_attr: setattr(acl, attr, True) for attr in false_attr: setattr(acl, attr, False) true_attr, false_attr = JackDawADDACL.hdrflag2attr(ace.AceFlags) for attr in true_attr: setattr(acl, attr, True) for attr in false_attr: setattr(acl, attr, False) acl.ace_sid = str(ace.Sid) if acl.owner_sid not in construct.ignoresids: outqueue.put((acl.owner_sid, acl.sid, 'Owner')) if acl.ace_sid in construct.ignoresids: continue if acl.ace_type not in [ 'ACCESS_ALLOWED_ACE_TYPE', 'ACCESS_ALLOWED_OBJECT_ACE_TYPE' ]: continue if acl.ace_type == 'ACCESS_ALLOWED_ACE_TYPE': if acl.ace_mask_generic_all == True: outqueue.put((acl.ace_sid, acl.sid, 'GenericALL')) if acl.ace_mask_generic_write == True: outqueue.put((acl.ace_sid, acl.sid, 'GenericWrite')) if acl.ace_mask_write_owner == True: outqueue.put((acl.ace_sid, acl.sid, 'WriteOwner')) if acl.ace_mask_write_dacl == True: outqueue.put((acl.ace_sid, acl.sid, 'WriteDacl')) if acl.object_type in [ 'user', 'domain' ] and acl.ace_mask_control_access == True: outqueue.put((acl.ace_sid, acl.sid, 'ExtendedRightALL')) if acl.ace_type == 'ACCESS_ALLOWED_OBJECT_ACE_TYPE': if acl.ace_hdr_flag_inherited == True and acl.ace_hdr_flag_inherit_only == True: continue if acl.ace_hdr_flag_inherited == True and acl.ace_inheritedobjecttype is not None: if not ace_applies(acl.ace_inheritedobjecttype, acl.object_type): continue if any([ acl.ace_mask_generic_all, acl.ace_mask_write_dacl, acl.ace_mask_write_owner, acl.ace_mask_generic_write ]): if acl.ace_objecttype is not None and not ace_applies( acl.ace_objecttype, acl.object_type): continue if acl.ace_mask_generic_all == True: outqueue.put((acl.ace_sid, acl.sid, 'GenericALL')) continue if acl.ace_mask_generic_write == True: outqueue.put((acl.ace_sid, acl.sid, 'GenericWrite')) if acl.object_type != 'domain': continue if acl.ace_mask_write_dacl == True: outqueue.put((acl.ace_sid, acl.sid, 'WriteDacl')) if acl.ace_mask_write_owner == True: outqueue.put((acl.ace_sid, acl.sid, 'WriteOwner')) if acl.ace_mask_write_prop == True: if acl.object_type in ['user', 'group' ] and acl.ace_objecttype is None: outqueue.put((acl.ace_sid, acl.sid, 'GenericWrite')) if acl.object_type == 'group' and acl.ace_objecttype == 'bf9679c0-0de6-11d0-a285-00aa003049e2': outqueue.put((acl.ace_sid, acl.sid, 'AddMember')) if acl.ace_mask_control_access == True: if acl.object_type in ['user', 'group' ] and acl.ace_objecttype is None: outqueue.put((acl.ace_sid, acl.sid, 'ExtendedAll')) if acl.object_type == 'domain' and acl.ace_objecttype == '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2': # 'Replicating Directory Changes All' outqueue.put((acl.ace_sid, acl.sid, 'GetChangesALL')) if acl.object_type == 'domain' and acl.ace_objecttype == '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2': # 'Replicating Directory Changes' outqueue.put((acl.ace_sid, acl.sid, 'GetChanges')) if acl.object_type == 'user' and acl.ace_objecttype == '00299570-246d-11d0-a768-00aa006e0529': # 'Replicating Directory Changes' outqueue.put((acl.ace_sid, acl.sid, 'User-Force-Change-Password'))
def x2sd(x): return SECURITY_DESCRIPTOR.from_bytes(x[0])
def calc_sd_edges(adsd): def helper(src, dst, label, ad_id=1): return [src, dst, label, ad_id] if adsd.sd is None: #print('No security descriptor! %s' % adsd.id) return [] buffer = [] sd = SECURITY_DESCRIPTOR.from_bytes(base64.b64decode(adsd.sd)) order_ctr = 0 for ace in sd.Dacl.aces: acl = JackDawADDACL() acl.ad_id = adsd.ad_id acl.object_type = adsd.object_type acl.object_type_guid = OBJECTTYPE_GUID_MAP.get(adsd.object_type) acl.owner_sid = str(sd.Owner) acl.group_sid = str(sd.Group) acl.ace_order = order_ctr order_ctr += 1 acl.guid = str(adsd.guid) if adsd.sid: acl.sid = str(adsd.sid) #if sd.cn: # acl.cn = sd.cn #if sd.distinguishedName: # acl.dn = str(sd.distinguishedName) acl.sd_control = sd.Control acl.ace_type = ace.AceType.name acl.ace_mask = ace.Mask t = getattr(ace, 'ObjectType', None) if t: acl.ace_objecttype = str(t) t = getattr(ace, 'InheritedObjectType', None) if t: acl.ace_inheritedobjecttype = str(t) ace.Mask = ADS_ACCESS_MASK(ace.Mask) acl.ace_sid = str(ace.Sid) buffer.append(helper(acl.owner_sid, acl.sid, 'Owner')) if acl.ace_type not in [ 'ACCESS_ALLOWED_ACE_TYPE', 'ACCESS_ALLOWED_OBJECT_ACE_TYPE' ]: continue if acl.ace_type == 'ACCESS_ALLOWED_ACE_TYPE': if ADS_ACCESS_MASK.GENERIC_ALL in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'GenericALL')) if ADS_ACCESS_MASK.GENERIC_WRITE in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'GenericWrite')) if ADS_ACCESS_MASK.WRITE_OWNER in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'WriteOwner')) if ADS_ACCESS_MASK.WRITE_DACL in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'WriteDacl')) if acl.object_type in [ 'user', 'domain' ] and ADS_ACCESS_MASK.CONTROL_ACCESS in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'ExtendedRightALL')) if acl.ace_type == 'ACCESS_ALLOWED_OBJECT_ACE_TYPE': if AceFlags.INHERITED_ACE in ace.AceFlags and AceFlags.INHERIT_ONLY_ACE in ace.AceFlags: continue if AceFlags.INHERITED_ACE in ace.AceFlags and acl.ace_inheritedobjecttype is not None: if not ace_applies(acl.ace_inheritedobjecttype, acl.object_type): continue if (ADS_ACCESS_MASK.GENERIC_ALL in ace.Mask) or ( ADS_ACCESS_MASK.WRITE_DACL in ace.Mask ) or (ADS_ACCESS_MASK.WRITE_OWNER in ace.Mask) or (ADS_ACCESS_MASK.GENERIC_WRITE in ace.Mask): if acl.ace_objecttype is not None and not ace_applies( acl.ace_objecttype, acl.object_type): continue if ADS_ACCESS_MASK.GENERIC_ALL in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'GenericALL')) continue if ADS_ACCESS_MASK.GENERIC_WRITE in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'GenericWrite')) if acl.object_type != 'domain': continue if ADS_ACCESS_MASK.WRITE_DACL in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'WriteDacl')) if ADS_ACCESS_MASK.WRITE_OWNER in ace.Mask: buffer.append(helper(acl.ace_sid, acl.sid, 'WriteOwner')) if ADS_ACCESS_MASK.WRITE_PROP in ace.Mask: if acl.object_type in ['user', 'group' ] and acl.ace_objecttype is None: buffer.append(helper(acl.ace_sid, acl.sid, 'GenericWrite')) if acl.object_type == 'group' and acl.ace_objecttype == 'bf9679c0-0de6-11d0-a285-00aa003049e2': buffer.append(helper(acl.ace_sid, acl.sid, 'AddMember')) if ADS_ACCESS_MASK.CONTROL_ACCESS in ace.Mask: if acl.object_type in ['user', 'group' ] and acl.ace_objecttype is None: buffer.append(helper(acl.ace_sid, acl.sid, 'ExtendedAll')) if acl.object_type == 'domain' and acl.ace_objecttype == '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2': # 'Replicating Directory Changes All' buffer.append(helper(acl.ace_sid, acl.sid, 'GetChangesALL')) if acl.object_type == 'domain' and acl.ace_objecttype == '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2': # 'Replicating Directory Changes' buffer.append(helper(acl.ace_sid, acl.sid, 'GetChanges')) if acl.object_type == 'user' and acl.ace_objecttype == '00299570-246d-11d0-a768-00aa006e0529': # 'Replicating Directory Changes' buffer.append( helper(acl.ace_sid, acl.sid, 'User-Force-Change-Password')) return buffer
import base64 from winacl.dtyp.security_descriptor import SECURITY_DESCRIPTOR, sddl_acl_control # '/home/devel/Desktop/projects/aiosmb/filesd' with open('/mnt/hgfs/!SHARED/ad2.txt','r') as f: for line in f: line = line.strip() if line == '': continue #sd_data = bytes.fromhex(line) sd_data = base64.b64decode(line) #print(sd_data) sd = SECURITY_DESCRIPTOR.from_bytes(sd_data) #print(sd) x = sd.to_sddl() #print(x) sd2 = SECURITY_DESCRIPTOR.from_sddl(x) #if sd2.to_sddl() != x: # print(x) # print(sd2.to_sddl()) # print('ERR!') # if sd == None: print('???') if sd.to_bytes() != sd2.to_bytes(): if sd != sd2: #print('diffing!') diff_res = sd.diff(sd2) if len(diff_res) == 1 and 'Sacl_deleted' in diff_res: