From 9329f8c9c44ba7d1baa086ebce2abb0a74c004ee Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Wed, 12 Nov 2008 22:53:25 +0000 Subject: [PATCH] Minor enhancement to be able to enumerate table columns and dump table entries also if the database name is not provided by using the current database on MySQL and MSSQL, the 'public' scheme on PostgreSQL and the 'USERS' TABLESPACE_NAME on Oracle. Minor bug fix so that when the user provide as SELECT statement to be processed an asterisk, now it also work if in the FROM there is no database name specified. Minor layout adjustments. --- lib/core/common.py | 11 ++++++++--- lib/core/settings.py | 2 +- lib/core/shell.py | 2 ++ lib/parse/cmdline.py | 4 ++-- lib/request/inject.py | 2 +- plugins/generic/enumeration.py | 20 ++++++++++++-------- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index 167ebb561..736b20ea8 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -507,15 +507,20 @@ def expandAsteriskForColumns(expression): # If the user provided an asterisk rather than the column(s) # name, sqlmap will retrieve the columns itself and reprocess # the SQL query string (expression) - asterisk = re.search("^SELECT\s+\*\s+FROM\s+(\w+)[\.]+(\w+)\s*", expression, re.I) + asterisk = re.search("^SELECT\s+\*\s+FROM\s+([\w\.\_]+)\s*", expression, re.I) if asterisk: infoMsg = "you did not provide the fields in your query. " infoMsg += "sqlmap will retrieve the column names itself" logger.info(infoMsg) - conf.db = asterisk.group(1) - conf.tbl = asterisk.group(2) + dbTbl = asterisk.group(1) + + if dbTbl and "." in dbTbl: + conf.db, conf.tbl = dbTbl.split(".") + else: + conf.tbl = dbTbl + columnsDict = conf.dbmsHandler.getColumns(onlyColNames=True) if columnsDict and conf.db in columnsDict and conf.tbl in columnsDict[conf.db]: diff --git a/lib/core/settings.py b/lib/core/settings.py index d949ad763..85aee29d9 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -56,7 +56,7 @@ SQLMAP_SOURCE_URL = "http://downloads.sourceforge.net/sqlmap/sqlmap-%s.zip" MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" ) MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql" PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog" ) -ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) +ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ] MYSQL_ALIASES = [ "mysql", "my" ] diff --git a/lib/core/shell.py b/lib/core/shell.py index 132112446..1199f7753 100644 --- a/lib/core/shell.py +++ b/lib/core/shell.py @@ -54,6 +54,8 @@ def queriesForAutoCompletion(): autoComplQuery = query elif isinstance(query, dict) and "inband" in query: autoComplQuery = query["inband"]["query"] + else: + continue autoComplQueries[autoComplQuery] = None diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index f3e5f6a10..b759efac9 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -168,11 +168,11 @@ def cmdLineParser(): enumeration.add_option("--columns", dest="getColumns", action="store_true", help="Enumerate DBMS database table columns " - "(req: -T, -D)") + "(req:-T opt:-D)") enumeration.add_option("--dump", dest="dumpTable", action="store_true", help="Dump DBMS database table entries " - "(req: -T, -D opt: -C, --start, --stop)") + "(req: -T, opt: -D, -C, --start, --stop)") enumeration.add_option("--dump-all", dest="dumpAll", action="store_true", help="Dump all DBMS databases tables entries") diff --git a/lib/request/inject.py b/lib/request/inject.py index 2f8c07b63..f8923d7de 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -372,7 +372,7 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None) expression = cleanQuery(expression) expression = expandAsteriskForColumns(expression) - value = None + value = None if inband and conf.unionUse and kb.dbms: value = __goInband(expression, expected) diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index 959f294e5..9d013d12c 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -730,8 +730,12 @@ class Enumeration: self.forceDbmsEnum() if not conf.db: - errMsg = "missing database parameter" - raise sqlmapMissingMandatoryOptionException, errMsg + warnMsg = "missing database parameter, sqlmap is going to " + warnMsg += "use the current database to enumerate table " + warnMsg += "'%s' columns" % conf.tbl + logger.warn(warnMsg) + + conf.db = self.getCurrentDb() infoMsg = "fetching columns " infoMsg += "for table '%s' " % conf.tbl @@ -740,10 +744,6 @@ class Enumeration: rootQuery = queries[kb.dbms].columns - if kb.dbms == "Oracle": - conf.db = conf.db.upper() - conf.tbl = conf.tbl.upper() - if conf.unionUse: if kb.dbms in ( "MySQL", "PostgreSQL" ): query = rootQuery["inband"]["query"] % (conf.tbl, conf.db) @@ -840,8 +840,12 @@ class Enumeration: self.forceDbmsEnum() if not conf.db: - errMsg = "missing database parameter" - raise sqlmapMissingMandatoryOptionException, errMsg + warnMsg = "missing database parameter, sqlmap is going to " + warnMsg += "use the current database to dump table " + warnMsg += "'%s' entries" % conf.tbl + logger.warn(warnMsg) + + conf.db = self.getCurrentDb() rootQuery = queries[kb.dbms].dumpTable