同步操作将从 yeqingchen1/sqlmap 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#!/usr/bin/env python"""Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)See the file 'LICENSE' for copying permission"""from lib.core.agent import agentfrom lib.core.common import arrayizeValuefrom lib.core.common import Backendfrom lib.core.common import extractRegexResultfrom lib.core.common import filterNonefrom lib.core.common import filterPairValuesfrom lib.core.common import flattenValuefrom lib.core.common import getLimitRangefrom lib.core.common import isInferenceAvailablefrom lib.core.common import isListLikefrom lib.core.common import isNoneValuefrom lib.core.common import isNumPosStrValuefrom lib.core.common import isTechniqueAvailablefrom lib.core.common import parseSqliteTableSchemafrom lib.core.common import popValuefrom lib.core.common import pushValuefrom lib.core.common import randomStrfrom lib.core.common import readInputfrom lib.core.common import safeSQLIdentificatorNamingfrom lib.core.common import singleTimeLogMessagefrom lib.core.common import singleTimeWarnMessagefrom lib.core.common import unArrayizeValuefrom lib.core.common import unsafeSQLIdentificatorNamingfrom lib.core.data import conffrom lib.core.data import kbfrom lib.core.data import loggerfrom lib.core.data import pathsfrom lib.core.data import queriesfrom lib.core.decorators import stackedmethodfrom lib.core.dicts import FIREBIRD_TYPESfrom lib.core.dicts import INFORMIX_TYPESfrom lib.core.enums import CHARSET_TYPEfrom lib.core.enums import DBMSfrom lib.core.enums import EXPECTEDfrom lib.core.enums import PAYLOADfrom lib.core.exception import SqlmapMissingMandatoryOptionExceptionfrom lib.core.exception import SqlmapNoneDataExceptionfrom lib.core.exception import SqlmapUserQuitExceptionfrom lib.core.settings import CURRENT_DBfrom lib.core.settings import REFLECTED_VALUE_MARKERfrom lib.request import injectfrom lib.techniques.union.use import unionUsefrom lib.utils.brute import columnExistsfrom lib.utils.brute import tableExistsfrom thirdparty import sixclass Databases(object):"""This class defines databases' enumeration functionalities for plugins."""def __init__(self):kb.data.currentDb = ""kb.data.cachedDbs = []kb.data.cachedTables = {}kb.data.cachedColumns = {}kb.data.cachedCounts = {}kb.data.dumpedTable = {}kb.data.cachedStatements = []def getCurrentDb(self):infoMsg = "fetching current database"logger.info(infoMsg)query = queries[Backend.getIdentifiedDbms()].current_db.queryif not kb.data.currentDb:kb.data.currentDb = unArrayizeValue(inject.getValue(query, safeCharEncode=False))if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL):warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms()warnMsg += "schema names for enumeration as the counterpart to database "warnMsg += "names on other DBMSes"singleTimeWarnMessage(warnMsg)return kb.data.currentDbdef getDbs(self):if len(kb.data.cachedDbs) > 0:return kb.data.cachedDbsinfoMsg = Noneif Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:warnMsg = "information_schema not available, "warnMsg += "back-end DBMS is MySQL < 5. database "warnMsg += "names will be fetched from 'mysql' database"logger.warn(warnMsg)elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL):warnMsg = "schema names are going to be used on %s " % Backend.getIdentifiedDbms()warnMsg += "for enumeration as the counterpart to database "warnMsg += "names on other DBMSes"logger.warn(warnMsg)infoMsg = "fetching database (schema) names"else:infoMsg = "fetching database names"if infoMsg:logger.info(infoMsg)rootQuery = queries[Backend.getIdentifiedDbms()].dbsif any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:query = rootQuery.inband.query2else:query = rootQuery.inband.queryvalues = inject.getValue(query, blind=False, time=False)if not isNoneValue(values):kb.data.cachedDbs = arrayizeValue(values)if not kb.data.cachedDbs and isInferenceAvailable() and not conf.direct:infoMsg = "fetching number of databases"logger.info(infoMsg)if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:query = rootQuery.blind.count2else:query = rootQuery.blind.countcount = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if not isNumPosStrValue(count):errMsg = "unable to retrieve the number of databases"logger.error(errMsg)else:plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2)indexRange = getLimitRange(count, plusOne=plusOne)for index in indexRange:if Backend.isDbms(DBMS.SYBASE):query = rootQuery.blind.query % (kb.data.cachedDbs[-1] if kb.data.cachedDbs else " ")elif Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:query = rootQuery.blind.query2 % indexelse:query = rootQuery.blind.query % indexdb = unArrayizeValue(inject.getValue(query, union=False, error=False))if not isNoneValue(db):kb.data.cachedDbs.append(safeSQLIdentificatorNaming(db))if not kb.data.cachedDbs and Backend.isDbms(DBMS.MSSQL):if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:blinds = (False, True)else:blinds = (True,)for blind in blinds:count = 0kb.data.cachedDbs = []while True:query = rootQuery.inband.query2 % countvalue = unArrayizeValue(inject.getValue(query, blind=blind))if not (value or "").strip():breakelse:kb.data.cachedDbs.append(value)count += 1if kb.data.cachedDbs:breakif not kb.data.cachedDbs:infoMsg = "falling back to current database"logger.info(infoMsg)self.getCurrentDb()if kb.data.currentDb:kb.data.cachedDbs = [kb.data.currentDb]else:errMsg = "unable to retrieve the database names"raise SqlmapNoneDataException(errMsg)else:kb.data.cachedDbs.sort()if kb.data.cachedDbs:kb.data.cachedDbs = [_ for _ in set(flattenValue(kb.data.cachedDbs)) if _]return kb.data.cachedDbsdef getTables(self, bruteForce=None):if len(kb.data.cachedTables) > 0:return kb.data.cachedTablesself.forceDbmsEnum()if bruteForce is None:if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:errMsg = "information_schema not available, "errMsg += "back-end DBMS is MySQL < 5.0"logger.error(errMsg)bruteForce = Trueelif Backend.isDbms(DBMS.ACCESS):try:tables = self.getTables(False)except SqlmapNoneDataException:tables = Noneif not tables:errMsg = "cannot retrieve table names, "errMsg += "back-end DBMS is Access"logger.error(errMsg)bruteForce = Trueelse:return tablesif conf.db == CURRENT_DB:conf.db = self.getCurrentDb()if conf.db and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):conf.db = conf.db.upper()if conf.db:dbs = conf.db.split(',')else:dbs = self.getDbs()dbs = [_ for _ in dbs if _ and _.strip()]for db in dbs:dbs[dbs.index(db)] = safeSQLIdentificatorNaming(db)if bruteForce:resumeAvailable = Falsefor db, table in kb.brute.tables:if db == conf.db:resumeAvailable = Truebreakif resumeAvailable and not conf.freshQueries:for db, table in kb.brute.tables:if db == conf.db:if conf.db not in kb.data.cachedTables:kb.data.cachedTables[conf.db] = [table]else:kb.data.cachedTables[conf.db].append(table)return kb.data.cachedTablesmessage = "do you want to use common table existence check? %s " % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS,) else "[y/N/q]")choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()if choice == 'N':returnelif choice == 'Q':raise SqlmapUserQuitExceptionelse:return tableExists(paths.COMMON_TABLES)infoMsg = "fetching tables for database"infoMsg += "%s: '%s'" % ("s" if len(dbs) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(unArrayizeValue(db)) for db in sorted(dbs)))logger.info(infoMsg)rootQuery = queries[Backend.getIdentifiedDbms()].tablesif any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:values = []for query, condition in ((rootQuery.inband.query, getattr(rootQuery.inband, "condition", None)), (getattr(rootQuery.inband, "query2", None), getattr(rootQuery.inband, "condition2", None))):if not isNoneValue(values) or not query:breakif condition:if not Backend.isDbms(DBMS.SQLITE):query += " WHERE %s" % conditionif conf.excludeSysDbs:infoMsg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))logger.info(infoMsg)query += " IN (%s)" % ','.join("'%s'" % unsafeSQLIdentificatorNaming(db) for db in sorted(dbs) if db not in self.excludeDbsList)else:query += " IN (%s)" % ','.join("'%s'" % unsafeSQLIdentificatorNaming(db) for db in sorted(dbs))if len(dbs) < 2 and ("%s," % condition) in query:query = query.replace("%s," % condition, "", 1)if query:values = inject.getValue(query, blind=False, time=False)if not isNoneValue(values):values = [_ for _ in arrayizeValue(values) if _]if len(values) > 0 and not isListLike(values[0]):values = [(dbs[0], _) for _ in values]for db, table in filterPairValues(values):table = unArrayizeValue(table)if not isNoneValue(table):db = safeSQLIdentificatorNaming(db)table = safeSQLIdentificatorNaming(table, True)if conf.getComments:_ = queries[Backend.getIdentifiedDbms()].table_commentif hasattr(_, "query"):if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = _.query % (unsafeSQLIdentificatorNaming(db.upper()), unsafeSQLIdentificatorNaming(table.upper()))else:query = _.query % (unsafeSQLIdentificatorNaming(db), unsafeSQLIdentificatorNaming(table))comment = unArrayizeValue(inject.getValue(query, blind=False, time=False))if not isNoneValue(comment):infoMsg = "retrieved comment '%s' for table '%s' " % (comment, unsafeSQLIdentificatorNaming(table))infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)logger.info(infoMsg)else:warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()warnMsg += "possible to get table comments"singleTimeWarnMessage(warnMsg)if db not in kb.data.cachedTables:kb.data.cachedTables[db] = [table]else:kb.data.cachedTables[db].append(table)if not kb.data.cachedTables and isInferenceAvailable() and not conf.direct:for db in dbs:if conf.excludeSysDbs and db in self.excludeDbsList:infoMsg = "skipping system database '%s'" % unsafeSQLIdentificatorNaming(db)logger.info(infoMsg)continueif conf.exclude and db in conf.exclude.split(','):infoMsg = "skipping database '%s'" % unsafeSQLIdentificatorNaming(db)singleTimeLogMessage(infoMsg)continueinfoMsg = "fetching number of tables for "infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(db)logger.info(infoMsg)if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.ACCESS):query = rootQuery.blind.countelse:query = rootQuery.blind.count % unsafeSQLIdentificatorNaming(db)count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if count == 0:warnMsg = "database '%s' " % unsafeSQLIdentificatorNaming(db)warnMsg += "appears to be empty"logger.warn(warnMsg)continueelif not isNumPosStrValue(count):warnMsg = "unable to retrieve the number of "warnMsg += "tables for database '%s'" % unsafeSQLIdentificatorNaming(db)logger.warn(warnMsg)continuetables = []plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2)indexRange = getLimitRange(count, plusOne=plusOne)for index in indexRange:if Backend.isDbms(DBMS.SYBASE):query = rootQuery.blind.query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " "))elif Backend.getIdentifiedDbms() in (DBMS.MAXDB, DBMS.ACCESS):query = rootQuery.blind.query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):query = rootQuery.blind.query % indexelif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX):query = rootQuery.blind.query % (index, unsafeSQLIdentificatorNaming(db))else:query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(db), index)table = unArrayizeValue(inject.getValue(query, union=False, error=False))if not isNoneValue(table):kb.hintValue = tabletable = safeSQLIdentificatorNaming(table, True)tables.append(table)if conf.getComments:_ = queries[Backend.getIdentifiedDbms()].table_commentif hasattr(_, "query"):if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = _.query % (unsafeSQLIdentificatorNaming(db.upper()), unsafeSQLIdentificatorNaming(table.upper()))else:query = _.query % (unsafeSQLIdentificatorNaming(db), unsafeSQLIdentificatorNaming(table))comment = unArrayizeValue(inject.getValue(query, union=False, error=False))if not isNoneValue(comment):infoMsg = "retrieved comment '%s' for table '%s' " % (comment, unsafeSQLIdentificatorNaming(table))infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)logger.info(infoMsg)else:warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()warnMsg += "possible to get table comments"singleTimeWarnMessage(warnMsg)if tables:kb.data.cachedTables[db] = tableselse:warnMsg = "unable to retrieve the table names "warnMsg += "for database '%s'" % unsafeSQLIdentificatorNaming(db)logger.warn(warnMsg)if isNoneValue(kb.data.cachedTables):kb.data.cachedTables.clear()if not kb.data.cachedTables:errMsg = "unable to retrieve the table names for any database"if bruteForce is None:logger.error(errMsg)return self.getTables(bruteForce=True)elif not conf.search:raise SqlmapNoneDataException(errMsg)else:for db, tables in kb.data.cachedTables.items():kb.data.cachedTables[db] = sorted(tables) if tables else tablesif kb.data.cachedTables:for db in kb.data.cachedTables:kb.data.cachedTables[db] = list(set(kb.data.cachedTables[db]))return kb.data.cachedTablesdef getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None, dumpMode=False):self.forceDbmsEnum()if conf.db is None or conf.db == CURRENT_DB:if conf.db is None:warnMsg = "missing database parameter. sqlmap is going "warnMsg += "to use the current database to enumerate "warnMsg += "table(s) columns"logger.warn(warnMsg)conf.db = self.getCurrentDb()if not conf.db:errMsg = "unable to retrieve the current "errMsg += "database name"raise SqlmapNoneDataException(errMsg)elif conf.db is not None:if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):conf.db = conf.db.upper()if ',' in conf.db:errMsg = "only one database name is allowed when enumerating "errMsg += "the tables' columns"raise SqlmapMissingMandatoryOptionException(errMsg)conf.db = safeSQLIdentificatorNaming(conf.db)if conf.col:if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):conf.col = conf.col.upper()colList = conf.col.split(',')else:colList = []if conf.exclude:colList = [_ for _ in colList if _ not in conf.exclude.split(',')]for col in colList:colList[colList.index(col)] = safeSQLIdentificatorNaming(col)colList = [_ for _ in colList if _]if conf.tbl:if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):conf.tbl = conf.tbl.upper()tblList = conf.tbl.split(',')else:self.getTables()if len(kb.data.cachedTables) > 0:if conf.db in kb.data.cachedTables:tblList = kb.data.cachedTables[conf.db]else:tblList = list(six.itervalues(kb.data.cachedTables))if tblList and isListLike(tblList[0]):tblList = tblList[0]tblList = list(tblList)elif not conf.search:errMsg = "unable to retrieve the tables "errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)raise SqlmapNoneDataException(errMsg)else:return kb.data.cachedColumnstblList = filterNone(safeSQLIdentificatorNaming(_, True) for _ in tblList)if bruteForce is None:if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:errMsg = "information_schema not available, "errMsg += "back-end DBMS is MySQL < 5.0"logger.error(errMsg)bruteForce = Trueelif Backend.isDbms(DBMS.ACCESS):errMsg = "cannot retrieve column names, "errMsg += "back-end DBMS is %s" % DBMS.ACCESSlogger.error(errMsg)bruteForce = Trueif bruteForce:resumeAvailable = Falsefor tbl in tblList:for db, table, colName, colType in kb.brute.columns:if db == conf.db and table == tbl:resumeAvailable = Truebreakif resumeAvailable and not conf.freshQueries or colList:columns = {}for column in colList:columns[column] = Nonefor tbl in tblList:for db, table, colName, colType in kb.brute.columns:if db == conf.db and table == tbl:columns[colName] = colTypeif conf.db in kb.data.cachedColumns:kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)] = columnselse:kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = {safeSQLIdentificatorNaming(tbl, True): columns}return kb.data.cachedColumnsmessage = "do you want to use common column existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS,) else "[y/N/q]")choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()if choice == 'N':returnelif choice == 'Q':raise SqlmapUserQuitExceptionelse:return columnExists(paths.COMMON_COLUMNS)rootQuery = queries[Backend.getIdentifiedDbms()].columnscondition = rootQuery.blind.condition if 'condition' in rootQuery.blind else Noneif any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:for tbl in tblList:if conf.db is not None and len(kb.data.cachedColumns) > 0 \and conf.db in kb.data.cachedColumns and tbl in \kb.data.cachedColumns[conf.db]:infoMsg = "fetched tables' columns on "infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)logger.info(infoMsg)return {conf.db: kb.data.cachedColumns[conf.db]}infoMsg = "fetching columns "condQuery = ""if len(colList) > 0:if colTuple:_, colCondParam = colTupleinfoMsg += "LIKE '%s' " % ", ".join(unsafeSQLIdentificatorNaming(col) for col in sorted(colList))else:colCondParam = "='%s'"infoMsg += "'%s' " % ", ".join(unsafeSQLIdentificatorNaming(col) for col in sorted(colList))condQueryStr = "%%s%s" % colCondParamcondQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))query += condQueryelif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))query += condQueryelif Backend.isDbms(DBMS.MSSQL):query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db,conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])query += condQuery.replace("[DB]", conf.db)elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):query = rootQuery.inband.query % unsafeSQLIdentificatorNaming(tbl)elif Backend.isDbms(DBMS.INFORMIX):query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl))query += condQueryif dumpMode and colList:values = [(_,) for _ in colList]else:infoMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)logger.info(infoMsg)values = Noneif Backend.isDbms(DBMS.MSSQL) and isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):expression = querykb.dumpColumns = []kb.rowXmlMode = Truefor column in (extractRegexResult(r"SELECT (?P<result>.+?) FROM", query) or "").split(','):kb.dumpColumns.append(randomStr().lower())expression = expression.replace(column, "%s AS %s" % (column, kb.dumpColumns[-1]), 1)values = unionUse(expression)kb.rowXmlMode = Falsekb.dumpColumns = Noneif values is None:values = inject.getValue(query, blind=False, time=False)if values and isinstance(values[0], six.string_types):values = [values]if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values):index, values = 1, []while True:query = rootQuery.inband.query2 % (conf.db, unsafeSQLIdentificatorNaming(tbl), index)value = unArrayizeValue(inject.getValue(query, blind=False, time=False))if isNoneValue(value) or value == " ":breakelse:values.append((value,))index += 1if Backend.isDbms(DBMS.SQLITE):if dumpMode and colList:if conf.db not in kb.data.cachedColumns:kb.data.cachedColumns[conf.db] = {}kb.data.cachedColumns[conf.db][safeSQLIdentificatorNaming(conf.tbl, True)] = dict((_, None) for _ in colList)else:parseSqliteTableSchema(unArrayizeValue(values))elif not isNoneValue(values):table = {}columns = {}for columnData in values:if not isNoneValue(columnData):columnData = [unArrayizeValue(_) for _ in columnData]name = safeSQLIdentificatorNaming(columnData[0])if name:if conf.getComments:_ = queries[Backend.getIdentifiedDbms()].column_commentif hasattr(_, "query"):if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = _.query % (unsafeSQLIdentificatorNaming(conf.db.upper()), unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(name.upper()))else:query = _.query % (unsafeSQLIdentificatorNaming(conf.db), unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(name))comment = unArrayizeValue(inject.getValue(query, blind=False, time=False))if not isNoneValue(comment):infoMsg = "retrieved comment '%s' for column '%s'" % (comment, name)logger.info(infoMsg)else:warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()warnMsg += "possible to get column comments"singleTimeWarnMessage(warnMsg)if len(columnData) == 1:columns[name] = Noneelse:key = int(columnData[1]) if isinstance(columnData[1], six.string_types) and columnData[1].isdigit() else columnData[1]if Backend.isDbms(DBMS.FIREBIRD):columnData[1] = FIREBIRD_TYPES.get(key, columnData[1])elif Backend.isDbms(DBMS.INFORMIX):notNull = Falseif isinstance(key, int) and key > 255:key -= 256notNull = TruecolumnData[1] = INFORMIX_TYPES.get(key, columnData[1])if notNull:columnData[1] = "%s NOT NULL" % columnData[1]columns[name] = columnData[1]if conf.db in kb.data.cachedColumns:kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)] = columnselse:table[safeSQLIdentificatorNaming(tbl, True)] = columnskb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = tableelif isInferenceAvailable() and not conf.direct:for tbl in tblList:if conf.db is not None and len(kb.data.cachedColumns) > 0 \and conf.db in kb.data.cachedColumns and tbl in \kb.data.cachedColumns[conf.db]:infoMsg = "fetched tables' columns on "infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)logger.info(infoMsg)return {conf.db: kb.data.cachedColumns[conf.db]}infoMsg = "fetching columns "condQuery = ""if len(colList) > 0:if colTuple:_, colCondParam = colTupleinfoMsg += "LIKE '%s' " % ", ".join(unsafeSQLIdentificatorNaming(col) for col in sorted(colList))else:colCondParam = "='%s'"infoMsg += "'%s' " % ", ".join(unsafeSQLIdentificatorNaming(col) for col in sorted(colList))condQueryStr = "%%s%s" % colCondParamcondQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))query += condQueryelif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))query += condQueryelif Backend.isDbms(DBMS.MSSQL):query = rootQuery.blind.count % (conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])query += condQuery.replace("[DB]", conf.db)elif Backend.isDbms(DBMS.FIREBIRD):query = rootQuery.blind.count % unsafeSQLIdentificatorNaming(tbl)query += condQueryelif Backend.isDbms(DBMS.INFORMIX):query = rootQuery.blind.count % (conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl))query += condQueryelif Backend.isDbms(DBMS.SQLITE):if dumpMode and colList:if conf.db not in kb.data.cachedColumns:kb.data.cachedColumns[conf.db] = {}kb.data.cachedColumns[conf.db][safeSQLIdentificatorNaming(conf.tbl, True)] = dict((_, None) for _ in colList)else:query = rootQuery.blind.query % unsafeSQLIdentificatorNaming(tbl)value = unArrayizeValue(inject.getValue(query, union=False, error=False))parseSqliteTableSchema(unArrayizeValue(value))return kb.data.cachedColumnstable = {}columns = {}if dumpMode and colList:count = 0for value in colList:columns[safeSQLIdentificatorNaming(value)] = Noneelse:infoMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)logger.info(infoMsg)count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if not isNumPosStrValue(count):if Backend.isDbms(DBMS.MSSQL):count, index, values = 0, 1, []while True:query = rootQuery.blind.query3 % (conf.db, unsafeSQLIdentificatorNaming(tbl), index)value = unArrayizeValue(inject.getValue(query, union=False, error=False))if isNoneValue(value) or value == " ":breakelse:columns[safeSQLIdentificatorNaming(value)] = Noneindex += 1if not columns:errMsg = "unable to retrieve the %scolumns " % ("number of " if not Backend.isDbms(DBMS.MSSQL) else "")errMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)logger.error(errMsg)continuefor index in getLimitRange(count):if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB):query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))query += condQueryfield = Noneelif Backend.isDbms(DBMS.H2):query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))query = query.replace(" ORDER BY ", "%s ORDER BY " % condQuery)field = Noneelif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))query += condQueryfield = Noneelif Backend.isDbms(DBMS.MSSQL):query = rootQuery.blind.query.replace("'%s'", "'%s'" % unsafeSQLIdentificatorNaming(tbl).split(".")[-1]).replace("%s", conf.db).replace("%d", str(index))query += condQuery.replace("[DB]", conf.db)field = condition.replace("[DB]", conf.db)elif Backend.isDbms(DBMS.FIREBIRD):query = rootQuery.blind.query % unsafeSQLIdentificatorNaming(tbl)query += condQueryfield = Noneelif Backend.isDbms(DBMS.INFORMIX):query = rootQuery.blind.query % (index, conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl))query += condQueryfield = conditionquery = agent.limitQuery(index, query, field, field)column = unArrayizeValue(inject.getValue(query, union=False, error=False))if not isNoneValue(column):if conf.getComments:_ = queries[Backend.getIdentifiedDbms()].column_commentif hasattr(_, "query"):if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = _.query % (unsafeSQLIdentificatorNaming(conf.db.upper()), unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(column.upper()))else:query = _.query % (unsafeSQLIdentificatorNaming(conf.db), unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(column))comment = unArrayizeValue(inject.getValue(query, union=False, error=False))if not isNoneValue(comment):infoMsg = "retrieved comment '%s' for column '%s'" % (comment, column)logger.info(infoMsg)else:warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()warnMsg += "possible to get column comments"singleTimeWarnMessage(warnMsg)if not onlyColNames:if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))elif Backend.isDbms(DBMS.MSSQL):query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db, conf.db, column, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])elif Backend.isDbms(DBMS.FIREBIRD):query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column)elif Backend.isDbms(DBMS.INFORMIX):query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl), column)colType = unArrayizeValue(inject.getValue(query, union=False, error=False))key = int(colType) if hasattr(colType, "isdigit") and colType.isdigit() else colTypeif Backend.isDbms(DBMS.FIREBIRD):colType = FIREBIRD_TYPES.get(key, colType)elif Backend.isDbms(DBMS.INFORMIX):notNull = Falseif isinstance(key, int) and key > 255:key -= 256notNull = TruecolType = INFORMIX_TYPES.get(key, colType)if notNull:colType = "%s NOT NULL" % colTypecolumn = safeSQLIdentificatorNaming(column)columns[column] = colTypeelse:column = safeSQLIdentificatorNaming(column)columns[column] = Noneif columns:if conf.db in kb.data.cachedColumns:kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)] = columnselse:table[safeSQLIdentificatorNaming(tbl, True)] = columnskb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = tableif not kb.data.cachedColumns:warnMsg = "unable to retrieve column names for "warnMsg += ("table '%s' " % unsafeSQLIdentificatorNaming(unArrayizeValue(tblList))) if len(tblList) == 1 else "any table "warnMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)logger.warn(warnMsg)if bruteForce is None:return self.getColumns(onlyColNames=onlyColNames, colTuple=colTuple, bruteForce=True)return kb.data.cachedColumns@stackedmethoddef getSchema(self):infoMsg = "enumerating database management system schema"logger.info(infoMsg)try:pushValue(conf.db)pushValue(conf.tbl)pushValue(conf.col)kb.data.cachedTables = {}kb.data.cachedColumns = {}self.getTables()infoMsg = "fetched tables: "infoMsg += ", ".join(["%s" % ", ".join("%s%s%s" % (unsafeSQLIdentificatorNaming(db), ".." if Backend.isDbms(DBMS.MSSQL) or Backend.isDbms(DBMS.SYBASE) else '.', unsafeSQLIdentificatorNaming(_)) for _ 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 = dbconf.tbl = tblself.getColumns()finally:conf.col = popValue()conf.tbl = popValue()conf.db = popValue()return kb.data.cachedColumnsdef _tableGetCount(self, db, table):if not db or not table:return Noneif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):db = db.upper()table = table.upper()if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):query = "SELECT %s FROM %s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(table, True))else:query = "SELECT %s FROM %s.%s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(table, True))query = agent.whereQuery(query)count = inject.getValue(query, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if isNumPosStrValue(count):if safeSQLIdentificatorNaming(db) not in kb.data.cachedCounts:kb.data.cachedCounts[safeSQLIdentificatorNaming(db)] = {}if int(count) in kb.data.cachedCounts[safeSQLIdentificatorNaming(db)]:kb.data.cachedCounts[safeSQLIdentificatorNaming(db)][int(count)].append(safeSQLIdentificatorNaming(table, True))else:kb.data.cachedCounts[safeSQLIdentificatorNaming(db)][int(count)] = [safeSQLIdentificatorNaming(table, True)]def getCount(self):if not conf.tbl:warnMsg = "missing table parameter, sqlmap will retrieve "warnMsg += "the number of entries for all database "warnMsg += "management system databases' tables"logger.warn(warnMsg)elif "." in conf.tbl:if not conf.db:conf.db, conf.tbl = conf.tbl.split('.', 1)if conf.tbl is not None and conf.db is None and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):warnMsg = "missing database parameter. sqlmap is going to "warnMsg += "use the current database to retrieve the "warnMsg += "number of entries for table '%s'" % unsafeSQLIdentificatorNaming(conf.tbl)logger.warn(warnMsg)conf.db = self.getCurrentDb()self.forceDbmsEnum()if conf.tbl:for table in conf.tbl.split(','):self._tableGetCount(conf.db, table)else:self.getTables()for db, tables in kb.data.cachedTables.items():for table in tables:self._tableGetCount(db, table)return kb.data.cachedCountsdef getStatements(self):infoMsg = "fetching SQL statements"logger.info(infoMsg)rootQuery = queries[Backend.getIdentifiedDbms()].statementsif any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:query = rootQuery.inband.querywhile True:values = inject.getValue(query, blind=False, time=False)if not isNoneValue(values):kb.data.cachedStatements = []for value in arrayizeValue(values):value = (unArrayizeValue(value) or "").strip()if not isNoneValue(value):kb.data.cachedStatements.append(value.strip())elif Backend.isDbms(DBMS.PGSQL) and "current_query" not in query:query = query.replace("query", "current_query")continuebreakif not kb.data.cachedStatements and isInferenceAvailable() and not conf.direct:infoMsg = "fetching number of statements"logger.info(infoMsg)query = rootQuery.blind.countcount = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if count == 0:return kb.data.cachedStatementselif not isNumPosStrValue(count):errMsg = "unable to retrieve the number of statements"raise SqlmapNoneDataException(errMsg)plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2)indexRange = getLimitRange(count, plusOne=plusOne)for index in indexRange:value = Noneif Backend.getIdentifiedDbms() in (DBMS.MYSQL,): # case with multiple processesquery = rootQuery.blind.query3 % indexidentifier = unArrayizeValue(inject.getValue(query, union=False, error=False, expected=EXPECTED.INT))if not isNoneValue(identifier):query = rootQuery.blind.query2 % identifiervalue = unArrayizeValue(inject.getValue(query, union=False, error=False, expected=EXPECTED.INT))if isNoneValue(value):query = rootQuery.blind.query % indexvalue = unArrayizeValue(inject.getValue(query, union=False, error=False))if not isNoneValue(value):kb.data.cachedStatements.append(value)if not kb.data.cachedStatements:errMsg = "unable to retrieve the statements"logger.error(errMsg)else:kb.data.cachedStatements = [_.replace(REFLECTED_VALUE_MARKER, "<payload>") for _ in kb.data.cachedStatements]return kb.data.cachedStatements
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。