Path: blob/master/plugins/dbms/firebird/fingerprint.py
2992 views
#!/usr/bin/env python12"""3Copyright (c) 2006-2025 sqlmap developers (https://sqlmap.org)4See the file 'LICENSE' for copying permission5"""67import re89from lib.core.common import Backend10from lib.core.common import Format11from lib.core.common import randomRange12from lib.core.common import randomStr13from lib.core.compat import xrange14from lib.core.convert import getUnicode15from lib.core.data import conf16from lib.core.data import kb17from lib.core.data import logger18from lib.core.enums import DBMS19from lib.core.session import setDbms20from lib.core.settings import FIREBIRD_ALIASES21from lib.core.settings import METADB_SUFFIX22from lib.request import inject23from plugins.generic.fingerprint import Fingerprint as GenericFingerprint2425class Fingerprint(GenericFingerprint):26def __init__(self):27GenericFingerprint.__init__(self, DBMS.FIREBIRD)2829def getFingerprint(self):30value = ""31wsOsFp = Format.getOs("web server", kb.headersFp)3233if wsOsFp:34value += "%s\n" % wsOsFp3536if kb.data.banner:37dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)3839if dbmsOsFp:40value += "%s\n" % dbmsOsFp4142value += "back-end DBMS: "43actVer = Format.getDbms()4445if not conf.extensiveFp:46value += actVer47return value4849actVer = Format.getDbms() + " (%s)" % (self._dialectCheck())50blank = " " * 1551value += "active fingerprint: %s" % actVer5253if kb.bannerFp:54banVer = kb.bannerFp.get("dbmsVersion")5556if banVer:57if re.search(r"-log$", kb.data.banner or ""):58banVer += ", logging enabled"5960banVer = Format.getDbms([banVer])61value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)6263htmlErrorFp = Format.getErrorParsedDBMSes()6465if htmlErrorFp:66value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)6768return value6970def _sysTablesCheck(self):71retVal = None72table = (73("1.0", ("EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)",)),74("1.5", ("NULLIF(%d,%d) IS NULL", "EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)")),75("2.0", ("EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", "BIT_LENGTH(%d)>0", "CHAR_LENGTH(%d)>0")),76("2.1", ("BIN_XOR(%d,%d)=0", "PI()>0.%d", "RAND()<1.%d", "FLOOR(1.%d)>=0")),77("2.5", ("'%s' SIMILAR TO '%s'",)), # Reference: https://firebirdsql.org/refdocs/langrefupd25-similar-to.html78("3.0", ("FALSE IS FALSE",)), # https://www.firebirdsql.org/file/community/conference-2014/pdf/02_fb.2014.whatsnew.30.en.pdf79)8081for i in xrange(len(table)):82version, checks = table[i]83failed = False84check = checks[randomRange(0, len(checks) - 1)].replace("%d", getUnicode(randomRange(1, 100))).replace("%s", getUnicode(randomStr()))85result = inject.checkBooleanExpression(check)8687if result:88retVal = version89else:90failed = True91break9293if failed:94break9596return retVal9798def _dialectCheck(self):99retVal = None100101if Backend.getIdentifiedDbms():102result = inject.checkBooleanExpression("EXISTS(SELECT CURRENT_DATE FROM RDB$DATABASE)")103retVal = "dialect 3" if result else "dialect 1"104105return retVal106107def checkDbms(self):108if not conf.extensiveFp and Backend.isDbmsWithin(FIREBIRD_ALIASES):109setDbms("%s %s" % (DBMS.FIREBIRD, Backend.getVersion()))110111self.getBanner()112113return True114115infoMsg = "testing %s" % DBMS.FIREBIRD116logger.info(infoMsg)117118result = inject.checkBooleanExpression("(SELECT COUNT(*) FROM RDB$DATABASE WHERE [RANDNUM]=[RANDNUM])>0")119120if result:121infoMsg = "confirming %s" % DBMS.FIREBIRD122logger.info(infoMsg)123124result = inject.checkBooleanExpression("EXISTS(SELECT CURRENT_USER FROM RDB$DATABASE)")125126if not result:127warnMsg = "the back-end DBMS is not %s" % DBMS.FIREBIRD128logger.warning(warnMsg)129130return False131132setDbms(DBMS.FIREBIRD)133134infoMsg = "actively fingerprinting %s" % DBMS.FIREBIRD135logger.info(infoMsg)136137version = self._sysTablesCheck()138139if version is not None:140Backend.setVersion(version)141setDbms("%s %s" % (DBMS.FIREBIRD, version))142143self.getBanner()144145return True146else:147warnMsg = "the back-end DBMS is not %s" % DBMS.FIREBIRD148logger.warning(warnMsg)149150return False151152def forceDbmsEnum(self):153conf.db = "%s%s" % (DBMS.FIREBIRD, METADB_SUFFIX)154155if conf.tbl:156conf.tbl = conf.tbl.upper()157158159