some refactoring (skipping duplicate messages in case that UNION/ERROR techniques failed and BOOLEAN/TIMED/STACKED are not available)

This commit is contained in:
Miroslav Stampar 2012-01-07 19:30:35 +00:00
parent 18930539cd
commit ff52931140
5 changed files with 35 additions and 28 deletions

View File

@ -2486,7 +2486,7 @@ def getTechniqueData(technique=None):
return retVal return retVal
def isTechniqueAvailable(technique=None): def isTechniqueAvailable(technique):
""" """
Returns True if there is injection data which sqlmap could use for Returns True if there is injection data which sqlmap could use for
technique specified technique specified
@ -2497,6 +2497,9 @@ def isTechniqueAvailable(technique=None):
else: else:
return getTechniqueData(technique) is not None return getTechniqueData(technique) is not None
def isInferenceAvailable():
return any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.STACKED, PAYLOAD.TECHNIQUE.TIME))
def setOptimize(): def setOptimize():
#conf.predictOutput = True #conf.predictOutput = True
conf.keepAlive = True conf.keepAlive = True

View File

@ -11,6 +11,7 @@ from lib.core.agent import agent
from lib.core.common import arrayizeValue from lib.core.common import arrayizeValue
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import getRange from lib.core.common import getRange
from lib.core.common import isInferenceAvailable
from lib.core.common import isNoneValue from lib.core.common import isNoneValue
from lib.core.common import isNumPosStrValue from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
@ -85,7 +86,7 @@ class Enumeration(GenericEnumeration):
rootQuery = queries[Backend.getIdentifiedDbms()].tables 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: for db in dbs:
if conf.excludeSysDbs and db in self.excludeDbsList: if conf.excludeSysDbs and db in self.excludeDbsList:
infoMsg = "skipping system database '%s'" % db infoMsg = "skipping system database '%s'" % db
@ -102,7 +103,7 @@ class Enumeration(GenericEnumeration):
if not isNoneValue(value): if not isNoneValue(value):
kb.data.cachedTables[db] = arrayizeValue(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: for db in dbs:
if conf.excludeSysDbs and db in self.excludeDbsList: if conf.excludeSysDbs and db in self.excludeDbsList:
infoMsg = "skipping system database '%s'" % db infoMsg = "skipping system database '%s'" % db
@ -190,7 +191,7 @@ class Enumeration(GenericEnumeration):
continue 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 = rootQuery.inband.query % db
query += tblQuery query += tblQuery
values = inject.getValue(query, blind=False) values = inject.getValue(query, blind=False)
@ -283,7 +284,7 @@ class Enumeration(GenericEnumeration):
continue 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 = rootQuery.inband.query % (db, db, db, db, db, db)
query += " AND %s" % colQuery.replace("[DB]", db) query += " AND %s" % colQuery.replace("[DB]", db)
values = inject.getValue(query, blind=False) values = inject.getValue(query, blind=False)

View File

@ -10,6 +10,7 @@ See the file 'doc/COPYING' for copying permission
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import getRange from lib.core.common import getRange
from lib.core.common import isInferenceAvailable
from lib.core.common import isNoneValue from lib.core.common import isNoneValue
from lib.core.common import isNumPosStrValue from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
@ -44,7 +45,7 @@ class Enumeration(GenericEnumeration):
# Set containing the list of DBMS administrators # Set containing the list of DBMS administrators
areAdmins = set() 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: if query2:
query = rootQuery.inband.query2 query = rootQuery.inband.query2
condition = rootQuery.inband.condition2 condition = rootQuery.inband.condition2
@ -90,7 +91,7 @@ class Enumeration(GenericEnumeration):
else: else:
kb.data.cachedUsersRoles[user] = list(roles) 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 = "=" conditionChar = "="
if conf.user: if conf.user:

View File

@ -36,7 +36,7 @@ class Enumeration(GenericEnumeration):
randStr = randomStr() randStr = randomStr()
query = rootQuery.inband.query 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] blinds = [False, True]
else: else:
blinds = [True] blinds = [True]
@ -90,7 +90,7 @@ class Enumeration(GenericEnumeration):
randStr = randomStr() randStr = randomStr()
query = rootQuery.inband.query 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] blinds = [False, True]
else: else:
blinds = [True] 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))) infoMsg += "%s: %s" % ("s" if len(dbs) > 1 else "", ", ".join(db for db in sorted(dbs)))
logger.info(infoMsg) 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] blinds = [False, True]
else: else:
blinds = [True] blinds = [True]
@ -204,7 +204,7 @@ class Enumeration(GenericEnumeration):
rootQuery = queries[Backend.getIdentifiedDbms()].columns 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] blinds = [False, True]
else: else:
blinds = [True] blinds = [True]

View File

@ -20,6 +20,7 @@ from lib.core.common import filterPairValues
from lib.core.common import getRange from lib.core.common import getRange
from lib.core.common import getCompiledRegex from lib.core.common import getCompiledRegex
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import isInferenceAvailable
from lib.core.common import isNoneValue from lib.core.common import isNoneValue
from lib.core.common import isNumPosStrValue from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable 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.MSSQL) and Backend.isVersionWithin(("2005", "2008")) )
condition |= ( Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema ) 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: if condition:
query = rootQuery.inband.query2 query = rootQuery.inband.query2
else: else:
@ -186,7 +187,7 @@ class Enumeration:
if not isNoneValue(value): if not isNoneValue(value):
kb.data.cachedUsers = arrayizeValue(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" infoMsg = "fetching number of database users"
logger.info(infoMsg) logger.info(infoMsg)
@ -252,7 +253,7 @@ class Enumeration:
users = filter(None, users) 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")): if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):
query = rootQuery.inband.query2 query = rootQuery.inband.query2
else: else:
@ -293,7 +294,7 @@ class Enumeration:
else: else:
kb.data.cachedUsersPasswords[user].append(password) 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): if not len(users):
users = self.getUsers() users = self.getUsers()
@ -452,7 +453,7 @@ class Enumeration:
# Set containing the list of DBMS administrators # Set containing the list of DBMS administrators
areAdmins = set() 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: if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
query = rootQuery.inband.query2 query = rootQuery.inband.query2
condition = rootQuery.inband.condition2 condition = rootQuery.inband.condition2
@ -537,7 +538,7 @@ class Enumeration:
else: else:
kb.data.cachedUsersPrivileges[user] = list(privileges) 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: if Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:
conditionChar = " LIKE " conditionChar = " LIKE "
else: else:
@ -736,7 +737,7 @@ class Enumeration:
rootQuery = queries[Backend.getIdentifiedDbms()].dbs 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: if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
query = rootQuery.inband.query2 query = rootQuery.inband.query2
else: else:
@ -746,7 +747,7 @@ class Enumeration:
if not isNoneValue(value): if not isNoneValue(value):
kb.data.cachedDbs = arrayizeValue(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" infoMsg = "fetching number of databases"
logger.info(infoMsg) logger.info(infoMsg)
@ -870,7 +871,7 @@ class Enumeration:
rootQuery = queries[Backend.getIdentifiedDbms()].tables 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 query = rootQuery.inband.query
condition = rootQuery.inband.condition if 'condition' in rootQuery.inband else None condition = rootQuery.inband.condition if 'condition' in rootQuery.inband else None
@ -904,7 +905,7 @@ class Enumeration:
else: else:
kb.data.cachedTables[db].append(table) 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: for db in dbs:
if conf.excludeSysDbs and db in self.excludeDbsList: if conf.excludeSysDbs and db in self.excludeDbsList:
infoMsg = "skipping system database '%s'" % db infoMsg = "skipping system database '%s'" % db
@ -1087,7 +1088,7 @@ class Enumeration:
rootQuery = queries[Backend.getIdentifiedDbms()].columns rootQuery = queries[Backend.getIdentifiedDbms()].columns
condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None 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: for tbl in tblList:
if conf.db is not None and len(kb.data.cachedColumns) > 0 \ if conf.db is not None and len(kb.data.cachedColumns) > 0 \
and conf.db in kb.data.cachedColumns and tbl in \ and conf.db in kb.data.cachedColumns and tbl in \
@ -1156,7 +1157,7 @@ class Enumeration:
table[safeSQLIdentificatorNaming(tbl, True)] = columns table[safeSQLIdentificatorNaming(tbl, True)] = columns
kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table 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: for tbl in tblList:
if conf.db is not None and len(kb.data.cachedColumns) > 0 \ if conf.db is not None and len(kb.data.cachedColumns) > 0 \
and conf.db in kb.data.cachedColumns and tbl in \ 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)]: or not kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]:
warnMsg = "unable to enumerate the columns for table " warnMsg = "unable to enumerate the columns for table "
warnMsg += "'%s' on database" % unsafeSQLIdentificatorNaming(tbl) 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) logger.warn(warnMsg)
continue continue
@ -1660,7 +1662,7 @@ class Enumeration:
index += 1 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 " infoMsg = "fetching number of "
if conf.col: if conf.col:
infoMsg += "column(s) '%s' " % colString infoMsg += "column(s) '%s' " % colString
@ -1924,7 +1926,7 @@ class Enumeration:
dbQuery = "%s%s" % (dbCond, dbCondParam) dbQuery = "%s%s" % (dbCond, dbCondParam)
dbQuery = dbQuery % unsafeSQLIdentificatorNaming(db) 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: if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
query = rootQuery.inband.query2 query = rootQuery.inband.query2
else: else:
@ -2044,7 +2046,7 @@ class Enumeration:
tblQuery = "%s%s" % (tblCond, tblCondParam) tblQuery = "%s%s" % (tblCond, tblCondParam)
tblQuery = tblQuery % tbl 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 = rootQuery.inband.query
query += tblQuery query += tblQuery
query += whereDbsQuery query += whereDbsQuery
@ -2213,7 +2215,7 @@ class Enumeration:
colQuery = "%s%s" % (colCond, colCondParam) colQuery = "%s%s" % (colCond, colCondParam)
colQuery = colQuery % unsafeSQLIdentificatorNaming(column) 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)): if not all((conf.db, conf.tbl)):
query = rootQuery.inband.query query = rootQuery.inband.query
query += colQuery query += colQuery