@ -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 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        # 根据不同的数据库类型,  
 
			
		
	
		
			
				
					        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数据库,   
 
			
		
	
		
			
				
					            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 ]  # 构建查询语句,   
 
			
		
	
		
			
				
					        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  # 构建查询语句,   
 
			
		
	
		
			
				
					        else : 
 
			
		
	
		
			
				
					            query  =  queries [ Backend . getIdentifiedDbms ( ) ] . is_dba . query 
 
			
		
	
		
			
				
					            query  =  queries [ Backend . getIdentifiedDbms ( ) ] . is_dba . query   # 构建查询语句,   
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        # 执行查询 
 
			
		
	
		
			
				
					        if  query : 
 
			
		
	
		
			
				
					            query  =  agent . forgeCaseStatement ( query ) 
 
			
		
	
		
			
				
					            kb . data . isDba  =  inject . checkBooleanExpression ( query )  or  False 
 
			
		
	
		
			
				
					            query  =  agent . forgeCaseStatement ( query )  # 注入时,   
 
			
		
	
		
			
				
					            kb . data . isDba  =  inject . checkBooleanExpression ( query )  or  False  # 执行查询,   
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        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 )