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 searchFilter = "(&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512)" \ "(!(UserAccountControl:1.2.840.113556.1.4.803:=2))" if self.__nonexpiring: searchFilter += '(UserAccountControl:1.2.840.113556.1.4.803:=65536)' if self.__lastset is not None: print self.__lastset PwdDate = int(time() - (int(self.__lastset) * 86400) + ((1970-1601) * 365.242190) *86400 * 10000000) print PwdDate searchFilter += '(pwdlastset<=%d)' % PwdDate if self.__requestUser is not None: searchFilter += '(sAMAccountName=%s))' % self.__requestUser else: searchFilter += ')' try: resp = ldapConnection.search(searchFilter=searchFilter, attributes=['servicePrincipalName', 'sAMAccountName', 'pwdLastSet', 'MemberOf', 'userAccountControl', 'lastLogon'], sizeLimit=999) 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
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
def _create_ldap_connection(self, queried_domain=str(), ads_path=str(), ads_prefix=str()): if not self._domain: self._domain = self._get_netfqdn() if not queried_domain: queried_domain = self._domain self._queried_domain = queried_domain base_dn = str() if ads_prefix: self._ads_prefix = ads_prefix base_dn = '{},'.format(self._ads_prefix) if ads_path: # TODO: manage ADS path starting with 'GC://' if ads_path.upper().startswith('LDAP://'): ads_path = ads_path[7:] self._ads_path = ads_path base_dn += self._ads_path else: base_dn += ','.join('dc={}'.format(x) for x in self._queried_domain.split('.')) try: ldap_connection = ldap.LDAPConnection('ldap://{}'.format(self._domain_controller), base_dn, self._domain_controller) except ldap.LDAPSessionError, e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL ldap_connection = ldap.LDAPConnection('ldaps://{}'.format(self._domain_controller), base_dn, self._domain_controller) else: raise e
def run(self): if self.__doKerberos: target = self.getMachineName() else: if self.__kdcHost is not None: target = self.__kdcHost else: target = self.__domain # Are we asked not to supply a password? if self.__no_pass is True: # Yes, just ask the TGT and exit logging.info('Getting TGT for %s' % self.__username) entry = self.getTGT(self.__username) self.outputTGT(entry, None) return # Connect to LDAP try: ldapConnection = ldap.LDAPConnection('ldap://%s' % 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' % 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: # Cannot authenticate, we will try to get this users' TGT (hoping it has PreAuth disabled) logging.info('Cannot authenticate %s, getting its TGT' % self.__username) entry = self.getTGT(self.__username) self.outputTGT(entry, None) return
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 run(self): target = self.__dc # Connect to LDAP try: ldapConnection = ldap.LDAPConnection('ldap://%s' % target, self.baseDN, self.__dc) ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) except ldap.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL ldapConnection = ldap.LDAPConnection('ldaps://%s' % target, self.baseDN, self.__dc) ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: raise try: resp = ldapConnection.search(searchFilter=self.__searchFilter, attributes=[], sizeLimit=999) except ldap.LDAPSearchError as 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 logging.debug('Total of records returned %d' % len(resp)) attributes = [] for item in resp: if isinstance(item, ldapasn1.SearchResultEntry) is not True: continue try: for attribute in item['attributes']: if str(attribute['type']) == self.__print_attribute: attributes.append(attribute['vals'][0]) except Exception as e: logging.error('Skipping item, cannot process due to error %s' % str(e)) pass return attributes
def hash_login(self, domain, username, ntlm_hash): lmhash = '' nthash = '' #This checks to see if we didn't provide the LM Hash if ntlm_hash.find(':') != -1: lmhash, nthash = ntlm_hash.split(':') else: nthash = ntlm_hash self.hash = ntlm_hash if lmhash: self.lmhash = lmhash if nthash: self.nthash = nthash self.username = username self.domain = domain # Create the baseDN domainParts = self.domain.split('.') for i in domainParts: self.baseDN += 'dc=%s,' % i # Remove last ',' self.baseDN = self.baseDN[:-1] if self.kdcHost is not None: target = self.kdcHost else: target = domain # Connect to LDAP try: self.ldapConnection = ldap_impacket.LDAPConnection( 'ldap://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) except ldap_impacket.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL self.ldapConnection = ldap_impacket.LDAPConnection( 'ldaps://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) try: self.ldapConnection.search(searchFilter='(objectCategory=nop)') out = u'{}{}:{}'.format('{}\\'.format(domain), username, nthash) self.logger.success(out) except ldap_impacket.LDAPSearchError as e: self.logger.error(u'{}\{}:{}'.format(self.domain, self.username, self.nthash)) return False return True
def plaintext_login(self, domain, username, password): self.username = username self.password = password self.domain = domain # Create the baseDN self.baseDN = '' domainParts = self.domain.split('.') for i in domainParts: self.baseDN += 'dc=%s,' % i # Remove last ',' self.baseDN = self.baseDN[:-1] if self.kdcHost is not None: target = self.kdcHost else: target = domain if self.password == '' and self.args.asreproast: hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username) if hash_TGT: self.logger.highlight(u'{}'.format(hash_TGT)) with open(self.args.asreproast, 'a+') as hash_asreproast: hash_asreproast.write(hash_TGT + '\n') return False # Connect to LDAP out = u'{}{}:{}'.format('{}\\'.format(domain), username, password) try: self.ldapConnection = ldap_impacket.LDAPConnection( 'ldap://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) self.logger.success(out) except ldap_impacket.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL try: self.ldapConnection = ldap_impacket.LDAPConnection( 'ldaps://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) self.logger.success(out) except ldap_impacket.LDAPSessionError as e: self.logger.error(u'{}\{}:{}'.format( self.domain, self.username, self.password)) else: self.logger.error(u'{}\{}:{}'.format(self.domain, self.username, self.password)) return False return True
def kerberos_login(self, domain, aesKey, kdcHost): if self.kdcHost is not None: target = self.kdcHost else: target = self.domain self.kdcHost = self.domain # Create the baseDN self.baseDN = '' domainParts = self.domain.split('.') for i in domainParts: self.baseDN += 'dc=%s,' % i # Remove last ',' self.baseDN = self.baseDN[:-1] try: self.ldapConnection = ldap_impacket.LDAPConnection( 'ldap://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.kerberosLogin(self.username, self.password, self.domain, self.lmhash, self.nthash, self.aesKey, kdcHost=self.kdcHost) except ldap_impacket.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL self.ldapConnection = ldap_impacket.LDAPConnection( 'ldaps://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.kerberosLogin(self.username, self.password, self.domain, self.lmhash, self.nthash, self.aesKey, kdcHost=self.kdcHost) else: errorCode = str(e).split()[-2][:-1] self.logger.error(u'{}\\{}:{} {}'.format( self.domain, self.username, self.password, ldap_error_status[errorCode] if errorCode in ldap_error_status else ''), color='magenta' if errorCode in ldap_error_status else 'red') return True
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 ldaps_con(self): try: self.con = ldap.LDAPConnection("ldaps://{}".format(self.ip)) self.ldaps = True return True except: return False
def kerberos_login(self, aesKey, kdcHost): # Create the baseDN domainParts = self.domain.split('.') for i in domainParts: self.baseDN += 'dc=%s,' % i # Remove last ',' self.baseDN = self.baseDN[:-1] if self.kdcHost is not None: target = self.kdcHost else: target = self.domain try: self.ldapConnection.kerberosLogin(self.username, self.password, self.domain, self.lmhash, self.nthash, self.aesKey, kdcHost=self.kdcHost) except ldap_impacket.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL self.ldapConnection = ldap_impacket.LDAPConnection( 'ldaps://%s' % target, self.baseDN, self.kdcHost) self.ldapConnection.kerberosLogin(self.username, self.password, self.domain, self.lmhash, self.nthash, self.aesKey, kdcHost=self.kdcHost) return True
def getLDAPConnection(self, hostname='', baseDN='', protocol='ldaps'): conn = ldap.LDAPConnection('%s://%s' % (protocol, hostname), baseDN) if self.kdc is not None: try: logging.debug('Authenticating to LDAP server using Kerberos') conn.kerberosLogin(self.username, self.password, self.domain, self.lm_hash, self.nt_hash, self.aes_key, self.kdc) except KerberosError as e: logging.warning('Kerberos login failed: %s' % e) return None else: logging.debug('Authenticating to LDAP server') try: conn.login(self.username, self.password, self.domain, self.lm_hash, self.nt_hash) except ldap.LDAPSessionError as e: if protocol == 'ldap' and 'strongerAuthRequired' in str(e): logging.warning('LDAP Authentication is refused because LDAP signing is enabled. ' 'Trying to connect over LDAPS instead...') return self.getLDAPConnection(hostname, baseDN, 'ldaps') else: logging.warning('Failure to authenticate with LDAP! Error %s' % e) return None return conn
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 on_login(self, context, connection): ''' Perform a second logon attempt without LDAP signing. ''' domain = connection.domain username = connection.username password = connection.password ldap_host = connection.conn.getRemoteHost() try: connection = ldap.LDAPConnection('ldap://{}'.format(ldap_host)) connection.login(username, password, domain, '', '') context.log.highlight('LDAP signing is NOT enforced on {}'.format(ldap_host)) except ldap.LDAPSessionError as e: error_msg = str(e) if 'strongerAuthRequired' in error_msg: context.log.info('LDAP signing is enforced on {}'.format(ldap_host)) else: context.log.error("Unexpected LDAP error: '{}'".format(error_msg)) except Exception as e: context.log.error("Unexpected LDAP error: '{}'".format(str(e)))
def test_sicilyNtlm(self): ldapConnection = ldap.LDAPConnection(self.url, self.baseDN) ldapConnection.login(user=self.username, password=self.password, domain=self.domain) self.dummySearch(ldapConnection)
def ldap_con(self): try: self.con = ldap.LDAPConnection("ldap://{}".format(self.ip)) return True except Exception as e: print(e) return False
def create_ldaps_con(self): try: self.con = ldap.LDAPConnection("ldaps://{}".format(self.host), ) self.ldaps = True return True except Exception as e: print(e) return False
def test_sicilyNtlmHashes(self): if len(self.hashes) > 0: lmhash, nthash = self.hashes.split(':') else: lmhash = '' nthash = '' ldapConnection = ldap.LDAPConnection(self.url, self.baseDN) ldapConnection.login(user=self.username, password=self.password, domain=self.domain, lmhash=lmhash, nthash=nthash ) self.dummySearch(ldapConnection)
def test_kerberosLoginHashes(self): if len(self.hashes) > 0: lmhash, nthash = self.hashes.split(':') else: lmhash = '' nthash = '' ldapConnection = ldap.LDAPConnection(self.url, self.baseDN) ldapConnection.kerberosLogin(self.username, '', self.domain, lmhash, nthash, '', None, None) self.dummySearch(ldapConnection)
def run(self): self.__target = self.__kdcHost # Connect to LDAP try: ldapConnection = ldap.LDAPConnection('ldap://%s' % self.__target, self.baseDN, self.__kdcHost) ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) 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) ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: raise
def getLDAPConnection(self, hostname='', baseDN='', protocol='ldaps'): conn = ldap.LDAPConnection('%s://%s' % (protocol, hostname), baseDN) if self.kdc is not None: try: logging.debug('Authenticating to LDAP server using Kerberos') conn.kerberosLogin(self.username, self.password, self.domain, self.lm_hash, self.nt_hash, self.aes_key, self.kdc) except KerberosError, e: logging.warning('Kerberos login failed: %s' % e) return None
def check(self, remote_host): try: ldapclient = ldap.LDAPConnection('ldap://%s' % remote_host) except: return try: #Default login method does not request for signature, allowing us to check auth result ldapclient.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) logging.info( 'LDAP signature not required on target %s (authentication was accepted)', remote_host) except ldap.LDAPSessionError as exc: if 'strongerAuthRequired:' in str(exc): logging.info( 'LDAP signature was required on target %s (authentication was rejected)', remote_host) else: logging.warning( 'Unexpected Exception while authenticating to %s: %s', remote_host, exc) ldapclient.close()
def ldaps_connect(self, srv): self.con = ldap.LDAPConnection("ldaps://{}".format(srv), ) self.ldaps = True
def ldap_connect(self, srv): self.con = ldap.LDAPConnection("ldap://{}".format(srv), )
def run(self): if self.__doKerberos: target = self.getMachineName() else: if self.__kdcHost is not None: target = self.__kdcHost else: target = self.__domain if self.__usersFile: self.request_users_file_TGTs() return # Are we asked not to supply a password? if self.__no_pass is True: # Yes, just ask the TGT and exit logging.info('Getting TGT for %s' % self.__username) entry = self.getTGT(self.__username) self.outputTGT(entry, None) return # Connect to LDAP try: ldapConnection = ldap.LDAPConnection('ldap://%s' % 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' % 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: # Cannot authenticate, we will try to get this users' TGT (hoping it has PreAuth disabled) logging.info('Cannot authenticate %s, getting its TGT' % self.__username) entry = self.getTGT(self.__username) self.outputTGT(entry, None) return # Building the search filter searchFilter = "(&(UserAccountControl:1.2.840.113556.1.4.803:=%d)" \ "(!(UserAccountControl:1.2.840.113556.1.4.803:=%d))(!(objectCategory=computer)))" % \ (UF_DONT_REQUIRE_PREAUTH, UF_ACCOUNTDISABLE) try: logging.debug('Search Filter=%s' % searchFilter) resp = ldapConnection.search(searchFilter=searchFilter, attributes=[ 'sAMAccountName', 'pwdLastSet', 'MemberOf', 'userAccountControl', 'lastLogon' ], sizeLimit=999) except ldap.LDAPSearchError as 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 answers = [] logging.debug('Total of records returned %d' % len(resp)) for item in resp: if isinstance(item, ldapasn1.SearchResultEntry) is not True: continue mustCommit = False sAMAccountName = '' memberOf = '' pwdLastSet = '' userAccountControl = 0 lastLogon = 'N/A' try: for attribute in item['attributes']: if str(attribute['type']) == 'sAMAccountName': sAMAccountName = str(attribute['vals'][0]) mustCommit = True elif str(attribute['type']) == 'userAccountControl': userAccountControl = "0x%x" % int(attribute['vals'][0]) elif str(attribute['type']) == 'memberOf': memberOf = str(attribute['vals'][0]) elif str(attribute['type']) == 'pwdLastSet': if str(attribute['vals'][0]) == '0': pwdLastSet = '<never>' else: pwdLastSet = str( datetime.datetime.fromtimestamp( self.getUnixTime( int(str(attribute['vals'][0]))))) elif str(attribute['type']) == 'lastLogon': if str(attribute['vals'][0]) == '0': lastLogon = '<never>' else: lastLogon = str( datetime.datetime.fromtimestamp( self.getUnixTime( int(str(attribute['vals'][0]))))) if mustCommit is True: answers.append([ sAMAccountName, memberOf, pwdLastSet, lastLogon, userAccountControl ]) except Exception as e: logging.debug("Exception:", exc_info=True) logging.error('Skipping item, cannot process due to error %s' % str(e)) pass if len(answers) > 0: self.printTable(answers, header=[ "Name", "MemberOf", "PasswordLastSet", "LastLogon", "UAC" ]) print('\n\n') if self.__requestTGT is True: usernames = [answer[0] for answer in answers] self.request_multiple_TGTs(usernames) else: print("No entries found!")
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 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) searchFilter = ldapasn1.Filter() searchFilter['present'] = ldapasn1.Present('servicePrincipalName') resp = ldapConnection.search(searchFilter=searchFilter, attributes=[ 'servicePrincipalName', 'sAMAccountName', 'pwdLastSet', 'MemberOf', 'userAccountControl' ]) answers = [] logging.debug('Total of records returned %d' % len(resp)) for item in resp: if isinstance(item, ldapasn1.SearchResultEntry) is not True: continue mustCommit = False sAMAccountName = '' memberOf = '' SPNs = [] pwdLastSet = '' userAccountControl = 0 for attribute in item['attributes']: if attribute['type'] == 'sAMAccountName': if str(attribute['vals'][0]).endswith('$') is False: # User Account sAMAccountName = str(attribute['vals'][0]) mustCommit = True elif attribute['type'] == 'userAccountControl': userAccountControl = str(attribute['vals'][0]) elif attribute['type'] == 'memberOf': memberOf = str(attribute['vals'][0]) elif attribute['type'] == 'pwdLastSet': pwdLastSet = str( datetime.fromtimestamp( self.getUnixTime(int(str(attribute['vals'][0]))))) elif attribute['type'] == 'servicePrincipalName': for spn in attribute['vals']: SPNs.append(str(spn)) if mustCommit is True: if int(userAccountControl) & UF_ACCOUNTDISABLE: logging.debug('Bypassing disabled account %s ' % sAMAccountName) else: for spn in SPNs: answers.append( [spn, sAMAccountName, memberOf, pwdLastSet]) if len(answers) > 0: self.printTable(answers, header=[ "ServicePrincipalName", "Name", "MemberOf", "PasswordLastSet" ]) print '\n\n' if self.__requestTGS is True: # Let's get unique user names an a SPN to request a TGS for users = dict((vals[1], vals[0]) for vals in answers) # Get a TGT for the current user TGT = self.getTGT() if self.__outputFileName is not None: fd = open(self.__outputFileName, 'w+') else: fd = None for user, SPN in users.iteritems(): try: serverName = Principal( SPN, type=constants.PrincipalNameType.NT_SRV_INST.value) tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS( serverName, self.__domain, self.__kdcHost, TGT['KDC_REP'], TGT['cipher'], TGT['sessionKey']) self.outputTGS(tgs, oldSessionKey, sessionKey, user, fd) except Exception, e: logging.error(str(e)) if fd is not None: fd.close()
def run(self): self.__target = self.__kdcHost # Connect to LDAP try: ldapConnection = ldap.LDAPConnection('ldap://%s' % self.__target, self.baseDN, self.__kdcHost) ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) 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) ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: raise # Building the search filter searchFilter = "(&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512)" \ "(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))" try: resp = ldapConnection.search(searchFilter=searchFilter, attributes=[ 'servicePrincipalName', 'sAMAccountName', 'pwdLastSet', 'MemberOf', 'userAccountControl', 'lastLogon' ], sizeLimit=999) except ldap.LDAPSearchError as e: if e.getErrorString().find('sizeLimitExceeded') >= 0: module.log( 'sizeLimitExceeded exception caught, giving up and processing the data received', level='debug') # We reached the sizeLimit, process the answers we have already and that's it. Until we implement # paged queries resp = e.getAnswers() else: raise answers = [] module.log('Total of records returned {}'.format(len(resp)), level='info') for item in resp: if isinstance(item, ldapasn1.SearchResultEntry) is not True: continue mustCommit = False sAMAccountName = '' memberOf = '' SPNs = [] pwdLastSet = '' userAccountControl = 0 lastLogon = 'N/A' try: for attribute in item['attributes']: if attribute['type'] == 'sAMAccountName': if str(attribute['vals'][0]).endswith('$') is False: # User Account sAMAccountName = str(attribute['vals'][0]) mustCommit = True elif attribute['type'] == 'userAccountControl': userAccountControl = str(attribute['vals'][0]) elif attribute['type'] == 'memberOf': memberOf = str(attribute['vals'][0]) elif attribute['type'] == 'pwdLastSet': if str(attribute['vals'][0]) == '0': pwdLastSet = '<never>' else: pwdLastSet = str( datetime.fromtimestamp( self.getUnixTime( int(str(attribute['vals'][0]))))) elif attribute['type'] == 'lastLogon': if str(attribute['vals'][0]) == '0': lastLogon = '<never>' else: lastLogon = str( datetime.fromtimestamp( self.getUnixTime( int(str(attribute['vals'][0]))))) elif attribute['type'] == 'servicePrincipalName': for spn in attribute['vals']: SPNs.append(str(spn)) if mustCommit is True: if int(userAccountControl) & UF_ACCOUNTDISABLE: module.log('Bypassing disabled account {}'.format( sAMAccountName), level='debug') else: for spn in SPNs: answers.append([ spn, sAMAccountName, memberOf, pwdLastSet, lastLogon ]) except Exception as e: module.log('Skipping item, cannot process due to error', level='error') if len(answers) > 0: self.printTable(answers, header=[ "ServicePrincipalName", "Name", "MemberOf", "PasswordLastSet", "LastLogon" ]) if self.__requestTGS is True: # Let's get unique user names and a SPN to request a TGS for users = dict((vals[1], vals[0]) for vals in answers) # Get a TGT for the current user TGT = self.getTGT() for user, SPN in users.items(): try: serverName = Principal( SPN, type=constants.PrincipalNameType.NT_SRV_INST.value) tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS( serverName, self.__domain, self.__kdcHost, TGT['KDC_REP'], TGT['cipher'], TGT['sessionKey']) self.outputTGS(tgs, oldSessionKey, sessionKey, user, SPN) except Exception as e: module.log('SPN Exception: {} - {}'.format( SPN, str(e)), level='error') else: module.log('No entries found!', level='info')
def test_kerberosLoginKeys(self): ldapConnection = ldap.LDAPConnection(self.url, self.baseDN) ldapConnection.kerberosLogin(self.username, '', self.domain, '', '', self.aesKey, None, None) self.dummySearch(ldapConnection)
def test_kerberosLogin(self): ldapConnection = ldap.LDAPConnection(self.url, self.baseDN) ldapConnection.kerberosLogin(self.username, self.password, self.domain) self.dummySearch(ldapConnection)