Example #1
0
def _resumeDBMS():
    """
    Resume stored DBMS information from HashDB
    """

    value = hashDBRetrieve(HASHDB_KEYS.DBMS)

    if not value:
        if conf.offline:
            errMsg = "unable to continue in offline mode "
            errMsg += "because of lack of usable "
            errMsg += "session data"
            raise SqlmapNoneDataException(errMsg)
        else:
            return

    dbms = value.lower()
    dbmsVersion = [UNKNOWN_DBMS_VERSION]
    _ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
    _ = re.search(r"\A%s (.*)" % _, dbms, re.I)

    if _:
        dbms = _.group(1).lower()
        dbmsVersion = [_.group(2)]

    if conf.dbms:
        check = True
        for aliases, _, _, _ in DBMS_DICT.values():
            if conf.dbms.lower() in aliases and dbms not in aliases:
                check = False
                break

        if not check:
            message = "you provided '%s' as a back-end DBMS, " % conf.dbms
            message += "but from a past scan information on the target URL "
            message += "sqlmap assumes the back-end DBMS is '%s'. " % dbms
            message += "Do you really want to force the back-end "
            message += "DBMS value? [y/N] "

            if not readInput(message, default='N', boolean=True):
                conf.dbms = None
                Backend.setDbms(dbms)
                Backend.setVersionList(dbmsVersion)
    else:
        infoMsg = "resuming back-end DBMS '%s' " % dbms
        logger.info(infoMsg)

        Backend.setDbms(dbms)
        Backend.setVersionList(dbmsVersion)
Example #2
0
def _resumeDBMS():
    """
    Resume stored DBMS information from HashDB
    """

    value = hashDBRetrieve(HASHDB_KEYS.DBMS)

    if not value:
        return

    dbms = value.lower()
    dbmsVersion = [UNKNOWN_DBMS_VERSION]
    _ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
    _ = re.search("%s ([\d\.]+)" % _, dbms, re.I)

    if _:
        dbms = _.group(1).lower()
        dbmsVersion = [_.group(2)]

    if conf.dbms:
        check = True
        for aliases, _, _, _ in DBMS_DICT.values():
            if conf.dbms.lower() in aliases and dbms not in aliases:
                check = False
                break

        if not check:
            message = "you provided '%s' as a back-end DBMS, " % conf.dbms
            message += "but from a past scan information on the target URL "
            message += "sqlmap assumes the back-end DBMS is '%s'. " % dbms
            message += "Do you really want to force the back-end "
            message += "DBMS value? [y/N] "
            test = readInput(message, default="N")

            if not test or test[0] in ("n", "N"):
                conf.dbms = None
                Backend.setDbms(dbms)
                Backend.setVersionList(dbmsVersion)
    else:
        infoMsg = "resuming back-end DBMS '%s' " % dbms
        logger.info(infoMsg)

        Backend.setDbms(dbms)
        Backend.setVersionList(dbmsVersion)
Example #3
0
def _resumeDBMS():
    """
    Resume stored DBMS information from HashDB
    """

    value = hashDBRetrieve(HASHDB_KEYS.DBMS)

    if not value:
        return

    dbms = value.lower()
    dbmsVersion = [UNKNOWN_DBMS_VERSION]
    _ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
    _ = re.search("%s ([\d\.]+)" % _, dbms, re.I)

    if _:
        dbms = _.group(1).lower()
        dbmsVersion = [_.group(2)]

    if conf.dbms:
        check = True
        for aliases, _, _, _ in DBMS_DICT.values():
            if conf.dbms.lower() in aliases and dbms not in aliases:
                check = False
                break

        if not check:
            message = "you provided '%s' as a back-end DBMS, " % conf.dbms
            message += "but from a past scan information on the target URL "
            message += "sqlmap assumes the back-end DBMS is '%s'. " % dbms
            message += "Do you really want to force the back-end "
            message += "DBMS value? [y/N] "
            test = readInput(message, default="N")

            if not test or test[0] in ("n", "N"):
                conf.dbms = None
                Backend.setDbms(dbms)
                Backend.setVersionList(dbmsVersion)
    else:
        infoMsg = "resuming back-end DBMS '%s' " % dbms
        logger.info(infoMsg)

        Backend.setDbms(dbms)
        Backend.setVersionList(dbmsVersion)
Example #4
0
    def checkDbms(self):
        """
        References for fingerprint:

        * http://dev.mysql.com/doc/refman/5.0/en/news-5-0-x.html (up to 5.0.89)
        * http://dev.mysql.com/doc/refman/5.1/en/news-5-1-x.html (up to 5.1.42)
        * http://dev.mysql.com/doc/refman/5.4/en/news-5-4-x.html (up to 5.4.4)
        * http://dev.mysql.com/doc/refman/5.5/en/news-5-5-x.html (up to 5.5.0)
        * http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html (manual has been withdrawn)
        """

        if not conf.extensiveFp and (Backend.isDbmsWithin(MYSQL_ALIASES) \
           or conf.dbms in MYSQL_ALIASES) and Backend.getVersion() and \
           Backend.getVersion() != UNKNOWN_DBMS_VERSION:
            v = Backend.getVersion().replace(">", "")
            v = v.replace("=", "")
            v = v.replace(" ", "")

            Backend.setVersion(v)

            setDbms("%s %s" % (DBMS.MYSQL, Backend.getVersion()))

            if Backend.isVersionGreaterOrEqualThan("5"):
                kb.data.has_information_schema = True

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.MYSQL
        logger.info(infoMsg)

        result = inject.checkBooleanExpression("QUARTER(NULL) IS NULL")

        if result:
            infoMsg = "confirming %s" % DBMS.MYSQL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression("USER() LIKE USER()")

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
                logger.warn(warnMsg)

                return False

            # reading information_schema on some platforms is causing annoying timeout exits
            # Reference: http://bugs.mysql.com/bug.php?id=15855

            # Determine if it is MySQL >= 5.0.0
            if inject.checkBooleanExpression(
                    "ISNULL(TIMESTAMPADD(MINUTE,[RANDNUM],0))"):
                kb.data.has_information_schema = True
                Backend.setVersion(">= 5.0.0")
                setDbms("%s 5" % DBMS.MYSQL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                infoMsg = "actively fingerprinting %s" % DBMS.MYSQL
                logger.info(infoMsg)

                # Check if it is MySQL >= 5.5.0
                if inject.checkBooleanExpression("TO_SECONDS(950501)>0"):
                    Backend.setVersion(">= 5.5.0")

                # Check if it is MySQL >= 5.1.2 and < 5.5.0
                elif inject.checkBooleanExpression(
                        "@@table_open_cache=@@table_open_cache"):
                    if inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.GLOBAL_STATUS LIMIT 0, 1)"
                    ):
                        Backend.setVersionList([">= 5.1.12", "< 5.5.0"])
                    elif inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PROCESSLIST LIMIT 0, 1)"
                    ):
                        Backend.setVersionList([">= 5.1.7", "< 5.1.12"])
                    elif inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PARTITIONS LIMIT 0, 1)"
                    ):
                        Backend.setVersion("= 5.1.6")
                    elif inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PLUGINS LIMIT 0, 1)"
                    ):
                        Backend.setVersionList([">= 5.1.5", "< 5.1.6"])
                    else:
                        Backend.setVersionList([">= 5.1.2", "< 5.1.5"])

                # Check if it is MySQL >= 5.0.0 and < 5.1.2
                elif inject.checkBooleanExpression("@@hostname=@@hostname"):
                    Backend.setVersionList([">= 5.0.38", "< 5.1.2"])
                elif inject.checkBooleanExpression(
                        "@@character_set_filesystem=@@character_set_filesystem"
                ):
                    Backend.setVersionList([">= 5.0.19", "< 5.0.38"])
                elif not inject.checkBooleanExpression(
                        "[RANDNUM]=(SELECT [RANDNUM] FROM DUAL WHERE [RANDNUM1]!=[RANDNUM2])"
                ):
                    Backend.setVersionList([">= 5.0.11", "< 5.0.19"])
                elif inject.checkBooleanExpression(
                        "@@div_precision_increment=@@div_precision_increment"):
                    Backend.setVersionList([">= 5.0.6", "< 5.0.11"])
                elif inject.checkBooleanExpression(
                        "@@automatic_sp_privileges=@@automatic_sp_privileges"):
                    Backend.setVersionList([">= 5.0.3", "< 5.0.6"])
                else:
                    Backend.setVersionList([">= 5.0.0", "< 5.0.3"])

            elif inject.checkBooleanExpression("DATABASE() LIKE SCHEMA()"):
                Backend.setVersion(">= 5.0.2")
                setDbms("%s 5" % DBMS.MYSQL)
                self.getBanner()

            elif inject.checkBooleanExpression(
                    "STRCMP(LOWER(CURRENT_USER()), UPPER(CURRENT_USER()))=0"):
                Backend.setVersion("< 5.0.0")
                setDbms("%s 4" % DBMS.MYSQL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                # Check which version of MySQL < 5.0.0 it is
                if inject.checkBooleanExpression(
                        "3=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.11", "< 5.0.0"])
                elif inject.checkBooleanExpression(
                        "2=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.1", "< 4.1.11"])
                elif inject.checkBooleanExpression(
                        "CURRENT_USER()=CURRENT_USER()"):
                    Backend.setVersionList([">= 4.0.6", "< 4.1.1"])

                    if inject.checkBooleanExpression(
                            "'utf8'=(SELECT CHARSET(CURRENT_USER()))"):
                        Backend.setVersion("= 4.1.0")
                    else:
                        Backend.setVersionList([">= 4.0.6", "< 4.1.0"])
                else:
                    Backend.setVersionList([">= 4.0.0", "< 4.0.6"])
            else:
                Backend.setVersion("< 4.0.0")
                setDbms("%s 3" % DBMS.MYSQL)
                self.getBanner()

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
            logger.warn(warnMsg)

            return False
Example #5
0
    def checkDbms(self):
        """
        References for fingerprint:

        * https://www.postgresql.org/docs/current/static/release.html
        """

        if not conf.extensiveFp and Backend.isDbmsWithin(PGSQL_ALIASES):
            setDbms(DBMS.PGSQL)

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.PGSQL
        logger.info(infoMsg)

        # NOTE: Vertica works too without the CONVERT_TO()
        result = inject.checkBooleanExpression(
            "CONVERT_TO('[RANDSTR]', QUOTE_IDENT(NULL)) IS NULL")

        if result:
            infoMsg = "confirming %s" % DBMS.PGSQL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression(
                "COALESCE([RANDNUM], NULL)=[RANDNUM]")

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
                logger.warn(warnMsg)

                return False

            setDbms(DBMS.PGSQL)

            self.getBanner()

            if not conf.extensiveFp:
                return True

            infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
            logger.info(infoMsg)

            if inject.checkBooleanExpression("SINH(0)=0"):
                Backend.setVersion(">= 12.0")
            elif inject.checkBooleanExpression("SHA256(NULL) IS NULL"):
                Backend.setVersion(">= 11.0")
            elif inject.checkBooleanExpression("XMLTABLE(NULL) IS NULL"):
                Backend.setVersionList([">= 10.0", "< 11.0"])
            elif inject.checkBooleanExpression("SIND(0)=0"):
                Backend.setVersionList([">= 9.6.0", "< 10.0"])
            elif inject.checkBooleanExpression("TO_JSONB(1) IS NOT NULL"):
                Backend.setVersionList([">= 9.5.0", "< 9.6.0"])
            elif inject.checkBooleanExpression("JSON_TYPEOF(NULL) IS NULL"):
                Backend.setVersionList([">= 9.4.0", "< 9.5.0"])
            elif inject.checkBooleanExpression(
                    "ARRAY_REPLACE(NULL,1,1) IS NULL"):
                Backend.setVersionList([">= 9.3.0", "< 9.4.0"])
            elif inject.checkBooleanExpression("ROW_TO_JSON(NULL) IS NULL"):
                Backend.setVersionList([">= 9.2.0", "< 9.3.0"])
            elif inject.checkBooleanExpression("REVERSE('sqlmap')='pamlqs'"):
                Backend.setVersionList([">= 9.1.0", "< 9.2.0"])
            elif inject.checkBooleanExpression("LENGTH(TO_CHAR(1,'EEEE'))>0"):
                Backend.setVersionList([">= 9.0.0", "< 9.1.0"])
            elif inject.checkBooleanExpression("2=(SELECT DIV(6,3))"):
                Backend.setVersionList([">= 8.4.0", "< 9.0.0"])
            elif inject.checkBooleanExpression(
                    "EXTRACT(ISODOW FROM CURRENT_TIMESTAMP)<8"):
                Backend.setVersionList([">= 8.3.0", "< 8.4.0"])
            elif inject.checkBooleanExpression(
                    "ISFINITE(TRANSACTION_TIMESTAMP())"):
                Backend.setVersionList([">= 8.2.0", "< 8.3.0"])
            elif inject.checkBooleanExpression("9=(SELECT GREATEST(5,9,1))"):
                Backend.setVersionList([">= 8.1.0", "< 8.2.0"])
            elif inject.checkBooleanExpression(
                    "3=(SELECT WIDTH_BUCKET(5.35,0.024,10.06,5))"):
                Backend.setVersionList([">= 8.0.0", "< 8.1.0"])
            elif inject.checkBooleanExpression(
                    "'d'=(SELECT SUBSTR(MD5('sqlmap'),1,1))"):
                Backend.setVersionList([">= 7.4.0", "< 8.0.0"])
            elif inject.checkBooleanExpression(
                    "'p'=(SELECT SUBSTR(CURRENT_SCHEMA(),1,1))"):
                Backend.setVersionList([">= 7.3.0", "< 7.4.0"])
            elif inject.checkBooleanExpression("8=(SELECT BIT_LENGTH(1))"):
                Backend.setVersionList([">= 7.2.0", "< 7.3.0"])
            elif inject.checkBooleanExpression(
                    "'a'=(SELECT SUBSTR(QUOTE_LITERAL('a'),2,1))"):
                Backend.setVersionList([">= 7.1.0", "< 7.2.0"])
            elif inject.checkBooleanExpression("8=(SELECT POW(2,3))"):
                Backend.setVersionList([">= 7.0.0", "< 7.1.0"])
            elif inject.checkBooleanExpression("'a'=(SELECT MAX('a'))"):
                Backend.setVersionList([">= 6.5.0", "< 6.5.3"])
            elif inject.checkBooleanExpression("VERSION()=VERSION()"):
                Backend.setVersionList([">= 6.4.0", "< 6.5.0"])
            elif inject.checkBooleanExpression(
                    "2=(SELECT SUBSTR(CURRENT_DATE,1,1))"):
                Backend.setVersionList([">= 6.3.0", "< 6.4.0"])
            elif inject.checkBooleanExpression(
                    "'s'=(SELECT SUBSTRING('sqlmap',1,1))"):
                Backend.setVersionList([">= 6.2.0", "< 6.3.0"])
            else:
                Backend.setVersion("< 6.2.0")

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
            logger.warn(warnMsg)

            return False
Example #6
0
    def checkDbms(self):
        """
        References for fingerprint:
        DATABASE_VERSION()
        version 2.2.6 added two-arg REPLACE functio REPLACE('a','a') compared to REPLACE('a','a','d')
        version 2.2.5 added SYSTIMESTAMP function
        version 2.2.3 added REGEXPR_SUBSTRING and REGEXPR_SUBSTRING_ARRAY functions
        version 2.2.0 added support for ROWNUM() function
        version 2.1.0 added MEDIAN aggregate function
        version < 2.0.1 added support for datetime ROUND and TRUNC functions
        version 2.0.0 added VALUES support
        version 1.8.0.4 Added org.hsqldbdb.Library function, getDatabaseFullProductVersion to return the
                        full version string, including the 4th digit (e.g 1.8.0.4).
        version 1.7.2 CASE statements added and INFORMATION_SCHEMA

        """

        if not conf.extensiveFp and Backend.isDbmsWithin(HSQLDB_ALIASES):
            setDbms("%s %s" % (DBMS.HSQLDB, Backend.getVersion()))

            if Backend.isVersionGreaterOrEqualThan("1.7.2"):
                kb.data.has_information_schema = True

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.HSQLDB
        logger.info(infoMsg)

        result = inject.checkBooleanExpression("CASEWHEN(1=1,1,0)=1")

        if result:
            infoMsg = "confirming %s" % DBMS.HSQLDB
            logger.info(infoMsg)

            result = inject.checkBooleanExpression("ROUNDMAGIC(PI())>=3")

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.HSQLDB
                logger.warn(warnMsg)

                return False
            else:
                result = inject.checkBooleanExpression("ZERO() IS 0")   # Note: check for H2 DBMS (sharing majority of same functions)
                if result:
                    warnMsg = "the back-end DBMS is not %s" % DBMS.HSQLDB
                    logger.warn(warnMsg)

                    return False

                kb.data.has_information_schema = True
                Backend.setVersion(">= 1.7.2")
                setDbms("%s 1.7.2" % DBMS.HSQLDB)

                banner = self.getBanner()
                if banner:
                    Backend.setVersion("= %s" % banner)
                else:
                    if inject.checkBooleanExpression("(SELECT [RANDNUM] FROM (VALUES(0)))=[RANDNUM]"):
                        Backend.setVersionList([">= 2.0.0", "< 2.3.0"])
                    else:
                        banner = unArrayizeValue(inject.getValue("\"org.hsqldbdb.Library.getDatabaseFullProductVersion\"()", safeCharEncode=True))
                        if banner:
                            Backend.setVersion("= %s" % banner)
                        else:
                            Backend.setVersionList([">= 1.7.2", "< 1.8.0"])

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.HSQLDB
            logger.warn(warnMsg)

            dbgMsg = "...or version is < 1.7.2"
            logger.debug(dbgMsg)

            return False
Example #7
0
    def checkDbms(self):
        """
        References for fingerprint:
        DATABASE_VERSION()
        version 2.2.6 added two-arg REPLACE functio REPLACE('a','a') compared to REPLACE('a','a','d')
        version 2.2.5 added SYSTIMESTAMP function
        version 2.2.3 added REGEXPR_SUBSTRING and REGEXPR_SUBSTRING_ARRAY functions
        version 2.2.0 added support for ROWNUM() function
        version 2.1.0 added MEDIAN aggregate function
        version < 2.0.1 added support for datetime ROUND and TRUNC functions
        version 2.0.0 added VALUES support
        version 1.8.0.4 Added org.hsqldbdb.Library function, getDatabaseFullProductVersion to return the
                        full version string, including the 4th digit (e.g 1.8.0.4).
        version 1.7.2 CASE statements added and INFORMATION_SCHEMA

        """

        if not conf.extensiveFp and Backend.isDbmsWithin(HSQLDB_ALIASES):
            setDbms("%s %s" % (DBMS.HSQLDB, Backend.getVersion()))

            if Backend.isVersionGreaterOrEqualThan("1.7.2"):
                kb.data.has_information_schema = True

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.HSQLDB
        logger.info(infoMsg)

        result = inject.checkBooleanExpression("CASEWHEN(1=1,1,0)=1")

        if result:
            infoMsg = "confirming %s" % DBMS.HSQLDB
            logger.info(infoMsg)

            result = inject.checkBooleanExpression("ROUNDMAGIC(PI())>=3")

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.HSQLDB
                logger.warn(warnMsg)

                return False
            else:
                kb.data.has_information_schema = True
                Backend.setVersion(">= 1.7.2")
                setDbms("%s 1.7.2" % DBMS.HSQLDB)

                banner = self.getBanner()
                if banner:
                    Backend.setVersion("= %s" % banner)
                else:
                    if inject.checkBooleanExpression("(SELECT [RANDNUM] FROM (VALUES(0)))=[RANDNUM]"):
                        Backend.setVersionList([">= 2.0.0", "< 2.3.0"])
                    else:
                        banner = unArrayizeValue(inject.getValue("\"org.hsqldbdb.Library.getDatabaseFullProductVersion\"()", safeCharEncode=True))
                        if banner:
                            Backend.setVersion("= %s" % banner)
                        else:
                            Backend.setVersionList([">= 1.7.2", "< 1.8.0"])

            return True
        else:
            warnMsg = "the back-end DBMS is not %s or version is < 1.7.2" % DBMS.HSQLDB
            logger.warn(warnMsg)

            return False
Example #8
0
    def checkDbms(self):
        """
        References for fingerprint:

        * http://www.postgresql.org/docs/9.1/interactive/release.html (up to 9.1.3)
        """

        if not conf.extensiveFp and (Backend.isDbmsWithin(PGSQL_ALIASES)
                                     or conf.dbms in PGSQL_ALIASES):
            setDbms(DBMS.PGSQL)

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.PGSQL
        logger.info(infoMsg)

        randInt = getUnicode(randomInt(1))
        result = inject.checkBooleanExpression("%s::int=%s" %
                                               (randInt, randInt))

        if result:
            infoMsg = "confirming %s" % DBMS.PGSQL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression("COALESCE(%s, NULL)=%s" %
                                                   (randInt, randInt))

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
                logger.warn(warnMsg)

                return False

            setDbms(DBMS.PGSQL)

            self.getBanner()

            if not conf.extensiveFp:
                return True

            infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
            logger.info(infoMsg)

            if inject.checkBooleanExpression("REVERSE('sqlmap')='pamlqs'"):
                Backend.setVersion(">= 9.1.0")
            elif inject.checkBooleanExpression("LENGTH(TO_CHAR(1, 'EEEE'))>0"):
                Backend.setVersionList([">= 9.0.0", "< 9.1.0"])
            elif inject.checkBooleanExpression("2=(SELECT DIV(6, 3))"):
                Backend.setVersionList([">= 8.4.0", "< 9.0.0"])
            elif inject.checkBooleanExpression(
                    "EXTRACT(ISODOW FROM CURRENT_TIMESTAMP)<8"):
                Backend.setVersionList([">= 8.3.0", "< 8.4.0"])
            elif inject.checkBooleanExpression(
                    "ISFINITE(TRANSACTION_TIMESTAMP())"):
                Backend.setVersionList([">= 8.2.0", "< 8.3.0"])
            elif inject.checkBooleanExpression("9=(SELECT GREATEST(5, 9, 1))"):
                Backend.setVersionList([">= 8.1.0", "< 8.2.0"])
            elif inject.checkBooleanExpression(
                    "3=(SELECT WIDTH_BUCKET(5.35, 0.024, 10.06, 5))"):
                Backend.setVersionList([">= 8.0.0", "< 8.1.0"])
            elif inject.checkBooleanExpression(
                    "'d'=(SELECT SUBSTR(MD5('sqlmap'), 1, 1))"):
                Backend.setVersionList([">= 7.4.0", "< 8.0.0"])
            elif inject.checkBooleanExpression(
                    "'p'=(SELECT SUBSTR(CURRENT_SCHEMA(), 1, 1))"):
                Backend.setVersionList([">= 7.3.0", "< 7.4.0"])
            elif inject.checkBooleanExpression("8=(SELECT BIT_LENGTH(1))"):
                Backend.setVersionList([">= 7.2.0", "< 7.3.0"])
            elif inject.checkBooleanExpression(
                    "'a'=(SELECT SUBSTR(QUOTE_LITERAL('a'), 2, 1))"):
                Backend.setVersionList([">= 7.1.0", "< 7.2.0"])
            elif inject.checkBooleanExpression("8=(SELECT POW(2, 3))"):
                Backend.setVersionList([">= 7.0.0", "< 7.1.0"])
            elif inject.checkBooleanExpression("'a'=(SELECT MAX('a'))"):
                Backend.setVersionList([">= 6.5.0", "< 6.5.3"])
            elif inject.checkBooleanExpression("VERSION()=VERSION()"):
                Backend.setVersionList([">= 6.4.0", "< 6.5.0"])
            elif inject.checkBooleanExpression(
                    "2=(SELECT SUBSTR(CURRENT_DATE, 1, 1))"):
                Backend.setVersionList([">= 6.3.0", "< 6.4.0"])
            elif inject.checkBooleanExpression(
                    "'s'=(SELECT SUBSTRING('sqlmap', 1, 1))"):
                Backend.setVersionList([">= 6.2.0", "< 6.3.0"])
            else:
                Backend.setVersion("< 6.2.0")

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
            logger.warn(warnMsg)

            return False
Example #9
0
    def checkDbms(self):
        """
        References for fingerprint:

        * http://dev.mysql.com/doc/refman/5.0/en/news-5-0-x.html (up to 5.0.89)
        * http://dev.mysql.com/doc/refman/5.1/en/news-5-1-x.html (up to 5.1.42)
        * http://dev.mysql.com/doc/refman/5.4/en/news-5-4-x.html (up to 5.4.4)
        * http://dev.mysql.com/doc/refman/5.5/en/news-5-5-x.html (up to 5.5.0)
        * http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html (manual has been withdrawn)
        """

        if not conf.extensiveFp and (Backend.isDbmsWithin(MYSQL_ALIASES) \
           or conf.dbms in MYSQL_ALIASES) and Backend.getVersion() and \
           Backend.getVersion() != UNKNOWN_DBMS_VERSION:
            v = Backend.getVersion().replace(">", "")
            v = v.replace("=", "")
            v = v.replace(" ", "")

            Backend.setVersion(v)

            setDbms("%s %s" % (DBMS.MYSQL, Backend.getVersion()))

            if Backend.isVersionGreaterOrEqualThan("5"):
                kb.data.has_information_schema = True

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.MYSQL
        logger.info(infoMsg)

        randInt = getUnicode(randomInt(1))
        result = inject.checkBooleanExpression("CONNECTION_ID()=CONNECTION_ID()")

        if result:
            infoMsg = "confirming %s" % DBMS.MYSQL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression("USER()=USER()")

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
                logger.warn(warnMsg)

                return False

            # reading information_schema on some platforms is causing annoying timeout exits
            # Reference: http://bugs.mysql.com/bug.php?id=15855

            # Determine if it is MySQL >= 5.0.0
            if inject.checkBooleanExpression("ISNULL(TIMESTAMPADD(MINUTE,%s,%s))" % (randInt, randInt)):
                kb.data.has_information_schema = True
                Backend.setVersion(">= 5.0.0")
                setDbms("%s 5" % DBMS.MYSQL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                infoMsg = "actively fingerprinting %s" % DBMS.MYSQL
                logger.info(infoMsg)

                # Check if it is MySQL >= 5.5.0
                if inject.checkBooleanExpression("TO_SECONDS(950501)>0"):
                    Backend.setVersion(">= 5.5.0")

                # Check if it is MySQL >= 5.1.2 and < 5.5.0
                elif inject.checkBooleanExpression("@@table_open_cache=@@table_open_cache"):
                    if inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.GLOBAL_STATUS LIMIT 0, 1)" % (randInt, randInt)):
                        Backend.setVersionList([">= 5.1.12", "< 5.5.0"])
                    elif inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1)" % (randInt,randInt)):
                        Backend.setVersionList([">= 5.1.7", "< 5.1.12"])
                    elif inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1)" % (randInt, randInt)):
                        Backend.setVersion("= 5.1.6")
                    elif inject.checkBooleanExpression("%s=(SELECT %s FROM information_schema.PLUGINS LIMIT 0, 1)" % (randInt, randInt)):
                        Backend.setVersionList([">= 5.1.5", "< 5.1.6"])
                    else:
                        Backend.setVersionList([">= 5.1.2", "< 5.1.5"])

                # Check if it is MySQL >= 5.0.0 and < 5.1.2
                elif inject.checkBooleanExpression("@@hostname=@@hostname"):
                    Backend.setVersionList([">= 5.0.38", "< 5.1.2"])
                elif inject.checkBooleanExpression("@@character_set_filesystem=@@character_set_filesystem"):
                    Backend.setVersionList([">= 5.0.19", "< 5.0.38"])
                elif not inject.checkBooleanExpression("%s=(SELECT %s FROM DUAL WHERE %s!=%s)" % (randInt, randInt, randInt, randInt)):
                    Backend.setVersionList([">= 5.0.11", "< 5.0.19"])
                elif inject.checkBooleanExpression("@@div_precision_increment=@@div_precision_increment"):
                    Backend.setVersionList([">= 5.0.6", "< 5.0.11"])
                elif inject.checkBooleanExpression("@@automatic_sp_privileges=@@automatic_sp_privileges"):
                    Backend.setVersionList([">= 5.0.3", "< 5.0.6"])
                else:
                    Backend.setVersionList([">= 5.0.0", "< 5.0.3"])

            # For cases when information_schema is missing
            elif inject.checkBooleanExpression("DATABASE() LIKE SCHEMA()"):
                Backend.setVersion(">= 5.0.2")
                setDbms("%s 5" % DBMS.MYSQL)
                self.getBanner()

            elif inject.checkBooleanExpression("STRCMP(LOWER(CURRENT_USER()), UPPER(CURRENT_USER()))=0"):
                Backend.setVersion("< 5.0.0")
                setDbms("%s 4" % DBMS.MYSQL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                # Check which version of MySQL < 5.0.0 it is
                if inject.checkBooleanExpression("3=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.11", "< 5.0.0"])
                elif inject.checkBooleanExpression("2=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.1", "< 4.1.11"])
                elif inject.checkBooleanExpression("CURRENT_USER()=CURRENT_USER()"):
                    Backend.setVersionList([">= 4.0.6", "< 4.1.1"])

                    if inject.checkBooleanExpression("'utf8'=(SELECT CHARSET(CURRENT_USER()))"):
                        Backend.setVersion("= 4.1.0")
                    else:
                        Backend.setVersionList([">= 4.0.6", "< 4.1.0"])
                else:
                    Backend.setVersionList([">= 4.0.0", "< 4.0.6"])
            else:
                Backend.setVersion("< 4.0.0")
                setDbms("%s 3" % DBMS.MYSQL)
                self.getBanner()

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
            logger.warn(warnMsg)

            return False
Example #10
0
    def checkDbms(self):
        """
        References for fingerprint:

        * https://www.postgresql.org/docs/current/static/release.html
        """

        if not conf.extensiveFp and Backend.isDbmsWithin(PGSQL_ALIASES):
            setDbms(DBMS.PGSQL)

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.PGSQL
        logger.info(infoMsg)

        result = inject.checkBooleanExpression("QUOTE_IDENT(NULL) IS NULL")

        if result:
            infoMsg = "confirming %s" % DBMS.PGSQL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression("COALESCE([RANDNUM], NULL)=[RANDNUM]")

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
                logger.warn(warnMsg)

                return False

            setDbms(DBMS.PGSQL)

            self.getBanner()

            if not conf.extensiveFp:
                return True

            infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
            logger.info(infoMsg)

            if inject.checkBooleanExpression("SHA256(NULL) IS NULL"):
                Backend.setVersion(">= 11.0")
            elif inject.checkBooleanExpression("XMLTABLE(NULL) IS NULL"):
                Backend.setVersionList([">= 10.0", "< 11.0"])
            elif inject.checkBooleanExpression("SIND(0)=0"):
                Backend.setVersionList([">= 9.6.0", "< 10.0"])
            elif inject.checkBooleanExpression("TO_JSONB(1) IS NOT NULL"):
                Backend.setVersionList([">= 9.5.0", "< 9.6.0"])
            elif inject.checkBooleanExpression("JSON_TYPEOF(NULL) IS NULL"):
                Backend.setVersionList([">= 9.4.0", "< 9.5.0"])
            elif inject.checkBooleanExpression("ARRAY_REPLACE(NULL,1,1) IS NULL"):
                Backend.setVersionList([">= 9.3.0", "< 9.4.0"])
            elif inject.checkBooleanExpression("ROW_TO_JSON(NULL) IS NULL"):
                Backend.setVersionList([">= 9.2.0", "< 9.3.0"])
            elif inject.checkBooleanExpression("REVERSE('sqlmap')='pamlqs'"):
                Backend.setVersionList([">= 9.1.0", "< 9.2.0"])
            elif inject.checkBooleanExpression("LENGTH(TO_CHAR(1,'EEEE'))>0"):
                Backend.setVersionList([">= 9.0.0", "< 9.1.0"])
            elif inject.checkBooleanExpression("2=(SELECT DIV(6,3))"):
                Backend.setVersionList([">= 8.4.0", "< 9.0.0"])
            elif inject.checkBooleanExpression("EXTRACT(ISODOW FROM CURRENT_TIMESTAMP)<8"):
                Backend.setVersionList([">= 8.3.0", "< 8.4.0"])
            elif inject.checkBooleanExpression("ISFINITE(TRANSACTION_TIMESTAMP())"):
                Backend.setVersionList([">= 8.2.0", "< 8.3.0"])
            elif inject.checkBooleanExpression("9=(SELECT GREATEST(5,9,1))"):
                Backend.setVersionList([">= 8.1.0", "< 8.2.0"])
            elif inject.checkBooleanExpression("3=(SELECT WIDTH_BUCKET(5.35,0.024,10.06,5))"):
                Backend.setVersionList([">= 8.0.0", "< 8.1.0"])
            elif inject.checkBooleanExpression("'d'=(SELECT SUBSTR(MD5('sqlmap'),1,1))"):
                Backend.setVersionList([">= 7.4.0", "< 8.0.0"])
            elif inject.checkBooleanExpression("'p'=(SELECT SUBSTR(CURRENT_SCHEMA(),1,1))"):
                Backend.setVersionList([">= 7.3.0", "< 7.4.0"])
            elif inject.checkBooleanExpression("8=(SELECT BIT_LENGTH(1))"):
                Backend.setVersionList([">= 7.2.0", "< 7.3.0"])
            elif inject.checkBooleanExpression("'a'=(SELECT SUBSTR(QUOTE_LITERAL('a'),2,1))"):
                Backend.setVersionList([">= 7.1.0", "< 7.2.0"])
            elif inject.checkBooleanExpression("8=(SELECT POW(2,3))"):
                Backend.setVersionList([">= 7.0.0", "< 7.1.0"])
            elif inject.checkBooleanExpression("'a'=(SELECT MAX('a'))"):
                Backend.setVersionList([">= 6.5.0", "< 6.5.3"])
            elif inject.checkBooleanExpression("VERSION()=VERSION()"):
                Backend.setVersionList([">= 6.4.0", "< 6.5.0"])
            elif inject.checkBooleanExpression("2=(SELECT SUBSTR(CURRENT_DATE,1,1))"):
                Backend.setVersionList([">= 6.3.0", "< 6.4.0"])
            elif inject.checkBooleanExpression("'s'=(SELECT SUBSTRING('sqlmap',1,1))"):
                Backend.setVersionList([">= 6.2.0", "< 6.3.0"])
            else:
                Backend.setVersion("< 6.2.0")

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
            logger.warn(warnMsg)

            return False
Example #11
0
    def checkDbms(self):
        """
        References for fingerprint:

        * http://www.postgresql.org/docs/9.1/interactive/release.html (up to 9.1.3)
        """

        if not conf.extensiveFp and (Backend.isDbmsWithin(PGSQL_ALIASES)
                                     or conf.dbms in PGSQL_ALIASES):
            setDbms(DBMS.PGSQL)

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.PGSQL
        logger.info(infoMsg)

        randInt = getUnicode(randomInt(1))
        result = inject.checkBooleanExpression(
            "%s::int=%s" % (randInt, randInt))

        if result:
            infoMsg = "confirming %s" % DBMS.PGSQL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression(
                "COALESCE(%s, NULL)=%s" % (randInt, randInt))

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
                logger.warn(warnMsg)

                return False

            setDbms(DBMS.PGSQL)

            self.getBanner()

            if not conf.extensiveFp:
                return True

            infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
            logger.info(infoMsg)

            if inject.checkBooleanExpression("REVERSE('sqlmap')='pamlqs'"):
                Backend.setVersion(">= 9.1.0")
            elif inject.checkBooleanExpression("LENGTH(TO_CHAR(1, 'EEEE'))>0"):
                Backend.setVersionList([">= 9.0.0", "< 9.1.0"])
            elif inject.checkBooleanExpression("2=(SELECT DIV(6, 3))"):
                Backend.setVersionList([">= 8.4.0", "< 9.0.0"])
            elif inject.checkBooleanExpression(
                    "EXTRACT(ISODOW FROM CURRENT_TIMESTAMP)<8"):
                Backend.setVersionList([">= 8.3.0", "< 8.4.0"])
            elif inject.checkBooleanExpression(
                    "ISFINITE(TRANSACTION_TIMESTAMP())"):
                Backend.setVersionList([">= 8.2.0", "< 8.3.0"])
            elif inject.checkBooleanExpression("9=(SELECT GREATEST(5, 9, 1))"):
                Backend.setVersionList([">= 8.1.0", "< 8.2.0"])
            elif inject.checkBooleanExpression(
                    "3=(SELECT WIDTH_BUCKET(5.35, 0.024, 10.06, 5))"):
                Backend.setVersionList([">= 8.0.0", "< 8.1.0"])
            elif inject.checkBooleanExpression(
                    "'d'=(SELECT SUBSTR(MD5('sqlmap'), 1, 1))"):
                Backend.setVersionList([">= 7.4.0", "< 8.0.0"])
            elif inject.checkBooleanExpression(
                    "'p'=(SELECT SUBSTR(CURRENT_SCHEMA(), 1, 1))"):
                Backend.setVersionList([">= 7.3.0", "< 7.4.0"])
            elif inject.checkBooleanExpression("8=(SELECT BIT_LENGTH(1))"):
                Backend.setVersionList([">= 7.2.0", "< 7.3.0"])
            elif inject.checkBooleanExpression(
                    "'a'=(SELECT SUBSTR(QUOTE_LITERAL('a'), 2, 1))"):
                Backend.setVersionList([">= 7.1.0", "< 7.2.0"])
            elif inject.checkBooleanExpression("8=(SELECT POW(2, 3))"):
                Backend.setVersionList([">= 7.0.0", "< 7.1.0"])
            elif inject.checkBooleanExpression("'a'=(SELECT MAX('a'))"):
                Backend.setVersionList([">= 6.5.0", "< 6.5.3"])
            elif inject.checkBooleanExpression("VERSION()=VERSION()"):
                Backend.setVersionList([">= 6.4.0", "< 6.5.0"])
            elif inject.checkBooleanExpression(
                    "2=(SELECT SUBSTR(CURRENT_DATE, 1, 1))"):
                Backend.setVersionList([">= 6.3.0", "< 6.4.0"])
            elif inject.checkBooleanExpression(
                    "'s'=(SELECT SUBSTRING('sqlmap', 1, 1))"):
                Backend.setVersionList([">= 6.2.0", "< 6.3.0"])
            else:
                Backend.setVersion("< 6.2.0")

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.PGSQL
            logger.warn(warnMsg)

            return False
Example #12
0
    def checkDbms(self):
        """
        References for fingerprint:

        * http://dev.mysql.com/doc/refman/5.0/en/news-5-0-x.html (up to 5.0.89)
        * http://dev.mysql.com/doc/refman/5.1/en/news-5-1-x.html (up to 5.1.42)
        * http://dev.mysql.com/doc/refman/5.4/en/news-5-4-x.html (up to 5.4.4)
        * http://dev.mysql.com/doc/refman/5.5/en/news-5-5-x.html (up to 5.5.0)
        * http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html (manual has been withdrawn)
        """

        if not conf.extensiveFp and Backend.isDbmsWithin(SHELL_ALIASES):
            setDbms("%s %s" % (DBMS.SHELL, Backend.getVersion()))

            if Backend.isVersionGreaterOrEqualThan("5"):
                kb.data.has_information_schema = True

            self.getBanner()

            return True

        infoMsg = "testing %s command injection" % DBMS.SHELL
        logger.info(infoMsg)

        result = inject.checkBooleanExpression(
            '$(expr substr "$(id)" 1 1) = "u"')

        if result:
            infoMsg = "confirming %s command injection" % DBMS.SHELL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression(
                '$(expr substr "$(pwd)" 1 1) = "/"')

            if not result:
                # Note: MemSQL doesn't support SESSION_USER()
                result = inject.checkBooleanExpression(
                    "GEOGRAPHY_AREA(NULL) IS NULL")

                if result:
                    hashDBWrite(HASHDB_KEYS.DBMS_FORK, FORK.MEMSQL)

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.SHELL
                logger.warn(warnMsg)

                return False

            # reading information_schema on some platforms is causing annoying timeout exits
            # Reference: http://bugs.mysql.com/bug.python?id=15855

            # Determine if it is MySQL >= 8.0.0
            if inject.checkBooleanExpression(
                    "version_compare(pythonversion(), \"7.0\") >= 0"):
                kb.data.has_information_schema = True
                Backend.setVersion(">= 7.0")
                setDbms("%s 7" % DBMS.SHELL)
                self.getBanner()

            # Determine if it is MySQL >= 5.0.0
            elif inject.checkBooleanExpression(
                    "ISNULL(TIMESTAMPADD(MINUTE,[RANDNUM],NULL))"):
                kb.data.has_information_schema = True
                Backend.setVersion(">= 5.0.0")
                setDbms("%s 5" % DBMS.SHELL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                infoMsg = "actively fingerprinting %s" % DBMS.SHELL
                logger.info(infoMsg)

                # Check if it is MySQL >= 5.7
                if inject.checkBooleanExpression("ISNULL(JSON_QUOTE(NULL))"):
                    Backend.setVersion(">= 5.7")

                # Check if it is MySQL >= 5.6
                elif inject.checkBooleanExpression(
                        "ISNULL(VALIDATE_PASSWORD_STRENGTH(NULL))"):
                    Backend.setVersion(">= 5.6")

                # Check if it is MySQL >= 5.5
                elif inject.checkBooleanExpression("TO_SECONDS(950501)>0"):
                    Backend.setVersion(">= 5.5")

                # Check if it is MySQL >= 5.1.2 and < 5.5.0
                elif inject.checkBooleanExpression(
                        "@@table_open_cache=@@table_open_cache"):
                    if inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.GLOBAL_STATUS LIMIT 0, 1)"
                    ):
                        Backend.setVersionList([">= 5.1.12", "< 5.5.0"])
                    elif inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PROCESSLIST LIMIT 0, 1)"
                    ):
                        Backend.setVersionList([">= 5.1.7", "< 5.1.12"])
                    elif inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PARTITIONS LIMIT 0, 1)"
                    ):
                        Backend.setVersion("= 5.1.6")
                    elif inject.checkBooleanExpression(
                            "[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PLUGINS LIMIT 0, 1)"
                    ):
                        Backend.setVersionList([">= 5.1.5", "< 5.1.6"])
                    else:
                        Backend.setVersionList([">= 5.1.2", "< 5.1.5"])

                # Check if it is MySQL >= 5.0.0 and < 5.1.2
                elif inject.checkBooleanExpression("@@hostname=@@hostname"):
                    Backend.setVersionList([">= 5.0.38", "< 5.1.2"])
                elif inject.checkBooleanExpression(
                        "@@character_set_filesystem=@@character_set_filesystem"
                ):
                    Backend.setVersionList([">= 5.0.19", "< 5.0.38"])
                elif not inject.checkBooleanExpression(
                        "[RANDNUM]=(SELECT [RANDNUM] FROM DUAL WHERE [RANDNUM1]!=[RANDNUM2])"
                ):
                    Backend.setVersionList([">= 5.0.11", "< 5.0.19"])
                elif inject.checkBooleanExpression(
                        "@@div_precision_increment=@@div_precision_increment"):
                    Backend.setVersionList([">= 5.0.6", "< 5.0.11"])
                elif inject.checkBooleanExpression(
                        "@@automatic_sp_privileges=@@automatic_sp_privileges"):
                    Backend.setVersionList([">= 5.0.3", "< 5.0.6"])
                else:
                    Backend.setVersionList([">= 5.0.0", "< 5.0.3"])

            elif inject.checkBooleanExpression("DATABASE() LIKE SCHEMA()"):
                Backend.setVersion(">= 5.0.2")
                setDbms("%s 5" % DBMS.SHELL)
                self.getBanner()

            elif inject.checkBooleanExpression(
                    "STRCMP(LOWER(CURRENT_USER()), UPPER(CURRENT_USER()))=0"):
                Backend.setVersion("< 5.0.0")
                setDbms("%s 4" % DBMS.SHELL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                # Check which version of MySQL < 5.0.0 it is
                if inject.checkBooleanExpression(
                        "3=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.11", "< 5.0.0"])
                elif inject.checkBooleanExpression(
                        "2=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.1", "< 4.1.11"])
                elif inject.checkBooleanExpression(
                        "CURRENT_USER()=CURRENT_USER()"):
                    Backend.setVersionList([">= 4.0.6", "< 4.1.1"])

                    if inject.checkBooleanExpression(
                            "'utf8'=(SELECT CHARSET(CURRENT_USER()))"):
                        Backend.setVersion("= 4.1.0")
                    else:
                        Backend.setVersionList([">= 4.0.6", "< 4.1.0"])
                else:
                    Backend.setVersionList([">= 4.0.0", "< 4.0.6"])
            else:
                Backend.setVersion("< 4.0.0")
                setDbms("%s 3" % DBMS.SHELL)
                self.getBanner()

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.SHELL
            logger.warn(warnMsg)

            return False
Example #13
0
def resumeConfKb(expression, url, value):
    if expression == "Injection data" and url == conf.url:
        injection = base64unpickle(value[:-1])

        logMsg = "resuming injection data from session file"
        logger.info(logMsg)

        if injection.place in conf.paramDict and \
           injection.parameter in conf.paramDict[injection.place]:

            if not conf.tech or intersect(conf.tech, injection.data.keys()):
                if intersect(conf.tech, injection.data.keys()):
                    injection.data = dict(
                        filter(lambda (key, item): key in conf.tech,
                               injection.data.items()))

                if injection not in kb.injections:
                    kb.injections.append(injection)
        else:
            warnMsg = "there is an injection in %s parameter '%s' " % (
                injection.place, injection.parameter)
            warnMsg += "but you did not provided it this time"
            logger.warn(warnMsg)

    elif expression == "Dynamic markings" and url == conf.url:
        kb.dynamicMarkings = base64unpickle(value[:-1])
        logMsg = "resuming dynamic markings from session file"
        logger.info(logMsg)

    elif expression == "DBMS" and url == conf.url:
        dbms = unSafeFormatString(value[:-1])
        dbms = dbms.lower()
        dbmsVersion = [UNKNOWN_DBMS_VERSION]

        logMsg = "resuming back-end DBMS '%s' " % dbms
        logMsg += "from session file"
        logger.info(logMsg)

        firstRegExp = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
        dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, dbms)

        if dbmsRegExp:
            dbms = dbmsRegExp.group(1)
            dbmsVersion = [dbmsRegExp.group(2)]

        if conf.dbms and conf.dbms.lower() != dbms:
            message = "you provided '%s' as back-end DBMS, " % conf.dbms
            message += "but from a past scan information on the target URL "
            message += "sqlmap assumes the back-end DBMS is %s. " % dbms
            message += "Do you really want to force the back-end "
            message += "DBMS value? [y/N] "
            test = readInput(message, default="N")

            if not test or test[0] in ("n", "N"):
                Backend.setDbms(dbms)
                Backend.setVersionList(dbmsVersion)
        else:
            Backend.setDbms(dbms)
            Backend.setVersionList(dbmsVersion)

    elif expression == "OS" and url == conf.url:
        os = unSafeFormatString(value[:-1])

        if os and os != 'None':
            logMsg = "resuming back-end DBMS operating system '%s' " % os
            logMsg += "from session file"
            logger.info(logMsg)

            if conf.os and conf.os.lower() != os.lower():
                message = "you provided '%s' as back-end DBMS operating " % conf.os
                message += "system, but from a past scan information on the "
                message += "target URL sqlmap assumes the back-end DBMS "
                message += "operating system is %s. " % os
                message += "Do you really want to force the back-end DBMS "
                message += "OS value? [y/N] "
                test = readInput(message, default="N")

                if not test or test[0] in ("n", "N"):
                    conf.os = os
            else:
                conf.os = os

    elif expression == "Remote temp path" and url == conf.url:
        conf.tmpPath = unSafeFormatString(value[:-1])

        logMsg = "resuming remote absolute path of temporary "
        logMsg += "files directory '%s' from session file" % conf.tmpPath
        logger.info(logMsg)

    elif expression == "TABLE_EXISTS" and url == conf.url:
        table = unSafeFormatString(value[:-1])
        split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL,
                                                        DBMS.SYBASE) else '.'

        if split in table:
            db, table = table.split(split)
        else:
            db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX)

        logMsg = "resuming brute forced table name "
        logMsg += "'%s' from session file" % table
        logger.info(logMsg)

        kb.brute.tables.append((db, table))

    elif expression == "COLUMN_EXISTS" and url == conf.url:
        table, column = unSafeFormatString(value[:-1]).split('|')
        colName, colType = column.split(' ')
        split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL,
                                                        DBMS.SYBASE) else '.'

        if split in table:
            db, table = table.split(split)
        else:
            db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX)

        logMsg = "resuming brute forced column name "
        logMsg += "'%s' for table '%s' from session file" % (colName, table)
        logger.info(logMsg)

        kb.brute.columns.append((db, table, colName, colType))
Example #14
0
def resumeConfKb(expression, url, value):
    if expression == "Injection data" and url == conf.url:
        try:
            injection = base64unpickle(value[:-1])
        except AttributeError:
            warnMsg = "there were some changes in data model "
            warnMsg += "preventing normal resume of previously stored "
            warnMsg += "injection data. please use the --flush-session "
            warnMsg += "to have it fixed"
            singleTimeWarnMessage(warnMsg)
            return

        infoMsg = "resuming injection data from session file"
        logger.info(infoMsg)

        if injection.place in conf.paramDict and \
           injection.parameter in conf.paramDict[injection.place]:

            if not conf.tech or intersect(conf.tech, injection.data.keys()):
                if intersect(conf.tech, injection.data.keys()):
                    injection.data = dict(filter(lambda (key, item): key in conf.tech, injection.data.items()))

                if injection not in kb.injections:
                    kb.injections.append(injection)
        else:
            warnMsg = "there is an injection in %s parameter '%s' " % (injection.place, injection.parameter)
            warnMsg += "but you did not provided it this time"
            logger.warn(warnMsg)

    elif expression == "Dynamic markings" and url == conf.url:
        kb.dynamicMarkings = base64unpickle(value[:-1])
        infoMsg = "resuming dynamic markings from session file"
        logger.info(infoMsg)

    elif expression == "DBMS" and url == conf.url:
        dbms = unSafeFormatString(value[:-1])
        dbms = dbms.lower()
        dbmsVersion = [UNKNOWN_DBMS_VERSION]

        infoMsg = "resuming back-end DBMS '%s' " % dbms
        infoMsg += "from session file"
        logger.info(infoMsg)

        firstRegExp = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
        dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, dbms)

        if dbmsRegExp:
            dbms = dbmsRegExp.group(1)
            dbmsVersion = [ dbmsRegExp.group(2) ]

        if conf.dbms and conf.dbms.lower() != dbms:
            message = "you provided '%s' as back-end DBMS, " % conf.dbms
            message += "but from a past scan information on the target URL "
            message += "sqlmap assumes the back-end DBMS is %s. " % dbms
            message += "Do you really want to force the back-end "
            message += "DBMS value? [y/N] "
            test = readInput(message, default="N")

            if not test or test[0] in ("n", "N"):
                conf.dbms = None
                Backend.setDbms(dbms)
                Backend.setVersionList(dbmsVersion)
        else:
            Backend.setDbms(dbms)
            Backend.setVersionList(dbmsVersion)

    elif expression == "OS" and url == conf.url:
        os = unSafeFormatString(value[:-1])

        if os and os != 'None':
            infoMsg = "resuming back-end DBMS operating system '%s' " % os
            infoMsg += "from session file"
            logger.info(infoMsg)

            if conf.os and conf.os.lower() != os.lower():
                message = "you provided '%s' as back-end DBMS operating " % conf.os
                message += "system, but from a past scan information on the "
                message += "target URL sqlmap assumes the back-end DBMS "
                message += "operating system is %s. " % os
                message += "Do you really want to force the back-end DBMS "
                message += "OS value? [y/N] "
                test = readInput(message, default="N")

                if not test or test[0] in ("n", "N"):
                    conf.os = os
            else:
                conf.os = os

            Backend.setOs(conf.os)

    elif expression == "Remote temp path" and url == conf.url and conf.tmpPath is None:
        conf.tmpPath = unSafeFormatString(value[:-1])

        infoMsg = "resuming remote absolute path of temporary "
        infoMsg += "files directory '%s' from session file" % conf.tmpPath
        logger.info(infoMsg)

    elif conf.freshQueries:
        pass

    elif expression == "TABLE_EXISTS" and url == conf.url:
        table = unSafeFormatString(value[:-1])
        split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.'

        if split in table:
            db, table = table.split(split)
        else:
            db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX)

        infoMsg = "resuming brute forced table name "
        infoMsg += "'%s' from session file" % table
        logger.info(infoMsg)

        kb.brute.tables.append((db, table))

    elif expression == "COLUMN_EXISTS" and url == conf.url:
        table, column = unSafeFormatString(value[:-1]).split('|')
        colName, colType = column.split(' ')
        split = '..' if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) else '.'

        if split in table:
            db, table = table.split(split)
        else:
            db = "%s%s" % (Backend.getIdentifiedDbms(), METADB_SUFFIX)

        infoMsg = "resuming brute forced column name "
        infoMsg += "'%s' for table '%s' from session file" % (colName, table)
        logger.info(infoMsg)

        kb.brute.columns.append((db, table, colName, colType))

    elif expression == "xp_cmdshell availability" and url == conf.url:
        kb.xpCmdshellAvailable = True if unSafeFormatString(value[:-1]).lower() == "true" else False
        infoMsg = "resuming xp_cmdshell availability"
        logger.info(infoMsg)
Example #15
0
    def checkDbms(self):
        """
        References for fingerprint:

        * http://dev.mysql.com/doc/refman/5.0/en/news-5-0-x.html (up to 5.0.89)
        * http://dev.mysql.com/doc/refman/5.1/en/news-5-1-x.html (up to 5.1.42)
        * http://dev.mysql.com/doc/refman/5.4/en/news-5-4-x.html (up to 5.4.4)
        * http://dev.mysql.com/doc/refman/5.5/en/news-5-5-x.html (up to 5.5.0)
        * http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html (manual has been withdrawn)
        """

        if not conf.extensiveFp and Backend.isDbmsWithin(MYSQL_ALIASES):
            setDbms("%s %s" % (DBMS.MYSQL, Backend.getVersion()))

            if Backend.isVersionGreaterOrEqualThan("5"):
                kb.data.has_information_schema = True

            self.getBanner()

            return True

        infoMsg = "testing %s" % DBMS.MYSQL
        logger.info(infoMsg)

        result = inject.checkBooleanExpression("QUARTER(NULL) IS NULL")

        if result:
            infoMsg = "confirming %s" % DBMS.MYSQL
            logger.info(infoMsg)

            result = inject.checkBooleanExpression("SESSION_USER() LIKE USER()")

            if not result:
                warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
                logger.warn(warnMsg)

                return False

            if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) is None:
                hashDBWrite(HASHDB_KEYS.DBMS_FORK, inject.checkBooleanExpression("VERSION() LIKE '%MariaDB%'") and "MariaDB" or "")

            # reading information_schema on some platforms is causing annoying timeout exits
            # Reference: http://bugs.mysql.com/bug.php?id=15855

            # Determine if it is MySQL >= 5.0.0
            if inject.checkBooleanExpression("ISNULL(TIMESTAMPADD(MINUTE,[RANDNUM],NULL))"):
                kb.data.has_information_schema = True
                Backend.setVersion(">= 5.0.0")
                setDbms("%s 5" % DBMS.MYSQL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                infoMsg = "actively fingerprinting %s" % DBMS.MYSQL
                logger.info(infoMsg)

                # Check if it is MySQL >= 5.5.0
                if inject.checkBooleanExpression("TO_SECONDS(950501)>0"):
                    Backend.setVersion(">= 5.5.0")

                # Check if it is MySQL >= 5.1.2 and < 5.5.0
                elif inject.checkBooleanExpression("@@table_open_cache=@@table_open_cache"):
                    if inject.checkBooleanExpression("[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.GLOBAL_STATUS LIMIT 0, 1)"):
                        Backend.setVersionList([">= 5.1.12", "< 5.5.0"])
                    elif inject.checkBooleanExpression("[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PROCESSLIST LIMIT 0, 1)"):
                        Backend.setVersionList([">= 5.1.7", "< 5.1.12"])
                    elif inject.checkBooleanExpression("[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PARTITIONS LIMIT 0, 1)"):
                        Backend.setVersion("= 5.1.6")
                    elif inject.checkBooleanExpression("[RANDNUM]=(SELECT [RANDNUM] FROM information_schema.PLUGINS LIMIT 0, 1)"):
                        Backend.setVersionList([">= 5.1.5", "< 5.1.6"])
                    else:
                        Backend.setVersionList([">= 5.1.2", "< 5.1.5"])

                # Check if it is MySQL >= 5.0.0 and < 5.1.2
                elif inject.checkBooleanExpression("@@hostname=@@hostname"):
                    Backend.setVersionList([">= 5.0.38", "< 5.1.2"])
                elif inject.checkBooleanExpression("@@character_set_filesystem=@@character_set_filesystem"):
                    Backend.setVersionList([">= 5.0.19", "< 5.0.38"])
                elif not inject.checkBooleanExpression("[RANDNUM]=(SELECT [RANDNUM] FROM DUAL WHERE [RANDNUM1]!=[RANDNUM2])"):
                    Backend.setVersionList([">= 5.0.11", "< 5.0.19"])
                elif inject.checkBooleanExpression("@@div_precision_increment=@@div_precision_increment"):
                    Backend.setVersionList([">= 5.0.6", "< 5.0.11"])
                elif inject.checkBooleanExpression("@@automatic_sp_privileges=@@automatic_sp_privileges"):
                    Backend.setVersionList([">= 5.0.3", "< 5.0.6"])
                else:
                    Backend.setVersionList([">= 5.0.0", "< 5.0.3"])

            elif inject.checkBooleanExpression("DATABASE() LIKE SCHEMA()"):
                Backend.setVersion(">= 5.0.2")
                setDbms("%s 5" % DBMS.MYSQL)
                self.getBanner()

            elif inject.checkBooleanExpression("STRCMP(LOWER(CURRENT_USER()), UPPER(CURRENT_USER()))=0"):
                Backend.setVersion("< 5.0.0")
                setDbms("%s 4" % DBMS.MYSQL)
                self.getBanner()

                if not conf.extensiveFp:
                    return True

                # Check which version of MySQL < 5.0.0 it is
                if inject.checkBooleanExpression("3=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.11", "< 5.0.0"])
                elif inject.checkBooleanExpression("2=(SELECT COERCIBILITY(USER()))"):
                    Backend.setVersionList([">= 4.1.1", "< 4.1.11"])
                elif inject.checkBooleanExpression("CURRENT_USER()=CURRENT_USER()"):
                    Backend.setVersionList([">= 4.0.6", "< 4.1.1"])

                    if inject.checkBooleanExpression("'utf8'=(SELECT CHARSET(CURRENT_USER()))"):
                        Backend.setVersion("= 4.1.0")
                    else:
                        Backend.setVersionList([">= 4.0.6", "< 4.1.0"])
                else:
                    Backend.setVersionList([">= 4.0.0", "< 4.0.6"])
            else:
                Backend.setVersion("< 4.0.0")
                setDbms("%s 3" % DBMS.MYSQL)
                self.getBanner()

            return True
        else:
            warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
            logger.warn(warnMsg)

            return False