diff --git a/plugins/dbms/maxdb/enumeration.py b/plugins/dbms/maxdb/enumeration.py index 95ec6a385..7b9d1d20a 100644 --- a/plugins/dbms/maxdb/enumeration.py +++ b/plugins/dbms/maxdb/enumeration.py @@ -7,16 +7,20 @@ See the file 'doc/COPYING' for copying permission from lib.core.common import Backend from lib.core.common import randomStr +from lib.core.common import readInput from lib.core.common import safeSQLIdentificatorNaming from lib.core.common import unsafeSQLIdentificatorNaming from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.data import paths from lib.core.data import queries from lib.core.exception import SqlmapMissingMandatoryOptionException from lib.core.exception import SqlmapNoneDataException +from lib.core.exception import SqlmapUserQuitException from lib.core.settings import CURRENT_DB from lib.utils.pivotdumptable import pivotDumpTable +from lib.techniques.brute.use import columnExists from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): @@ -91,7 +95,7 @@ class Enumeration(GenericEnumeration): return kb.data.cachedTables - def getColumns(self, onlyColNames=False): + def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None, dumpMode=False): self.forceDbmsEnum() if conf.db is None or conf.db == CURRENT_DB: @@ -111,6 +115,17 @@ class Enumeration(GenericEnumeration): conf.db = safeSQLIdentificatorNaming(conf.db) + if conf.col: + colList = conf.col.split(",") + else: + colList = [] + + if conf.excludeCol: + colList = [_ for _ in colList if _ not in conf.excludeCol.split(',')] + + for col in colList: + colList[colList.index(col)] = safeSQLIdentificatorNaming(col) + if conf.tbl: tblList = conf.tbl.split(",") else: @@ -129,6 +144,43 @@ class Enumeration(GenericEnumeration): for tbl in tblList: tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl, True) + if bruteForce: + resumeAvailable = False + + for tbl in tblList: + for db, table, colName, colType in kb.brute.columns: + if db == conf.db and table == tbl: + resumeAvailable = True + break + + if resumeAvailable and not conf.freshQueries or colList: + columns = {} + + for column in colList: + columns[column] = None + + for tbl in tblList: + for db, table, colName, colType in kb.brute.columns: + if db == conf.db and table == tbl: + columns[colName] = colType + + if conf.db in kb.data.cachedColumns: + kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)] = columns + else: + kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = {safeSQLIdentificatorNaming(tbl, True): columns} + + return kb.data.cachedColumns + + message = "do you want to use common column existence check? [y/N/q] " + test = readInput(message, default="Y" if "Y" in message else "N") + + if test[0] in ("n", "N"): + return + elif test[0] in ("q", "Q"): + raise SqlmapUserQuitException + else: + return columnExists(paths.COMMON_COLUMNS) + rootQuery = queries[Backend.getIdentifiedDbms()].columns for tbl in tblList: @@ -141,6 +193,12 @@ class Enumeration(GenericEnumeration): return {conf.db: kb.data.cachedColumns[conf.db]} + if dumpMode and colList: + table = {} + table[safeSQLIdentificatorNaming(tbl)] = dict((_, None) for _ in colList) + kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table + continue + infoMsg = "fetching columns " infoMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl) infoMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db) diff --git a/plugins/dbms/sybase/enumeration.py b/plugins/dbms/sybase/enumeration.py index 09a0356af..e0707d9b4 100644 --- a/plugins/dbms/sybase/enumeration.py +++ b/plugins/dbms/sybase/enumeration.py @@ -9,19 +9,23 @@ from lib.core.common import Backend from lib.core.common import filterPairValues from lib.core.common import isTechniqueAvailable from lib.core.common import randomStr +from lib.core.common import readInput from lib.core.common import safeSQLIdentificatorNaming from lib.core.common import unArrayizeValue from lib.core.common import unsafeSQLIdentificatorNaming from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.data import paths from lib.core.data import queries from lib.core.dicts import SYBASE_TYPES from lib.core.enums import PAYLOAD from lib.core.exception import SqlmapMissingMandatoryOptionException from lib.core.exception import SqlmapNoneDataException +from lib.core.exception import SqlmapUserQuitException from lib.core.settings import CURRENT_DB from lib.utils.pivotdumptable import pivotDumpTable +from lib.techniques.brute.use import columnExists from plugins.generic.enumeration import Enumeration as GenericEnumeration class Enumeration(GenericEnumeration): @@ -159,7 +163,7 @@ class Enumeration(GenericEnumeration): return kb.data.cachedTables - def getColumns(self, onlyColNames=False): + def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None, dumpMode=False): self.forceDbmsEnum() if conf.db is None or conf.db == CURRENT_DB: @@ -208,6 +212,43 @@ class Enumeration(GenericEnumeration): for tbl in tblList: tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl) + if bruteForce: + resumeAvailable = False + + for tbl in tblList: + for db, table, colName, colType in kb.brute.columns: + if db == conf.db and table == tbl: + resumeAvailable = True + break + + if resumeAvailable and not conf.freshQueries or colList: + columns = {} + + for column in colList: + columns[column] = None + + for tbl in tblList: + for db, table, colName, colType in kb.brute.columns: + if db == conf.db and table == tbl: + columns[colName] = colType + + if conf.db in kb.data.cachedColumns: + kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)] = columns + else: + kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = {safeSQLIdentificatorNaming(tbl, True): columns} + + return kb.data.cachedColumns + + message = "do you want to use common column existence check? [y/N/q] " + test = readInput(message, default="Y" if "Y" in message else "N") + + if test[0] in ("n", "N"): + return + elif test[0] in ("q", "Q"): + raise SqlmapUserQuitException + else: + return columnExists(paths.COMMON_COLUMNS) + rootQuery = queries[Backend.getIdentifiedDbms()].columns if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct: @@ -225,7 +266,7 @@ class Enumeration(GenericEnumeration): return {conf.db: kb.data.cachedColumns[conf.db]} - if colList: + if dumpMode and colList: table = {} table[safeSQLIdentificatorNaming(tbl)] = dict((_, None) for _ in colList) kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py index 8070fc0ad..23e0b4cf6 100644 --- a/plugins/generic/databases.py +++ b/plugins/generic/databases.py @@ -238,7 +238,7 @@ class Databases: return kb.data.cachedTables - message = "do you want to use common table existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS,) else "[y/N/q]") + message = "do you want to use common table existence check? %s " % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS,) else "[y/N/q]") test = readInput(message, default="Y" if "Y" in message else "N") if test[0] in ("n", "N"):