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