@ -5,45 +5,50 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 
			
		
	
		
		
			
				
					
					See  the  file  ' LICENSE '  for  copying  permission See  the  file  ' LICENSE '  for  copying  permission  
			
		
	
		
		
			
				
					
					""" """  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					import  re # 导入必要的模块  
			
				
				
			
		
	
		
		
			
				
					
					
import  re  # 导入正则表达式模块,用于进行模式匹配  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . agent  import  agent 
 
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  arrayizeValue from  lib . core . agent  import  agent  # 导入 agent 模块,用于执行 SQL 注入  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  getLimitRange from  lib . core . common  import  arrayizeValue  # 导入 arrayizeValue 函数,用于将值转换为列表  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  isInferenceAvailable from  lib . core . common  import  getLimitRange  # 导入 getLimitRange 函数,用于生成限制范围  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  isNoneValue from  lib . core . common  import  isInferenceAvailable  # 导入 isInferenceAvailable 函数,用于检查是否可以使用推断注入  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  isNumPosStrValue from  lib . core . common  import  isNoneValue  # 导入 isNoneValue 函数,用于检查值是否为 None  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  isTechniqueAvailable from  lib . core . common  import  isNumPosStrValue  # 导入 isNumPosStrValue 函数,用于检查值是否为正数字字符串  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  safeSQLIdentificatorNaming from  lib . core . common  import  isTechniqueAvailable  # 导入 isTechniqueAvailable 函数,用于检查指定的注入技术是否可用  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  safeStringFormat from  lib . core . common  import  safeSQLIdentificatorNaming  # 导入 safeSQLIdentificatorNaming 函数,用于安全地命名 SQL 标识符  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  singleTimeLogMessage from  lib . core . common  import  safeStringFormat  # 导入 safeStringFormat 函数,用于安全地格式化字符串  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  unArrayizeValue from  lib . core . common  import  singleTimeLogMessage  # 导入 singleTimeLogMessage 函数,用于只输出一次的日志消息  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . common  import  unsafeSQLIdentificatorNaming from  lib . core . common  import  unArrayizeValue  # 导入 unArrayizeValue 函数,用于从列表中提取值  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . compat  import  xrange from  lib . core . common  import  unsafeSQLIdentificatorNaming  # 导入 unsafeSQLIdentificatorNaming 函数,用于不安全地命名 SQL 标识符  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . data  import  conf from  lib . core . compat  import  xrange  # 导入 xrange 函数,用于兼容 Python 2 和 3 的循环  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . data  import  kb from  lib . core . data  import  conf  # 导入 conf 对象,用于访问全局配置信息  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . data  import  logger from  lib . core . data  import  kb  # 导入 kb 对象,用于访问全局知识库  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . data  import  queries from  lib . core . data  import  logger  # 导入 logger 对象,用于输出日志  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . enums  import  CHARSET_TYPE from  lib . core . data  import  queries  # 导入 queries 对象,用于获取预定义的 SQL 查询语句  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . enums  import  DBMS from  lib . core . enums  import  CHARSET_TYPE  # 导入 CHARSET_TYPE 枚举,定义字符集类型  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . enums  import  EXPECTED from  lib . core . enums  import  DBMS  # 导入 DBMS 枚举,定义数据库管理系统类型  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . enums  import  PAYLOAD from  lib . core . enums  import  EXPECTED  # 导入 EXPECTED 枚举,定义期望的返回值类型  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . exception  import  SqlmapNoneDataException from  lib . core . enums  import  PAYLOAD  # 导入 PAYLOAD 枚举,定义注入类型  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . core . settings  import  CURRENT_DB from  lib . core . exception  import  SqlmapNoneDataException  # 导入 SqlmapNoneDataException 异常类,用于表示没有数据  
			
				
				
			
		
	
		
		
			
				
					
					from  lib . request  import  inject from  lib . core . settings  import  CURRENT_DB  # 导入 CURRENT_DB 常量,表示当前数据库  
			
				
				
			
		
	
		
		
			
				
					
					from  plugins . generic . enumeration  import  Enumeration  as  GenericEnumeration from  lib . request  import  inject  # 导入 inject 函数,用于执行 SQL 注入请求  
			
				
				
			
		
	
		
		
			
				
					
					from  thirdparty  import  six from  plugins . generic . enumeration  import  Enumeration  as  GenericEnumeration  # 导入 GenericEnumeration 类,作为当前类的父类  
			
				
				
			
		
	
		
		
			
				
					
					
from  thirdparty  import  six  # 导入 six 模块,用于兼容 Python 2 和 3  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# 定义 Enumeration 类,继承自 GenericEnumeration  
			
		
	
		
		
			
				
					
					class  Enumeration ( GenericEnumeration ) : class  Enumeration ( GenericEnumeration ) :  
			
		
	
		
		
			
				
					
					    # 定义 getPrivileges 方法,用于获取数据库用户的权限 
 
			
		
	
		
		
			
				
					
					    def  getPrivileges ( self ,  * args ,  * * kwargs ) : 
    def  getPrivileges ( self ,  * args ,  * * kwargs ) : 
 
			
		
	
		
		
			
				
					
					        # 输出警告信息,说明在 Microsoft SQL Server 上无法获取用户权限,只会检查是否是 DBA 
 
			
		
	
		
		
			
				
					
					        warnMsg  =  " on Microsoft SQL Server it is not possible to fetch  " 
        warnMsg  =  " on Microsoft SQL Server it is not possible to fetch  " 
 
			
		
	
		
		
			
				
					
					        warnMsg  + =  " database users privileges, sqlmap will check whether  " 
        warnMsg  + =  " database users privileges, sqlmap will check whether  " 
 
			
		
	
		
		
			
				
					
					        warnMsg  + =  " or not the database users are database administrators " 
        warnMsg  + =  " or not the database users are database administrators " 
 
			
		
	
		
		
			
				
					
					        logger . warning ( warnMsg ) 
        logger . warning ( warnMsg ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        users  =  [ ] 
        users  =  [ ]  # 初始化用户列表  
 
			
				
				
			
		
	
		
		
			
				
					
					        areAdmins  =  set ( ) 
        areAdmins  =  set ( )  # 初始化管理员集合  
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果配置中指定了用户,则使用该用户,否则获取所有用户 
 
			
		
	
		
		
			
				
					
					        if  conf . user : 
        if  conf . user : 
 
			
		
	
		
		
			
				
					
					            users  =  [ conf . user ] 
            users  =  [ conf . user ] 
 
			
		
	
		
		
			
				
					
					        elif  not  len ( kb . data . cachedUsers ) : 
        elif  not  len ( kb . data . cachedUsers ) : 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -51,91 +56,114 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					        else : 
        else : 
 
			
		
	
		
		
			
				
					
					            users  =  kb . data . cachedUsers 
            users  =  kb . data . cachedUsers 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 遍历用户列表 
 
			
		
	
		
		
			
				
					
					        for  user  in  users : 
        for  user  in  users : 
 
			
		
	
		
		
			
				
					
					            user  =  unArrayizeValue ( user ) 
            user  =  unArrayizeValue ( user )  # 从列表中提取用户  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            if  user  is  None : 
            if  user  is  None :  # 如果用户为 None,   
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                continue 
                continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            isDba  =  self . isDba ( user ) 
            isDba  =  self . isDba ( user )  # 检查用户是否为 DBA  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            if  isDba  is  True : 
            if  isDba  is  True :  # 如果是 DBA,   
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                areAdmins . add ( user ) 
                areAdmins . add ( user ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            kb . data . cachedUsersPrivileges [ user ]  =  None 
            kb . data . cachedUsersPrivileges [ user ]  =  None  # 设置用户的权限信息为 None  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 返回用户的权限信息和管理员集合 
 
			
		
	
		
		
			
				
					
					        return  ( kb . data . cachedUsersPrivileges ,  areAdmins ) 
        return  ( kb . data . cachedUsersPrivileges ,  areAdmins ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    # 定义 getTables 方法,用于获取数据库表 
 
			
		
	
		
		
			
				
					
					    def  getTables ( self ) : 
    def  getTables ( self ) : 
 
			
		
	
		
		
			
				
					
					        # 如果知识库中已缓存表信息,则直接返回 
 
			
		
	
		
		
			
				
					
					        if  len ( kb . data . cachedTables )  >  0 : 
        if  len ( kb . data . cachedTables )  >  0 : 
 
			
		
	
		
		
			
				
					
					            return  kb . data . cachedTables 
            return  kb . data . cachedTables 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        self . forceDbmsEnum ( ) 
        self . forceDbmsEnum ( )  # 强制执行 DBMS 枚举  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果配置中指定了当前数据库,则获取当前数据库 
 
			
		
	
		
		
			
				
					
					        if  conf . db  ==  CURRENT_DB : 
        if  conf . db  ==  CURRENT_DB : 
 
			
		
	
		
		
			
				
					
					            conf . db  =  self . getCurrentDb ( ) 
            conf . db  =  self . getCurrentDb ( ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果配置中指定了数据库,则分割数据库字符串,否则获取所有数据库 
 
			
		
	
		
		
			
				
					
					        if  conf . db : 
        if  conf . db : 
 
			
		
	
		
		
			
				
					
					            dbs  =  conf . db . split ( ' , ' ) 
            dbs  =  conf . db . split ( ' , ' ) 
 
			
		
	
		
		
			
				
					
					        else : 
        else : 
 
			
		
	
		
		
			
				
					
					            dbs  =  self . getDbs ( ) 
            dbs  =  self . getDbs ( ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 对每个数据库名进行安全命名 
 
			
		
	
		
		
			
				
					
					        for  db  in  dbs : 
        for  db  in  dbs : 
 
			
		
	
		
		
			
				
					
					            dbs [ dbs . index ( db ) ]  =  safeSQLIdentificatorNaming ( db ) 
            dbs [ dbs . index ( db ) ]  =  safeSQLIdentificatorNaming ( db ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 移除空字符串的数据库 
 
			
		
	
		
		
			
				
					
					        dbs  =  [ _  for  _  in  dbs  if  _ ] 
        dbs  =  [ _  for  _  in  dbs  if  _ ] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 输出获取表信息的提示信息 
 
			
		
	
		
		
			
				
					
					        infoMsg  =  " fetching tables for database " 
        infoMsg  =  " fetching tables for database " 
 
			
		
	
		
		
			
				
					
					        infoMsg  + =  " %s :  %s "  %  ( " s "  if  len ( dbs )  >  1  else  " " ,  " ,  " . join ( db  if  isinstance ( db ,  six . string_types )  else  db [ 0 ]  for  db  in  sorted ( dbs ) ) ) 
        infoMsg  + =  " %s :  %s "  %  ( " s "  if  len ( dbs )  >  1  else  " " ,  " ,  " . join ( db  if  isinstance ( db ,  six . string_types )  else  db [ 0 ]  for  db  in  sorted ( dbs ) ) ) 
 
			
		
	
		
		
			
				
					
					        logger . info ( infoMsg ) 
        logger . info ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 获取 SQL Server 的表查询语句 
 
			
		
	
		
		
			
				
					
					        rootQuery  =  queries [ DBMS . MSSQL ] . tables 
        rootQuery  =  queries [ DBMS . MSSQL ] . tables 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 检查是否可以使用 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 : 
 
			
		
	
		
		
			
				
					
					            # 遍历数据库列表 
 
			
		
	
		
		
			
				
					
					            for  db  in  dbs : 
            for  db  in  dbs : 
 
			
		
	
		
		
			
				
					
					                # 如果配置中排除了系统数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " skipping system database  ' %s ' "  %  db 
                    infoMsg  =  " skipping system database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                    singleTimeLogMessage ( infoMsg ) 
                    singleTimeLogMessage ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果配置中指定了排除的数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " skipping database  ' %s ' "  %  db 
                    infoMsg  =  " skipping database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                    singleTimeLogMessage ( infoMsg ) 
                    singleTimeLogMessage ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 尝试使用不同的查询语句获取表信息 
 
			
		
	
		
		
			
				
					
					                for  query  in  ( rootQuery . inband . query ,  rootQuery . inband . query2 ,  rootQuery . inband . query3 ) : 
                for  query  in  ( rootQuery . inband . query ,  rootQuery . inband . query2 ,  rootQuery . inband . query3 ) : 
 
			
		
	
		
		
			
				
					
					                    query  =  query . replace ( " %s " ,  db ) 
                    query  =  query . replace ( " %s " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    value  =  inject . getValue ( query ,  blind = False ,  time = False ) 
                    value  =  inject . getValue ( query ,  blind = False ,  time = False )  # 执行注入并获取结果  
 
			
				
				
			
		
	
		
		
			
				
					
					                    if  not  isNoneValue ( value ) : 
                    if  not  isNoneValue ( value ) :  # 如果结果不为 None,   
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                        break 
                        break 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果获取到了表信息,则进行处理 
 
			
		
	
		
		
			
				
					
					                if  not  isNoneValue ( value ) : 
                if  not  isNoneValue ( value ) : 
 
			
		
	
		
		
			
				
					
					                    value  =  [ _  for  _  in  arrayizeValue ( value )  if  _ ] 
                    value  =  [ _  for  _  in  arrayizeValue ( value )  if  _ ]  # 将结果转换为列表  
 
			
				
				
			
		
	
		
		
			
				
					
					                    value  =  [ safeSQLIdentificatorNaming ( unArrayizeValue ( _ ) ,  True )  for  _  in  value ] 
                    value  =  [ safeSQLIdentificatorNaming ( unArrayizeValue ( _ ) ,  True )  for  _  in  value ]  # 安全命名表名  
 
			
				
				
			
		
	
		
		
			
				
					
					                    kb . data . cachedTables [ db ]  =  value 
                    kb . data . cachedTables [ db ]  =  value  # 将表信息缓存到知识库  
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果没有获取到表信息,并且可以使用推断注入,则使用推断注入获取表信息 
 
			
		
	
		
		
			
				
					
					        if  not  kb . data . cachedTables  and  isInferenceAvailable ( )  and  not  conf . direct : 
        if  not  kb . data . cachedTables  and  isInferenceAvailable ( )  and  not  conf . direct : 
 
			
		
	
		
		
			
				
					
					            # 遍历数据库列表 
 
			
		
	
		
		
			
				
					
					            for  db  in  dbs : 
            for  db  in  dbs : 
 
			
		
	
		
		
			
				
					
					                # 如果配置中排除了系统数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " skipping system database  ' %s ' "  %  db 
                    infoMsg  =  " skipping system database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                    singleTimeLogMessage ( infoMsg ) 
                    singleTimeLogMessage ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果配置中指定了排除的数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " skipping database  ' %s ' "  %  db 
                    infoMsg  =  " skipping database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                    singleTimeLogMessage ( infoMsg ) 
                    singleTimeLogMessage ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 输出获取表数量的提示信息 
 
			
		
	
		
		
			
				
					
					                infoMsg  =  " fetching number of tables for  " 
                infoMsg  =  " fetching number of tables for  " 
 
			
		
	
		
		
			
				
					
					                infoMsg  + =  " database  ' %s ' "  %  db 
                infoMsg  + =  " database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                logger . info ( infoMsg ) 
                logger . info ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 尝试使用不同的查询语句获取表数量 
 
			
		
	
		
		
			
				
					
					                for  query  in  ( rootQuery . blind . count ,  rootQuery . blind . count2 ,  rootQuery . blind . count3 ) : 
                for  query  in  ( rootQuery . blind . count ,  rootQuery . blind . count2 ,  rootQuery . blind . count3 ) : 
 
			
		
	
		
		
			
				
					
					                    _  =  query . replace ( " %s " ,  db ) 
                    _  =  query . replace ( " %s " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    count  =  inject . getValue ( _ ,  union = False ,  error = False ,  expected = EXPECTED . INT ,  charsetType = CHARSET_TYPE . DIGITS ) 
                    count  =  inject . getValue ( _ ,  union = False ,  error = False ,  expected = EXPECTED . INT ,  charsetType = CHARSET_TYPE . DIGITS )  # 执行推断注入并获取结果  
 
			
				
				
			
		
	
		
		
			
				
					
					                    if  not  isNoneValue ( count ) : 
                    if  not  isNoneValue ( count ) :  # 如果结果不为 None,   
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                        break 
                        break 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果没有获取到有效的表数量,则跳过 
 
			
		
	
		
		
			
				
					
					                if  not  isNumPosStrValue ( count ) : 
                if  not  isNumPosStrValue ( count ) : 
 
			
		
	
		
		
			
				
					
					                    if  count  !=  0 : 
                    if  count  !=  0 : 
 
			
		
	
		
		
			
				
					
					                        warnMsg  =  " unable to retrieve the number of  " 
                        warnMsg  =  " unable to retrieve the number of  " 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -143,17 +171,18 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                        logger . warning ( warnMsg ) 
                        logger . warning ( warnMsg ) 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                tables  =  [ ] 
                tables  =  [ ]  # 初始化表列表  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 遍历表索引,获取每个表名 
 
			
		
	
		
		
			
				
					
					                for  index  in  xrange ( int ( count ) ) : 
                for  index  in  xrange ( int ( count ) ) : 
 
			
		
	
		
		
			
				
					
					                    _  =  safeStringFormat ( ( rootQuery . blind . query  if  query  ==  rootQuery . blind . count  else  rootQuery . blind . query2  if  query  ==  rootQuery . blind . count2  else  rootQuery . blind . query3 ) . replace ( " %s " ,  db ) ,  index ) 
                    _  =  safeStringFormat ( ( rootQuery . blind . query  if  query  ==  rootQuery . blind . count  else  rootQuery . blind . query2  if  query  ==  rootQuery . blind . count2  else  rootQuery . blind . query3 ) . replace ( " %s " ,  db ) ,  index ) 
 
			
		
	
		
		
			
				
					
					
                    table  =  inject . getValue ( _ ,  union = False ,  error = False )  # 执行推断注入并获取结果 
 
			
				
				
			
		
	
		
		
			
				
					
					                    table  =  inject . getValue ( _ ,  union = False ,  error = False ) 
                    if  not  isNoneValue ( table ) :  # 如果结果不为 None,  
 
			
				
				
			
		
	
		
		
			
				
					
					                    if  not  isNoneValue ( table ) : 
 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                        kb . hintValue  =  table 
                        kb . hintValue  =  table 
 
			
		
	
		
		
			
				
					
					                        table  =  safeSQLIdentificatorNaming ( table ,  True ) 
                        table  =  safeSQLIdentificatorNaming ( table ,  True )  # 安全命名表名  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                        tables . append ( table ) 
                        tables . append ( table ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果获取到了表信息,则进行缓存,否则输出警告信息 
 
			
		
	
		
		
			
				
					
					                if  tables : 
                if  tables : 
 
			
		
	
		
		
			
				
					
					                    kb . data . cachedTables [ db ]  =  tables 
                    kb . data . cachedTables [ db ]  =  tables 
 
			
		
	
		
		
			
				
					
					                else : 
                else : 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -161,25 +190,31 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                    warnMsg  + =  " for database  ' %s ' "  %  db 
                    warnMsg  + =  " for database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                    logger . warning ( warnMsg ) 
                    logger . warning ( warnMsg ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果没有获取到表信息,并且没有指定搜索,则抛出异常 
 
			
		
	
		
		
			
				
					
					        if  not  kb . data . cachedTables  and  not  conf . search : 
        if  not  kb . data . cachedTables  and  not  conf . search : 
 
			
		
	
		
		
			
				
					
					            errMsg  =  " unable to retrieve the tables for any database " 
            errMsg  =  " unable to retrieve the tables for any database " 
 
			
		
	
		
		
			
				
					
					            raise  SqlmapNoneDataException ( errMsg ) 
            raise  SqlmapNoneDataException ( errMsg ) 
 
			
		
	
		
		
			
				
					
					        else : 
        else : 
 
			
		
	
		
		
			
				
					
					            # 对缓存的表名进行排序 
 
			
		
	
		
		
			
				
					
					            for  db ,  tables  in  kb . data . cachedTables . items ( ) : 
            for  db ,  tables  in  kb . data . cachedTables . items ( ) : 
 
			
		
	
		
		
			
				
					
					                kb . data . cachedTables [ db ]  =  sorted ( tables )  if  tables  else  tables 
                kb . data . cachedTables [ db ]  =  sorted ( tables )  if  tables  else  tables 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 返回缓存的表信息 
 
			
		
	
		
		
			
				
					
					        return  kb . data . cachedTables 
        return  kb . data . cachedTables 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    # 定义 searchTable 方法,用于搜索指定的表 
 
			
		
	
		
		
			
				
					
					    def  searchTable ( self ) : 
    def  searchTable ( self ) : 
 
			
		
	
		
		
			
				
					
					        foundTbls  =  { } 
        foundTbls  =  { }  # 初始化找到的表字典  
 
			
				
				
			
		
	
		
		
			
				
					
					        tblList  =  conf . tbl . split ( ' , ' ) 
        tblList  =  conf . tbl . split ( ' , ' )  # 获取要搜索的表列表  
 
			
				
				
			
		
	
		
		
			
				
					
					        rootQuery  =  queries [ DBMS . MSSQL ] . search_table 
        rootQuery  =  queries [ DBMS . MSSQL ] . search_table  # 获取 SQL Server 的表搜索查询语句  
 
			
				
				
			
		
	
		
		
			
				
					
					        tblCond  =  rootQuery . inband . condition 
        tblCond  =  rootQuery . inband . condition  # 获取表搜索条件  
 
			
				
				
			
		
	
		
		
			
				
					
					        tblConsider ,  tblCondParam  =  self . likeOrExact ( " table " ) 
        tblConsider ,  tblCondParam  =  self . likeOrExact ( " table " )  # 获取表搜索的方式 (LIKE 或 EXACT)  
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果配置中指定了当前数据库,则获取当前数据库 
 
			
		
	
		
		
			
				
					
					        if  conf . db  ==  CURRENT_DB : 
        if  conf . db  ==  CURRENT_DB : 
 
			
		
	
		
		
			
				
					
					            conf . db  =  self . getCurrentDb ( ) 
            conf . db  =  self . getCurrentDb ( ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果配置中指定了数据库,则分割数据库字符串,否则获取所有数据库 
 
			
		
	
		
		
			
				
					
					        if  conf . db : 
        if  conf . db : 
 
			
		
	
		
		
			
				
					
					            enumDbs  =  conf . db . split ( ' , ' ) 
            enumDbs  =  conf . db . split ( ' , ' ) 
 
			
		
	
		
		
			
				
					
					        elif  not  len ( kb . data . cachedDbs ) : 
        elif  not  len ( kb . data . cachedDbs ) : 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -187,40 +222,48 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					        else : 
        else : 
 
			
		
	
		
		
			
				
					
					            enumDbs  =  kb . data . cachedDbs 
            enumDbs  =  kb . data . cachedDbs 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 初始化每个数据库的表搜索结果 
 
			
		
	
		
		
			
				
					
					        for  db  in  enumDbs : 
        for  db  in  enumDbs : 
 
			
		
	
		
		
			
				
					
					            db  =  safeSQLIdentificatorNaming ( db ) 
            db  =  safeSQLIdentificatorNaming ( db ) 
 
			
		
	
		
		
			
				
					
					            foundTbls [ db ]  =  [ ] 
            foundTbls [ db ]  =  [ ] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 遍历要搜索的表列表 
 
			
		
	
		
		
			
				
					
					        for  tbl  in  tblList : 
        for  tbl  in  tblList : 
 
			
		
	
		
		
			
				
					
					            tbl  =  safeSQLIdentificatorNaming ( tbl ,  True ) 
            tbl  =  safeSQLIdentificatorNaming ( tbl ,  True )  # 安全命名表名  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 输出搜索表信息的提示信息 
 
			
		
	
		
		
			
				
					
					            infoMsg  =  " searching table " 
            infoMsg  =  " searching table " 
 
			
		
	
		
		
			
				
					
					            if  tblConsider  ==  " 1 " : 
            if  tblConsider  ==  " 1 " : 
 
			
		
	
		
		
			
				
					
					                infoMsg  + =  " s LIKE " 
                infoMsg  + =  " s LIKE " 
 
			
		
	
		
		
			
				
					
					            infoMsg  + =  "   ' %s ' "  %  unsafeSQLIdentificatorNaming ( tbl ) 
            infoMsg  + =  "   ' %s ' "  %  unsafeSQLIdentificatorNaming ( tbl ) 
 
			
		
	
		
		
			
				
					
					            logger . info ( infoMsg ) 
            logger . info ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 构建表搜索查询条件 
 
			
		
	
		
		
			
				
					
					            tblQuery  =  " %s %s "  %  ( tblCond ,  tblCondParam ) 
            tblQuery  =  " %s %s "  %  ( tblCond ,  tblCondParam ) 
 
			
		
	
		
		
			
				
					
					            tblQuery  =  tblQuery  %  unsafeSQLIdentificatorNaming ( tbl ) 
            tblQuery  =  tblQuery  %  unsafeSQLIdentificatorNaming ( tbl ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 遍历数据库列表 
 
			
		
	
		
		
			
				
					
					            for  db  in  foundTbls . keys ( ) : 
            for  db  in  foundTbls . keys ( ) : 
 
			
		
	
		
		
			
				
					
					                db  =  safeSQLIdentificatorNaming ( db ) 
                db  =  safeSQLIdentificatorNaming ( db )  # 安全命名数据库名  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果配置中排除了系统数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " skipping system database  ' %s ' "  %  db 
                    infoMsg  =  " skipping system database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                    singleTimeLogMessage ( infoMsg ) 
                    singleTimeLogMessage ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果配置中指定了排除的数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " skipping database  ' %s ' "  %  db 
                    infoMsg  =  " skipping database  ' %s ' "  %  db 
 
			
		
	
		
		
			
				
					
					                    singleTimeLogMessage ( infoMsg ) 
                    singleTimeLogMessage ( infoMsg ) 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 检查是否可以使用 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 : 
 
			
		
	
		
		
			
				
					
					                    query  =  rootQuery . inband . query . replace ( " %s " ,  db ) 
                    query  =  rootQuery . inband . query . replace ( " %s " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    query  + =  tblQuery 
                    query  + =  tblQuery 
 
			
		
	
		
		
			
				
					
					                    values  =  inject . getValue ( query ,  blind = False ,  time = False ) 
                    values  =  inject . getValue ( query ,  blind = False ,  time = False )  # 执行注入并获取结果  
 
			
				
				
			
		
	
		
		
			
				
					
					
                     # 如果获取到了表信息,则进行处理   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                    if  not  isNoneValue ( values ) : 
                    if  not  isNoneValue ( values ) : 
 
			
		
	
		
		
			
				
					
					                        if  isinstance ( values ,  six . string_types ) : 
                        if  isinstance ( values ,  six . string_types ) : 
 
			
		
	
		
		
			
				
					
					                            values  =  [ values ] 
                            values  =  [ values ] 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -230,7 +273,9 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                                continue 
                                continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                            foundTbls [ db ] . append ( foundTbl ) 
                            foundTbls [ db ] . append ( foundTbl ) 
 
			
		
	
		
		
			
				
					
					                # 如果无法使用上述注入,则使用推断注入搜索表信息 
 
			
		
	
		
		
			
				
					
					                else : 
                else : 
 
			
		
	
		
		
			
				
					
					                    # 输出获取表数量的提示信息 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " fetching number of table " 
                    infoMsg  =  " fetching number of table " 
 
			
		
	
		
		
			
				
					
					                    if  tblConsider  ==  " 1 " : 
                    if  tblConsider  ==  " 1 " : 
 
			
		
	
		
		
			
				
					
					                        infoMsg  + =  " s LIKE " 
                        infoMsg  + =  " s LIKE " 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -240,8 +285,8 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                    query  =  rootQuery . blind . count 
                    query  =  rootQuery . blind . count 
 
			
		
	
		
		
			
				
					
					                    query  =  query . replace ( " %s " ,  db ) 
                    query  =  query . replace ( " %s " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    query  + =  "  AND  %s "  %  tblQuery 
                    query  + =  "  AND  %s "  %  tblQuery 
 
			
		
	
		
		
			
				
					
					                    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 ) : 
 
			
		
	
		
		
			
				
					
					                        warnMsg  =  " no table " 
                        warnMsg  =  " no table " 
 
			
		
	
		
		
			
				
					
					                        if  tblConsider  ==  " 1 " : 
                        if  tblConsider  ==  " 1 " : 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -252,50 +297,57 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                        continue 
                        continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                    indexRange  =  getLimitRange ( count ) 
                    indexRange  =  getLimitRange ( count )  # 生成索引范围  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                    # 遍历表索引,获取每个表名 
 
			
		
	
		
		
			
				
					
					                    for  index  in  indexRange : 
                    for  index  in  indexRange : 
 
			
		
	
		
		
			
				
					
					                        query  =  rootQuery . blind . query 
                        query  =  rootQuery . blind . query 
 
			
		
	
		
		
			
				
					
					                        query  =  query . replace ( " %s " ,  db ) 
                        query  =  query . replace ( " %s " ,  db ) 
 
			
		
	
		
		
			
				
					
					                        query  + =  "  AND  %s "  %  tblQuery 
                        query  + =  "  AND  %s "  %  tblQuery 
 
			
		
	
		
		
			
				
					
					                        query  =  agent . limitQuery ( index ,  query ,  tblCond ) 
                        query  =  agent . limitQuery ( index ,  query ,  tblCond ) 
 
			
		
	
		
		
			
				
					
					                        tbl  =  inject . getValue ( query ,  union = False ,  error = False ) 
                        tbl  =  inject . getValue ( query ,  union = False ,  error = False )  # 执行推断注入并获取结果  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                        kb . hintValue  =  tbl 
                        kb . hintValue  =  tbl 
 
			
		
	
		
		
			
				
					
					                        foundTbls [ db ] . append ( tbl ) 
                        foundTbls [ db ] . append ( tbl ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 清理空的数据库表列表 
 
			
		
	
		
		
			
				
					
					        for  db ,  tbls  in  list ( foundTbls . items ( ) ) : 
        for  db ,  tbls  in  list ( foundTbls . items ( ) ) : 
 
			
		
	
		
		
			
				
					
					            if  len ( tbls )  ==  0 : 
            if  len ( tbls )  ==  0 : 
 
			
		
	
		
		
			
				
					
					                foundTbls . pop ( db ) 
                foundTbls . pop ( db ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果没有找到任何表,则输出警告信息 
 
			
		
	
		
		
			
				
					
					        if  not  foundTbls : 
        if  not  foundTbls : 
 
			
		
	
		
		
			
				
					
					            warnMsg  =  " no databases contain any of the provided tables " 
            warnMsg  =  " no databases contain any of the provided tables " 
 
			
		
	
		
		
			
				
					
					            logger . warning ( warnMsg ) 
            logger . warning ( warnMsg ) 
 
			
		
	
		
		
			
				
					
					            return 
            return 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        conf . dumper . dbTables ( foundTbls ) 
        conf . dumper . dbTables ( foundTbls )  # 将找到的表信息输出到文件  
 
			
				
				
			
		
	
		
		
			
				
					
					        self . dumpFoundTables ( foundTbls ) 
        self . dumpFoundTables ( foundTbls )  # 输出找到的表信息  
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    # 定义 searchColumn 方法,用于搜索指定的列 
 
			
		
	
		
		
			
				
					
					    def  searchColumn ( self ) : 
    def  searchColumn ( self ) : 
 
			
		
	
		
		
			
				
					
					        rootQuery  =  queries [ DBMS . MSSQL ] . search_column 
        rootQuery  =  queries [ DBMS . MSSQL ] . search_column  # 获取 SQL Server 的列搜索查询语句 
 
			
				
				
			
		
	
		
		
			
				
					
					        foundCols  =  { } 
        foundCols  =  { }  # 初始化找到的列字典 
 
			
				
				
			
		
	
		
		
			
				
					
					        dbs  =  { } 
        dbs  =  { }  # 初始化数据库字典 
 
			
				
				
			
		
	
		
		
			
				
					
					        whereTblsQuery  =  " " 
        whereTblsQuery  =  " "  # 初始化表 WHERE 条件 
 
			
				
				
			
		
	
		
		
			
				
					
					        infoMsgTbl  =  " " 
        infoMsgTbl  =  " "  # 初始化表信息 
 
			
				
				
			
		
	
		
		
			
				
					
					        infoMsgDb  =  " " 
        infoMsgDb  =  " "  # 初始化数据库信息 
 
			
				
				
			
		
	
		
		
			
				
					
					        colList  =  conf . col . split ( ' , ' ) 
        colList  =  conf . col . split ( ' , ' )  # 获取要搜索的列列表 
 
			
				
				
			
		
	
		
		
			
				
					
					
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					        # 如果配置中指定了排除的列,则跳过 
 
			
		
	
		
		
			
				
					
					        if  conf . exclude : 
        if  conf . exclude : 
 
			
		
	
		
		
			
				
					
					            colList  =  [ _  for  _  in  colList  if  re . search ( conf . exclude ,  _ ,  re . I )  is  None ] 
            colList  =  [ _  for  _  in  colList  if  re . search ( conf . exclude ,  _ ,  re . I )  is  None ] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        origTbl  =  conf . tbl 
        origTbl  =  conf . tbl  # 保存原始的表配置  
 
			
				
				
			
		
	
		
		
			
				
					
					        origDb  =  conf . db 
        origDb  =  conf . db  # 保存原始的数据库配置  
 
			
				
				
			
		
	
		
		
			
				
					
					        colCond  =  rootQuery . inband . condition 
        colCond  =  rootQuery . inband . condition  # 获取列搜索条件  
 
			
				
				
			
		
	
		
		
			
				
					
					        tblCond  =  rootQuery . inband . condition2 
        tblCond  =  rootQuery . inband . condition2  # 获取表搜索条件  
 
			
				
				
			
		
	
		
		
			
				
					
					        colConsider ,  colCondParam  =  self . likeOrExact ( " column " ) 
        colConsider ,  colCondParam  =  self . likeOrExact ( " column " )  # 获取列搜索的方式 (LIKE 或 EXACT)  
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果配置中指定了当前数据库,则获取当前数据库 
 
			
		
	
		
		
			
				
					
					        if  conf . db  ==  CURRENT_DB : 
        if  conf . db  ==  CURRENT_DB : 
 
			
		
	
		
		
			
				
					
					            conf . db  =  self . getCurrentDb ( ) 
            conf . db  =  self . getCurrentDb ( ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 如果配置中指定了数据库,则分割数据库字符串,否则获取所有数据库 
 
			
		
	
		
		
			
				
					
					        if  conf . db : 
        if  conf . db : 
 
			
		
	
		
		
			
				
					
					            enumDbs  =  conf . db . split ( ' , ' ) 
            enumDbs  =  conf . db . split ( ' , ' ) 
 
			
		
	
		
		
			
				
					
					        elif  not  len ( kb . data . cachedDbs ) : 
        elif  not  len ( kb . data . cachedDbs ) : 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -303,30 +355,36 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					        else : 
        else : 
 
			
		
	
		
		
			
				
					
					            enumDbs  =  kb . data . cachedDbs 
            enumDbs  =  kb . data . cachedDbs 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 初始化每个数据库的列搜索结果 
 
			
		
	
		
		
			
				
					
					        for  db  in  enumDbs : 
        for  db  in  enumDbs : 
 
			
		
	
		
		
			
				
					
					            db  =  safeSQLIdentificatorNaming ( db ) 
            db  =  safeSQLIdentificatorNaming ( db ) 
 
			
		
	
		
		
			
				
					
					            dbs [ db ]  =  { } 
            dbs [ db ]  =  { } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        # 遍历要搜索的列列表 
 
			
		
	
		
		
			
				
					
					        for  column  in  colList : 
        for  column  in  colList : 
 
			
		
	
		
		
			
				
					
					            column  =  safeSQLIdentificatorNaming ( column ) 
            column  =  safeSQLIdentificatorNaming ( column )  # 安全命名列名  
 
			
				
				
			
		
	
		
		
			
				
					
					            conf . db  =  origDb 
            conf . db  =  origDb  # 恢复原始的数据库配置  
 
			
				
				
			
		
	
		
		
			
				
					
					            conf . tbl  =  origTbl 
            conf . tbl  =  origTbl  # 恢复原始的表配置  
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 输出搜索列信息的提示信息 
 
			
		
	
		
		
			
				
					
					            infoMsg  =  " searching column " 
            infoMsg  =  " searching column " 
 
			
		
	
		
		
			
				
					
					            if  colConsider  ==  " 1 " : 
            if  colConsider  ==  " 1 " : 
 
			
		
	
		
		
			
				
					
					                infoMsg  + =  " s LIKE " 
                infoMsg  + =  " s LIKE " 
 
			
		
	
		
		
			
				
					
					            infoMsg  + =  "   ' %s ' "  %  unsafeSQLIdentificatorNaming ( column ) 
            infoMsg  + =  "   ' %s ' "  %  unsafeSQLIdentificatorNaming ( column ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            foundCols [ column ]  =  { } 
            foundCols [ column ]  =  { }  # 初始化每个列的搜索结果  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 如果配置中指定了表,则构建表的 WHERE 条件 
 
			
		
	
		
		
			
				
					
					            if  conf . tbl : 
            if  conf . tbl : 
 
			
		
	
		
		
			
				
					
					                _  =  conf . tbl . split ( ' , ' ) 
                _  =  conf . tbl . split ( ' , ' ) 
 
			
		
	
		
		
			
				
					
					                whereTblsQuery  =  "  AND ( "  +  "  OR  " . join ( " %s  =  ' %s ' "  %  ( tblCond ,  unsafeSQLIdentificatorNaming ( tbl ) )  for  tbl  in  _ )  +  " ) " 
                whereTblsQuery  =  "  AND ( "  +  "  OR  " . join ( " %s  =  ' %s ' "  %  ( tblCond ,  unsafeSQLIdentificatorNaming ( tbl ) )  for  tbl  in  _ )  +  " ) " 
 
			
		
	
		
		
			
				
					
					                infoMsgTbl  =  "  for table %s   ' %s ' "  %  ( " s "  if  len ( _ )  >  1  else  " " ,  " ,  " . join ( tbl  for  tbl  in  _ ) ) 
                infoMsgTbl  =  "  for table %s   ' %s ' "  %  ( " s "  if  len ( _ )  >  1  else  " " ,  " ,  " . join ( tbl  for  tbl  in  _ ) ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 如果配置中指定了当前数据库,则获取当前数据库 
 
			
		
	
		
		
			
				
					
					            if  conf . db  ==  CURRENT_DB : 
            if  conf . db  ==  CURRENT_DB : 
 
			
		
	
		
		
			
				
					
					                conf . db  =  self . getCurrentDb ( ) 
                conf . db  =  self . getCurrentDb ( ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 如果配置中指定了数据库,则构建数据库信息,否则获取所有数据库 
 
			
		
	
		
		
			
				
					
					            if  conf . db : 
            if  conf . db : 
 
			
		
	
		
		
			
				
					
					                _  =  conf . db . split ( ' , ' ) 
                _  =  conf . db . split ( ' , ' ) 
 
			
		
	
		
		
			
				
					
					                infoMsgDb  =  "  in database %s   ' %s ' "  %  ( " s "  if  len ( _ )  >  1  else  " " ,  " ,  " . join ( db  for  db  in  _ ) ) 
                infoMsgDb  =  "  in database %s   ' %s ' "  %  ( " s "  if  len ( _ )  >  1  else  " " ,  " ,  " . join ( db  for  db  in  _ ) ) 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -337,30 +395,35 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            logger . info ( " %s %s %s "  %  ( infoMsg ,  infoMsgTbl ,  infoMsgDb ) ) 
            logger . info ( " %s %s %s "  %  ( infoMsg ,  infoMsgTbl ,  infoMsgDb ) ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 构建列搜索查询条件 
 
			
		
	
		
		
			
				
					
					            colQuery  =  " %s %s "  %  ( colCond ,  colCondParam ) 
            colQuery  =  " %s %s "  %  ( colCond ,  colCondParam ) 
 
			
		
	
		
		
			
				
					
					            colQuery  =  colQuery  %  unsafeSQLIdentificatorNaming ( column ) 
            colQuery  =  colQuery  %  unsafeSQLIdentificatorNaming ( column ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            # 遍历数据库列表 
 
			
		
	
		
		
			
				
					
					            for  db  in  ( _  for  _  in  dbs  if  _ ) : 
            for  db  in  ( _  for  _  in  dbs  if  _ ) : 
 
			
		
	
		
		
			
				
					
					                db  =  safeSQLIdentificatorNaming ( db ) 
                db  =  safeSQLIdentificatorNaming ( db )  # 安全命名数据库名  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果配置中排除了系统数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
                if  conf . excludeSysDbs  and  db  in  self . excludeDbsList : 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 如果配置中指定了排除的数据库,则跳过 
 
			
		
	
		
		
			
				
					
					                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
                if  conf . exclude  and  re . search ( conf . exclude ,  db ,  re . I )  is  not  None : 
 
			
		
	
		
		
			
				
					
					                    continue 
                    continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                # 检查是否可以使用 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 : 
 
			
		
	
		
		
			
				
					
					                    query  =  rootQuery . inband . query  %  ( db ,  db ,  db ,  db ,  db ,  db ) 
                    query  =  rootQuery . inband . query  %  ( db ,  db ,  db ,  db ,  db ,  db ) 
 
			
		
	
		
		
			
				
					
					                    query  + =  "  AND  %s "  %  colQuery . replace ( " [DB] " ,  db ) 
                    query  + =  "  AND  %s "  %  colQuery . replace ( " [DB] " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    query  + =  whereTblsQuery . replace ( " [DB] " ,  db ) 
                    query  + =  whereTblsQuery . replace ( " [DB] " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    values  =  inject . getValue ( query ,  blind = False ,  time = False ) 
                    values  =  inject . getValue ( query ,  blind = False ,  time = False )  # 执行注入并获取结果  
 
			
				
				
			
		
	
		
		
			
				
					
					
                     # 如果获取到了列信息,则进行处理   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                    if  not  isNoneValue ( values ) : 
                    if  not  isNoneValue ( values ) : 
 
			
		
	
		
		
			
				
					
					                        if  isinstance ( values ,  six . string_types ) : 
                        if  isinstance ( values ,  six . string_types ) : 
 
			
		
	
		
		
			
				
					
					                            values  =  [ values ] 
                            values  =  [ values ] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                        for  foundTbl  in  values : 
                        for  foundTbl  in  values : 
 
			
		
	
		
		
			
				
					
					                            foundTbl  =  safeSQLIdentificatorNaming ( unArrayizeValue ( foundTbl ) ,  True ) 
                            foundTbl  =  safeSQLIdentificatorNaming ( unArrayizeValue ( foundTbl ) ,  True )  # 安全命名表名  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                            if  foundTbl  is  None : 
                            if  foundTbl  is  None : 
 
			
		
	
		
		
			
				
					
					                                continue 
                                continue 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -373,7 +436,7 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                                conf . tbl  =  foundTbl 
                                conf . tbl  =  foundTbl 
 
			
		
	
		
		
			
				
					
					                                conf . col  =  column 
                                conf . col  =  column 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                                self . getColumns ( onlyColNames = True ,  colTuple = ( colConsider ,  colCondParam ) ,  bruteForce = False ) 
                                self . getColumns ( onlyColNames = True ,  colTuple = ( colConsider ,  colCondParam ) ,  bruteForce = False )  # 获取列信息  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                                if  db  in  kb . data . cachedColumns  and  foundTbl  in  kb . data . cachedColumns [ db ]  and  not  isNoneValue ( kb . data . cachedColumns [ db ] [ foundTbl ] ) : 
                                if  db  in  kb . data . cachedColumns  and  foundTbl  in  kb . data . cachedColumns [ db ]  and  not  isNoneValue ( kb . data . cachedColumns [ db ] [ foundTbl ] ) : 
 
			
		
	
		
		
			
				
					
					                                    dbs [ db ] [ foundTbl ] . update ( kb . data . cachedColumns [ db ] [ foundTbl ] ) 
                                    dbs [ db ] [ foundTbl ] . update ( kb . data . cachedColumns [ db ] [ foundTbl ] ) 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -386,9 +449,11 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                                foundCols [ column ] [ db ] . append ( foundTbl ) 
                                foundCols [ column ] [ db ] . append ( foundTbl ) 
 
			
		
	
		
		
			
				
					
					                            else : 
                            else : 
 
			
		
	
		
		
			
				
					
					                                foundCols [ column ] [ db ]  =  [ foundTbl ] 
                                foundCols [ column ] [ db ]  =  [ foundTbl ] 
 
			
		
	
		
		
			
				
					
					                # 如果无法使用上述注入,则使用推断注入搜索列信息 
 
			
		
	
		
		
			
				
					
					                else : 
                else : 
 
			
		
	
		
		
			
				
					
					                    foundCols [ column ] [ db ]  =  [ ] 
                    foundCols [ column ] [ db ]  =  [ ] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                    # 输出获取包含该列的表数量的提示信息 
 
			
		
	
		
		
			
				
					
					                    infoMsg  =  " fetching number of tables containing column " 
                    infoMsg  =  " fetching number of tables containing column " 
 
			
		
	
		
		
			
				
					
					                    if  colConsider  ==  " 1 " : 
                    if  colConsider  ==  " 1 " : 
 
			
		
	
		
		
			
				
					
					                        infoMsg  + =  " s LIKE " 
                        infoMsg  + =  " s LIKE " 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -399,8 +464,9 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                    query  =  query  %  ( db ,  db ,  db ,  db ,  db ,  db ) 
                    query  =  query  %  ( db ,  db ,  db ,  db ,  db ,  db ) 
 
			
		
	
		
		
			
				
					
					                    query  + =  "  AND  %s "  %  colQuery . replace ( " [DB] " ,  db ) 
                    query  + =  "  AND  %s "  %  colQuery . replace ( " [DB] " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    query  + =  whereTblsQuery . replace ( " [DB] " ,  db ) 
                    query  + =  whereTblsQuery . replace ( " [DB] " ,  db ) 
 
			
		
	
		
		
			
				
					
					                    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 ) : 
 
			
		
	
		
		
			
				
					
					                        warnMsg  =  " no tables contain column " 
                        warnMsg  =  " no tables contain column " 
 
			
		
	
		
		
			
				
					
					                        if  colConsider  ==  " 1 " : 
                        if  colConsider  ==  " 1 " : 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -411,18 +477,19 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                        continue 
                        continue 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                    indexRange  =  getLimitRange ( count ) 
                    indexRange  =  getLimitRange ( count )  # 生成索引范围  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                    # 遍历表索引,获取每个表名 
 
			
		
	
		
		
			
				
					
					                    for  index  in  indexRange : 
                    for  index  in  indexRange : 
 
			
		
	
		
		
			
				
					
					                        query  =  rootQuery . blind . query 
                        query  =  rootQuery . blind . query 
 
			
		
	
		
		
			
				
					
					                        query  =  query  %  ( db ,  db ,  db ,  db ,  db ,  db ) 
                        query  =  query  %  ( db ,  db ,  db ,  db ,  db ,  db ) 
 
			
		
	
		
		
			
				
					
					                        query  + =  "  AND  %s "  %  colQuery . replace ( " [DB] " ,  db ) 
                        query  + =  "  AND  %s "  %  colQuery . replace ( " [DB] " ,  db ) 
 
			
		
	
		
		
			
				
					
					                        query  + =  whereTblsQuery . replace ( " [DB] " ,  db ) 
                        query  + =  whereTblsQuery . replace ( " [DB] " ,  db ) 
 
			
		
	
		
		
			
				
					
					                        query  =  agent . limitQuery ( index ,  query ,  colCond . replace ( " [DB] " ,  db ) ) 
                        query  =  agent . limitQuery ( index ,  query ,  colCond . replace ( " [DB] " ,  db ) ) 
 
			
		
	
		
		
			
				
					
					                        tbl  =  inject . getValue ( query ,  union = False ,  error = False ) 
                        tbl  =  inject . getValue ( query ,  union = False ,  error = False )  # 执行推断注入并获取结果  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                        kb . hintValue  =  tbl 
                        kb . hintValue  =  tbl 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                        tbl  =  safeSQLIdentificatorNaming ( tbl ,  True ) 
                        tbl  =  safeSQLIdentificatorNaming ( tbl ,  True )  # 安全命名表名  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                        if  tbl  not  in  dbs [ db ] : 
                        if  tbl  not  in  dbs [ db ] : 
 
			
		
	
		
		
			
				
					
					                            dbs [ db ] [ tbl ]  =  { } 
                            dbs [ db ] [ tbl ]  =  { } 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -432,7 +499,7 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                            conf . tbl  =  tbl 
                            conf . tbl  =  tbl 
 
			
		
	
		
		
			
				
					
					                            conf . col  =  column 
                            conf . col  =  column 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                            self . getColumns ( onlyColNames = True ,  colTuple = ( colConsider ,  colCondParam ) ,  bruteForce = False ) 
                            self . getColumns ( onlyColNames = True ,  colTuple = ( colConsider ,  colCondParam ) ,  bruteForce = False )  # 获取列信息  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                            if  db  in  kb . data . cachedColumns  and  tbl  in  kb . data . cachedColumns [ db ] : 
                            if  db  in  kb . data . cachedColumns  and  tbl  in  kb . data . cachedColumns [ db ] : 
 
			
		
	
		
		
			
				
					
					                                dbs [ db ] [ tbl ] . update ( kb . data . cachedColumns [ db ] [ tbl ] ) 
                                dbs [ db ] [ tbl ] . update ( kb . data . cachedColumns [ db ] [ tbl ] ) 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -440,7 +507,7 @@ class Enumeration(GenericEnumeration):
 
			
		
	
		
		
			
				
					
					                        else : 
                        else : 
 
			
		
	
		
		
			
				
					
					                            dbs [ db ] [ tbl ] [ column ]  =  None 
                            dbs [ db ] [ tbl ] [ column ]  =  None 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                        foundCols [ column ] [ db ] . append ( tbl ) 
                        foundCols [ column ] [ db ] . append ( tbl )  # 将找到的表添加到结果中  
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        conf . dumper . dbColumns ( foundCols ,  colConsider ,  dbs ) 
        conf . dumper . dbColumns ( foundCols ,  colConsider ,  dbs )  # 将找到的列信息输出到文件  
 
			
				
				
			
		
	
		
		
			
				
					
					        self . dumpFoundColumn ( dbs ,  foundCols ,  colConsider ) 
        self . dumpFoundColumn ( dbs ,  foundCols ,  colConsider )  # 输出找到的列信息