diff --git a/src/sqlmap-master/plugins/generic/users.py b/src/sqlmap-master/plugins/generic/users.py index 27bed7e..26cd185 100644 --- a/src/sqlmap-master/plugins/generic/users.py +++ b/src/sqlmap-master/plugins/generic/users.py @@ -52,69 +52,100 @@ from thirdparty.six.moves import zip as _zip class Users(object): """ This class defines users' enumeration functionalities for plugins. + 这个类定义了插件的用户枚举功能。 """ def __init__(self): - kb.data.currentUser = "" - kb.data.isDba = None - kb.data.cachedUsers = [] - kb.data.cachedUsersPasswords = {} - kb.data.cachedUsersPrivileges = {} - kb.data.cachedUsersRoles = {} + # 初始化用户相关的数据存储 + kb.data.currentUser = "" # 当前用户 + kb.data.isDba = None # 是否是DBA + kb.data.cachedUsers = [] # 缓存的用户列表 + kb.data.cachedUsersPasswords = {} # 缓存的用户密码哈希 + kb.data.cachedUsersPrivileges = {} # 缓存的用户权限 + kb.data.cachedUsersRoles = {} # 缓存的用户角色 def getCurrentUser(self): + """ + Retrieves the current database user. + 获取当前数据库用户 + """ infoMsg = "fetching current user" logger.info(infoMsg) + # 获取当前用户的SQL查询语句 query = queries[Backend.getIdentifiedDbms()].current_user.query + # 如果当前用户没有被获取过,则进行获取 if not kb.data.currentUser: kb.data.currentUser = unArrayizeValue(inject.getValue(query)) return kb.data.currentUser def isDba(self, user=None): + """ + Tests if the current or specified user is a DBA. + 测试当前或指定用户是否是DBA(数据库管理员)。 + + Args: + user (str, optional): 要测试的用户,默认为None,表示测试当前用户 + + Returns: + bool: 是否是DBA + """ infoMsg = "testing if current user is DBA" logger.info(infoMsg) query = None + # 根据不同的数据库类型,构造不同的SQL查询语句 if Backend.isDbms(DBMS.MYSQL): - self.getCurrentUser() + self.getCurrentUser() # 先获取当前用户 if Backend.isDbms(DBMS.MYSQL) and Backend.isFork(FORK.DRIZZLE): - kb.data.isDba = "root" in (kb.data.currentUser or "") + kb.data.isDba = "root" in (kb.data.currentUser or "") # Drizzle数据库,通过用户名判断是否为root用户 elif kb.data.currentUser: - query = queries[Backend.getIdentifiedDbms()].is_dba.query % kb.data.currentUser.split("@")[0] + query = queries[Backend.getIdentifiedDbms()].is_dba.query % kb.data.currentUser.split("@")[0] # 构建查询语句,判断是否为MySQL的DBA elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and user is not None: - query = queries[Backend.getIdentifiedDbms()].is_dba.query2 % user + query = queries[Backend.getIdentifiedDbms()].is_dba.query2 % user # 构建查询语句,判断是否为SQL Server或Sybase的DBA else: - query = queries[Backend.getIdentifiedDbms()].is_dba.query + query = queries[Backend.getIdentifiedDbms()].is_dba.query # 构建查询语句,判断是否为其他数据库的DBA + # 执行查询 if query: - query = agent.forgeCaseStatement(query) - kb.data.isDba = inject.checkBooleanExpression(query) or False + query = agent.forgeCaseStatement(query) # 注入时,构造Case语句 + kb.data.isDba = inject.checkBooleanExpression(query) or False # 执行查询,并判断是否为DBA return kb.data.isDba def getUsers(self): + """ + Retrieves database users. + 获取数据库用户。 + + Returns: + list: 用户列表 + """ infoMsg = "fetching database users" logger.info(infoMsg) + # 获取查询用户表的SQL查询语句 rootQuery = queries[Backend.getIdentifiedDbms()].users + # 判断是否需要使用不同的查询语句 condition = (Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008"))) condition |= (Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema) + # 优先使用union, error, query技术进行查询,否则使用盲注技术 if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct: if Backend.isDbms(DBMS.MYSQL) and Backend.isFork(FORK.DRIZZLE): - query = rootQuery.inband.query3 + query = rootQuery.inband.query3 # Drizzle数据库的查询语句 elif condition: - query = rootQuery.inband.query2 + query = rootQuery.inband.query2 # 条件判断下的查询语句 else: - query = rootQuery.inband.query + query = rootQuery.inband.query # 通用查询语句 - values = inject.getValue(query, blind=False, time=False) + values = inject.getValue(query, blind=False, time=False) # 执行查询语句,获取用户列表 + # 处理返回的用户列表 if not isNoneValue(values): kb.data.cachedUsers = [] for value in arrayizeValue(values): @@ -122,18 +153,19 @@ class Users(object): if not isNoneValue(value): kb.data.cachedUsers.append(value) + # 如果没有使用union, error, query技术获取到用户,则使用盲注技术进行获取 if not kb.data.cachedUsers and isInferenceAvailable() and not conf.direct: infoMsg = "fetching number of database users" logger.info(infoMsg) if Backend.isDbms(DBMS.MYSQL) and Backend.isFork(FORK.DRIZZLE): - query = rootQuery.blind.count3 + query = rootQuery.blind.count3 # Drizzle数据库的查询语句 elif condition: - query = rootQuery.blind.count2 + query = rootQuery.blind.count2 # 条件判断下的查询语句 else: - query = rootQuery.blind.count + query = rootQuery.blind.count # 通用查询语句 - count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) + count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) # 获取用户数量 if count == 0: return kb.data.cachedUsers @@ -142,8 +174,9 @@ class Users(object): raise SqlmapNoneDataException(errMsg) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES - indexRange = getLimitRange(count, plusOne=plusOne) + 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 " ") @@ -166,8 +199,16 @@ class Users(object): return kb.data.cachedUsers def getPasswordHashes(self): + """ + Retrieves password hashes of database users. + 获取数据库用户的密码哈希值。 + + Returns: + dict: 用户名和密码哈希的字典 + """ infoMsg = "fetching database users password hashes" + # 获取查询密码哈希的SQL查询语句 rootQuery = queries[Backend.getIdentifiedDbms()].passwords if conf.user == CURRENT_USER: @@ -177,7 +218,7 @@ class Users(object): logger.info(infoMsg) if conf.user and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2): - conf.user = conf.user.upper() + conf.user = conf.user.upper() # Oracle和DB2数据库的用户名为大写 if conf.user: users = conf.user.split(',') @@ -187,28 +228,31 @@ class Users(object): parsedUser = re.search(r"['\"]?(.*?)['\"]?\@", user) if parsedUser: - users[users.index(user)] = parsedUser.groups()[0] + users[users.index(user)] = parsedUser.groups()[0] # 处理MySQL的用户名格式,去掉引号和@后面的部分 else: users = [] users = [_ for _ in users if _] + # 优先使用union, error, query技术进行查询,否则使用盲注技术 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.query2 + query = rootQuery.inband.query2 # SQL Server 2005和2008的查询语句 else: - query = rootQuery.inband.query + query = rootQuery.inband.query # 通用查询语句 - condition = rootQuery.inband.condition + condition = rootQuery.inband.condition # 查询条件 + # 如果指定了用户,则加入查询条件 if conf.user: query += " WHERE " query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users)) + # 处理Sybase数据库的特殊情况 if Backend.isDbms(DBMS.SYBASE): getCurrentThreadData().disableStdOut = True - retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=False) + retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=False) # 使用pivotDumpTable函数获取用户名和密码哈希 if retVal: for user, password in filterPairValues(_zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])): @@ -219,13 +263,14 @@ class Users(object): getCurrentThreadData().disableStdOut = False else: - values = inject.getValue(query, blind=False, time=False) + 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) + values = inject.getValue(query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr"), blind=False, time=False) # SQL Server的特殊情况,替换函数 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) + values = inject.getValue(query.replace("authentication_string", "password"), blind=False, time=False) # MySQL的特殊情况,替换字段 + # 处理返回的用户名和密码哈希 for user, password in filterPairValues(values): if not user or user == " ": continue @@ -237,19 +282,21 @@ class Users(object): else: kb.data.cachedUsersPasswords[user].append(password) + # 如果没有使用union, error, query技术获取到密码哈希,则使用盲注技术进行获取 if not kb.data.cachedUsersPasswords and isInferenceAvailable() and not conf.direct: fallback = False if not len(users): - users = self.getUsers() + 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] + users[users.index(user)] = parsedUser.groups()[0] # 处理MySQL的用户名格式,去掉引号和@后面的部分 + # 处理Sybase数据库的特殊情况 if Backend.isDbms(DBMS.SYBASE): getCurrentThreadData().disableStdOut = True @@ -268,8 +315,9 @@ class Users(object): getCurrentThreadData().disableStdOut = False else: - retrievedUsers = set() + retrievedUsers = set() # 已获取密码哈希的用户 + # 循环盲注查询密码哈希 for user in users: user = unArrayizeValue(user) @@ -277,26 +325,26 @@ class Users(object): continue if Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO): - count = 1 + count = 1 # Informix和Virtuoso数据库的特殊情况,直接查询密码哈希 else: infoMsg = "fetching number of password hashes " infoMsg += "for user '%s'" % user logger.info(infoMsg) if Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")): - query = rootQuery.blind.count2 % user + query = rootQuery.blind.count2 % user # SQL Server 2005和2008的查询语句 else: - query = rootQuery.blind.count % user + query = rootQuery.blind.count % user # 通用查询语句 - count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) + count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) # 获取密码哈希数量 if not isNumPosStrValue(count): if Backend.isDbms(DBMS.MSSQL): fallback = True - count = inject.getValue(query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr"), union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) + count = inject.getValue(query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr"), union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) # SQL Server的特殊情况,替换函数 elif Backend.isDbms(DBMS.MYSQL): fallback = True - count = inject.getValue(query.replace("authentication_string", "password"), union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) + count = inject.getValue(query.replace("authentication_string", "password"), union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) # MySQL的特殊情况,替换字段 if not isNumPosStrValue(count): warnMsg = "unable to retrieve the number of password " @@ -310,33 +358,34 @@ class Users(object): passwords = [] plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES - indexRange = getLimitRange(count, plusOne=plusOne) + 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) + query = rootQuery.blind.query2 % (user, index, user) # SQL Server 2005和2008的查询语句 else: - query = rootQuery.blind.query % (user, index, user) + query = rootQuery.blind.query % (user, index, user) # 通用查询语句 if fallback: - query = query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr") + query = query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr") # SQL Server的特殊情况,替换函数 elif Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO): - query = rootQuery.blind.query % (user,) + query = rootQuery.blind.query % (user,) # Informix和Virtuoso数据库的特殊情况 elif Backend.isDbms(DBMS.HSQLDB): - query = rootQuery.blind.query % (index, user) + query = rootQuery.blind.query % (index, user) # HSQLDB数据库的特殊情况 else: - query = rootQuery.blind.query % (user, index) + query = rootQuery.blind.query % (user, index) # 通用查询语句 if Backend.isDbms(DBMS.MYSQL): if fallback: - query = query.replace("authentication_string", "password") + query = query.replace("authentication_string", "password") # MySQL的特殊情况,替换字段 password = unArrayizeValue(inject.getValue(query, union=False, error=False)) - password = parsePasswordHash(password) + password = parsePasswordHash(password) # 解析密码哈希 passwords.append(password) @@ -355,26 +404,37 @@ class Users(object): logger.error(errMsg) else: for user in kb.data.cachedUsersPasswords: - kb.data.cachedUsersPasswords[user] = list(set(kb.data.cachedUsersPasswords[user])) + kb.data.cachedUsersPasswords[user] = list(set(kb.data.cachedUsersPasswords[user])) # 去重密码哈希 - storeHashesToFile(kb.data.cachedUsersPasswords) + 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() + choice = readInput(message, default='Y').upper() # 提示是否进行字典攻击 if choice == 'N': pass elif choice == 'Q': raise SqlmapUserQuitException else: - attackCachedUsersPasswords() + attackCachedUsersPasswords() # 进行字典攻击 return kb.data.cachedUsersPasswords def getPrivileges(self, query2=False): + """ + Retrieves privileges of database users. + 获取数据库用户的权限 + + Args: + query2 (bool, optional): 是否使用第二种查询方式,默认为False + + Returns: + tuple: 用户名和权限的字典,以及DBA用户的集合 + """ infoMsg = "fetching database users privileges" + # 获取查询权限的SQL查询语句 rootQuery = queries[Backend.getIdentifiedDbms()].privileges if conf.user == CURRENT_USER: @@ -401,36 +461,38 @@ class Users(object): users = [_ for _ in users if _] # Set containing the list of DBMS administrators - areAdmins = set() + areAdmins = set() # 存储DBA用户的集合 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.query2 - condition = rootQuery.inband.condition2 + query = rootQuery.inband.query2 # MySQL 5.0以下版本的查询语句 + condition = rootQuery.inband.condition2 # MySQL 5.0以下版本的查询条件 elif Backend.isDbms(DBMS.ORACLE) and query2: - query = rootQuery.inband.query2 - condition = rootQuery.inband.condition2 + query = rootQuery.inband.query2 # Oracle的第二种查询方式 + condition = rootQuery.inband.condition2 # Oracle的第二种查询条件 else: - query = rootQuery.inband.query - condition = rootQuery.inband.condition + query = rootQuery.inband.query # 通用查询语句 + condition = rootQuery.inband.condition # 通用查询条件 + # 如果指定了用户,则加入查询条件 if 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)) + query += " OR ".join("%s LIKE '%%%s%%'" % (condition, user) for user in sorted(users)) # MySQL 5.0以上版本的查询条件 else: - query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users)) + query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users)) # 通用查询条件 - values = inject.getValue(query, blind=False, time=False) + 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) + return self.getPrivileges(query2=True) # 如果没有获取到权限信息,尝试使用第二种查询方式 if not isNoneValue(values): + # 处理返回的权限信息 for value in values: user = None privileges = set() @@ -438,7 +500,7 @@ class Users(object): for count in xrange(0, len(value or [])): # The first column is always the username if count == 0: - user = value[count] + user = value[count] # 获取用户名 # The other columns are the privileges else: @@ -451,23 +513,23 @@ class Users(object): # True, 0 otherwise if Backend.isDbms(DBMS.PGSQL) and getUnicode(privilege).isdigit(): if int(privilege) == 1 and count in PGSQL_PRIVS: - privileges.add(PGSQL_PRIVS[count]) + privileges.add(PGSQL_PRIVS[count]) # PostgreSQL的权限处理 # In MySQL >= 5.0 and Oracle we get the list # of privileges as string elif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema) or Backend.getIdentifiedDbms() in (DBMS.VERTICA, DBMS.MIMERSQL, DBMS.CUBRID): - privileges.add(privilege) + privileges.add(privilege) # MySQL 5.0以上版本和Oracle的权限处理 # In MySQL < 5.0 we get Y if the privilege is # True, N otherwise elif Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema: if privilege.upper() == 'Y': - privileges.add(MYSQL_PRIVS[count]) + privileges.add(MYSQL_PRIVS[count]) # MySQL 5.0以下版本的权限处理 # In Firebird we get one letter for each privilege elif Backend.isDbms(DBMS.FIREBIRD): if privilege.strip() in FIREBIRD_PRIVS: - privileges.add(FIREBIRD_PRIVS[privilege.strip()]) + privileges.add(FIREBIRD_PRIVS[privilege.strip()]) # Firebird的权限处理 # In DB2 we get Y or G if the privilege is # True, N otherwise @@ -487,21 +549,21 @@ class Users(object): i += 1 - privileges.add(privilege) + privileges.add(privilege) # DB2的权限处理 if user in kb.data.cachedUsersPrivileges: - kb.data.cachedUsersPrivileges[user] = list(privileges.union(kb.data.cachedUsersPrivileges[user])) + 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" + conditionChar = "LIKE" # MySQL 5.0以上版本的模糊查询 else: - conditionChar = "=" + conditionChar = "=" # 通用查询 if not len(users): - users = self.getUsers() + users = self.getUsers() # 获取用户列表 if Backend.isDbms(DBMS.MYSQL): for user in users: @@ -510,33 +572,34 @@ class Users(object): if parsedUser: users[users.index(user)] = parsedUser.groups()[0] - retrievedUsers = set() + retrievedUsers = set() # 已获取权限的用户 + # 循环盲注查询权限 for user in users: outuser = user if user in retrievedUsers: continue if Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema: - user = "%%%s%%" % user + user = "%%%s%%" % user # MySQL 5.0以上版本的模糊查询 if Backend.isDbms(DBMS.INFORMIX): - count = 1 + count = 1 # Informix数据库的特殊情况,直接查询权限 else: infoMsg = "fetching number of privileges " infoMsg += "for user '%s'" % outuser logger.info(infoMsg) if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema: - query = rootQuery.blind.count2 % user + query = rootQuery.blind.count2 % user # MySQL 5.0以下版本的查询语句 elif Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema: - query = rootQuery.blind.count % (conditionChar, user) + query = rootQuery.blind.count % (conditionChar, user) # MySQL 5.0以上版本的查询语句 elif Backend.isDbms(DBMS.ORACLE) and query2: - query = rootQuery.blind.count2 % user + query = rootQuery.blind.count2 % user # Oracle的第二种查询方式 else: - query = rootQuery.blind.count % user + query = rootQuery.blind.count % user # 通用查询语句 - count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) + count = 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: @@ -556,21 +619,22 @@ class Users(object): privileges = set() plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES - indexRange = getLimitRange(count, plusOne=plusOne) + 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) + query = rootQuery.blind.query2 % (user, index) # MySQL 5.0以下版本的查询语句 elif Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema: - query = rootQuery.blind.query % (conditionChar, user, index) + query = rootQuery.blind.query % (conditionChar, user, index) # MySQL 5.0以上版本的查询语句 elif Backend.isDbms(DBMS.ORACLE) and query2: - query = rootQuery.blind.query2 % (user, index) + query = rootQuery.blind.query2 % (user, index) # Oracle的第二种查询方式 elif Backend.isDbms(DBMS.FIREBIRD): - query = rootQuery.blind.query % (index, user) + query = rootQuery.blind.query % (index, user) # Firebird数据库的查询语句 elif Backend.isDbms(DBMS.INFORMIX): - query = rootQuery.blind.query % (user,) + query = rootQuery.blind.query % (user,) # Informix数据库的查询语句 else: - query = rootQuery.blind.query % (user, index) + query = rootQuery.blind.query % (user, index) # 通用查询语句 privilege = unArrayizeValue(inject.getValue(query, union=False, error=False)) @@ -586,14 +650,14 @@ class Users(object): for priv in privs: if priv.isdigit() and int(priv) == 1 and i in PGSQL_PRIVS: - privileges.add(PGSQL_PRIVS[i]) + privileges.add(PGSQL_PRIVS[i]) # PostgreSQL的权限处理 i += 1 # In MySQL >= 5.0 and Oracle we get the list # of privileges as string elif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema) or Backend.getIdentifiedDbms() in (DBMS.VERTICA, DBMS.MIMERSQL, DBMS.CUBRID): - privileges.add(privilege) + privileges.add(privilege) # MySQL 5.0以上版本和Oracle的权限处理 # In MySQL < 5.0 we get Y if the privilege is # True, N otherwise @@ -606,19 +670,19 @@ class Users(object): if priv.upper() == 'Y': for position, mysqlPriv in MYSQL_PRIVS.items(): if position == i: - privileges.add(mysqlPriv) + privileges.add(mysqlPriv) # MySQL 5.0以下版本的权限处理 i += 1 # In Firebird we get one letter for each privilege elif Backend.isDbms(DBMS.FIREBIRD): if privilege.strip() in FIREBIRD_PRIVS: - privileges.add(FIREBIRD_PRIVS[privilege.strip()]) + privileges.add(FIREBIRD_PRIVS[privilege.strip()]) # Firebird的权限处理 # In Informix we get one letter for the highest privilege elif Backend.isDbms(DBMS.INFORMIX): if privilege.strip() in INFORMIX_PRIVS: - privileges.add(INFORMIX_PRIVS[privilege.strip()]) + privileges.add(INFORMIX_PRIVS[privilege.strip()]) # Informix的权限处理 # In DB2 we get Y or G if the privilege is # True, N otherwise @@ -633,7 +697,7 @@ class Users(object): if priv.upper() in ('Y', 'G'): for position, db2Priv in DB2_PRIVS.items(): if position == i: - privilege += ", " + db2Priv + privilege += ", " + db2Priv # DB2的权限处理 i += 1 @@ -661,13 +725,6 @@ class Users(object): 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.warning(warnMsg) + areAdmins.add(user) # 判断是否为DBA - return self.getPrivileges(query2) + return (kb.data.cachedUsersPrivileges) \ No newline at end of file