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)))
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()
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)
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)))
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)
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()
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)))
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)))
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.
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()
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