def dummySearch(self, ldapConnection): # Let's do a search just to be sure it's working searchFilter = ldapasn1.Filter() searchFilter['present'] = ldapasn1.Present('servicePrincipalName') resp = ldapConnection.search(searchFilter=searchFilter, attributes=['servicePrincipalName', 'sAMAccountName', 'userPrincipalName', 'MemberOf', 'pwdLastSet', 'whenCreated']) for item in resp: print item.prettyPrint()
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): 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) # Building the following filter: # (&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))) # (servicePrincipalName=*) and0 = ldapasn1.Filter() and0['present'] = ldapasn1.Present('servicePrincipalName') # (UserAccountControl:1.2.840.113556.1.4.803:=512) and1 = ldapasn1.Filter() and1['extensibleMatch'] = ldapasn1.MatchingRuleAssertion() and1['extensibleMatch']['matchingRule'] = ldapasn1.MatchingRuleId( '1.2.840.113556.1.4.803') and1['extensibleMatch']['type'] = ldapasn1.TypeDescription( 'UserAccountControl') and1['extensibleMatch']['matchValue'] = ldapasn1.matchValueAssertion( UF_NORMAL_ACCOUNT) and1['extensibleMatch']['dnAttributes'] = False # !(UserAccountControl:1.2.840.113556.1.4.803:=2) and2 = ldapasn1.Not() and2['notFilter'] = ldapasn1.Filter() and2['notFilter']['extensibleMatch'] = ldapasn1.MatchingRuleAssertion() and2['notFilter']['extensibleMatch'][ 'matchingRule'] = ldapasn1.MatchingRuleId('1.2.840.113556.1.4.803') and2['notFilter']['extensibleMatch'][ 'type'] = ldapasn1.TypeDescription('UserAccountControl') and2['notFilter']['extensibleMatch'][ 'matchValue'] = ldapasn1.matchValueAssertion(UF_ACCOUNTDISABLE) and2['notFilter']['extensibleMatch']['dnAttributes'] = False searchFilter = ldapasn1.Filter() searchFilter['and'] = ldapasn1.And() searchFilter['and'][0] = and0 searchFilter['and'][1] = and1 # searchFilter['and'][2] = and2 # Exception here, setting verifyConstraints to False so pyasn1 doesn't warn about incompatible tags searchFilter['and'].setComponentByPosition(2, and2, verifyConstraints=False) resp = ldapConnection.search(searchFilter=searchFilter, attributes=[ 'servicePrincipalName', 'sAMAccountName', 'pwdLastSet', 'MemberOf', 'userAccountControl', 'lastLogon' ], sizeLimit=9999) 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'] == '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: logging.debug('Bypassing disabled account %s ' % sAMAccountName) else: for spn in SPNs: answers.append([ spn, sAMAccountName, memberOf, pwdLastSet, lastLogon ]) if len(answers) > 0: self.printTable(answers, header=[ "ServicePrincipalName", "Name", "MemberOf", "PasswordLastSet", "LastLogon" ]) 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()
ldapConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) else: raise # Building the following filter: # (&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))) # (servicePrincipalName=*) and0 = ldapasn1.Filter() and0['present'] = ldapasn1.Present('servicePrincipalName') # (UserAccountControl:1.2.840.113556.1.4.803:=512) and1 = ldapasn1.Filter() and1['extensibleMatch'] = ldapasn1.MatchingRuleAssertion() and1['extensibleMatch']['matchingRule'] = ldapasn1.MatchingRuleId( '1.2.840.113556.1.4.803') and1['extensibleMatch']['type'] = ldapasn1.TypeDescription( 'UserAccountControl') and1['extensibleMatch']['matchValue'] = ldapasn1.matchValueAssertion( UF_NORMAL_ACCOUNT) and1['extensibleMatch']['dnAttributes'] = False # !(UserAccountControl:1.2.840.113556.1.4.803:=2) and2 = ldapasn1.Not() and2['notFilter'] = ldapasn1.Filter()