diff --git a/lib/controller/action.py b/lib/controller/action.py index faef3b489..41035cae9 100644 --- a/lib/controller/action.py +++ b/lib/controller/action.py @@ -90,14 +90,11 @@ def action(): if conf.getTables: conf.dumper.dbTables(conf.dbmsHandler.getTables()) - if conf.commonTables: - conf.dumper.dbTables(tableExists(paths.COMMON_TABLES)) - if conf.getColumns: conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns()) - if conf.commonColumns: - conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS)) + if conf.getSchema: + conf.dumper.dbTableColumns(conf.dbmsHandler.getSchema()) if conf.dumpTable: conf.dumper.dbTableValues(conf.dbmsHandler.dumpTable()) @@ -114,6 +111,13 @@ def action(): if conf.sqlShell: conf.dbmsHandler.sqlShell() + # Brute force options + if conf.commonTables: + conf.dumper.dbTables(tableExists(paths.COMMON_TABLES)) + + if conf.commonColumns: + conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS)) + # User-defined function options if conf.udfInject: conf.dbmsHandler.udfInjectCustom() diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 9852210ac..6ceae3e73 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -92,6 +92,7 @@ optDict = { "getDbs": ("boolean", "Databases"), "getTables": ("boolean", "Tables"), "getColumns": ("boolean", "Columns"), + "getSchema": "boolean", "dumpTable": "boolean", "dumpAll": "boolean", "search": "boolean", diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index 8cf4604e4..29c782ae0 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -276,6 +276,9 @@ def cmdLineParser(): enumeration.add_option("--columns", dest="getColumns", action="store_true", default=False, help="Enumerate DBMS database table columns") + enumeration.add_option("--schema", dest="getSchema", action="store_true", + default=False, help="Enumerate DBMS schema") + enumeration.add_option("--dump", dest="dumpTable", action="store_true", default=False, help="Dump DBMS database table entries") diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index a281100a4..84e51fa82 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -822,7 +822,6 @@ class Enumeration: if Backend.getIdentifiedDbms() == DBMS.MSSQL: query = safeStringFormat(query, conf.db) value = inject.getValue(query, blind=False) - value = filter(lambda x: x, value) if value: @@ -904,12 +903,43 @@ class Enumeration: return kb.data.cachedTables + def getSchema(self): + pushValue(conf.db) + pushValue(conf.tbl) + + conf.db = None + conf.tbl = None + + self.getTables() + + infoMsg = "fetched tables: " + infoMsg += ", ".join(["%s" % ", ".join("%s%s%s" % (db, ".." if \ + Backend.isDbms(DBMS.MSSQL) or Backend.isDbms(DBMS.SYBASE) \ + else ".", t) for t in tbl) for db, tbl in \ + kb.data.cachedTables.items()]) + logger.info(infoMsg) + + for db, tables in kb.data.cachedTables.items(): + for tbl in tables: + conf.db = db + conf.tbl = tbl + + self.getColumns() + + conf.tbl = popValue() + conf.db = popValue() + + return kb.data.cachedColumns + def getColumns(self, onlyColNames=False): bruteForce = False if not conf.tbl: - errMsg = "missing table parameter" - raise sqlmapMissingMandatoryOptionException, errMsg + warnMsg = "missing table parameter, sqlmap will enumerate " + warnMsg += "the whole database management system schema" + logger.warn(warnMsg) + + return self.getSchema() if "." in conf.tbl: if not conf.db: @@ -954,7 +984,10 @@ class Enumeration: if db == conf.db and table == conf.tbl: columns[colName] = colType - kb.data.cachedColumns[conf.db] = {conf.tbl: columns} + if conf.db in kb.data.cachedColumns: + kb.data.cachedColumns[conf.db][conf.tbl] = columns + else: + kb.data.cachedColumns[conf.db] = {conf.tbl: columns} return kb.data.cachedColumns @@ -1019,8 +1052,11 @@ class Enumeration: else: columns[name] = columnData[1] - table[conf.tbl] = columns - kb.data.cachedColumns[conf.db] = table + if conf.db in kb.data.cachedColumns: + kb.data.cachedColumns[conf.db][conf.tbl] = columns + else: + table[conf.tbl] = columns + kb.data.cachedColumns[conf.db] = table if not kb.data.cachedColumns and not conf.direct: infoMsg = "fetching number of columns " @@ -1112,8 +1148,11 @@ class Enumeration: columns[column] = None if columns: - table[conf.tbl] = columns - kb.data.cachedColumns[conf.db] = table + if conf.db in kb.data.cachedColumns: + kb.data.cachedColumns[conf.db][conf.tbl] = columns + else: + table[conf.tbl] = columns + kb.data.cachedColumns[conf.db] = table if not kb.data.cachedColumns: errMsg = "unable to retrieve the columns " diff --git a/sqlmap.conf b/sqlmap.conf index 25a8791eb..59251baf4 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -306,11 +306,14 @@ getDbs = False getTables = False # Enumerate back-end database management system database table columns. -# Requires: tbl -# Optional: db, col +# Optional: db, tbl, col # Valid: True or False getColumns = False +# Enumerate back-end database management system schema. +# Valid: True or False +getSchema = False + # Dump back-end database management system database table entries. # Requires: tbl and/or col # Optional: db