From ff529311403a292ce4eddfd200e792b053190fbe Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Sat, 7 Jan 2012 19:30:35 +0000 Subject: [PATCH] some refactoring (skipping duplicate messages in case that UNION/ERROR techniques failed and BOOLEAN/TIMED/STACKED are not available) --- lib/core/common.py | 5 +++- plugins/dbms/mssqlserver/enumeration.py | 9 ++++--- plugins/dbms/oracle/enumeration.py | 5 ++-- plugins/dbms/sybase/enumeration.py | 8 +++--- plugins/generic/enumeration.py | 36 +++++++++++++------------ 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index 2f5494b98..35911b08f 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -2486,7 +2486,7 @@ def getTechniqueData(technique=None): return retVal -def isTechniqueAvailable(technique=None): +def isTechniqueAvailable(technique): """ Returns True if there is injection data which sqlmap could use for technique specified @@ -2497,6 +2497,9 @@ def isTechniqueAvailable(technique=None): else: return getTechniqueData(technique) is not None +def isInferenceAvailable(): + return any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.STACKED, PAYLOAD.TECHNIQUE.TIME)) + def setOptimize(): #conf.predictOutput = True conf.keepAlive = True diff --git a/plugins/dbms/mssqlserver/enumeration.py b/plugins/dbms/mssqlserver/enumeration.py index 650e6baa3..d10797e5f 100644 --- a/plugins/dbms/mssqlserver/enumeration.py +++ b/plugins/dbms/mssqlserver/enumeration.py @@ -11,6 +11,7 @@ from lib.core.agent import agent from lib.core.common import arrayizeValue from lib.core.common import Backend from lib.core.common import getRange +from lib.core.common import isInferenceAvailable from lib.core.common import isNoneValue from lib.core.common import isNumPosStrValue from lib.core.common import isTechniqueAvailable @@ -85,7 +86,7 @@ class Enumeration(GenericEnumeration): rootQuery = queries[Backend.getIdentifiedDbms()].tables - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: for db in dbs: if conf.excludeSysDbs and db in self.excludeDbsList: infoMsg = "skipping system database '%s'" % db @@ -102,7 +103,7 @@ class Enumeration(GenericEnumeration): if not isNoneValue(value): kb.data.cachedTables[db] = arrayizeValue(value) - if not kb.data.cachedTables and not conf.direct: + if not kb.data.cachedTables and isInferenceAvailable() and not conf.direct: for db in dbs: if conf.excludeSysDbs and db in self.excludeDbsList: infoMsg = "skipping system database '%s'" % db @@ -190,7 +191,7 @@ class Enumeration(GenericEnumeration): continue - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: query = rootQuery.inband.query % db query += tblQuery values = inject.getValue(query, blind=False) @@ -283,7 +284,7 @@ class Enumeration(GenericEnumeration): continue - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: query = rootQuery.inband.query % (db, db, db, db, db, db) query += " AND %s" % colQuery.replace("[DB]", db) values = inject.getValue(query, blind=False) diff --git a/plugins/dbms/oracle/enumeration.py b/plugins/dbms/oracle/enumeration.py index 142a36b02..6cb3b03b0 100644 --- a/plugins/dbms/oracle/enumeration.py +++ b/plugins/dbms/oracle/enumeration.py @@ -10,6 +10,7 @@ See the file 'doc/COPYING' for copying permission from lib.core.agent import agent from lib.core.common import Backend from lib.core.common import getRange +from lib.core.common import isInferenceAvailable from lib.core.common import isNoneValue from lib.core.common import isNumPosStrValue from lib.core.common import isTechniqueAvailable @@ -44,7 +45,7 @@ class Enumeration(GenericEnumeration): # Set containing the list of DBMS administrators areAdmins = set() - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: if query2: query = rootQuery.inband.query2 condition = rootQuery.inband.condition2 @@ -90,7 +91,7 @@ class Enumeration(GenericEnumeration): else: kb.data.cachedUsersRoles[user] = list(roles) - if not kb.data.cachedUsersRoles and not conf.direct: + if not kb.data.cachedUsersRoles and isInferenceAvailable() and not conf.direct: conditionChar = "=" if conf.user: diff --git a/plugins/dbms/sybase/enumeration.py b/plugins/dbms/sybase/enumeration.py index fd15a72b7..fb48398dc 100644 --- a/plugins/dbms/sybase/enumeration.py +++ b/plugins/dbms/sybase/enumeration.py @@ -36,7 +36,7 @@ class Enumeration(GenericEnumeration): randStr = randomStr() query = rootQuery.inband.query - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: blinds = [False, True] else: blinds = [True] @@ -90,7 +90,7 @@ class Enumeration(GenericEnumeration): randStr = randomStr() query = rootQuery.inband.query - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: blinds = [False, True] else: blinds = [True] @@ -130,7 +130,7 @@ class Enumeration(GenericEnumeration): infoMsg += "%s: %s" % ("s" if len(dbs) > 1 else "", ", ".join(db for db in sorted(dbs))) logger.info(infoMsg) - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: blinds = [False, True] else: blinds = [True] @@ -204,7 +204,7 @@ class Enumeration(GenericEnumeration): rootQuery = queries[Backend.getIdentifiedDbms()].columns - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: blinds = [False, True] else: blinds = [True] diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index 24a39d049..aaf720e07 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -20,6 +20,7 @@ from lib.core.common import filterPairValues from lib.core.common import getRange from lib.core.common import getCompiledRegex from lib.core.common import getUnicode +from lib.core.common import isInferenceAvailable from lib.core.common import isNoneValue from lib.core.common import isNumPosStrValue from lib.core.common import isTechniqueAvailable @@ -176,7 +177,7 @@ class Enumeration: condition = ( Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")) ) condition |= ( Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema ) - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: if condition: query = rootQuery.inband.query2 else: @@ -186,7 +187,7 @@ class Enumeration: if not isNoneValue(value): kb.data.cachedUsers = arrayizeValue(value) - if not kb.data.cachedUsers and not conf.direct: + if not kb.data.cachedUsers and isInferenceAvailable() and not conf.direct: infoMsg = "fetching number of database users" logger.info(infoMsg) @@ -252,7 +253,7 @@ class Enumeration: users = filter(None, users) - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")): query = rootQuery.inband.query2 else: @@ -293,7 +294,7 @@ class Enumeration: else: kb.data.cachedUsersPasswords[user].append(password) - if not kb.data.cachedUsersPasswords and not conf.direct: + if not kb.data.cachedUsersPasswords and isInferenceAvailable() and not conf.direct: if not len(users): users = self.getUsers() @@ -452,7 +453,7 @@ class Enumeration: # Set containing the list of DBMS administrators areAdmins = set() - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema: query = rootQuery.inband.query2 condition = rootQuery.inband.condition2 @@ -537,7 +538,7 @@ class Enumeration: else: kb.data.cachedUsersPrivileges[user] = list(privileges) - if not kb.data.cachedUsersPrivileges and not conf.direct: + if not kb.data.cachedUsersPrivileges and isInferenceAvailable() and not conf.direct: if Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema: conditionChar = " LIKE " else: @@ -736,7 +737,7 @@ class Enumeration: rootQuery = queries[Backend.getIdentifiedDbms()].dbs - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema: query = rootQuery.inband.query2 else: @@ -746,7 +747,7 @@ class Enumeration: if not isNoneValue(value): kb.data.cachedDbs = arrayizeValue(value) - if not kb.data.cachedDbs and not conf.direct: + if not kb.data.cachedDbs and isInferenceAvailable() and not conf.direct: infoMsg = "fetching number of databases" logger.info(infoMsg) @@ -870,7 +871,7 @@ class Enumeration: rootQuery = queries[Backend.getIdentifiedDbms()].tables - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: query = rootQuery.inband.query condition = rootQuery.inband.condition if 'condition' in rootQuery.inband else None @@ -904,7 +905,7 @@ class Enumeration: else: kb.data.cachedTables[db].append(table) - if not kb.data.cachedTables and not conf.direct: + if not kb.data.cachedTables and isInferenceAvailable() and not conf.direct: for db in dbs: if conf.excludeSysDbs and db in self.excludeDbsList: infoMsg = "skipping system database '%s'" % db @@ -1087,7 +1088,7 @@ class Enumeration: rootQuery = queries[Backend.getIdentifiedDbms()].columns condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: for tbl in tblList: if conf.db is not None and len(kb.data.cachedColumns) > 0 \ and conf.db in kb.data.cachedColumns and tbl in \ @@ -1156,7 +1157,7 @@ class Enumeration: table[safeSQLIdentificatorNaming(tbl, True)] = columns kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table - if not kb.data.cachedColumns and not conf.direct: + if not kb.data.cachedColumns and isInferenceAvailable() and not conf.direct: for tbl in tblList: if conf.db is not None and len(kb.data.cachedColumns) > 0 \ and conf.db in kb.data.cachedColumns and tbl in \ @@ -1565,7 +1566,8 @@ class Enumeration: or not kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]: warnMsg = "unable to enumerate the columns for table " warnMsg += "'%s' on database" % unsafeSQLIdentificatorNaming(tbl) - warnMsg += " '%s', skipping" % unsafeSQLIdentificatorNaming(conf.db) + warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(conf.db) + warnMsg += ", skipping" if len(tblList) > 1 else "" logger.warn(warnMsg) continue @@ -1660,7 +1662,7 @@ class Enumeration: index += 1 - if not kb.data.dumpedTable and not conf.direct: + if not kb.data.dumpedTable and isInferenceAvailable() and not conf.direct: infoMsg = "fetching number of " if conf.col: infoMsg += "column(s) '%s' " % colString @@ -1924,7 +1926,7 @@ class Enumeration: dbQuery = "%s%s" % (dbCond, dbCondParam) dbQuery = dbQuery % unsafeSQLIdentificatorNaming(db) - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema: query = rootQuery.inband.query2 else: @@ -2044,7 +2046,7 @@ class Enumeration: tblQuery = "%s%s" % (tblCond, tblCondParam) tblQuery = tblQuery % tbl - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: query = rootQuery.inband.query query += tblQuery query += whereDbsQuery @@ -2213,7 +2215,7 @@ class Enumeration: colQuery = "%s%s" % (colCond, colCondParam) colQuery = colQuery % unsafeSQLIdentificatorNaming(column) - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: + if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR)) or conf.direct: if not all((conf.db, conf.tbl)): query = rootQuery.inband.query query += colQuery