示例#1
0
 def ldap_query(self, searchFilter, attrs, parser):
     sc = ldap.SimplePagedResultsControl(size=9999)
     try:
         resp = self.con.search(searchBase=self.baseDN, searchFilter=searchFilter, attributes=attrs,
                                searchControls=[sc], sizeLimit=0, timeLimit=50, perRecordCallback=parser)
     except ldap.LDAPSearchError as e:
         raise Exception("ldap_query error: {}".format(str(e)))
示例#2
0
 def get_all_users(self):
     if "users" in self.cache:
         return self.cache['users']
     else:
         try:
             self.users = []
             ldapConnection = ldap.LDAPConnection(f'ldap://{self.target}',
                                                  self.get_base_context(),
                                                  None)
             ldapConnection.login('', '', self.get_domain(), '', '')
             searchFilter = "(&(sAMAccountName=*)(objectCategory=user))"
             sc = ldap.SimplePagedResultsControl(size=100)
             ldapConnection.search(searchFilter=searchFilter,
                                   attributes=[
                                       'sAMAccountName', 'pwdLastSet',
                                       'mail', 'lastLogon',
                                       'sambaNTPassword'
                                   ],
                                   sizeLimit=0,
                                   searchControls=[sc],
                                   perRecordCallback=self.processRecord)
             return self.users
         except ldap.LDAPSearchError as ldap_search_err:
             # raise
             print(f"LDAPSearchError: {ldap_search_err}")
         ldapConnection.close()
示例#3
0
    def run(self):

        try:
            ldapConnection = ldap.LDAPConnection('ldap://%s' % self.domain, self.baseDN)
            ldapConnection.login(self.u_name, self.passwd, self.domain, self.lmhash, self.nthash)
            print(running, end='')
            print('Connected to {} as {}'.format(self.domain, self.u_name))
            os.mkdir(self.domain)
        except Exception as err:
            if 'invalidCredentials' in str(err):
                print(error, end='')
                sys.exit('Error: Invalid credentials')
            if 'Connection error' in str(err):
                print(error, end='')
                sys.exit('Error: Cannot connect to server')


        if self.options.users:
            filter = "(&(objectCategory=Person)(sAMAccountName=*))"
        elif self.options.computers:
            filter = "(&(objectCategory=Computer)(objectClass=*))"
        elif self.options.username:
            filter = "(&(objectCategory=Person)(sAMAccountName={}))".format(self.options.username)
        elif self.options.computerName:
            filter = "(&(objectCategory=Computer)(cn={}))".format(self.options.computerName)
        else:
            filter = "(&(objectCategory=*)(objectClass=*))"



        sc = ldap.SimplePagedResultsControl(size=100)

        print(Fore.YELLOW + '[-]', end='')
        print("Starting to map the domain, this could take a while...")
        ldapConnection.search(searchFilter = filter, searchControls=[sc], perRecordCallback=self.processRecord)
示例#4
0
    def on_login(self, context, connection):
        '''
        On a successful LDAP login we perform a search for all PKI Enrollment Server or Certificate Templates Names.
        '''
        if self.server is None:
            search_filter = '(objectClass=pKIEnrollmentService)'
        else:
            search_filter = '(distinguishedName=CN={},CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,'.format(self.server)
            self.context.log.highlight('Using PKI CN: {}'.format(self.server))

        context.log.debug("Starting LDAP search with search filter '{}'".format(search_filter))

        try:
            sc = ldap.SimplePagedResultsControl()

            if self.server is None:
                resp = connection.ldapConnection.search(searchFilter=search_filter,
                                            attributes=[],
                                            sizeLimit=0, searchControls=[sc],
                                            perRecordCallback=self.process_servers,
                                            searchBase='CN=Configuration,' + connection.ldapConnection._baseDN)
            else:
                resp = connection.ldapConnection.search(searchFilter=search_filter + connection.ldapConnection._baseDN + ')',
                                            attributes=['certificateTemplates'],
                                            sizeLimit=0, searchControls=[sc],
                                            perRecordCallback=self.process_templates,
                                            searchBase='CN=Configuration,' + connection.ldapConnection._baseDN)

        except LDAPSearchError as e:
            context.log.error('Obtained unexpected exception: {}'.format(str(e)))
示例#5
0
    def search(self,
               searchFilter='(objectClass=*)',
               attributes=[],
               searchBase=None,
               scope=None):
        if self.ldap is None:
            self.ldap_connect()

        sc = ldap.SimplePagedResultsControl()

        try:
            search_result = self.ldap.search(searchFilter=searchFilter,
                                             scope=scope,
                                             attributes=attributes,
                                             sizeLimit=0,
                                             searchControls=[sc],
                                             searchBase=searchBase)
        except ldap.LDAPSearchError as e:
            if 'sizeLimitExceeded' in e.getErrorString():
                search_result = e.getAnswers()
            else:
                logging.warning('LDAP search error: %s' % e)
                raise

        return self.dictionize(search_result)
示例#6
0
    def run(self):
        if self.__doKerberos:
            self.__target = self.getMachineName()
        else:
            if self.__kdcHost is not None:
                self.__target = self.__kdcHost
            else:
                self.__target = self.__domain

        # Connect to LDAP
        try:
            ldapConnection = ldap.LDAPConnection('ldap://%s'%self.__target, self.baseDN, self.__kdcHost)
            if self.__doKerberos is not True:
                ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash)
            else:
                ldapConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash,
                                             self.__aesKey, kdcHost=self.__kdcHost)
        except ldap.LDAPSessionError as e:
            if str(e).find('strongerAuthRequired') >= 0:
                # We need to try SSL
                ldapConnection = ldap.LDAPConnection('ldaps://%s' % self.__target, self.baseDN, self.__kdcHost)
                if self.__doKerberos is not True:
                    ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash)
                else:
                    ldapConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash,
                                                 self.__aesKey, kdcHost=self.__kdcHost)
            else:
                raise

        logging.info('Querying %s for information about domain.' % self.__target)
        # Print header
        print((self.__outputFormat.format(*self.__header)))
        print(('  '.join(['-' * itemLen for itemLen in self.__colLen])))

        # Building the search filter
        if self.__all:
            searchFilter = "(&(sAMAccountName=*)(objectCategory=user)"
        else:
            searchFilter = "(&(sAMAccountName=*)(mail=*)(!(UserAccountControl:1.2.840.113556.1.4.803:=%d))" % UF_ACCOUNTDISABLE

        if self.__requestUser is not None:
            searchFilter += '(sAMAccountName:=%s))' % self.__requestUser
        else:
            searchFilter += ')'

        try:
            logging.debug('Search Filter=%s' % searchFilter)
            sc = ldap.SimplePagedResultsControl(size=100)
            ldapConnection.search(searchFilter=searchFilter,
                                  attributes=['sAMAccountName', 'pwdLastSet', 'mail', 'lastLogon'],
                                  sizeLimit=0, searchControls = [sc], perRecordCallback=self.processRecord)
        except ldap.LDAPSearchError:
                raise

        ldapConnection.close()
示例#7
0
    def on_login(self, context, connection):
        '''
        On successful LDAP login we perform a search for all user objects that have a description.
        Users can specify additional LDAP filters that are applied to the query.
        '''
        self.create_log_file(connection.conn.getRemoteHost(),
                             datetime.now().strftime("%Y%m%d_%H%M%S"))
        context.log.debug(
            "Starting LDAP search with search filter '{}'".format(
                self.search_filter))

        try:
            sc = ldap.SimplePagedResultsControl()
            connection.ldapConnection.search(
                searchFilter=self.search_filter,
                attributes=['sAMAccountName', 'description'],
                sizeLimit=0,
                searchControls=[sc],
                perRecordCallback=self.process_record)

        except LDAPSearchError as e:
            context.log.error('Obtained unexpected exception: {}'.format(
                str(e)))
示例#8
0
    def on_login(self, context, connection):
        '''
        On a successful LDAP login we perform a search for all PKI Enrollment Services.
        '''
        search_filter = '(objectClass=pKIEnrollmentService)'

        context.log.debug(
            "Starting LDAP search with search filter '{}'".format(
                search_filter))

        try:
            sc = ldap.SimplePagedResultsControl()
            resp = connection.ldapConnection.search(
                searchFilter=search_filter,
                attributes=['dNSHostName', 'msPKI-Enrollment-Servers'],
                sizeLimit=0,
                searchControls=[sc],
                perRecordCallback=self.process_record,
                searchBase='CN=Configuration,' +
                connection.ldapConnection._baseDN)

        except LDAPSearchError as e:
            context.log.error('Obtained unexpected exception: {}'.format(
                str(e)))
示例#9
0
        print self.__outputFormat.format(*self.__header)
        print '  '.join(['-' * itemLen for itemLen in self.__colLen])

        # Building the search filter
        if self.__allusers:
            searchFilter = "(&(sAMAccountName=*)(objectCategory=user)"
        else:
            searchFilter = "(&(sAMAccountName=*)(mail=*)"

        if self.__requestUser is not None:
            searchFilter += '(sAMAccountName:=%s))' % self.__requestUser
        else:
            searchFilter += ')'

        try:
            sc = ldap.SimplePagedResultsControl()
            resp = ldapConnection.search(searchFilter=searchFilter,
                                         attributes=[
                                             'sAMAccountName', 'pwdLastSet',
                                             'mail', 'lastLogon'
                                         ],
                                         sizeLimit=0,
                                         searchControls=[sc],
                                         perRecordCallback=self.processRecord)
        except ldap.LDAPSearchError, e:
            raise

        ldapConnection.close()


# Process command-line arguments.
示例#10
0
    def run(self):
        if self.__doKerberos:
            self.__target = self.getMachineName()
        else:
            if self.__kdcHost is not None:
                self.__target = self.__kdcHost
            else:
                self.__target = self.__domain

        # Connect to LDAP
        try:
            ldapConnection = ldap.LDAPConnection('ldap://%s' % self.__target,
                                                 self.baseDN, self.__kdcHost)
            if self.__doKerberos is not True:
                ldapConnection.login(self.__username, self.__password,
                                     self.__domain, self.__lmhash,
                                     self.__nthash)
            else:
                ldapConnection.kerberosLogin(self.__username,
                                             self.__password,
                                             self.__domain,
                                             self.__lmhash,
                                             self.__nthash,
                                             self.__aesKey,
                                             kdcHost=self.__kdcHost)
        except ldap.LDAPSessionError as e:
            if str(e).find('strongerAuthRequired') >= 0:
                # We need to try SSL
                ldapConnection = ldap.LDAPConnection(
                    'ldaps://%s' % self.__target, self.baseDN, self.__kdcHost)
                if self.__doKerberos is not True:
                    ldapConnection.login(self.__username, self.__password,
                                         self.__domain, self.__lmhash,
                                         self.__nthash)
                else:
                    ldapConnection.kerberosLogin(self.__username,
                                                 self.__password,
                                                 self.__domain,
                                                 self.__lmhash,
                                                 self.__nthash,
                                                 self.__aesKey,
                                                 kdcHost=self.__kdcHost)
            else:
                raise

        #logging.info('Querying %s for information about domain.' % self.__target)
        # Print header
        #print((self.__outputFormat.format(*self.__header)))
        #print(('  '.join(['-' * itemLen for itemLen in self.__colLen])))

        # Building the search filter
        #if self.__all:
        #    searchFilter = "(&(sAMAccountName=*)(objectCategory=user)"
        #    #searchFilter = "(&(sAMAccountName=*)(objectCategory=computer)"
        #else:
        #    searchFilter = "(&(sAMAccountName=*)(mail=*)(!(UserAccountControl:1.2.840.113556.1.4.803:=%d))" % UF_ACCOUNTDISABLE

        ## Changes MV
        if self.__objectType == "user":
            searchFilter = "(&(sAMAccountName=*)(objectCategory=user)(badPwdCount<=3)"

        elif self.__objectType == "computer":

            #lastLogon<=131592420000000000 1/1/2018
            def dt_to_filetime(dt):
                EPOCH_AS_FILETIME = 116444736000000000  # January 1, 1970 as MS file time
                HUNDREDS_OF_NANOSECONDS = 10000000
                return EPOCH_AS_FILETIME + (timegm(dt.timetuple()) *
                                            HUNDREDS_OF_NANOSECONDS)

            dt = datetime.now() - timedelta(days=2)
            filetime = dt_to_filetime(dt)

            #searchFilter = "(&(sAMAccountName=*)(objectCategory=computer)(lastLogon<=131592420000000000)"
            #searchFilter = "(&(sAMAccountName=*)(objectCategory=computer)(lastLogon<=131592420000000000)(!(userAccountControl:1.2.840.113556.1.4.803:=8192))"
            searchFilter = "(&(sAMAccountName=*)(objectCategory=computer)(lastLogon>=" + str(
                filetime
            ) + ")(!(userAccountControl:1.2.840.113556.1.4.803:=8192))"

        elif self.__objectType == "dc":
            #https://ldapwiki.com/wiki/Active%20Directory%20Computer%20Related%20LDAP%20Query
            searchFilter = "(&(objectCategory=Computer)(userAccountControl:1.2.840.113556.1.4.803:=8192)"

        ## Changes MV

        if self.__requestUser is not None:
            searchFilter += '(sAMAccountName:=%s))' % self.__requestUser
        else:
            searchFilter += ')'

        try:
            logging.debug('Search Filter=%s' % searchFilter)
            sc = ldap.SimplePagedResultsControl(size=250)
            #ldapConnection.search(searchFilter=searchFilter,attributes=['sAMAccountName', 'pwdLastSet', 'mail', 'lastLogon'],sizeLimit=0, searchControls = [sc], perRecordCallback=self.processRecord)
            answers = ldapConnection.search(searchFilter=searchFilter,
                                            attributes=[
                                                'sAMAccountName', 'pwdLastSet',
                                                'mail', 'lastLogon'
                                            ],
                                            sizeLimit=0,
                                            searchControls=[sc],
                                            perRecordCallback=None)

            return answers
        except ldap.LDAPSearchError:
            raise

        ldapConnection.close()
示例#11
0
class GetADUsers:
    @staticmethod
    def printTable(items, header):
        colLen = []
        for i, col in enumerate(header):
            rowMaxLen = max([len(row[i]) for row in items])
            colLen.append(max(rowMaxLen, len(col)))

        outputFormat = ' '.join(
            ['{%d:%ds} ' % (num, width) for num, width in enumerate(colLen)])

        # Print header
        print outputFormat.format(*header)
        print '  '.join(['-' * itemLen for itemLen in colLen])

        # And now the rows
        for row in items:
            print outputFormat.format(*row)

    def __init__(self, username, password, domain, cmdLineOptions):
        self.options = cmdLineOptions
        self.__username = username
        self.__password = password
        self.__domain = domain
        self.__lmhash = ''
        self.__nthash = ''
        self.__aesKey = cmdLineOptions.aesKey
        self.__doKerberos = cmdLineOptions.k
        self.__target = None
        self.__kdcHost = cmdLineOptions.dc_ip
        self.__requestUser = cmdLineOptions.user
        self.__allusers = cmdLineOptions.all_users
        if cmdLineOptions.hashes is not None:
            self.__lmhash, self.__nthash = cmdLineOptions.hashes.split(':')

        # Create the baseDN
        domainParts = self.__domain.split('.')
        self.baseDN = ''
        for i in domainParts:
            self.baseDN += 'dc=%s,' % i
        # Remove last ','
        self.baseDN = self.baseDN[:-1]

    def getMachineName(self):
        if self.__kdcHost is not None:
            s = SMBConnection(self.__kdcHost, self.__kdcHost)
        else:
            s = SMBConnection(self.__domain, self.__domain)
        try:
            s.login('', '')
        except Exception:
            if s.getServerName() == '':
                raise ('Error while anonymous logging into %s' % self.__domain)
        else:
            s.logoff()
        return s.getServerName()

    @staticmethod
    def getUnixTime(t):
        t -= 116444736000000000
        t /= 10000000
        return t

    def run(self):
        if self.__doKerberos:
            self.__target = self.getMachineName()
        else:
            if self.__kdcHost is not None:
                self.__target = self.__kdcHost
            else:
                self.__target = self.__domain

        # Connect to LDAP
        try:
            ldapConnection = ldap.LDAPConnection('ldap://%s' % self.__target,
                                                 self.baseDN, self.__kdcHost)
            if self.__doKerberos is not True:
                ldapConnection.login(self.__username, self.__password,
                                     self.__domain, self.__lmhash,
                                     self.__nthash)
            else:
                ldapConnection.kerberosLogin(self.__username,
                                             self.__password,
                                             self.__domain,
                                             self.__lmhash,
                                             self.__nthash,
                                             self.__aesKey,
                                             kdcHost=self.__kdcHost)
        except ldap.LDAPSessionError, e:
            if str(e).find('strongerAuthRequired') >= 0:
                # We need to try SSL
                ldapConnection = ldap.LDAPConnection(
                    'ldaps://%s' % self.__target, self.baseDN, self.__kdcHost)
                if self.__doKerberos is not True:
                    ldapConnection.login(self.__username, self.__password,
                                         self.__domain, self.__lmhash,
                                         self.__nthash)
                else:
                    ldapConnection.kerberosLogin(self.__username,
                                                 self.__password,
                                                 self.__domain,
                                                 self.__lmhash,
                                                 self.__nthash,
                                                 self.__aesKey,
                                                 kdcHost=self.__kdcHost)
            else:
                raise

        # Building the search filter
        if self.__allusers:
            searchFilter = "(&(sAMAccountName=*)(objectCategory=user)"
        else:
            searchFilter = "(&(sAMAccountName=*)(mail=*)"

        if self.__requestUser is not None:
            searchFilter += '(sAMAccountName:=%s))' % self.__requestUser
        else:
            searchFilter += ')'

        try:
            logging.info(
                'Querying %s for information about domain. Be patient...' %
                self.__target)
            sc = ldap.SimplePagedResultsControl()
            resp = ldapConnection.search(searchFilter=searchFilter,
                                         attributes=[
                                             'sAMAccountName', 'pwdLastSet',
                                             'mail', 'lastLogon'
                                         ],
                                         sizeLimit=0,
                                         searchControls=[sc])
        except ldap.LDAPSearchError, e:
            if e.getErrorString().find('sizeLimitExceeded') >= 0:
                logging.debug(
                    'sizeLimitExceeded exception caught, giving up and processing the data received'
                )
                # We reached the sizeLimit, process the answers we have already and that's it. Until we implement
                # paged queries
                resp = e.getAnswers()
                pass
            else:
                raise