From 685a8e7d2c39a3eeeb421521285cb5bb2fff3ba7 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Tue, 2 Nov 2010 11:59:24 +0000 Subject: [PATCH] refactoring of hard coded dbms names --- lib/controller/handler.py | 1 + lib/core/agent.py | 27 ++-- lib/core/common.py | 11 +- lib/core/settings.py | 11 ++ lib/parse/banner.py | 11 +- lib/request/direct.py | 3 +- lib/request/inject.py | 19 +-- lib/takeover/abstraction.py | 18 ++- lib/takeover/metasploit.py | 15 +- lib/takeover/udf.py | 13 +- lib/techniques/error/use.py | 3 +- lib/techniques/inband/union/test.py | 4 +- lib/techniques/inband/union/use.py | 17 ++- plugins/dbms/access/enumeration.py | 3 +- plugins/dbms/access/fingerprint.py | 3 +- plugins/dbms/firebird/enumeration.py | 3 +- plugins/dbms/firebird/fingerprint.py | 5 +- plugins/dbms/maxdb/enumeration.py | 3 +- plugins/dbms/maxdb/fingerprint.py | 5 +- plugins/dbms/mssqlserver/enumeration.py | 3 +- plugins/dbms/mssqlserver/fingerprint.py | 7 +- plugins/dbms/mysql/enumeration.py | 3 +- plugins/dbms/mysql/fingerprint.py | 7 +- plugins/dbms/oracle/enumeration.py | 3 +- plugins/dbms/oracle/fingerprint.py | 5 +- plugins/dbms/postgresql/enumeration.py | 3 +- plugins/dbms/postgresql/fingerprint.py | 5 +- plugins/dbms/sqlite/enumeration.py | 3 +- plugins/dbms/sqlite/fingerprint.py | 5 +- plugins/dbms/sybase/enumeration.py | 3 +- plugins/dbms/sybase/fingerprint.py | 5 +- plugins/generic/enumeration.py | 187 ++++++++++++------------ plugins/generic/filesystem.py | 7 +- plugins/generic/misc.py | 11 +- plugins/generic/takeover.py | 25 ++-- 35 files changed, 251 insertions(+), 206 deletions(-) diff --git a/lib/controller/handler.py b/lib/controller/handler.py index 1aad55252..9f9316fc3 100644 --- a/lib/controller/handler.py +++ b/lib/controller/handler.py @@ -12,6 +12,7 @@ from lib.core.common import pushValue from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.settings import DBMS from lib.core.settings import MSSQL_ALIASES from lib.core.settings import MYSQL_ALIASES from lib.core.settings import ORACLE_ALIASES diff --git a/lib/core/agent.py b/lib/core/agent.py index 4e0769d3a..f5e1becc6 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -21,6 +21,7 @@ from lib.core.data import kb from lib.core.data import queries from lib.core.datatype import advancedDict from lib.core.exception import sqlmapNoneDataException +from lib.core.settings import DBMS from lib.core.settings import PAYLOAD_DELIMITER class Agent: @@ -219,7 +220,7 @@ class Agent: # SQLite version 2 does not support neither CAST() nor IFNULL(), # introduced only in SQLite version 3 - if kb.dbms == "SQLite": + if kb.dbms == DBMS.SQLITE: return field if field.startswith("(CASE"): @@ -324,13 +325,13 @@ class Agent: def simpleConcatQuery(self, query1, query2): concatenatedQuery = "" - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: concatenatedQuery = "CONCAT(%s,%s)" % (query1, query2) - elif kb.dbms in ( "PostgreSQL", "Oracle", "SQLite" ): + elif kb.dbms in ( DBMS.POSTGRESQL, DBMS.ORACLE, DBMS.SQLITE ): concatenatedQuery = "%s||%s" % (query1, query2) - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: concatenatedQuery = "%s+%s" % (query1, query2) return concatenatedQuery @@ -372,7 +373,7 @@ class Agent: concatenatedQuery = query fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query) - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: if fieldsSelectCase: concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1) concatenatedQuery += ",'%s')" % kb.misc.stop @@ -385,7 +386,7 @@ class Agent: elif fieldsNoSelect: concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.misc.start, concatenatedQuery, kb.misc.stop) - elif kb.dbms in ( "PostgreSQL", "Oracle", "SQLite" ): + elif kb.dbms in ( DBMS.POSTGRESQL, DBMS.ORACLE, DBMS.SQLITE ): if fieldsSelectCase: concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1) concatenatedQuery += "||'%s'" % kb.misc.stop @@ -398,10 +399,10 @@ class Agent: elif fieldsNoSelect: concatenatedQuery = "'%s'||%s||'%s'" % (kb.misc.start, concatenatedQuery, kb.misc.stop) - if kb.dbms == "Oracle" and " FROM " not in concatenatedQuery and ( fieldsSelect or fieldsNoSelect ): + if kb.dbms == DBMS.ORACLE and " FROM " not in concatenatedQuery and ( fieldsSelect or fieldsNoSelect ): concatenatedQuery += " FROM DUAL" - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: if fieldsSelectTop: topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1) concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.misc.start), 1) @@ -467,7 +468,7 @@ class Agent: intoRegExp = intoRegExp.group(1) query = query[:query.index(intoRegExp)] - if kb.dbms == "Oracle" and inbandQuery.endswith(" FROM DUAL"): + if kb.dbms == DBMS.ORACLE and inbandQuery.endswith(" FROM DUAL"): inbandQuery = inbandQuery[:-len(" FROM DUAL")] for element in range(kb.unionCount): @@ -487,7 +488,7 @@ class Agent: conditionIndex = query.index(" FROM ") inbandQuery += query[conditionIndex:] - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: if " FROM " not in inbandQuery: inbandQuery += " FROM DUAL" @@ -531,11 +532,11 @@ class Agent: limitStr = queries[kb.dbms].limit.query % (num, 1) limitedQuery += " %s" % limitStr - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: limitStr = queries[kb.dbms].limit.query % (num+1, num+1) limitedQuery += " %s" % limitStr - elif kb.dbms == "Oracle": + elif kb.dbms == DMBS.ORACLE: if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery: orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):] limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")] @@ -547,7 +548,7 @@ class Agent: limitedQuery = limitedQuery % fromFrom limitedQuery += "=%d" % (num + 1) - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: forgeNotIn = True if " ORDER BY " in limitedQuery: diff --git a/lib/core/common.py b/lib/core/common.py index 104c9fbaf..c842c3663 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -48,6 +48,7 @@ from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapMissingDependence from lib.core.exception import sqlmapSyntaxException from lib.core.optiondict import optDict +from lib.core.settings import DBMS from lib.core.settings import DESCRIPTION from lib.core.settings import IS_WIN from lib.core.settings import PLATFORM @@ -599,7 +600,7 @@ def parsePasswordHash(password): if not password or password == " ": password = "NULL" - if kb.dbms == "Microsoft SQL Server" and password != "NULL" and isHexEncodedString(password): + if kb.dbms == DBMS.MSSQL and password != "NULL" and isHexEncodedString(password): hexPassword = password password = "%s\n" % hexPassword password += "%sheader: %s\n" % (blank, hexPassword[:6]) @@ -909,20 +910,20 @@ def getDelayQuery(andCond=False): banVer = kb.bannerFp["dbmsVersion"] - if (kb.dbms == "MySQL" and banVer >= "5.0.12") or (kb.dbms == "PostgreSQL" and banVer >= "8.2"): + if (kb.dbms == DBMS.MYSQL and banVer >= "5.0.12") or (kb.dbms == DBMS.POSTGRESQL and banVer >= "8.2"): query = queries[kb.dbms].timedelay.query % conf.timeSec else: query = queries[kb.dbms].timedelay.query2 % conf.timeSec - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: query = queries[kb.dbms].timedelay.query else: query = queries[kb.dbms].timedelay.query % conf.timeSec if andCond: - if kb.dbms in ( "MySQL", "SQLite" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.SQLITE ): query = query.replace("SELECT ", "") - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: query = "(%s)>0" % query return query diff --git a/lib/core/settings.py b/lib/core/settings.py index b40b603a3..a663f062e 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -89,6 +89,17 @@ SYBASE_ALIASES = [ "sybase", "sybase sql server" ] SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES SUPPORTED_OS = ( "linux", "windows" ) +class DBMS: + MYSQL = "MySQL" + ORACLE = "Oracle" + POSTGRESQL = "PostgreSQL" + MSSQL = "Microsoft SQL Server" + SQLITE = "SQLite" + ACCESS = "Microsoft Access" + FIREBIRD = "Firebird" + MAXDB = "SAP MaxDB" + SYBASE = "Sybase" + SQL_STATEMENTS = { "SQL SELECT statement": ( "select ", diff --git a/lib/parse/banner.py b/lib/parse/banner.py index 42efc0bde..157c3b76c 100644 --- a/lib/parse/banner.py +++ b/lib/parse/banner.py @@ -17,6 +17,7 @@ from lib.core.common import parseXmlFile from lib.core.common import sanitizeStr from lib.core.data import kb from lib.core.data import paths +from lib.core.settings import DBMS from lib.parse.handler import FingerprintHandler class MSSQLBannerHandler(ContentHandler): @@ -93,13 +94,13 @@ def bannerParser(banner): xmlfile = None - if kb.dbms == "Microsoft SQL Server": + if kb.dbms == DBMS.MSSQL: xmlfile = paths.MSSQL_XML - elif kb.dbms == "MySQL": + elif kb.dbms == DBMS.MYSQL: xmlfile = paths.MYSQL_XML - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: xmlfile = paths.ORACLE_XML - elif kb.dbms == "PostgreSQL": + elif kb.dbms == DBMS.POSTGRESQL: xmlfile = paths.PGSQL_XML if not xmlfile: @@ -107,7 +108,7 @@ def bannerParser(banner): checkFile(xmlfile) - if kb.dbms == "Microsoft SQL Server": + if kb.dbms == DBMS.MSSQL: handler = MSSQLBannerHandler(banner, kb.bannerFp) parseXmlFile(xmlfile, handler) diff --git a/lib/request/direct.py b/lib/request/direct.py index e54d8fcff..3486da0a4 100644 --- a/lib/request/direct.py +++ b/lib/request/direct.py @@ -16,6 +16,7 @@ from lib.core.convert import utf8decode from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.settings import DBMS from lib.core.settings import SQL_STATEMENTS from lib.utils.timeout import timeout @@ -24,7 +25,7 @@ def direct(query, content=True): select = False query = agent.payloadDirect(query) - if kb.dbms == "Oracle" and query.startswith("SELECT ") and " FROM " not in query: + if kb.dbms == DBMS.ORACLE and query.startswith("SELECT ") and " FROM " not in query: query = "%s FROM DUAL" % query for sqlTitle, sqlStatements in SQL_STATEMENTS.items(): diff --git a/lib/request/inject.py b/lib/request/inject.py index 2465f335d..42dbe9ad4 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -26,6 +26,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.settings import DBMS from lib.core.unescaper import unescaper from lib.request.connect import Connect as Request from lib.request.direct import direct @@ -122,7 +123,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r _, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression) rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I) - if rdbRegExp and kb.dbms == "Firebird": + if rdbRegExp and kb.dbms == DBMS.FIREBIRD: expressionFieldsList = [expressionFields] if len(expressionFieldsList) > 1: @@ -141,8 +142,8 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r limitRegExp = re.search(queries[kb.dbms].limitregexp.query, expression, re.I) topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I) - if limitRegExp or ( kb.dbms == "Microsoft SQL Server" and topLimit ): - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if limitRegExp or ( kb.dbms == DBMS.MSSQL and topLimit ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStop = queries[kb.dbms].limitgroupstop.query @@ -152,7 +153,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r stopLimit = limitRegExp.group(int(limitGroupStop)) limitCond = int(stopLimit) > 1 - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: if limitRegExp: limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStop = queries[kb.dbms].limitgroupstop.query @@ -167,7 +168,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r stopLimit = int(topLimit.group(1)) limitCond = int(stopLimit) > 1 - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: limitCond = False else: limitCond = True @@ -181,16 +182,16 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r # From now on we need only the expression until the " LIMIT " # (or similar, depending on the back-end DBMS) word - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): stopLimit += startLimit untilLimitChar = expression.index(queries[kb.dbms].limitstring.query) expression = expression[:untilLimitChar] - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: stopLimit += startLimit if not stopLimit or stopLimit <= 1: - if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"): + if kb.dbms == DBMS.ORACLE and expression.endswith("FROM DUAL"): test = "n" elif batch: test = "y" @@ -289,7 +290,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r return outputs - elif kb.dbms == "Oracle" and expression.startswith("SELECT ") and " FROM " not in expression: + elif kb.dbms == DBMS.ORACLE and expression.startswith("SELECT ") and " FROM " not in expression: expression = "%s FROM DUAL" % expression outputs = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected, resumeValue=resumeValue, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar) diff --git a/lib/takeover/abstraction.py b/lib/takeover/abstraction.py index f432b6e3f..a1c43c8d5 100644 --- a/lib/takeover/abstraction.py +++ b/lib/takeover/abstraction.py @@ -13,11 +13,13 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.exception import sqlmapUnsupportedFeatureException +from lib.core.settings import DBMS from lib.core.shell import autoCompletion from lib.takeover.udf import UDF from lib.takeover.web import Web from lib.takeover.xp_cmdshell import xp_cmdshell + class Abstraction(Web, UDF, xp_cmdshell): """ This class defines an abstraction layer for OS takeover functionalities @@ -36,10 +38,10 @@ class Abstraction(Web, UDF, xp_cmdshell): if self.webBackdoorUrl and not kb.stackedTest: self.webBackdoorRunCmd(cmd) - elif kb.dbms in ( "MySQL", "PostgreSQL" ): + elif kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): self.udfExecCmd(cmd, silent=silent) - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: self.xpCmdshellExecCmd(cmd, silent=silent) else: @@ -50,10 +52,10 @@ class Abstraction(Web, UDF, xp_cmdshell): if self.webBackdoorUrl and not kb.stackedTest: return self.webBackdoorRunCmd(cmd) - elif kb.dbms in ( "MySQL", "PostgreSQL" ): + elif kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): return self.udfEvalCmd(cmd, first, last) - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: return self.xpCmdshellEvalCmd(cmd, first, last) else: @@ -88,13 +90,13 @@ class Abstraction(Web, UDF, xp_cmdshell): logger.info(infoMsg) else: - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): infoMsg = "going to use injected sys_eval and sys_exec " infoMsg += "user-defined functions for operating system " infoMsg += "command execution" logger.info(infoMsg) - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: infoMsg = "going to use xp_cmdshell extended procedure for " infoMsg += "operating system command execution" logger.info(infoMsg) @@ -146,9 +148,9 @@ class Abstraction(Web, UDF, xp_cmdshell): warnMsg += "the session user is not a database administrator" logger.warn(warnMsg) - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): self.udfInjectSys() - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: if mandatory: self.xpCmdshellInit() else: diff --git a/lib/takeover/metasploit.py b/lib/takeover/metasploit.py index f5f9be229..1caa84ea7 100644 --- a/lib/takeover/metasploit.py +++ b/lib/takeover/metasploit.py @@ -32,6 +32,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.exception import sqlmapDataException from lib.core.exception import sqlmapFilePathException +from lib.core.settings import DBMS from lib.core.subprocessng import blockingReadFromFD from lib.core.subprocessng import blockingWriteToFD from lib.core.subprocessng import pollProcess @@ -185,13 +186,13 @@ class Metasploit: if __payloadStr == "windows/vncinject": choose = False - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: debugMsg = "by default MySQL on Windows runs as SYSTEM " debugMsg += "user, it is likely that the the VNC " debugMsg += "injection will be successful" logger.debug(debugMsg) - elif kb.dbms == "PostgreSQL": + elif kb.dbms == DBMS.POSTGRESQL: choose = True warnMsg = "by default PostgreSQL on Windows runs as " @@ -199,7 +200,7 @@ class Metasploit: warnMsg += "injection will be successful" logger.warn(warnMsg) - elif kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ): + elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): choose = True warnMsg = "it is unlikely that the VNC injection will be " @@ -228,12 +229,12 @@ class Metasploit: break elif choice == "1": - if kb.dbms == "PostgreSQL": + if kb.dbms == DBMS.POSTGRESQL: logger.warn("beware that the VNC injection might not work") break - elif kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ): + elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): break elif not choice.isdigit(): @@ -553,7 +554,7 @@ class Metasploit: # This is useful for sqlmap because on PostgreSQL it is not # possible to write files bigger than 8192 bytes abusing the # lo_export() feature implemented in sqlmap. - if kb.dbms == "PostgreSQL": + if kb.dbms == DBMS.POSTGRESQL: self.__fileFormat = "exe-small" else: self.__fileFormat = "exe" @@ -655,7 +656,7 @@ class Metasploit: self.__forgeMsfConsoleResource() self.__forgeMsfConsoleCmd() - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): self.uncPath = "\\\\\\\\%s\\\\%s" % (self.lhostStr, self.__randFile) else: self.uncPath = "\\\\%s\\%s" % (self.lhostStr, self.__randFile) diff --git a/lib/takeover/udf.py b/lib/takeover/udf.py index 34b28b016..1dc93ce7a 100644 --- a/lib/takeover/udf.py +++ b/lib/takeover/udf.py @@ -20,6 +20,7 @@ from lib.core.exception import sqlmapFilePathException from lib.core.exception import sqlmapMissingMandatoryOptionException from lib.core.exception import sqlmapUnsupportedFeatureException from lib.core.exception import sqlmapUserQuitException +from lib.core.settings import DBMS from lib.core.unescaper import unescaper from lib.request import inject from lib.techniques.outband.stacked import stackedTest @@ -102,7 +103,7 @@ class UDF: return output def udfCheckNeeded(self): - if ( not conf.rFile or ( conf.rFile and kb.dbms != "PostgreSQL" ) ) and "sys_fileread" in self.sysUdfs: + if ( not conf.rFile or ( conf.rFile and kb.dbms != DBMS.POSTGRESQL ) ) and "sys_fileread" in self.sysUdfs: self.sysUdfs.pop("sys_fileread") if not conf.osPwn: @@ -141,9 +142,9 @@ class UDF: if udf in self.udfToCreate and udf not in self.createdUdf: self.udfCreateFromSharedLib(udf, inpRet) - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: supportTblType = "longtext" - elif kb.dbms == "PostgreSQL": + elif kb.dbms == DBMS.POSTGRESQL: supportTblType = "text" self.udfCreateSupportTbl(supportTblType) @@ -154,7 +155,7 @@ class UDF: self.udfInjectCore(self.sysUdfs) def udfInjectCustom(self): - if kb.dbms not in ( "MySQL", "PostgreSQL" ): + if kb.dbms not in ( DBMS.MYSQL, DBMS.POSTGRESQL ): errMsg = "UDF injection feature is not yet implemented on %s" % kb.dbms raise sqlmapUnsupportedFeatureException(errMsg) @@ -236,9 +237,9 @@ class UDF: else: logger.warn("you need to specify the name of the UDF") - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: defaultType = "string" - elif kb.dbms == "PostgreSQL": + elif kb.dbms == DBMS.POSTGRESQL: defaultType = "text" self.udfs[udfName]["input"] = [] diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py index 6a68f20f1..7639adbdd 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -20,6 +20,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries from lib.core.session import setError +from lib.core.settings import DBMS from lib.core.unescaper import unescaper from lib.request.connect import Connect as Request from lib.utils.resume import resume @@ -49,7 +50,7 @@ def errorUse(expression, returnPayload=False): _, _, _, _, _, _, fieldToCastStr = agent.getFields(expression) nulledCastedField = agent.nullAndCastField(fieldToCastStr) - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: nulledCastedField = nulledCastedField.replace("AS CHAR)", "AS CHAR(100))") # fix for that 'Subquery returns more than 1 row' expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1) diff --git a/lib/techniques/inband/union/test.py b/lib/techniques/inband/union/test.py index 7c0a131ad..ce53adf8f 100644 --- a/lib/techniques/inband/union/test.py +++ b/lib/techniques/inband/union/test.py @@ -124,13 +124,13 @@ def __unionTestByNULLBruteforce(comment): query = agent.prefixQuery("UNION ALL SELECT NULL") for count in range(0, 50): - if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"): + if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"): query = query[:-len(" FROM DUAL")] if count: query += ", NULL" - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: query += " FROM DUAL" commentedQuery = agent.postfixQuery(query, comment) diff --git a/lib/techniques/inband/union/use.py b/lib/techniques/inband/union/use.py index 6066408f7..c87ec8869 100644 --- a/lib/techniques/inband/union/use.py +++ b/lib/techniques/inband/union/use.py @@ -18,6 +18,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.settings import DBMS from lib.core.unescaper import unescaper from lib.request.connect import Connect as Request from lib.techniques.inband.union.test import unionTest @@ -68,7 +69,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh limitRegExp = re.search(queries[kb.dbms].limitregexp.query, expression, re.I) if limitRegExp: - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStop = queries[kb.dbms].limitgroupstop.query @@ -78,7 +79,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh stopLimit = limitRegExp.group(int(limitGroupStop)) limitCond = int(stopLimit) > 1 - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStop = queries[kb.dbms].limitgroupstop.query @@ -88,7 +89,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh stopLimit = limitRegExp.group(int(limitGroupStop)) limitCond = int(stopLimit) > 1 - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: limitCond = False else: limitCond = True @@ -102,12 +103,12 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh # From now on we need only the expression until the " LIMIT " # (or similar, depending on the back-end DBMS) word - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): stopLimit += startLimit untilLimitChar = expression.index(queries[kb.dbms].limitstring.query) expression = expression[:untilLimitChar] - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: stopLimit += startLimit elif dump: if conf.limitStart: @@ -116,7 +117,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh stopLimit = conf.limitStop if not stopLimit or stopLimit <= 1: - if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"): + if kb.dbms == DBMS.ORACLE and expression.endswith("FROM DUAL"): test = False else: test = True @@ -170,9 +171,9 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh return for num in xrange(startLimit, stopLimit): - if kb.dbms == "Microsoft SQL Server": + if kb.dbms == DBMS.MSSQL: field = expressionFieldsList[0] - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: field = expressionFieldsList else: field = None diff --git a/plugins/dbms/access/enumeration.py b/plugins/dbms/access/enumeration.py index 2f04dcd04..11d1258a4 100644 --- a/plugins/dbms/access/enumeration.py +++ b/plugins/dbms/access/enumeration.py @@ -8,12 +8,13 @@ See the file 'doc/COPYING' for copying permission """ from lib.core.data import logger +from lib.core.settings import DBMS from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "Microsoft Access") + GenericEnumeration.__init__(self, DBMS.ACCESS) def getDbs(self): warnMsg = "on Microsoft Access it is not possible to enumerate databases" diff --git a/plugins/dbms/access/fingerprint.py b/plugins/dbms/access/fingerprint.py index 0f959dc0e..2c6b04b4d 100644 --- a/plugins/dbms/access/fingerprint.py +++ b/plugins/dbms/access/fingerprint.py @@ -20,6 +20,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import ACCESS_ALIASES from lib.request.connect import Connect as Request @@ -152,7 +153,7 @@ class Fingerprint(GenericFingerprint): def checkDbms(self): if conf.dbms in ACCESS_ALIASES: - setDbms("Microsoft Access") + setDbms(DBMS.ACCESS) if not conf.extensiveFp: return True diff --git a/plugins/dbms/firebird/enumeration.py b/plugins/dbms/firebird/enumeration.py index 9610d6f8e..2f10f0f4d 100644 --- a/plugins/dbms/firebird/enumeration.py +++ b/plugins/dbms/firebird/enumeration.py @@ -8,12 +8,13 @@ See the file 'doc/COPYING' for copying permission """ from lib.core.data import logger +from lib.core.settings import DBMS from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "Firebird") + GenericEnumeration.__init__(self, DBMS.FIREBIRD) def getDbs(self): warnMsg = "on Firebird it is not possible to enumerate databases" diff --git a/plugins/dbms/firebird/fingerprint.py b/plugins/dbms/firebird/fingerprint.py index d6375db8d..2407443f3 100644 --- a/plugins/dbms/firebird/fingerprint.py +++ b/plugins/dbms/firebird/fingerprint.py @@ -20,6 +20,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import FIREBIRD_ALIASES from lib.request.connect import Connect as Request @@ -103,7 +104,7 @@ class Fingerprint(GenericFingerprint): def checkDbms(self): if conf.dbms in FIREBIRD_ALIASES: - setDbms("Firebird") + setDbms(DBMS.FIREBIRD) self.getBanner() @@ -131,7 +132,7 @@ class Fingerprint(GenericFingerprint): return False - setDbms("Firebird") + setDbms(DBMS.FIREBIRD) self.getBanner() diff --git a/plugins/dbms/maxdb/enumeration.py b/plugins/dbms/maxdb/enumeration.py index 3e2b428f0..ba42084bd 100644 --- a/plugins/dbms/maxdb/enumeration.py +++ b/plugins/dbms/maxdb/enumeration.py @@ -8,12 +8,13 @@ See the file 'doc/COPYING' for copying permission """ from lib.core.data import logger +from lib.core.settings import DBMS from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "SAP MaxDB") + GenericEnumeration.__init__(self, DBMS.MAXDB) def getDbs(self): warnMsg = "on SAP MaxDB it is not possible to enumerate databases" diff --git a/plugins/dbms/maxdb/fingerprint.py b/plugins/dbms/maxdb/fingerprint.py index dcc94da05..3930aa867 100644 --- a/plugins/dbms/maxdb/fingerprint.py +++ b/plugins/dbms/maxdb/fingerprint.py @@ -20,6 +20,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import MAXDB_ALIASES from lib.request.connect import Connect as Request @@ -105,7 +106,7 @@ class Fingerprint(GenericFingerprint): def checkDbms(self): if conf.dbms in MAXDB_ALIASES: - setDbms("SAP MaxDB") + setDbms(DBMS.MAXDB) self.getBanner() @@ -133,7 +134,7 @@ class Fingerprint(GenericFingerprint): return False - setDbms("SAP MaxDB") + setDbms(DBMS.MAXDB) self.getBanner() diff --git a/plugins/dbms/mssqlserver/enumeration.py b/plugins/dbms/mssqlserver/enumeration.py index 3d0feb48b..9872b574b 100644 --- a/plugins/dbms/mssqlserver/enumeration.py +++ b/plugins/dbms/mssqlserver/enumeration.py @@ -14,13 +14,14 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries from lib.core.exception import sqlmapNoneDataException +from lib.core.settings import DBMS from lib.request import inject from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "Microsoft SQL Server") + GenericEnumeration.__init__(self, DBMS.MSSQL) def getPrivileges(self): warnMsg = "on Microsoft SQL Server it is not possible to fetch " diff --git a/plugins/dbms/mssqlserver/fingerprint.py b/plugins/dbms/mssqlserver/fingerprint.py index 8cbf71a49..5bbeda926 100644 --- a/plugins/dbms/mssqlserver/fingerprint.py +++ b/plugins/dbms/mssqlserver/fingerprint.py @@ -17,6 +17,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import MSSQL_ALIASES from lib.request import inject from lib.request.connect import Connect as Request @@ -71,7 +72,7 @@ class Fingerprint(GenericFingerprint): 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]) + setDbms("%s %s" % (DBMS.MSSQL, kb.dbmsVersion[0])) self.getBanner() @@ -133,9 +134,9 @@ class Fingerprint(GenericFingerprint): break if kb.dbmsVersion: - setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0]) + setDbms("%s %s" % (DBMS.MSSQL, kb.dbmsVersion[0])) else: - setDbms("Microsoft SQL Server") + setDbms(DBMS.MSSQL) self.getBanner() diff --git a/plugins/dbms/mysql/enumeration.py b/plugins/dbms/mysql/enumeration.py index d43c120e9..3ada23a9c 100644 --- a/plugins/dbms/mysql/enumeration.py +++ b/plugins/dbms/mysql/enumeration.py @@ -7,8 +7,9 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ +from lib.core.settings import DBMS from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "MySQL") + GenericEnumeration.__init__(self, DBMS.MYSQL) diff --git a/plugins/dbms/mysql/fingerprint.py b/plugins/dbms/mysql/fingerprint.py index b95b7ebd5..045436b69 100644 --- a/plugins/dbms/mysql/fingerprint.py +++ b/plugins/dbms/mysql/fingerprint.py @@ -19,6 +19,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import MYSQL_ALIASES from lib.request import inject from lib.request.connect import Connect as Request @@ -141,7 +142,7 @@ class Fingerprint(GenericFingerprint): """ if conf.dbms in MYSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit(): - setDbms("MySQL %s" % kb.dbmsVersion[0]) + setDbms("%s %s" % (DBMS.MYSQL, kb.dbmsVersion[0])) if int(kb.dbmsVersion[0]) >= 5: kb.data.has_information_schema = True @@ -176,7 +177,7 @@ class Fingerprint(GenericFingerprint): kb.data.has_information_schema = True kb.dbmsVersion = [">= 5.0.0"] - setDbms("MySQL 5") + setDbms("%s 5" % DBMS.MYSQL) self.getBanner() @@ -214,7 +215,7 @@ class Fingerprint(GenericFingerprint): else: kb.dbmsVersion = ["< 5.0.0"] - setDbms("MySQL 4") + setDbms("%s 4" % DBMS.MYSQL) self.getBanner() diff --git a/plugins/dbms/oracle/enumeration.py b/plugins/dbms/oracle/enumeration.py index bf398d079..fcb171a94 100644 --- a/plugins/dbms/oracle/enumeration.py +++ b/plugins/dbms/oracle/enumeration.py @@ -14,13 +14,14 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries from lib.core.exception import sqlmapNoneDataException +from lib.core.settings import DBMS from lib.request import inject from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "Oracle") + GenericEnumeration.__init__(self, DBMS.ORACLE) def getRoles(self, query2=False): infoMsg = "fetching database users roles" diff --git a/plugins/dbms/oracle/fingerprint.py b/plugins/dbms/oracle/fingerprint.py index e9ea2f1c3..2793b8427 100644 --- a/plugins/dbms/oracle/fingerprint.py +++ b/plugins/dbms/oracle/fingerprint.py @@ -17,6 +17,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import ORACLE_ALIASES from lib.request import inject from lib.request.connect import Connect as Request @@ -64,7 +65,7 @@ class Fingerprint(GenericFingerprint): def checkDbms(self): if conf.dbms in ORACLE_ALIASES: - setDbms("Oracle") + setDbms(DBMS.ORACLE) self.getBanner() @@ -100,7 +101,7 @@ class Fingerprint(GenericFingerprint): return False - setDbms("Oracle") + setDbms(DBMS.ORACLE) self.getBanner() diff --git a/plugins/dbms/postgresql/enumeration.py b/plugins/dbms/postgresql/enumeration.py index d11dac32e..a98726acb 100644 --- a/plugins/dbms/postgresql/enumeration.py +++ b/plugins/dbms/postgresql/enumeration.py @@ -7,8 +7,9 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) See the file 'doc/COPYING' for copying permission """ +from lib.core.settings import DBMS from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "PostgreSQL") + GenericEnumeration.__init__(self, DBMS.POSTGRESQL) diff --git a/plugins/dbms/postgresql/fingerprint.py b/plugins/dbms/postgresql/fingerprint.py index e0b558409..29d598ca9 100644 --- a/plugins/dbms/postgresql/fingerprint.py +++ b/plugins/dbms/postgresql/fingerprint.py @@ -19,6 +19,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import PGSQL_ALIASES from lib.core.settings import PGSQL_SYSTEM_DBS from lib.request import inject @@ -73,7 +74,7 @@ class Fingerprint(GenericFingerprint): """ if conf.dbms in PGSQL_ALIASES: - setDbms("PostgreSQL") + setDbms(DBMS.POSTGRESQL) self.getBanner() @@ -101,7 +102,7 @@ class Fingerprint(GenericFingerprint): return False - setDbms("PostgreSQL") + setDbms(DBMS.POSTGRESQL) self.getBanner() diff --git a/plugins/dbms/sqlite/enumeration.py b/plugins/dbms/sqlite/enumeration.py index 3526ea40b..d2d8c8b3c 100644 --- a/plugins/dbms/sqlite/enumeration.py +++ b/plugins/dbms/sqlite/enumeration.py @@ -10,12 +10,13 @@ See the file 'doc/COPYING' for copying permission from lib.core.data import conf from lib.core.data import logger from lib.core.exception import sqlmapUnsupportedFeatureException +from lib.core.settings import DBMS from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "SQLite") + GenericEnumeration.__init__(self, DBMS.SQLITE) def getCurrentUser(self): warnMsg = "on SQLite it is not possible to enumerate the current user" diff --git a/plugins/dbms/sqlite/fingerprint.py b/plugins/dbms/sqlite/fingerprint.py index ce891b19b..a050509c9 100644 --- a/plugins/dbms/sqlite/fingerprint.py +++ b/plugins/dbms/sqlite/fingerprint.py @@ -15,6 +15,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import SQLITE_ALIASES from lib.request import inject from lib.request.connect import Connect as Request @@ -69,7 +70,7 @@ class Fingerprint(GenericFingerprint): """ if conf.dbms in SQLITE_ALIASES: - setDbms("SQLite") + setDbms(DBMS.SQLITE) self.getBanner() @@ -95,7 +96,7 @@ class Fingerprint(GenericFingerprint): return False - setDbms("SQLite") + setDbms(DBMS.SQLITE) self.getBanner() diff --git a/plugins/dbms/sybase/enumeration.py b/plugins/dbms/sybase/enumeration.py index 8c10c6edd..a5ddea132 100644 --- a/plugins/dbms/sybase/enumeration.py +++ b/plugins/dbms/sybase/enumeration.py @@ -10,9 +10,10 @@ See the file 'doc/COPYING' for copying permission from lib.core.data import conf from lib.core.data import logger from lib.core.exception import sqlmapUnsupportedFeatureException +from lib.core.settings import DBMS from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): def __init__(self): - GenericEnumeration.__init__(self, "Sybase") + GenericEnumeration.__init__(self, DBMS.SYBASE) diff --git a/plugins/dbms/sybase/fingerprint.py b/plugins/dbms/sybase/fingerprint.py index 17ede81e9..24578249b 100644 --- a/plugins/dbms/sybase/fingerprint.py +++ b/plugins/dbms/sybase/fingerprint.py @@ -16,6 +16,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.session import setDbms +from lib.core.settings import DBMS from lib.core.settings import SYBASE_ALIASES from lib.request import inject from lib.request.connect import Connect as Request @@ -63,7 +64,7 @@ class Fingerprint(GenericFingerprint): def checkDbms(self): if conf.dbms in SYBASE_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit(): - setDbms("Sybase %s" % kb.dbmsVersion[0]) + setDbms("%s %s" % (DBMS.SYBASE, kb.dbmsVersion[0])) self.getBanner() @@ -94,7 +95,7 @@ class Fingerprint(GenericFingerprint): return False - setDbms("Sybase") + setDbms(DBMS.SYBASE) self.getBanner() diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index 2bd7ccb86..a8ddf9313 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -35,6 +35,7 @@ from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapUnsupportedFeatureException from lib.core.exception import sqlmapUserQuitException from lib.core.session import setOs +from lib.core.settings import DBMS from lib.core.settings import SQL_STATEMENTS from lib.core.shell import autoCompletion from lib.core.unescaper import unescaper @@ -135,8 +136,8 @@ class Enumeration: rootQuery = queries[kb.dbms].users - condition = ( kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ) ) - condition |= ( kb.dbms == "MySQL" and not kb.data.has_information_schema ) + condition = ( kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ) ) + condition |= ( kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema ) if kb.unionPosition is not None or conf.direct: if condition: @@ -162,14 +163,14 @@ class Enumeration: errMsg = "unable to retrieve the number of database users" raise sqlmapNoneDataException, errMsg - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: plusOne = True else: plusOne = False indexRange = getRange(count, plusOne=plusOne) for index in indexRange: - if kb.dbms == "Sybase": + if kb.dbms == DBMS.SYBASE: query = rootQuery.blind.query % (kb.data.cachedUsers[-1] if kb.data.cachedUsers else " ") elif condition: query = rootQuery.blind.query2 % index @@ -198,7 +199,7 @@ class Enumeration: logger.info(infoMsg) if kb.unionPosition is not None or conf.direct: - if kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ): + if kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): query = rootQuery.inband.query2 else: query = rootQuery.inband.query @@ -211,7 +212,7 @@ class Enumeration: query += " WHERE " query += " OR ".join("%s = '%s'" % (condition, user) for user in users) else: - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: parsedUser = re.search("[\047]*(.*?)[\047]*\@", conf.user) if parsedUser: @@ -248,7 +249,7 @@ class Enumeration: retrievedUsers = set() for user in users: - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: parsedUser = re.search("[\047]*(.*?)[\047]*\@", user) if parsedUser: @@ -261,7 +262,7 @@ class Enumeration: infoMsg += "for user '%s'" % user logger.info(infoMsg) - if kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ): + if kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): query = rootQuery.blind.count2 % user else: query = rootQuery.blind.count % user @@ -278,14 +279,14 @@ class Enumeration: passwords = [] - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: plusOne = True else: plusOne = False indexRange = getRange(count, plusOne=plusOne) for index in indexRange: - if kb.dbms == "Sybase": + if kb.dbms == DBMS.SYBASE: if index > 0: warnMsg = "unable to retrieve other password " warnMsg += "hashes for user '%s'" % user @@ -295,7 +296,7 @@ class Enumeration: query = rootQuery.blind.query % user pushValue(conf.verbose) conf.verbose = 0 - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: if kb.dbmsVersion[0] in ( "2005", "2008" ): query = rootQuery.blind.query2 % (user, index, user) else: @@ -303,7 +304,7 @@ class Enumeration: else: query = rootQuery.blind.query % (user, index) password = inject.getValue(query, inband=False) - if kb.dbms == "Sybase": + if kb.dbms == DBMS.SYBASE: conf.verbose = popValue() password = "0x%s" % strToHex(password) infoMsg = "retrieved: %s" % password @@ -330,24 +331,24 @@ class Enumeration: def __isAdminFromPrivileges(self, privileges): # In PostgreSQL the usesuper privilege means that the # user is DBA - dbaCondition = ( kb.dbms == "PostgreSQL" and "super" in privileges ) + dbaCondition = ( kb.dbms == DBMS.POSTGRESQL and "super" in privileges ) # In Oracle the DBA privilege means that the # user is DBA - dbaCondition |= ( kb.dbms == "Oracle" and "DBA" in privileges ) + dbaCondition |= ( kb.dbms == DBMS.ORACLE and "DBA" in privileges ) # In MySQL >= 5.0 the SUPER privilege means # that the user is DBA - dbaCondition |= ( kb.dbms == "MySQL" and kb.data.has_information_schema and "SUPER" in privileges ) + dbaCondition |= ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema and "SUPER" in privileges ) # In MySQL < 5.0 the super_priv privilege means # that the user is DBA - dbaCondition |= ( kb.dbms == "MySQL" and not kb.data.has_information_schema and "super_priv" in privileges ) + dbaCondition |= ( kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema and "super_priv" in privileges ) # In Firebird there is no specific privilege that means # that the user is DBA # TODO: confirm - dbaCondition |= ( kb.dbms == "Firebird" and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges ) + dbaCondition |= ( kb.dbms == DBMS.FIREBIRD and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges ) return dbaCondition @@ -410,10 +411,10 @@ class Enumeration: } if kb.unionPosition is not None or conf.direct: - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.inband.query2 condition = rootQuery.inband.condition2 - elif kb.dbms == "Oracle" and query2: + elif kb.dbms == DBMS.ORACLE and query2: query = rootQuery.inband.query2 condition = rootQuery.inband.condition2 else: @@ -425,7 +426,7 @@ class Enumeration: query += " WHERE " # NOTE: I assume that the user provided is not in # MySQL >= 5.0 syntax 'user'@'host' - if kb.dbms == "MySQL" and kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema: queryUser = "%" + conf.user + "%" query += " OR ".join("%s LIKE '%s'" % (condition, "%" + user + "%") for user in users) else: @@ -433,7 +434,7 @@ class Enumeration: values = inject.getValue(query, blind=False, error=False) - if not values and kb.dbms == "Oracle" and not query2: + if not values and kb.dbms == DBMS.ORACLE and not query2: infoMsg = "trying with table USER_SYS_PRIVS" logger.info(infoMsg) @@ -455,19 +456,19 @@ class Enumeration: # In PostgreSQL we get 1 if the privilege is # True, 0 otherwise - if kb.dbms == "PostgreSQL" and getUnicode(privilege).isdigit(): + if kb.dbms == DBMS.POSTGRESQL and getUnicode(privilege).isdigit(): for position, pgsqlPriv in pgsqlPrivs: if count == position and int(privilege) == 1: privileges.add(pgsqlPriv) # In MySQL >= 5.0 and Oracle we get the list # of privileges as string - elif kb.dbms == "Oracle" or ( kb.dbms == "MySQL" and kb.data.has_information_schema ): + elif kb.dbms == DBMS.ORACLE or ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema ): privileges.add(privilege) # In MySQL < 5.0 we get Y if the privilege is # True, N otherwise - elif kb.dbms == "MySQL" and not kb.data.has_information_schema: + elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: for position, mysqlPriv in mysqlPrivs: if count == position and privilege.upper() == "Y": privileges.add(mysqlPriv) @@ -484,7 +485,7 @@ class Enumeration: conditionChar = "=" if conf.user: - if kb.dbms == "MySQL" and kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema: conditionChar = " LIKE " if "," in conf.user: @@ -511,7 +512,7 @@ class Enumeration: for user in users: unescapedUser = None - if kb.dbms == "MySQL" and kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema: unescapedUser = unescaper.unescape(user, quote=False) if user in retrievedUsers: @@ -526,18 +527,18 @@ class Enumeration: else: queryUser = user - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.blind.count2 % queryUser - elif kb.dbms == "MySQL" and kb.data.has_information_schema: + elif kb.dbms == DBMS.MYSQL and kb.data.has_information_schema: query = rootQuery.blind.count % (conditionChar, queryUser) - elif kb.dbms == "Oracle" and query2: + elif kb.dbms == DBMS.ORACLE and query2: query = rootQuery.blind.count2 % queryUser else: query = rootQuery.blind.count % queryUser count = inject.getValue(query, inband=False, expected="int", charsetType=2) if not count.isdigit() or not len(count) or count == "0": - if not count.isdigit() and kb.dbms == "Oracle" and not query2: + if not count.isdigit() and kb.dbms == DBMS.ORACLE and not query2: infoMsg = "trying with table USER_SYS_PRIVS" logger.info(infoMsg) @@ -553,20 +554,20 @@ class Enumeration: privileges = set() - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: plusOne = True else: plusOne = False indexRange = getRange(count, plusOne=plusOne) for index in indexRange: - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.blind.query2 % (queryUser, index) - elif kb.dbms == "MySQL" and kb.data.has_information_schema: + elif kb.dbms == DBMS.MYSQL and kb.data.has_information_schema: query = rootQuery.blind.query % (conditionChar, queryUser, index) - elif kb.dbms == "Oracle" and query2: + elif kb.dbms == DBMS.ORACLE and query2: query = rootQuery.blind.query2 % (queryUser, index) - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: query = rootQuery.blind.query % (index, queryUser) else: query = rootQuery.blind.query % (queryUser, index) @@ -574,7 +575,7 @@ class Enumeration: # In PostgreSQL we get 1 if the privilege is True, # 0 otherwise - if kb.dbms == "PostgreSQL" and ", " in privilege: + if kb.dbms == DBMS.POSTGRESQL and ", " in privilege: privilege = privilege.replace(", ", ",") privs = privilege.split(",") i = 1 @@ -589,12 +590,12 @@ class Enumeration: # In MySQL >= 5.0 and Oracle we get the list # of privileges as string - elif kb.dbms == "Oracle" or ( kb.dbms == "MySQL" and kb.data.has_information_schema ): + elif kb.dbms == DBMS.ORACLE or ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema ): privileges.add(privilege) # In MySQL < 5.0 we get Y if the privilege is # True, N otherwise - elif kb.dbms == "MySQL" and not kb.data.has_information_schema: + elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: privilege = privilege.replace(", ", ",") privs = privilege.split(",") i = 1 @@ -608,7 +609,7 @@ class Enumeration: i += 1 # In Firebird we get one letter for each privilege - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: privileges.add(firebirdPrivs[privilege.strip()]) if self.__isAdminFromPrivileges(privileges): @@ -617,7 +618,7 @@ class Enumeration: # In MySQL < 5.0 we break the cycle after the first # time we get the user's privileges otherwise we # duplicate the same query - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: break if privileges: @@ -644,7 +645,7 @@ class Enumeration: return self.getPrivileges(query2) def getDbs(self): - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: warnMsg = "information_schema not available, " warnMsg += "back-end DBMS is MySQL < 5. database " warnMsg += "names will be fetched from 'mysql' database" @@ -656,7 +657,7 @@ class Enumeration: rootQuery = queries[kb.dbms].dbs if kb.unionPosition is not None or conf.direct: - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.inband.query2 else: query = rootQuery.inband.query @@ -669,7 +670,7 @@ class Enumeration: infoMsg = "fetching number of databases" logger.info(infoMsg) - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.blind.count2 else: query = rootQuery.blind.count @@ -682,9 +683,9 @@ class Enumeration: indexRange = getRange(count) for index in indexRange: - if kb.dbms == "Sybase": + if kb.dbms == DBMS.SYBASE: query = rootQuery.blind.query % (kb.data.cachedDbs[-1] if kb.data.cachedDbs else " ") - elif kb.dbms == "MySQL" and not kb.data.has_information_schema: + elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.blind.query2 % index else: query = rootQuery.blind.query % index @@ -702,13 +703,13 @@ class Enumeration: def getTables(self): bruteForce = False - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: errMsg = "information_schema not available, " errMsg += "back-end DBMS is MySQL < 5.0" logger.error(errMsg) bruteForce = True - elif kb.dbms == "Microsoft Access": + elif kb.dbms == DBMS.ACCESS: errMsg = "cannot retrieve table names, " errMsg += "back-end DBMS is Access" logger.error(errMsg) @@ -738,7 +739,7 @@ class Enumeration: query = rootQuery.inband.query condition = rootQuery.inband.condition - if conf.db and kb.dbms != "SQLite": + if conf.db and kb.dbms != DBMS.SQLITE: if "," in conf.db: dbs = conf.db.split(",") query += " WHERE " @@ -754,14 +755,14 @@ class Enumeration: value = inject.getValue(query, blind=False, error=False) if value: - if kb.dbms == "SQLite": + if kb.dbms == DBMS.SQLITE: if isinstance(value, basestring): - value = [[ "SQLite", value ]] + value = [[ DBMS.SQLITE, value ]] elif isinstance(value, (list, tuple, set)): newValue = [] for v in value: - newValue.append([ "SQLite", v]) + newValue.append([ DBMS.SQLITE, v]) value = newValue @@ -794,7 +795,7 @@ class Enumeration: infoMsg += "database '%s'" % db logger.info(infoMsg) - if kb.dbms in ("SQLite", "Firebird"): + if kb.dbms in (DBMS.SQLITE, DBMS.FIREBIRD): query = rootQuery.blind.count else: query = rootQuery.blind.count % db @@ -808,16 +809,16 @@ class Enumeration: tables = [] - if kb.dbms in ( "Microsoft SQL Server", "Oracle" ): + if kb.dbms in ( DBMS.MSSQL, DBMS.ORACLE ): plusOne = True else: plusOne = False indexRange = getRange(count, plusOne=plusOne) for index in indexRange: - if kb.dbms == "Sybase": + if kb.dbms == DBMS.SYBASE: query = rootQuery.blind.query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")) - elif kb.dbms in ("SQLite", "Firebird"): + elif kb.dbms in (DBMS.SQLITE, DBMS.FIREBIRD): query = rootQuery.blind.query % index else: query = rootQuery.blind.query % (db, index) @@ -875,7 +876,7 @@ class Enumeration: return retVal def getColumns(self, onlyColNames=False): - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: errMsg = "information_schema not available, " errMsg += "back-end DBMS is MySQL < 5.0" raise sqlmapUnsupportedFeatureException, errMsg @@ -920,7 +921,7 @@ class Enumeration: infoMsg = "fetching columns " if conf.col: - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: conf.col = conf.col.upper() colList = conf.col.split(",") condQuery = " AND (" + " OR ".join("%s LIKE '%s'" % (condition, "%" + col + "%") for col in colList) + ")" @@ -933,19 +934,19 @@ class Enumeration: logger.info(infoMsg) if kb.unionPosition is not None or conf.direct: - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): query = rootQuery.inband.query % (conf.tbl, conf.db) query += condQuery - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: query = rootQuery.inband.query % conf.tbl.upper() query += condQuery - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.tbl) query += condQuery.replace("[DB]", conf.db) - elif kb.dbms == "SQLite": + elif kb.dbms == DBMS.SQLITE: query = rootQuery.inband.query % conf.tbl value = inject.getValue(query, blind=False, error=False) @@ -954,7 +955,7 @@ class Enumeration: table = {} columns = {} - if kb.dbms == "SQLite": + if kb.dbms == DBMS.SQLITE: for match in re.finditer(getCompiledRegex(r"(\w+) ([A-Z]+)[,\r\n]"), value): columns[match.group(1)] = match.group(2) else: @@ -970,16 +971,16 @@ class Enumeration: infoMsg += " on database '%s'" % conf.db logger.info(infoMsg) - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): query = rootQuery.blind.count % (conf.tbl, conf.db) query += condQuery - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: query = rootQuery.blind.count % conf.tbl.upper() query += condQuery - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: query = rootQuery.blind.count % (conf.db, conf.db, conf.tbl) query += condQuery.replace("[DB]", conf.db) - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: query = rootQuery.blind.count % (conf.tbl) query += condQuery @@ -997,22 +998,22 @@ class Enumeration: indexRange = getRange(count) for index in indexRange: - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): query = rootQuery.blind.query % (conf.tbl, conf.db) query += condQuery field = None - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: query = rootQuery.blind.query % (conf.tbl.upper()) query += condQuery field = None - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: query = rootQuery.blind.query % (conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.tbl) query += condQuery.replace("[DB]", conf.db) field = condition.replace("[DB]", conf.db) - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: query = rootQuery.blind.query % (conf.tbl) query += condQuery field = None @@ -1021,20 +1022,20 @@ class Enumeration: column = inject.getValue(query, inband=False) if not onlyColNames: - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): query = rootQuery.blind.query2 % (conf.tbl, column, conf.db) - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: query = rootQuery.blind.query2 % (conf.tbl.upper(), column) - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db, conf.db, column, conf.db, conf.db, conf.db, conf.tbl) - elif kb.dbms == "Firebird": + elif kb.dbms == DBMS.FIREBIRD: query = rootQuery.blind.query2 % (conf.tbl, column) colType = inject.getValue(query, inband=False) - if kb.dbms == "Firebird": + if kb.dbms == DBMS.FIREBIRD: colType = firebirdTypes[colType] if colType in firebirdTypes else colType columns[column] = colType @@ -1091,7 +1092,7 @@ class Enumeration: kb.data.cachedColumns[conf.db][conf.tbl][column] = None elif not kb.data.cachedColumns: - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: errMsg = "information_schema not available, " errMsg += "back-end DBMS is MySQL < 5.0" raise sqlmapUnsupportedFeatureException, errMsg @@ -1112,9 +1113,9 @@ class Enumeration: entriesCount = 0 if kb.unionPosition is not None or conf.direct: - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: query = rootQuery.inband.query % (colString, conf.tbl.upper()) - elif kb.dbms == "SQLite": + elif kb.dbms == DBMS.SQLITE: query = rootQuery.inband.query % (colString, conf.tbl) else: query = rootQuery.inband.query % (colString, conf.db, conf.tbl) @@ -1160,9 +1161,9 @@ class Enumeration: infoMsg += "on database '%s'" % conf.db logger.info(infoMsg) - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: query = rootQuery.blind.count % conf.tbl.upper() - elif kb.dbms == "SQLite": + elif kb.dbms == DBMS.SQLITE: query = rootQuery.blind.count % conf.tbl else: query = rootQuery.blind.count % (conf.db, conf.tbl) @@ -1182,7 +1183,7 @@ class Enumeration: lengths = {} entries = {} - if kb.dbms in ("Oracle", "Microsoft SQL Server", "Sybase"): + if kb.dbms in (DBMS.ORACLE, DBMS.MSSQL, DBMS.SYBASE): plusOne = True else: plusOne = False @@ -1196,19 +1197,19 @@ class Enumeration: if column not in entries: entries[column] = [] - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): query = rootQuery.blind.query % (column, conf.db, conf.tbl, index) - elif kb.dbms == "Oracle": + elif kb.dbms == DBMS.ORACLE: query = rootQuery.blind.query % (column, column, conf.tbl.upper(), index) - elif kb.dbms in ("Microsoft SQL Server", "Sybase"): + elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): query = rootQuery.blind.query % (column, index, conf.db, conf.tbl, colList[0], colList[0], colList[0]) - elif kb.dbms == "SQLite": + elif kb.dbms == DBMS.SQLITE: query = rootQuery.blind.query % (column, conf.tbl, index) value = inject.getValue(query, inband=False) @@ -1245,7 +1246,7 @@ class Enumeration: return kb.data.dumpedTable def dumpAll(self): - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: errMsg = "information_schema not available, " errMsg += "back-end DBMS is MySQL < 5.0" raise sqlmapUnsupportedFeatureException, errMsg @@ -1345,7 +1346,7 @@ class Enumeration: rootQuery = queries[kb.dbms].search_db dbList = conf.db.split(",") - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: dbCond = rootQuery.inband.condition2 else: dbCond = rootQuery.inband.condition @@ -1370,7 +1371,7 @@ class Enumeration: dbQuery = dbQuery % db if kb.unionPosition is not None or conf.direct: - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.inband.query2 else: query = rootQuery.inband.query @@ -1391,7 +1392,7 @@ class Enumeration: infoMsg += " '%s'" % db logger.info(infoMsg) - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.blind.count2 else: query = rootQuery.blind.count @@ -1411,7 +1412,7 @@ class Enumeration: indexRange = getRange(count) for index in indexRange: - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: query = rootQuery.blind.query2 else: query = rootQuery.blind.query @@ -1424,7 +1425,7 @@ class Enumeration: return foundDbs def searchTable(self): - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: errMsg = "information_schema not available, " errMsg += "back-end DBMS is MySQL < 5.0" raise sqlmapUnsupportedFeatureException, errMsg @@ -1438,7 +1439,7 @@ class Enumeration: tblConsider, tblCondParam = self.likeOrExact("table") for tbl in tblList: - if kb.dbms == "Oracle": + if kb.dbms == DBMS.ORACLE: tbl = tbl.upper() infoMsg = "searching table" @@ -1545,7 +1546,7 @@ class Enumeration: return foundTbls def searchColumn(self): - if kb.dbms == "MySQL" and not kb.data.has_information_schema: + if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: errMsg = "information_schema not available, " errMsg += "back-end DBMS is MySQL < 5.0" raise sqlmapUnsupportedFeatureException, errMsg diff --git a/plugins/generic/filesystem.py b/plugins/generic/filesystem.py index 142c35f01..c71a5b72a 100644 --- a/plugins/generic/filesystem.py +++ b/plugins/generic/filesystem.py @@ -19,6 +19,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.exception import sqlmapUndefinedMethod +from lib.core.settings import DBMS from lib.request import inject from lib.techniques.outband.stacked import stackedTest @@ -84,13 +85,13 @@ class Filesystem: return fileLines def __checkWrittenFile(self, wFile, dFile, fileType): - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile - elif kb.dbms == "PostgreSQL": + elif kb.dbms == DBMS.POSTGRESQL: lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self.oid - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: self.createSupportTbl(self.fileTblName, self.tblField, "text") # Reference: http://msdn.microsoft.com/en-us/library/ms188365.aspx diff --git a/plugins/generic/misc.py b/plugins/generic/misc.py index 893abd4f9..bb05dd009 100644 --- a/plugins/generic/misc.py +++ b/plugins/generic/misc.py @@ -21,6 +21,7 @@ from lib.core.data import queries from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapUnsupportedFeatureException from lib.core.session import setRemoteTempPath +from lib.core.settings import DBMS from lib.request import inject from lib.techniques.outband.stacked import stackedTest @@ -55,13 +56,13 @@ class Miscellaneous: infoMsg = "detecting back-end DBMS version from its banner" logger.info(infoMsg) - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: first, last = 1, 6 - elif kb.dbms == "PostgreSQL": + elif kb.dbms == DBMS.POSTGRESQL: first, last = 12, 6 - elif kb.dbms == "Microsoft SQL Server": + elif kb.dbms == DBMS.MSSQL: first, last = 29, 9 else: @@ -120,7 +121,7 @@ class Miscellaneous: if not onlyFileTbl: inject.goStacked("DROP TABLE %s" % self.cmdTblName, silent=True) - if kb.dbms == "Microsoft SQL Server": + if kb.dbms == DBMS.MSSQL: return if udfDict is None: @@ -133,7 +134,7 @@ class Miscellaneous: if not output or output in ("y", "Y"): dropStr = "DROP FUNCTION %s" % udf - if kb.dbms == "PostgreSQL": + if kb.dbms == DBMS.POSTGRESQL: inp = ", ".join(i for i in inpRet["input"]) dropStr += "(%s)" % inp diff --git a/plugins/generic/takeover.py b/plugins/generic/takeover.py index f7c6bcedf..52ada1213 100644 --- a/plugins/generic/takeover.py +++ b/plugins/generic/takeover.py @@ -20,6 +20,7 @@ from lib.core.exception import sqlmapMissingPrivileges from lib.core.exception import sqlmapNotVulnerableException from lib.core.exception import sqlmapUndefinedMethod from lib.core.exception import sqlmapUnsupportedDBMSException +from lib.core.settings import DBMS from lib.takeover.abstraction import Abstraction from lib.takeover.icmpsh import ICMPsh from lib.takeover.metasploit import Metasploit @@ -45,7 +46,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): if kb.stackedTest or conf.direct: web = False - elif not kb.stackedTest and kb.dbms == "MySQL": + elif not kb.stackedTest and kb.dbms == DBMS.MYSQL: infoMsg = "going to use a web backdoor for command execution" logger.info(infoMsg) @@ -68,7 +69,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): if kb.stackedTest or conf.direct: web = False - elif not kb.stackedTest and kb.dbms == "MySQL": + elif not kb.stackedTest and kb.dbms == DBMS.MYSQL: infoMsg = "going to use a web backdoor for command prompt" logger.info(infoMsg) @@ -153,7 +154,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): errMsg += "is unlikely to receive commands send from you" logger.error(errMsg) - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSGRESQL ): self.sysUdfs.pop("sys_bineval") if kb.stackedTest or conf.direct: @@ -163,7 +164,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): self.initEnv(web=web) if tunnel == 1: - if kb.dbms in ( "MySQL", "PostgreSQL" ): + if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ): msg = "how do you want to execute the Metasploit shellcode " msg += "on the back-end database underlying operating system?" msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)" @@ -193,7 +194,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): self.uploadMsfPayloadStager() if kb.os == "Windows" and conf.privEsc: - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: debugMsg = "by default MySQL on Windows runs as SYSTEM " debugMsg += "user, no need to privilege escalate" logger.debug(debugMsg) @@ -211,7 +212,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): self.uploadIcmpshSlave(web=web) self.icmpPwn() - elif not kb.stackedTest and kb.dbms == "MySQL": + elif not kb.stackedTest and kb.dbms == DBMS.MYSQL: web = True infoMsg = "going to use a web backdoor to establish the tunnel" @@ -262,13 +263,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): raise sqlmapUnsupportedDBMSException(errMsg) if not kb.stackedTest and not conf.direct: - if kb.dbms in ( "PostgreSQL", "Microsoft SQL Server" ): + if kb.dbms in ( DBMS.POSTGRESQL, DBMS.MSSQL ): errMsg = "on this back-end DBMS it is only possible to " errMsg += "perform the SMB relay attack if stacked " errMsg += "queries are supported" raise sqlmapUnsupportedDBMSException(errMsg) - elif kb.dbms == "MySQL": + elif kb.dbms == DBMS.MYSQL: debugMsg = "since stacked queries are not supported, " debugMsg += "sqlmap is going to perform the SMB relay " debugMsg += "attack via inference blind SQL injection" @@ -277,18 +278,18 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): printWarn = True warnMsg = "it is unlikely that this attack will be successful " - if kb.dbms == "MySQL": + if kb.dbms == DBMS.MYSQL: warnMsg += "because by default MySQL on Windows runs as " warnMsg += "Local System which is not a real user, it does " warnMsg += "not send the NTLM session hash when connecting to " warnMsg += "a SMB service" - elif kb.dbms == "PostgreSQL": + elif kb.dbms == DBMS.POSTGRESQL: warnMsg += "because by default PostgreSQL on Windows runs " warnMsg += "as postgres user which is a real user of the " warnMsg += "system, but not within the Administrators group" - elif kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ): + elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): warnMsg += "because often Microsoft SQL Server %s " % kb.dbmsVersion[0] warnMsg += "runs as Network Service which is not a real user, " warnMsg += "it does not send the NTLM session hash when " @@ -308,7 +309,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): if not kb.stackedTest and not conf.direct: return - if not kb.dbms == "Microsoft SQL Server" or kb.dbmsVersion[0] not in ( "2000", "2005" ): + if not kb.dbms == DBMS.MSSQL or kb.dbmsVersion[0] not in ( "2000", "2005" ): errMsg = "the back-end DBMS must be Microsoft SQL Server " errMsg += "2000 or 2005 to be able to exploit the heap-based " errMsg += "buffer overflow in the 'sp_replwritetovarbin' "