diff --git a/plugins/dbms/mssqlserver/enumeration.py b/plugins/dbms/mssqlserver/enumeration.py index 13b0eaa12..31a2727ab 100644 --- a/plugins/dbms/mssqlserver/enumeration.py +++ b/plugins/dbms/mssqlserver/enumeration.py @@ -22,6 +22,8 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ +from lib.core.agent import agent +from lib.core.common import getRange from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger @@ -116,3 +118,89 @@ class Enumeration(GenericEnumeration): raise sqlmapNoneDataException(errMsg) return kb.data.cachedTables + + def searchTable(self): + rootQuery = queries[kb.dbms].searchTable + foundTbls = {} + tblList = conf.tbl.split(",") + tblCond = rootQuery["inband"]["condition"] + dbCond = rootQuery["inband"]["condition2"] + + tblConsider, tblCondParam = self.likeOrExact("table") + + if not len(kb.data.cachedDbs): + enumDbs = self.getDbs() + else: + enumDbs = kb.data.cachedDbs + + for db in enumDbs: + foundTbls[db] = [] + + for tbl in tblList: + infoMsg = "searching table" + if tblConsider == "1": + infoMsg += "s like" + infoMsg += " '%s'" % tbl + logger.info(infoMsg) + + if conf.excludeSysDbs: + exclDbsQuery = "".join(" AND '%s' != %s" % (db, dbCond) for db in self.excludeDbsList) + infoMsg = "skipping system databases '%s'" % ", ".join(db for db in self.excludeDbsList) + logger.info(infoMsg) + else: + exclDbsQuery = "" + + tblQuery = "%s%s" % (tblCond, tblCondParam) + tblQuery = tblQuery % tbl + + for db in foundTbls.keys(): + if kb.unionPosition or conf.direct: + query = rootQuery["inband"]["query"] % db + query += tblQuery + query += exclDbsQuery + values = inject.getValue(query, blind=False) + + if values: + if isinstance(values, str): + values = [ values ] + + for foundTbl in values: + foundTbls[db].append(foundTbl) + else: + infoMsg = "fetching number of table" + if tblConsider == "1": + infoMsg += "s like" + infoMsg += " '%s' in database '%s'" % (tbl, db) + logger.info(infoMsg) + + query = rootQuery["blind"]["count2"] + query = query % db + query += " AND %s" % tblQuery + count = inject.getValue(query, inband=False, expected="int", charsetType=2) + + if not count.isdigit() or not len(count) or count == "0": + warnMsg = "no table" + if tblConsider == "1": + warnMsg += "s like" + warnMsg += " '%s' " % tbl + warnMsg += "in database '%s'" % db + logger.warn(warnMsg) + + continue + + indexRange = getRange(count) + + for index in indexRange: + query = rootQuery["blind"]["query2"] + query = query % db + query += " AND %s" % tblQuery + query = agent.limitQuery(index, query, tblCond) + tbl = inject.getValue(query, inband=False) + kb.hintValue = tbl + foundTbls[db].append(tbl) + + for db, tbls in foundTbls.items(): + if len(tbls) == 0: + foundTbls.pop(db) + + return foundTbls diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index cca9123b2..5ddf6e206 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -1269,8 +1269,125 @@ class Enumeration: return foundDbs def searchTable(self): - errMsg = "search for table names is not supported yet" - raise sqlmapUnsupportedFeatureException, errMsg + if kb.dbms == "MySQL" and not kb.data.has_information_schema: + errMsg = "information_schema not available, " + errMsg += "back-end DBMS is MySQL < 5.0" + raise sqlmapUnsupportedFeatureException, errMsg + + rootQuery = queries[kb.dbms].searchTable + foundTbls = {} + tblList = conf.tbl.split(",") + tblCond = rootQuery["inband"]["condition"] + dbCond = rootQuery["inband"]["condition2"] + + tblConsider, tblCondParam = self.likeOrExact("table") + + for tbl in tblList: + if kb.dbms == "Oracle": + tbl = tbl.upper() + + infoMsg = "searching table" + if tblConsider == "1": + infoMsg += "s like" + infoMsg += " '%s'" % tbl + logger.info(infoMsg) + + if conf.excludeSysDbs: + exclDbsQuery = "".join(" AND '%s' != %s" % (db, dbCond) for db in self.excludeDbsList) + infoMsg = "skipping system databases '%s'" % ", ".join(db for db in self.excludeDbsList) + logger.info(infoMsg) + else: + exclDbsQuery = "" + + tblQuery = "%s%s" % (tblCond, tblCondParam) + tblQuery = tblQuery % tbl + + if kb.unionPosition or conf.direct: + query = rootQuery["inband"]["query"] + query += tblQuery + query += exclDbsQuery + values = inject.getValue(query, blind=False) + + if values: + if isinstance(values, str): + values = [ values ] + + for foundDb, foundTbl in values: + if foundDb in foundTbls: + foundTbls[foundDb].append(foundTbl) + else: + foundTbls[foundDb] = [ foundTbl ] + else: + infoMsg = "fetching number of databases with table" + if tblConsider == "1": + infoMsg += "s like" + infoMsg += " '%s'" % tbl + logger.info(infoMsg) + + query = rootQuery["blind"]["count"] + query += tblQuery + query += exclDbsQuery + count = inject.getValue(query, inband=False, expected="int", charsetType=2) + + if not count.isdigit() or not len(count) or count == "0": + warnMsg = "no databases have table" + if tblConsider == "1": + warnMsg += "s like" + warnMsg += " '%s'" % tbl + logger.warn(warnMsg) + + continue + + indexRange = getRange(count) + + for index in indexRange: + query = rootQuery["blind"]["query"] + query += tblQuery + query += exclDbsQuery + query = agent.limitQuery(index, query) + foundDb = inject.getValue(query, inband=False) + foundTbls[foundDb] = [] + + if tblConsider == "2": + foundTbls[foundDb].append(tbl) + + if tblConsider == "2": + continue + + for db in foundTbls.keys(): + infoMsg = "fetching number of table" + if tblConsider == "1": + infoMsg += "s like" + infoMsg += " '%s' in database '%s'" % (tbl, db) + logger.info(infoMsg) + + query = rootQuery["blind"]["count2"] + query = query % db + query += " AND %s" % tblQuery + count = inject.getValue(query, inband=False, expected="int", charsetType=2) + + if not count.isdigit() or not len(count) or count == "0": + warnMsg = "no table" + if tblConsider == "1": + warnMsg += "s like" + warnMsg += " '%s' " % tbl + warnMsg += "in database '%s'" % db + logger.warn(warnMsg) + + continue + + indexRange = getRange(count) + + for index in indexRange: + query = rootQuery["blind"]["query2"] + query = query % db + query += " AND %s" % tblQuery + query = agent.limitQuery(index, query) + foundTbl = inject.getValue(query, inband=False) + kb.hintValue = foundTbl + foundTbls[db].append(foundTbl) + + return foundTbls def searchColumn(self): if kb.dbms == "MySQL" and not kb.data.has_information_schema: @@ -1291,7 +1408,16 @@ class Enumeration: if kb.dbms == "Oracle": column = column.upper() conf.db = "USERS" - elif kb.dbms == "Microsoft SQL Server": + + infoMsg = "searching column" + if colConsider == "1": + infoMsg += "s like" + infoMsg += " '%s'" % column + logger.info(infoMsg) + + foundCols[column] = {} + + if kb.dbms == "Microsoft SQL Server": if not conf.db: if not len(kb.data.cachedDbs): enumDbs = self.getDbs() @@ -1300,8 +1426,6 @@ class Enumeration: conf.db = ",".join(db for db in enumDbs) - foundCols[column] = {} - if conf.db: for db in conf.db.split(","): dbs[db] = {} diff --git a/plugins/generic/misc.py b/plugins/generic/misc.py index fac8a018a..9f0f92f50 100644 --- a/plugins/generic/misc.py +++ b/plugins/generic/misc.py @@ -32,6 +32,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapUnsupportedFeatureException from lib.core.session import setRemoteTempPath from lib.request import inject diff --git a/xml/queries.xml b/xml/queries.xml index 496401f17..8235e4aaa 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -63,7 +63,10 @@ - + + + + @@ -136,7 +139,11 @@ - + + + + + @@ -205,7 +212,10 @@ - + + + + @@ -265,7 +275,10 @@ - + + + +