Exemple #1
0
    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()
Exemple #2
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
        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()
Exemple #3
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
        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()
Exemple #4
0
                    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()